private void EmitNodeWriteAssign(IndirectVarUse node, CodeGenerator codeGenerator) { ChainBuilder chain = codeGenerator.ChainBuilder; // Note that for cases 1,3,4,5,6,9 EmitAssign is never called!!! // 2,7,8 if (chain.IsMember) { // 2,8 if (chain.Exists) { // 8: b[]->$a chain.EmitSetObjectField(); } else { // 2: $b->a Debug.Assert(node.IsMemberOf is SimpleVarUse || node.IsMemberOf is FunctionCall); if (node.IsMemberOf is FunctionCall) { codeGenerator.ChainBuilder.LoadAddressOfFunctionReturnValue = true; } assignmentCallback(codeGenerator, PhpTypeCode.Object); SimpleVarUse svu = node.IsMemberOf as SimpleVarUse; if (svu != null) { SimpleVarUseHelper.EmitLoadAddress_StoreBack(svu, codeGenerator); } // else do nothing } chain.End(); } else { // 7: $a //codeGenerator.EmitVariableStoreAssign(this); this.EmitStoreAssign(node, codeGenerator); } }
public static void EmitAssign(this SimpleVarUse /*!*/ node, CodeGenerator codeGenerator) { node.NodeCompiler <ISimpleVarUseCompiler>().EmitAssign(node, codeGenerator); }
public static void EmitLoadAddress(this SimpleVarUse node, CodeGenerator codeGenerator) { node.NodeCompiler <ISimpleVarUseCompiler>().EmitLoadAddress(node, codeGenerator); }
public static void EmitLoadAddress_StoreBack(this SimpleVarUse /*!*/ node, CodeGenerator codeGenerator) { node.NodeCompiler <ISimpleVarUseCompiler>().EmitLoadAddress_StoreBack(node, codeGenerator); }
void ISimpleVarUseCompiler.EmitLoadAddress(SimpleVarUse node, CodeGenerator codeGenerator) { EmitLoadAddress((T)node, codeGenerator); }
void ISimpleVarUseCompiler.EmitAssign(SimpleVarUse node, CodeGenerator codeGenerator) { EmitAssign((T)node, codeGenerator); }
void ISimpleVarUseCompiler.EmitName(SimpleVarUse node, CodeGenerator codeGenerator) { EmitName((T)node, codeGenerator); }
/// <summary> /// Emits IL instructions that read the value of an instance field. /// </summary> /// <param name="node">Instance.</param> /// <param name="codeGenerator">The current <see cref="CodeGenerator"/>.</param> /// <param name="wantRef">If <B>false</B> the field value should be left on the evaluation stack, /// if <B>true</B> the <see cref="PhpReference"/> should be left on the evaluation stack.</param> /// <returns> /// Nothing is expected on the evaluation stack. A <see cref="PhpReference"/> (if <paramref name="wantRef"/> /// is <B>true</B>) or the field value itself (if <paramref name="wantRef"/> is <B>false</B>) is left on the /// evaluation stack. /// </returns> internal virtual PhpTypeCode EmitReadField(T /*!*/ node, CodeGenerator codeGenerator, bool wantRef) { ILEmitter il = codeGenerator.IL; DirectVarUse direct_instance = node.IsMemberOf as DirectVarUse; if (direct_instance != null && direct_instance.IsMemberOf == null && direct_instance.VarName.IsThisVariableName) { return(EmitReadFieldOfThis(node, codeGenerator, wantRef)); } if (!wantRef) { //codeGenerator.ChainBuilder.Lengthen(); //PhpTypeCode type_code = isMemberOf.Emit(codeGenerator); //Debug.Assert(type_code == PhpTypeCode.Object || type_code == PhpTypeCode.DObject); //// CALL Operators.GetProperty(STACK,<field name>,<type desc>,<quiet>); //EmitName(codeGenerator); //codeGenerator.EmitLoadClassContext(); //il.LoadBool(codeGenerator.ChainBuilder.QuietRead); //il.Emit(OpCodes.Call, Methods.Operators.GetProperty); //return PhpTypeCode.Object; string fieldName = (node is DirectVarUse) ? (node as DirectVarUse).VarName.Value : null; Expression fieldNameExpr = (node is IndirectVarUse) ? (node as IndirectVarUse).VarNameEx : null; bool quietRead = wantRef ? false : codeGenerator.ChainBuilder.QuietRead; return(codeGenerator.CallSitesBuilder.EmitGetProperty( codeGenerator, wantRef, node.IsMemberOf, null, null, null, fieldName, fieldNameExpr, quietRead)); } // call GetProperty/GetObjectPropertyRef codeGenerator.ChainBuilder.Lengthen(); // loads the variable which field is gotten: PhpTypeCode var_type_code = node.IsMemberOf.Emit(codeGenerator); if (codeGenerator.ChainBuilder.Exists) { Debug.Assert(var_type_code == PhpTypeCode.DObject); // CALL Operators.GetObjectPropertyRef(STACK,<field name>,<type desc>); EmitName(node, codeGenerator); codeGenerator.EmitLoadClassContext(); il.Emit(OpCodes.Call, Methods.Operators.GetObjectPropertyRef); } else { Debug.Assert(var_type_code == PhpTypeCode.ObjectAddress); // CALL Operators.GetPropertyRef(ref STACK,<field name>,<type desc>,<script context>); EmitName(node, codeGenerator); codeGenerator.EmitLoadClassContext(); codeGenerator.EmitLoadScriptContext(); il.Emit(OpCodes.Call, Methods.Operators.GetPropertyRef); // stores the value of variable back: SimpleVarUse simple_var = node.IsMemberOf as SimpleVarUse; if (simple_var != null) { simple_var.EmitLoadAddress_StoreBack(codeGenerator); } } return(PhpTypeCode.PhpReference); }