internal override void EmitUnset(CodeGenerator codeGenerator) { //Template: "unset(x)" x = null Debug.Assert(access == AccessType.Read); // Cases 1, 4, 5, 6, 9 never reached Debug.Assert(codeGenerator.ChainBuilder.IsMember == false); // Case 3 never reached Debug.Assert(codeGenerator.ChainBuilder.IsArrayItem == false); codeGenerator.ChainBuilder.QuietRead = true; // 2, 7, 8 if (this.isMemberOf != null) { // 2: $b->a // 8: b[]->a codeGenerator.ChainBuilder.Create(); codeGenerator.ChainBuilder.Begin(); codeGenerator.ChainBuilder.QuietRead = true; EmitUnsetField(codeGenerator); codeGenerator.ChainBuilder.End(); return; } // 7: $a // Check if the variable is auto-global ILEmitter il = codeGenerator.IL; if (codeGenerator.VariableIsAutoGlobal(varName)) { codeGenerator.EmitAutoGlobalStorePrepare(varName); il.Emit(OpCodes.Ldnull); codeGenerator.EmitAutoGlobalStoreAssign(); return; } // Unset this variable if (codeGenerator.OptimizedLocals) { // Template: // unset(x) x = null // unset(p) p.value = null <- this case isn't valid. When p is reference just create a new PhpReference VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName]; if (entry.IsPhpReference) { il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void); entry.Variable.EmitStore(il); } else { il.Emit(OpCodes.Ldnull); entry.Variable.EmitStore(il); } } else { // CALL Operators.UnsetVariable(<script context>, <local variable table>, <variable name>); codeGenerator.EmitLoadScriptContext(); codeGenerator.EmitLoadRTVariablesTable(); EmitName(codeGenerator); il.Emit(OpCodes.Call, Methods.Operators.UnsetVariable); } }
internal override void EmitStoreAssign(CodeGenerator codeGenerator) { ILEmitter il = codeGenerator.IL; if (varName.IsThisVariableName) { // emit error throwing code il.Emit(OpCodes.Pop); codeGenerator.EmitPhpException(Methods.PhpException.CannotReassignThis); } else if (codeGenerator.VariableIsAutoGlobal(varName)) { // Check if the variable is auto-global codeGenerator.EmitAutoGlobalStoreAssign(); } else if (codeGenerator.OptimizedLocals) { // Template: // "WRITE($x,value);" // **** // if specified variable is of type PhpReference // ldloc local // **** // Otherwise do nothing VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName]; if (entry.IsPhpReference) il.Emit(OpCodes.Stfld, Fields.PhpReference_Value); else entry.Variable.EmitStore(il); } else { // CALL Operators.SetVariable(STACK:table,STACK:name,STACK:value); il.Emit(OpCodes.Call, Methods.Operators.SetVariable); } }