public EmitDelegateConvert(ILEmitter preceedingCode, ILEmitter itemToConvert, TypeReference targetType)
     : base(preceedingCode)
 {
     _inner = new EmptyEmitter(preceedingCode)
                 .Call(Importer.DelegateConvertChangeType, itemToConvert, new EmptyEmitter(preceedingCode).TypeOf(targetType))
                 .CastClass(targetType);
 }
 public static int InsertInstructions(this MethodDefinition method, ILEmitter weakHandler, int insertPoint)
 {
     foreach (var i in weakHandler.Emit())
     {
         method.Body.Instructions.Insert(insertPoint, i);
         ++insertPoint;
     }
     return insertPoint;
 }
Ejemplo n.º 3
0
        protected override void EmitCleanupManaged(ILCodeStream codeStream)
        {
            // Only do cleanup if it is IN
            if (!In)
            {
                return;
            }

            ILEmitter   emitter = _ilCodeStreams.Emitter;
            ILCodeLabel lNull   = emitter.NewCodeLabel();

            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.brfalse, lNull);

            LoadNativeValue(codeStream);
            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.call, emitter.NewToken(
                                Context.GetHelperEntryPoint("InteropHelpers", "AsAnyCleanupNative")));

            codeStream.EmitLabel(lNull);
        }
Ejemplo n.º 4
0
        /// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            if (type == Types.File)
            {
                EmitToAbsoluteSourcePath(codeGenerator);
            }
            else if (type == Types.Dir)
            {
                ILEmitter il = codeGenerator.IL;

                // CALL Path.GetDirectory( Operators.ToAbsoluteSourcePath(...) )
                EmitToAbsoluteSourcePath(codeGenerator);
                il.Emit(OpCodes.Call, Methods.Path.GetDirectoryName);
            }
            else
            {
                Debug.Fail("Pseudo constant " + type.ToString() + " expected to be already evaluated.");
            }

            return(PhpTypeCode.String);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Ensure the call sites container is created and return the <see cref="TypeBuilder"/>.
        /// </summary>
        /// <returns></returns>
        private TypeBuilder /*!*/ EnsureContainer()
        {
            if (containerClass == null)
            {
                if (this.classContext != null && this.classContext.IsGeneric)
                {
                    // we will emit single call sites in the class context. It is easier than to build generic sites container.
                    Debug.Assert(this.classContext.RealTypeBuilder != null);
                    return(this.classContext.RealTypeBuilder);
                }

                Debug.Assert(staticCtorEmitter == null);

                var containerClassName = string.Format("<{0}>o_Sitescontainer'{1}", this.userFriendlyName.Replace('.', '_'), System.Threading.Interlocked.Increment(ref nextContainerId));
                containerClass = moduleBuilder.DefineType(PluginHandler.ConvertCallSiteName(containerClassName), TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Abstract);

                staticCtorEmitter = new ILEmitter(containerClass.DefineTypeInitializer());
            }

            return(containerClass);
        }
Ejemplo n.º 6
0
        protected override void EmitEntryPoint(MethodBuilder /*!*/ builder)
        {
            PureCompilationUnit unit = PureModuleBuilder.PureCompilationUnit;

            Debug.Assert(unit.EntryPoint != null);

            ILEmitter il = new ILEmitter(builder);

            // LOAD new RoutineDelegate(<main PHP method>);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ldftn, unit.EntryPoint.ArgLessInfo);
            il.Emit(OpCodes.Newobj, Constructors.RoutineDelegate);

            // ScriptContext.RunApplication(<main helper delegate>, null, null);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Call, Methods.ScriptContext.RunApplication);

            // RETURN;
            il.Emit(OpCodes.Ret);
        }
Ejemplo n.º 7
0
        protected override TypeDesc MarshalReturn(TypeDesc managedType, ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream returnValueMarshallingCodeStream)
        {
            var nativeType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr);

            var vSafeHandle  = emitter.NewLocal(managedType);
            var vReturnValue = emitter.NewLocal(nativeType);

            marshallingCodeStream.Emit(ILOpcode.newobj, emitter.NewToken(managedType.GetDefaultConstructor()));
            marshallingCodeStream.EmitStLoc(vSafeHandle);

            returnValueMarshallingCodeStream.EmitStLoc(vReturnValue);

            returnValueMarshallingCodeStream.EmitLdLoc(vSafeHandle);
            returnValueMarshallingCodeStream.EmitLdLoc(vReturnValue);
            returnValueMarshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                                      PInvokeMethodData.SafeHandleType.GetKnownMethod("SetHandle", null)));

            returnValueMarshallingCodeStream.EmitLdLoc(vSafeHandle);

            return(nativeType);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Define new instance of CallSite&lt;<paramref name="delegateType"/>&gt; and initialize it with specified binder.
        /// </summary>
        /// <param name="bodyEmitter"><see cref="ILEmitter"/> of the body that is using this call site. This method may emit initialization of the call site into this <paramref name="bodyEmitter"/>.</param>
        /// <param name="userFriendlyName">User friendly name used as name for the CallSite field.</param>
        /// <param name="delegateType">CallSite type argument.</param>
        /// <param name="binderInstanceEmitter">Function used to emit initialization of the binder from within the call sites container .cctor.</param>
        /// <returns>The <see cref="FieldInfo"/> containing the instance of the created CallSite.</returns>
        public FieldInfo /*!*/ DefineCallSite(ILEmitter /*!*/ bodyEmitter, string /*!*/ userFriendlyName, Type /*!*/ delegateType, Action <ILEmitter> /*!*/ binderInstanceEmitter)
        {
            Debug.Assert(userFriendlyName != null && delegateType != null && binderInstanceEmitter != null);

            userFriendlyName += ("'" + (callSitesCount++));

            // call site type
            var callSiteType = Types.CallSiteGeneric[0].MakeGenericType(delegateType);

            // define the field:
            // public static readonly CallSite<delegateType> <userFriendlyName>
            var attrs = FieldAttributes.Static | FieldAttributes.InitOnly | ((staticCtorEmitter == null) ? FieldAttributes.Private : FieldAttributes.Assembly);
            var field = this.DefineField(PluginHandler.ConvertCallSiteName(userFriendlyName), callSiteType, attrs);

            if (staticCtorEmitter == null) // => this.classContext != null
            {
                // emit initialization of the call site just in the body of current method (as it is in C#, we need current generic arguments):
                Debug.Assert(this.classContext != null);

                // check if the call site if not null, otherwise initialize it first:

                // if (<field> == null) <InitializeCallSite>;
                Label ifend = bodyEmitter.DefineLabel();
                bodyEmitter.Emit(OpCodes.Ldsfld, field);
                bodyEmitter.Emit(OpCodes.Brtrue, ifend);

                // init the field:
                InitializeCallSite(bodyEmitter, callSiteType, field, binderInstanceEmitter);

                bodyEmitter.MarkLabel(ifend);
            }
            else
            {
                // init the field in .cctor:
                InitializeCallSite(staticCtorEmitter, callSiteType, field, binderInstanceEmitter);
            }

            //
            return(field);
        }
Ejemplo n.º 9
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);
            }
        }
Ejemplo n.º 10
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);
            }
        }
Ejemplo n.º 11
0
        public override MethodIL EmitIL()
        {
            ILEmitter       emitter     = new ILEmitter();
            ILCodeStream    codeStream  = emitter.NewCodeStream();
            ILLocalVariable returnValue = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));

            MetadataType startup = Context.GetHelperType("StartupCodeHelpers");

            codeStream.Emit(ILOpcode.call, emitter.NewToken(startup.GetKnownMethod("Initialize", null)));

            // Initialize command line args
            string initArgsName = (Context.Target.OperatingSystem == TargetOS.Windows)
                                ? "InitializeCommandLineArgsW"
                                : "InitializeCommandLineArgs";
            MethodDesc initArgs = startup.GetKnownMethod(initArgsName, null);

            codeStream.Emit(ILOpcode.ldarg_0); // argc
            codeStream.Emit(ILOpcode.ldarg_1); // argv
            codeStream.Emit(ILOpcode.call, emitter.NewToken(initArgs));

            // Call program Main
            if (_mainMethod.Signature.Length > 0)
            {
                TypeDesc environ = Context.SystemModule.GetKnownType("System", "Environment");
                codeStream.Emit(ILOpcode.call, emitter.NewToken(environ.GetKnownMethod("GetCommandLineArgs", null)));
            }
            codeStream.Emit(ILOpcode.call, emitter.NewToken(_mainMethod));
            if (_mainMethod.Signature.ReturnType.IsVoid)
            {
                codeStream.EmitLdc(0);
            }
            codeStream.EmitStLoc(returnValue);

            codeStream.Emit(ILOpcode.call, emitter.NewToken(startup.GetKnownMethod("Shutdown", null)));

            codeStream.EmitLdLoc(returnValue);
            codeStream.Emit(ILOpcode.ret);

            return(emitter.Link());
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Stores a value on the top of the stack to a specified variable.
        /// </summary>
        internal void StoreLocalAssign(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);
            }
        }
Ejemplo n.º 13
0
        private static ILEmitter.Label MakeReturnLabel(ILEmitter il)
        {
            // We replace all `ret`s with a simple branch to force potential execution of post-original code

            // Create a helper label as well
            // We mark the label as not emitted so that potential postfix code can mark it
            var resultLabel = il.DeclareLabel();

            resultLabel.emitted     = false;
            resultLabel.instruction = Instruction.Create(OpCodes.Ret);

            foreach (var ins in il.IL.Body.Instructions.Where(ins => ins.MatchRet()))
            {
                ins.OpCode  = OpCodes.Br;
                ins.Operand = resultLabel.instruction;
                resultLabel.targets.Add(ins);
            }

            // Already append `ret` for other code to use as emitBefore point
            il.IL.Append(resultLabel.instruction);
            return(resultLabel);
        }
Ejemplo n.º 14
0
            public override PhpTypeCode Emit(PseudoConstUse node, CodeGenerator codeGenerator)
            {
                switch (node.Type)
                {
                case PseudoConstUse.Types.File:
                    EmitToAbsoluteSourcePath(codeGenerator);
                    break;

                case PseudoConstUse.Types.Dir:
                    ILEmitter il = codeGenerator.IL;
                    // CALL Path.GetDirectory( Operators.ToAbsoluteSourcePath(...) )
                    EmitToAbsoluteSourcePath(codeGenerator);
                    il.Emit(OpCodes.Call, Methods.Path.GetDirectoryName);
                    break;

                default:
                    Debug.Fail("Pseudo constant " + node.Type.ToString() + " expected to be already evaluated.");
                    throw null;
                }

                return(PhpTypeCode.String);
            }
Ejemplo n.º 15
0
        /// <summary>
        /// Loads the value represented by this object from the runtime variables table,
        /// stores it to a local variable and loads the address of this local.
        /// </summary>
        /// <remarks>This method is used only in non-optimized user functions and global code.
        /// Specified local variable is obtained from current <see cref="ILEmitter"/> by
        /// <see cref="ILEmitter.GetTemporaryLocal"/> and stored to <see cref="TabledLocalAddressStorage"/>
        /// for later use. Once the local become useless, <see cref="ILEmitter.ReturnTemporaryLocal"/>
        /// should be called.
        /// </remarks>
        /// <param name="codeGenerator">Currently used <see cref="CodeGenerator"/>.</param>
        internal virtual void LoadTabledVariableAddress(CodeGenerator codeGenerator)
        {
            // This function should be call only once on every SimpleVarUse object
            // TODO: ASSERTION FAILS (e.g. PhpMyAdmin, common.lib.php)
            // Debug.Assert(this.TabledLocalAddressStorage == null);
            ILEmitter il = codeGenerator.IL;

            // Load the value represented by this node from the runtime variables table

            // LOAD Operators.GetVariableUnchecked(<script context>, <local variables table>, <variable name>);
            codeGenerator.EmitLoadScriptContext();
            codeGenerator.EmitLoadRTVariablesTable();
            EmitName(codeGenerator);
            codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.GetVariableUnchecked);

            // Get local from ILEmitter
            this.TabledLocalAddressStorage = il.GetTemporaryLocal(Types.Object[0]);
            // Store the value
            il.Stloc(this.TabledLocalAddressStorage);
            // Load the address
            il.Ldloca(this.TabledLocalAddressStorage);
        }
Ejemplo n.º 16
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 ...
            }
        }
Ejemplo n.º 17
0
            /// <summary>
            /// Emit lambda function that returns values used for sorting and
            /// call to OrderedSequence.OrderBy method (with current LINQ context as
            /// first and generated lambda as a second parameter)
            /// </summary>
            public override PhpTypeCode Emit(LinqBuilder codeGenerator)
            {
                ILEmitter il = codeGenerator.IL;

                // NEW Func[object,object](<linq context>, <&lambda>);
                codeGenerator.EmitLoadLinqContext();
                il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Comparer_{0}>",
                                                                              codeGenerator.GetNextComparerNum()), valueVar, expression, PhpTypeCode.Object));
                il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor);

                // LOAD Select[object,object](<source>, <delegate>);
                if (isThenBy)
                {
                    il.Emit(OpCodes.Call, ordering == Ordering.Descending ? LinqExterns.ThenByDescending : LinqExterns.ThenBy);
                }
                else
                {
                    il.Emit(OpCodes.Call, ordering == Ordering.Descending ? LinqExterns.OrderByDescending : LinqExterns.OrderBy);
                }

                return(base.Emit(codeGenerator));
            }
Ejemplo n.º 18
0
        /// <summary>
        /// Emits dynamic inclusion.
        /// </summary>
        private PhpTypeCode EmitDynamicInclusion(CodeGenerator /*!*/ codeGenerator)
        {
            // do not generate dynamic auto inclusions:
            if (InclusionTypesEnum.IsAutoInclusion(inclusionType))
            {
                return(PhpTypeCode.Void);
            }

            ILEmitter il = codeGenerator.IL;

            // CALL context.DynamicInclude(<file name>,<relative includer source path>,variables,self,includer);
            codeGenerator.EmitLoadScriptContext();
            codeGenerator.EmitConversion(fileNameEx, PhpTypeCode.String);
            il.Emit(OpCodes.Ldstr, codeGenerator.SourceUnit.SourceFile.RelativePath.ToString());
            codeGenerator.EmitLoadRTVariablesTable();
            codeGenerator.EmitLoadSelf();
            codeGenerator.EmitLoadClassContext();
            il.LoadLiteral(inclusionType);
            il.Emit(OpCodes.Call, Methods.ScriptContext.DynamicInclude);

            return(PhpTypeCode.Object);
        }
        public PInvokeILCodeStreams()
        {
            Emitter = new ILEmitter();

            // We have these code streams:
            // - FunctionPointerLoadStream is used to load the function pointer to call
            // - MarshallingCodeStream is used to convert each argument into a native type and
            // store that into the local
            // - CallsiteSetupCodeStream is used to used to load each previously generated local
            // and call the actual target native method.
            // - ReturnValueMarshallingCodeStream is used to convert the native return value
            // to managed one.
            // - UnmarshallingCodestream is used to propagate [out] native arguments values to
            // managed ones.
            // - CleanupCodestream is used to perform a guaranteed cleanup
            FunctionPointerLoadStream        = Emitter.NewCodeStream();
            MarshallingCodeStream            = Emitter.NewCodeStream();
            CallsiteSetupCodeStream          = Emitter.NewCodeStream();
            ReturnValueMarshallingCodeStream = Emitter.NewCodeStream();
            UnmarshallingCodestream          = Emitter.NewCodeStream();
            CleanupCodeStream = Emitter.NewCodeStream();
        }
Ejemplo n.º 20
0
        public static void EmitArgFullPreCall(ILEmitter /*!*/ il, IPlace /*!*/ stack, bool argsAware,
                                              int formalParamCount, int formalTypeParamCount, out LocalBuilder locArgsCount)
        {
            if (argsAware)
            {
                locArgsCount = il.DeclareLocal(typeof(int));

                // locArgsCount = stack.MakeArgsAware(<formal tpye param count | formal param count>);
                stack.EmitLoad(il);
                il.LdcI4((formalTypeParamCount << 16) | formalParamCount);
                il.Emit(OpCodes.Call, Methods.PhpStack.MakeArgsAware);
                il.Stloc(locArgsCount);
            }
            else
            {
                locArgsCount = null;

                // CALL stack.RemoveFrame();
                stack.EmitLoad(il);
                il.Emit(OpCodes.Call, Methods.PhpStack.RemoveFrame);
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Emits IL instructions that transfer the control to the target label for <B>break</B> statement
        /// having parameter that cannot be evaluated at compile time.
        /// </summary>
        /// <remarks>This function is used to generate code for <B>break v;</B> where <i>v</i> is a variable.</remarks>
        public void EmitBreakRuntime()
        {
            int       i;
            ILEmitter il = codeGenerator.IL;

            Label[] jumpTable = new Label[stack.Count + 1];
            Label   exitLabel = il.DefineLabel();

            Debug.Assert(stack.Count != 0);

            for (i = 0; i <= stack.Count; i++)
            {
                jumpTable[i] = il.DefineLabel();
            }

            // The value according to we switch is already present on the evaluation stack
            LocalBuilder break_level_count = il.DeclareLocal(typeof(Int32));

            il.Emit(OpCodes.Dup);
            il.Stloc(break_level_count);
            il.Emit(OpCodes.Switch, jumpTable);

            // Default case
            il.Ldloc(break_level_count);
            codeGenerator.EmitPhpException(Methods.PhpException.InvalidBreakLevelCount);
            il.Emit(OpCodes.Br, exitLabel);

            il.MarkLabel(jumpTable[0]);
            EmitBranchToExit((StackItem)stack[stack.Count - 1]);

            for (i = 1; i <= stack.Count; i++)
            {
                il.MarkLabel(jumpTable[i]);
                EmitBranchToExit((StackItem)stack[stack.Count - i]);
            }

            il.MarkLabel(exitLabel);
        }
Ejemplo n.º 22
0
        public void DefineContextType()
        {
            linqContextBuilder = cg.IL.TypeBuilder.DefineNestedType(ContextTypeName + cg.IL.GetNextUniqueIndex(),
                                                                    TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.Sealed,
                                                                    typeof(PHP.Core.LinqContext), null);

            // .ctor:

            ConstructorBuilder ctor = linqContextBuilder.DefineConstructor(MethodAttributes.Assembly,
                                                                           CallingConventions.HasThis, Types.LinqContextArgs);

            ILEmitter il = new ILEmitter(ctor);

            il.Ldarg(0);
            il.Ldarg(1);
            il.Ldarg(2);
            il.Ldarg(3);
            il.Ldarg(4);
            il.Emit(OpCodes.Call, Constructors.LinqContext);
            il.Emit(OpCodes.Ret);

            linqContextCtor = ctor;
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Generates IL for the IsSupported property that reads this information from a field initialized by the runtime
        /// at startup. Only works for intrinsics that the code generator can generate detection code for.
        /// </summary>
        public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupportedField)
        {
            Debug.Assert(IsIsSupportedMethod(method));
            Debug.Assert(isSupportedField.IsStatic && isSupportedField.FieldType.IsWellKnownType(WellKnownType.Int32));

            string id = InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType);

            Debug.Assert(method.Context.Target.Architecture == TargetArchitecture.X64 ||
                         method.Context.Target.Architecture == TargetArchitecture.X86);
            int flag = XArchIntrinsicConstants.FromHardwareIntrinsicId(id);

            var          emit       = new ILEmitter();
            ILCodeStream codeStream = emit.NewCodeStream();

            codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField));
            codeStream.EmitLdc(flag);
            codeStream.Emit(ILOpcode.and);
            codeStream.EmitLdc(0);
            codeStream.Emit(ILOpcode.cgt_un);
            codeStream.Emit(ILOpcode.ret);

            return(emit.Link(method));
        }
Ejemplo n.º 24
0
            /// <summary>
            /// Emits the catch-block.
            /// </summary>
            /// <param name="node">Instance.</param>
            /// <param name="codeGenerator">A code generator.</param>
            /// <param name="exceptionLocal">A local variable containing an instance of <see cref="Library.SPL.Exception"/>.</param>
            /// <param name="endLabel">A label in IL stream where the processing of the try-catch blocks ends.</param>
            /// <param name="nextCatchLabel">A label in IL stream where the next catch block processing begins.</param>
            public void Emit(CatchItem /*!*/ node, CodeGenerator /*!*/ codeGenerator,
                             LocalBuilder /*!*/ exceptionLocal,
                             Label endLabel, Label nextCatchLabel)
            {
                ILEmitter il = codeGenerator.IL;

                codeGenerator.MarkSequencePoint(node.Variable);

                // IF !InstanceOf(<class name>) GOTO next_catch;
                il.Ldloc(exceptionLocal);
                resolvedType.EmitInstanceOf(codeGenerator, null);
                il.Emit(OpCodes.Brfalse, nextCatchLabel);

                // variable = exception;
                node.Variable.Emit(codeGenerator);
                il.Ldloc(exceptionLocal);
                SimpleVarUseHelper.EmitAssign(node.Variable, codeGenerator);

                node.Statements.Emit(codeGenerator);

                // LEAVE end;
                il.Emit(OpCodes.Leave, endLabel);
            }
        public ILEmitter Emit(ILEmitter il, Label _)
        {
            var variableType = _variable.VariableType;

            Debug.Assert(!variableType.IsPrimitive(), $"{variableType.DisplayName()} is not expected.");

            var comparisons = _membersProvider
                              .GetMembers(variableType)
                              .Select(_resolver.GetComparisonEmitter)
                              .ToArray();

            for (var i = 0; i < comparisons.Length; i++)
            {
                using (il.LocalsScope()) {
                    il.DefineLabel(out var gotoNext)
                    .Emit(comparisons[i].Emit(gotoNext))
                    .Emit(comparisons[i].EmitCheckForResult(gotoNext))
                    .MarkLabel(gotoNext);
                }
            }

            return(il);
        }
Ejemplo n.º 26
0
        protected override void EmitMarshalReturnValueManagedToNative()
        {
            ILEmitter    emitter = _ilCodeStreams.Emitter;
            ILCodeStream returnValueMarshallingCodeStream = _ilCodeStreams.ReturnValueMarshallingCodeStream;
            ILCodeStream marshallingCodeStream            = _ilCodeStreams.MarshallingCodeStream;

            NativeParameterType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr);

            var vSafeHandle  = emitter.NewLocal(ManagedParameterType);
            var vReturnValue = emitter.NewLocal(NativeParameterType);

            marshallingCodeStream.Emit(ILOpcode.newobj, emitter.NewToken(ManagedParameterType.GetDefaultConstructor()));
            marshallingCodeStream.EmitStLoc(vSafeHandle);

            returnValueMarshallingCodeStream.EmitStLoc(vReturnValue);

            returnValueMarshallingCodeStream.EmitLdLoc(vSafeHandle);
            returnValueMarshallingCodeStream.EmitLdLoc(vReturnValue);
            returnValueMarshallingCodeStream.Emit(ILOpcode.call, emitter.NewToken(
                                                      PInvokeMethodData.SafeHandleType.GetKnownMethod("SetHandle", null)));

            returnValueMarshallingCodeStream.EmitLdLoc(vSafeHandle);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Defines the (<see cref="ScriptContext"/>) constructor.
        /// </summary>
        /// <param name="typeBuilder">The type builder.</param>
        /// <returns>The constructor builder.</returns>
        /// <remarks>
        /// Part of the constructor body - containing a call to parent's short constructor - is generated.
        /// At least an <see cref="OpCodes.Ret"/> has to be emitted to make the constructor complete.
        /// </remarks>
        public static ConstructorBuilder DefineShortConstructor(TypeBuilder typeBuilder)
        {
            ConstructorBuilder ctor_builder = typeBuilder.DefineConstructor(ShortConstructorAttributes,
                                                                            CallingConventions.Standard, ShortConstructorParamTypes);

            // annotate with EditorBrowsable attribute
#if !SILVERLIGHT // Not available on Silverlight
            ctor_builder.SetCustomAttribute(AttributeBuilders.EditorBrowsableNever);
#endif

            // define parameter names
            ctor_builder.DefineParameter(1, ParameterAttributes.None, "context");
            ctor_builder.DefineParameter(2, ParameterAttributes.None, "newInstance");

            // call the base type's short constructor
            ILEmitter il = new ILEmitter(ctor_builder);
            il.Ldarg(FunctionBuilder.ArgThis);
            il.Ldarg(FunctionBuilder.ArgContextInstance);
            il.Ldarg(2);
            il.Emit(OpCodes.Call, typeBuilder.BaseType.GetConstructor(ShortConstructorParamTypes));

            return(ctor_builder);
        }
Ejemplo n.º 28
0
        protected override void AllocManagedToNative(ILCodeStream codeStream)
        {
            ILEmitter   emitter = _ilCodeStreams.Emitter;
            ILCodeLabel lNull   = emitter.NewCodeLabel();

            codeStream.EmitLdc(0);
            codeStream.Emit(ILOpcode.conv_i);
            StoreNativeValue(codeStream);

            LoadManagedValue(codeStream);
            codeStream.Emit(ILOpcode.brfalse, lNull);

            TypeDesc nativeStructType = InteropStateManager.GetStructMarshallingNativeType(ManagedType);

            ILLocalVariable lNativeType = emitter.NewLocal(nativeStructType);

            codeStream.EmitLdLoca(lNativeType);
            codeStream.Emit(ILOpcode.initobj, emitter.NewToken(nativeStructType));
            codeStream.EmitLdLoca(lNativeType);
            StoreNativeValue(codeStream);

            codeStream.EmitLabel(lNull);
        }
Ejemplo n.º 29
0
        internal override void EmitLoadAddress_StoreBack(CodeGenerator codeGenerator, bool duplicate_value)
        {
            ILEmitter il = codeGenerator.IL;

            // Skip $this->a
            if (varName.IsThisVariableName)
            {
                // Take no action
                return;
            }

            if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                // Take no action
                return;
            }
            if (codeGenerator.OptimizedLocals)
            {
                // Take no action
                return;
            }
            this.StoreTabledVariableBack(codeGenerator, duplicate_value);
        }
Ejemplo n.º 30
0
        internal override void EmitStoreRefPrepare(CodeGenerator codeGenerator)
        {
            ILEmitter il = codeGenerator.IL;

            if (varName.IsThisVariableName)
            {
                // error throwing code will be emitted in EmitVariableStoreRefAssign
            }
            else if (codeGenerator.VariableIsAutoGlobal(varName))
            {
                // Check if the variable is auto-global
                codeGenerator.EmitAutoGlobalStoreRefPrepare(varName);
            }
            else if (codeGenerator.OptimizedLocals)
            {
                // Template:
                //		WRITE ref ($x,value);

                //		DO NOTHING !!!!
                // now load the value then store to local variable
            }
            else
            {
                // Template:
                //		WRITE ref ($x,value); // by Martin
                //
                //		ldarg.1
                //		ldstr "name"
                //		LOAD value
                //		call instance IDictionary.set_Item(object)

                codeGenerator.EmitLoadScriptContext();
                codeGenerator.EmitLoadRTVariablesTable();
                EmitName(codeGenerator);
                // now load value, then call EmitVariableStoreRefAssignGlobalContext() to emit stfld ...
            }
        }
        public ILEmitter Emit(ILEmitter il, Label gotoNext)
        {
            var variableType = _variable.VariableType;

            _variable.Load(il, Arg.X).Stloc(variableType, out var nullableX);
            _variable.Load(il, Arg.Y).Stloc(variableType, out var nullableY);

            var isMember = !(_variable is ArgumentVariable);

            if (isMember)
            {
                _emitCheckNullablesForValue(il, LoadLocalAddress(nullableX), LoadLocalAddress(nullableY), variableType, gotoNext);
            }

            var nullableVariables = new NullableVariables(variableType, _variable.OwnerType, new Dictionary <int, LocalBuilder>(2)
            {
                [Arg.X] = nullableX,
                [Arg.Y] = nullableY
            });

            return(_resolver
                   .GetComparisonEmitter(nullableVariables)
                   .Emit(il, gotoNext));
        }
Ejemplo n.º 32
0
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            ILEmitter il    = codeGenerator.IL;
            int       indir = this.count - 2;

            // cast object to correct tuple type:
            //   Tuple<Tuple<...Tuple<object, object>, .. >, object>, object>
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Castclass, LinqExterns.GetTupleInfo(indir).Type);

            // Find value at specified index (tup.First.First....First/Second);
            int timesFirst = index - ((index == count - 1) ? 1 : 0);

            for (int i = 0; i < timesFirst; i++)
            {
                il.Emit(OpCodes.Call, LinqExterns.GetTupleInfo(indir - i).SecondGetter);
            }

            // The last value is stored in Second, other values are stored in First
            il.Emit(OpCodes.Call, (index == count - 1)?
                    LinqExterns.GetTupleInfo(indir - timesFirst).SecondGetter:
                    LinqExterns.GetTupleInfo(indir - timesFirst).FirstGetter);
            return(PhpTypeCode.Object);
        }
Ejemplo n.º 33
0
 public EmitTypeOf(ILEmitter preceedingCode, TypeReference targetType)
     : base(preceedingCode)
 {
     _inner = new EmptyEmitter(preceedingCode).Call(Importer.GetTypeFromHandle, new EmptyEmitter(preceedingCode).LdToken(targetType));
 }
Ejemplo n.º 34
0
 public EmitCall(ILEmitter preceedingCode, MethodReference targetMethod, params ILEmitter[] methodParameters)
     : base(preceedingCode)
 {
     _methodParameters = methodParameters.Aggregate((prev, next) => prev.Concat(next));
     _targetMethod = targetMethod;
 }
 public EmitLoadMethodFirstArg(ILEmitter preceedingCode)
     : base(preceedingCode)
 {
 }
 public static ILEmitter DelegateConvert(this ILEmitter preceedingCode, ILEmitter itemToConvert, TypeReference targetType)
 {
     return new EmitDelegateConvert(preceedingCode, itemToConvert, targetType);
 }
Ejemplo n.º 37
0
 public EmitCastClass(ILEmitter preceedingCode, TypeReference targetType)
     : base(preceedingCode)
 {
     _targetType = targetType;
 }
Ejemplo n.º 38
0
            public override MethodIL EmitIL()
            {
                ILEmitter emit = new ILEmitter();
                ILCodeStream codeStream = emit.NewCodeStream();

                for (int i = 0; i < Signature.Length; i++)
                    codeStream.EmitLdArg(i);

                codeStream.Emit(ILOpcode.call, emit.NewToken(_mainMethod));

                codeStream.Emit(ILOpcode.ret);

                return emit.Link(this);
            }
Ejemplo n.º 39
0
        public override MethodIL EmitIL()
        {
            ILEmitter emitter = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            ModuleDesc developerExperience = Context.ResolveAssembly(new AssemblyName("System.Private.DeveloperExperience.Console"), false);
            if (developerExperience != null)
            {
                TypeDesc connectorType = developerExperience.GetKnownType("Internal.DeveloperExperience", "DeveloperExperienceConnectorConsole");
                MethodDesc initializeMethod = connectorType.GetKnownMethod("Initialize", null);
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initializeMethod));
            }

            MetadataType startup = Context.GetHelperType("StartupCodeHelpers");

            // Initialize command line args if the class library supports this
            string initArgsName = (Context.Target.OperatingSystem == TargetOS.Windows)
                                ? "InitializeCommandLineArgsW"
                                : "InitializeCommandLineArgs";
            MethodDesc initArgs = startup.GetMethod(initArgsName, null);
            if (initArgs != null)
            {
                codeStream.Emit(ILOpcode.ldarg_0); // argc
                codeStream.Emit(ILOpcode.ldarg_1); // argv
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initArgs));
            }

            // Call program Main
            if (_mainMethod.Signature.Length > 0)
            {
                // TODO: better exception
                if (initArgs == null)
                    throw new Exception("Main() has parameters, but the class library doesn't support them");

                codeStream.Emit(ILOpcode.call, emitter.NewToken(startup.GetKnownMethod("GetMainMethodArguments", null)));
            }
            codeStream.Emit(ILOpcode.call, emitter.NewToken(_mainMethod));

            MethodDesc setLatchedExitCode = startup.GetMethod("SetLatchedExitCode", null);
            MethodDesc shutdown = startup.GetMethod("Shutdown", null);

            // The class library either supports "advanced shutdown", or doesn't. No half-implementations allowed.
            Debug.Assert((setLatchedExitCode != null) == (shutdown != null));

            if (setLatchedExitCode != null)
            {
                // If the main method has a return value, save it
                if (!_mainMethod.Signature.ReturnType.IsVoid)
                {
                    codeStream.Emit(ILOpcode.call, emitter.NewToken(setLatchedExitCode));
                }

                // Ask the class library to shut down and return exit code.
                codeStream.Emit(ILOpcode.call, emitter.NewToken(shutdown));
            }
            else
            {
                // This is a class library that doesn't have SetLatchedExitCode/Shutdown.
                // If the main method returns void, we simply use 0 exit code.
                if (_mainMethod.Signature.ReturnType.IsVoid)
                {
                    codeStream.EmitLdc(0);
                }
            }

            codeStream.Emit(ILOpcode.ret);

            return emitter.Link(this);
        }
Ejemplo n.º 40
0
 public EmitFieldStore(ILEmitter preceedingCode, FieldReference field, ILEmitter fieldValue)
     : base(preceedingCode)
 {
     _fieldValue = fieldValue;
     _field = field;
 }
Ejemplo n.º 41
0
 public EmitReturn(ILEmitter preceedingCode)
     : base(preceedingCode)
 {
 }
Ejemplo n.º 42
0
 public static ILEmitter FindWeak(this ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandlerDelegate, ILEmitter strongEventHandler)
 {
     return new EmitFindWeak(preceedingCode, closedHandlerType, eventHandlerDelegate, strongEventHandler);
 }
Ejemplo n.º 43
0
 public EmitMakeWeak(ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandler, ILEmitter unsubscribe)
     : base(preceedingCode)
 {
     var openMakeWeak = Importer.OpenMakeWeakT;
     _inner = new EmptyEmitter(preceedingCode).Call(openMakeWeak.MakeMethodClosedGeneric(closedHandlerType.GenericArguments[0]), eventHandler, unsubscribe);
 }
Ejemplo n.º 44
0
 public EmptyEmitter(ILEmitter template)
     : this(template.Method, template.Importer)
 {
 }
Ejemplo n.º 45
0
 // Code is linear: each emitter must have a preceeding emitter
 protected IlEmitterBase(ILEmitter preceedingCode)
 {
     _preceedingCode = preceedingCode;
 }
Ejemplo n.º 46
0
 public EmitLoadMethod(ILEmitter preceedingCode, MethodReference targetMethod)
     : base(preceedingCode)
 {
     _targetMethod = targetMethod;
 }
Ejemplo n.º 47
0
 public static ILEmitter MakeWeak(this ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandler, ILEmitter unsubscribe)
 {
     return new EmitMakeWeak(preceedingCode, closedHandlerType, eventHandler, unsubscribe);
 }
Ejemplo n.º 48
0
 public EmitNewObject(ILEmitter preceedingCode, MethodReference ctor, params ILEmitter[] ctorParameters)
     : base(preceedingCode)
 {
     _ctorParameters = ctorParameters.Aggregate((prev, next) => prev.Concat(next));
     _ctor = ctor;
 }
 public static ILEmitter CallDelegateRemove(this ILEmitter preceedingCode, ILEmitter itemToRemoveFrom, ILEmitter itemToRemove)
 {
     return new EmitDelegateRemove(preceedingCode, itemToRemoveFrom, itemToRemove);
 }
Ejemplo n.º 50
0
 public EmitLdToken(ILEmitter preceedingCode, TypeReference targetType)
     : base(preceedingCode)
 {
     _targetType = targetType;
 }
Ejemplo n.º 51
0
 public static ILEmitter StoreField(this ILEmitter preceedingCode, ILEmitter fieldValue, FieldReference field)
 {
     return new EmitFieldStore(preceedingCode, field, fieldValue);
 }
Ejemplo n.º 52
0
 public EmitFindWeak(ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandlerDelegate, ILEmitter strongEventHandler)
     : base(preceedingCode)
 {
     var openFindWeak = Importer.OpenFindWeakT;
     _inner = new EmptyEmitter(preceedingCode).Call(openFindWeak.MakeMethodClosedGeneric(closedHandlerType.GenericArguments[0]), eventHandlerDelegate, strongEventHandler);
 }
Ejemplo n.º 53
0
 public EmitFieldLoad(ILEmitter preceedingCode, FieldReference field)
     : base(preceedingCode)
 {
     _field = field;
 }
 public EmitDelegateRemove(ILEmitter preceedingCode, ILEmitter itemToRemoveFrom, ILEmitter itemToRemove)
     : base(preceedingCode)
 {
     _inner = new EmptyEmitter(preceedingCode).Call(Importer.DelegateRemove, itemToRemoveFrom, itemToRemove);
 }