/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator) { Debug.Assert(access == AccessType.None || access == AccessType.Read || access == AccessType.ReadRef || access == AccessType.ReadUnknown); Statistics.AST.AddNode("Assign.Ref"); //ChainBuilder.RefErrorLabelInfo labelInfo; ILEmitter il = codeGenerator.IL; // Strict Standards: Only variables should be assigned by reference /*if (rvalue is FunctionCall)//TODO: only variables (but also variables given by function call return value!) * { * il.LdcI4( (int)PhpError.Strict ); * il.Emit(OpCodes.Ldstr, CoreResources.GetString("only_vars_assign ed_by_ref")); * codeGenerator.EmitPhpException(il,Methods.PhpException.Throw); * }*/ // PREPARE: codeGenerator.ChainBuilder.Create(); lvalue.Emit(codeGenerator); // LOAD <right hand side>: codeGenerator.ChainBuilder.Create(); rvalue.Emit(codeGenerator); codeGenerator.ChainBuilder.End(); PhpTypeCode result; // Dup source value if assignment is read switch (access) { case AccessType.Read: case AccessType.ReadUnknown: case AccessType.ReadRef: { // DUP il.Emit(OpCodes.Dup); // STORE tmp il.Stloc(il.GetAssignmentLocalRef()); // STORE prepared,result lvalue.EmitAssign(codeGenerator); // LOAD DEREF tmp il.Ldloc(il.GetAssignmentLocalRef()); if (access == AccessType.Read) { il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value); result = PhpTypeCode.Object; } else { result = PhpTypeCode.PhpReference; } break; } case AccessType.None: lvalue.EmitAssign(codeGenerator); result = PhpTypeCode.Void; break; default: Debug.Fail(); result = PhpTypeCode.Invalid; break; } codeGenerator.ChainBuilder.End(); return(result); }