///// <summary>
        ///// Prepares local variable for a store operation.
        ///// </summary>
        //internal void StoreLocalPrepare(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        //{
        //    Debug.Assert(variable == null ^ variableName == null);
        //}

        /// <summary>
        /// Unsets a specified variable.
        /// </summary>
        internal void UnsetLocal(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        {
            ILEmitter il = codeGenerator.IL;

            Debug.Assert(variable == null ^ variableName == null);

            if (variable != null)
            {
                if (variable.IsPhpReference)
                {
                    // <variable> = new PhpReference();
                    il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void);
                    variable.Variable.EmitStore(il);
                }
                else
                {
                    il.Emit(OpCodes.Ldnull);
                    variable.Variable.EmitStore(il);
                }
            }
            else
            {
                // CALL Operators.SetVariable(<local variables table>,<name>,null);
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                il.Ldloc(variableName);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Call, Methods.Operators.SetVariable);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Emit reference load of variable named <paramref name="varName"/>.
        /// </summary>
        internal static void EmitLoadRef(CodeGenerator /*!*/ codeGenerator, VariableName varName)
        {
            ILEmitter il = codeGenerator.IL;

            // Check if the variable is auto-global
            if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                codeGenerator.EmitAutoGlobalLoadRef(varName);
                return;
            }

            if (codeGenerator.OptimizedLocals)
            {
                // Template: for DirectVarUse
                //		"LOAD ref $x;"
                //
                //		ldloc loc // Local variable should be of type PhpReference
                VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName];
                entry.Variable.EmitLoad(il);
            }
            else
            {
                // Template:
                //		PhpReference Operators.GetVariableRef(IDictionary table, string name)
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                il.Emit(OpCodes.Ldstr, varName.Value);
                il.Emit(OpCodes.Call, Methods.Operators.GetVariableRef);
            }
        }
Beispiel #3
0
        internal override void EmitStoreRefAssign(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.EmitAutoGlobalStoreRefAssign(varName);
            }
            else if (codeGenerator.OptimizedLocals)
            {
                VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName];
                entry.Variable.EmitStore(il);
            }
            else
            {
                // call instance IDictionary.set_Item(object, object)
                // OBSOLETE: il.Emit(OpCodes.Callvirt, Methods.IDictionary_SetItem);
                il.Emit(OpCodes.Call, Methods.Operators.SetVariableRef);
            }
        }
        /// <summary>
        /// Loads a value of a specified variable. If the variable is of type <see cref="PhpReference"/>, it is dereferenced.
        /// </summary>
        internal void LoadLocal(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        {
            ILEmitter il = codeGenerator.IL;

            Debug.Assert(variable == null ^ variableName == null);

            if (variable != null)
            {
                // LOAD DEREF <variable>;
                variable.Variable.EmitLoad(il);
                if (variable.IsPhpReference)
                {
                    il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
                }
            }
            else
            {
                // LOAD Operators.GetVariable[Unchecked](<script context>, <local variables table>, <variable name>);
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                il.Ldloc(variableName);
                if (codeGenerator.ChainBuilder.QuietRead)
                {
                    il.Emit(OpCodes.Call, Methods.Operators.GetVariableUnchecked);
                }
                else
                {
                    il.Emit(OpCodes.Call, Methods.Operators.GetVariable);
                }
            }
        }
        /// <summary>
        /// Stores a reference on the top of the stack to a specified variable.
        /// </summary>
        internal void StoreLocalRefAssign(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        {
            ILEmitter il = codeGenerator.IL;

            Debug.Assert(variable == null ^ variableName == null);

            if (variable != null)
            {
                Debug.Assert(variable.IsPhpReference);
                variable.Variable.EmitStore(il);
            }
            else
            {
                // temp = STACK
                LocalBuilder temp = il.GetTemporaryLocal(Types.PhpReference[0], true);
                il.Stloc(temp);

                // CALL Operators.SetVariableRef(<local variables table>,<name>,temp);
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                il.Ldloc(variableName);
                il.Ldloc(temp);
                il.Emit(OpCodes.Call, Methods.Operators.SetVariableRef);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Emit load of variable named <paramref name="varName"/>.
        /// </summary>
        internal static PhpTypeCode EmitLoad(CodeGenerator codeGenerator, VariableName varName)
        {
            ILEmitter il = codeGenerator.IL;

            // Check if the variable is auto-global
            if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                codeGenerator.EmitAutoGlobalLoad(varName);
                return(PhpTypeCode.Object);
            }

            // Variable is local
            if (codeGenerator.OptimizedLocals)
            {
                // Template:
                //			ldloc loc
                //	***** // If the specidied variable is of type PhpReference
                //				ldfld PhpReference.value
                //	*****
                VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName];
                entry.Variable.EmitLoad(il);
                if (entry.IsPhpReference)
                {
                    il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
                }

                return(PhpTypeCode.Object);
            }

            // LOAD Operators.GetVariable[Unchecked](<script context>, <local variable table>, <name>);
            codeGenerator.EmitLoadScriptContext();
            codeGenerator.EmitLoadRTVariablesTable();
            il.Emit(OpCodes.Ldstr, varName.Value);

            if (codeGenerator.ChainBuilder.QuietRead)
            {
                il.Emit(OpCodes.Call, Methods.Operators.GetVariableUnchecked);
            }
            else
            {
                il.Emit(OpCodes.Call, Methods.Operators.GetVariable);
            }

            return(PhpTypeCode.Object);
        }
        /// <summary>
        /// Loads a specified reference local variable.
        /// </summary>
        internal void LoadLocalRef(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        {
            ILEmitter il = codeGenerator.IL;

            Debug.Assert(variable == null ^ variableName == null);

            if (variable != null)
            {
                Debug.Assert(variable.IsPhpReference);
                variable.Variable.EmitLoad(il);
            }
            else
            {
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                il.Ldloc(variableName);
                il.Emit(OpCodes.Call, Methods.Operators.GetVariableRef);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Loads an address of a variable on the stack.
        /// </summary>
        internal override void EmitLoadAddress(CodeGenerator codeGenerator)
        {
            ILEmitter il = codeGenerator.IL;

            if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                codeGenerator.EmitAutoGlobalLoadAddress(varName);
                return;
            }
            if (codeGenerator.OptimizedLocals)
            {
                // Template: for DirectVarUse
                //	***** // If the specidied variable is of type PhpReference
                //				ldloc loc
                //				ldflda PhpReference.value
                //	***** // Otherwise
                //				ldloca loc
                //	*****
                VariablesTable.Entry entry = codeGenerator.CurrentVariablesTable[varName];
                if (entry.IsPhpReference)
                {
                    // Load variable (of type PhpReference) from IPlace
                    entry.Variable.EmitLoad(il);
                    // ... and get address (ref) of its Value field
                    il.Emit(OpCodes.Ldflda, Fields.PhpReference_Value);
                }
                else
                {
                    // Load address of variable from IPlace
                    entry.Variable.EmitLoadAddress(il);
                }
                return;
            }
            else
            {
                // Template:
                //		object Operators.GetVariableUnchecked(IDictionary table, string name) //returns variable value
                this.LoadTabledVariableAddress(codeGenerator);
            }
        }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
        internal override void EmitStorePrepare(CodeGenerator codeGenerator)
        {
            ILEmitter il = codeGenerator.IL;

            if (varName.IsThisVariableName)
            {
                // Error throwing code will be emitted in EmitVariableStoreAssign
            }
            else if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                // Check if the variable is auto-global
                codeGenerator.EmitAutoGlobalStorePrepare(varName);
            }
            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)
                {
                    entry.Variable.EmitLoad(il);
                }
                // Otherwise do nothing
                // Now load the value, then call EmitVariableStoreAssignOptimized() to store the value ...
            }
            else
            {
                // Template:
                //		void Operators.SetVariable(table, "x", PhpVariable.Copy(Operators.getValue(table, "x"), CopyReason.Assigned));
                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                EmitName(codeGenerator);
                // Now load the value, then call SetVariable() to store the value ...
            }
        }
Beispiel #11
0
        /// <summary>
        /// Loads and address of a specified variable.
        /// </summary>
        internal void LoadLocalAddress(CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
        {
            ILEmitter il = codeGenerator.IL;

            Debug.Assert(variable == null ^ variableName == null);

            if (variable != null)
            {
                if (variable.IsPhpReference)
                {
                    // LOAD ADDR <variable>.value;
                    variable.Variable.EmitLoad(il);
                    il.Emit(OpCodes.Ldflda, Fields.PhpReference_Value);
                }
                else
                {
                    variable.Variable.EmitLoadAddress(il);
                }
            }
            else
            {
                LoadTabledVariableAddress(codeGenerator);
            }
        }
Beispiel #12
0
        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);
            }
        }
            /// <summary>
            /// Stores a value on the top of the stack to a specified variable.
            /// </summary>
            internal static void StoreLocalAssign(IndirectVarUse node, CodeGenerator codeGenerator, VariablesTable.Entry variable, LocalBuilder variableName)
            {
                ILEmitter il = codeGenerator.IL;

                Debug.Assert(variable == null ^ variableName == null);
                LocalBuilder temp;

                if (variable != null)
                {
                    if (variable.IsPhpReference)
                    {
                        // temp = STACK
                        temp = il.GetTemporaryLocal(Types.Object[0], true);
                        il.Stloc(temp);

                        // <variable>.value = temp;
                        variable.Variable.EmitLoad(il);
                        il.Ldloc(temp);
                        il.Emit(OpCodes.Stfld, Fields.PhpReference_Value);
                    }
                    else
                    {
                        variable.Variable.EmitStore(il);
                    }
                }
                else
                {
                    // temp = STACK
                    temp = il.GetTemporaryLocal(Types.Object[0], true);
                    il.Stloc(temp);

                    // CALL Operators.SetVariable(<local variables table>,<name>,temp);
                    codeGenerator.EmitLoadScriptContext();
                    codeGenerator.EmitLoadRTVariablesTable();
                    il.Ldloc(variableName);
                    il.Ldloc(temp);
                    il.Emit(OpCodes.Call, Methods.Operators.SetVariable);
                }
            }