/// <summary> /// Emits IL instructions that write a value to an instance field. /// </summary> /// <param name="codeGenerator">The current <see cref="CodeGenerator"/>.</param> /// <param name="writeRef">If <B>true</B> the value being written is a <see cref="PhpReference"/> /// instance, if <B>false</B> it is an <see cref="Object"/> instance.</param> /// <returns>Delegate to a method that emits code to be executed when the actual value has been /// loaded on the evaluation stack.</returns> /// <remarks> /// If the field could be resolved at compile time (because <see cref="VarLikeConstructUse.isMemberOf"/> is <c>$this</c> or a /// variable is proved to be of a certain type by type analysis), direct field writing code is emitted. /// Otherwise, <see cref="Operators.SetProperty"/> or <see cref="Operators.SetObjectProperty"/> call is emitted. /// </remarks> internal virtual AssignmentCallback EmitWriteField(CodeGenerator /*!*/ codeGenerator, bool writeRef) { ILEmitter il = codeGenerator.IL; DirectVarUse direct_instance = isMemberOf as DirectVarUse; if (direct_instance != null && direct_instance.IsMemberOf == null && direct_instance.VarName.IsThisVariableName) { return(EmitWriteFieldOfThis(codeGenerator, writeRef)); } if (isMemberOf is ItemUse || isMemberOf is StaticFieldUse || isMemberOf.IsMemberOf != null) { // we are part of a chain // Lengthen for hop over -> codeGenerator.ChainBuilder.Lengthen(); FunctionCall funcCall = isMemberOf as FunctionCall; if (funcCall == null) { isMemberOf.Emit(codeGenerator); EmitName(codeGenerator); } else { codeGenerator.ChainBuilder.LoadAddressOfFunctionReturnValue = true; isMemberOf.Emit(codeGenerator); codeGenerator.ChainBuilder.RecastValueReturnedByFunctionCall(); EmitName(codeGenerator); } return(new AssignmentCallback(EmitCallSetObjectField)); } else { return(delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode) { codeGen.ChainBuilder.Lengthen(); // CALL Operators.SetProperty(STACK,ref <instance>,<field name>,<handle>,<script context>); isMemberOf.Emit(codeGen); EmitName(codeGen); codeGen.EmitLoadClassContext(); codeGen.EmitLoadScriptContext(); // invoke the operator codeGen.IL.Emit(OpCodes.Call, Methods.Operators.SetProperty); }); } }
/// <summary> /// Called when derived class visited. /// </summary> /// <param name="x"></param> virtual public void VisitFunctionCall(FunctionCall x) { foreach (ActualParam p in x.CallSignature.Parameters) VisitElement(p); }
/// <summary> /// Called when derived class visited. /// </summary> /// <param name="x"></param> virtual public void VisitFunctionCall(FunctionCall x) { VisitVarLikeConstructUse(x); foreach (ActualParam p in x.CallSignature.Parameters) VisitElement(p); }