コード例 #1
0
            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);
                }
            }
コード例 #2
0
 public static void EmitAssign(this SimpleVarUse /*!*/ node, CodeGenerator codeGenerator)
 {
     node.NodeCompiler <ISimpleVarUseCompiler>().EmitAssign(node, codeGenerator);
 }
コード例 #3
0
 public static void EmitLoadAddress(this SimpleVarUse node, CodeGenerator codeGenerator)
 {
     node.NodeCompiler <ISimpleVarUseCompiler>().EmitLoadAddress(node, codeGenerator);
 }
コード例 #4
0
 public static void EmitLoadAddress_StoreBack(this SimpleVarUse /*!*/ node, CodeGenerator codeGenerator)
 {
     node.NodeCompiler <ISimpleVarUseCompiler>().EmitLoadAddress_StoreBack(node, codeGenerator);
 }
コード例 #5
0
 void ISimpleVarUseCompiler.EmitLoadAddress(SimpleVarUse node, CodeGenerator codeGenerator)
 {
     EmitLoadAddress((T)node, codeGenerator);
 }
コード例 #6
0
 void ISimpleVarUseCompiler.EmitAssign(SimpleVarUse node, CodeGenerator codeGenerator)
 {
     EmitAssign((T)node, codeGenerator);
 }
コード例 #7
0
 void ISimpleVarUseCompiler.EmitName(SimpleVarUse node, CodeGenerator codeGenerator)
 {
     EmitName((T)node, codeGenerator);
 }
コード例 #8
0
            /// <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);
            }