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; }
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); }
/// <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); }
/// <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); }
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); }
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); }
/// <summary> /// Define new instance of CallSite<<paramref name="delegateType"/>> 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); }
/// <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); } }
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); } }
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()); }
/// <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); } }
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); }
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); }
/// <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); }
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 ... } }
/// <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)); }
/// <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(); }
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); } }
/// <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); }
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; }
/// <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)); }
/// <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); }
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); }
/// <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); }
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); }
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); }
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)); }
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); }
public EmitTypeOf(ILEmitter preceedingCode, TypeReference targetType) : base(preceedingCode) { _inner = new EmptyEmitter(preceedingCode).Call(Importer.GetTypeFromHandle, new EmptyEmitter(preceedingCode).LdToken(targetType)); }
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); }
public EmitCastClass(ILEmitter preceedingCode, TypeReference targetType) : base(preceedingCode) { _targetType = targetType; }
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); }
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); }
public EmitFieldStore(ILEmitter preceedingCode, FieldReference field, ILEmitter fieldValue) : base(preceedingCode) { _fieldValue = fieldValue; _field = field; }
public EmitReturn(ILEmitter preceedingCode) : base(preceedingCode) { }
public static ILEmitter FindWeak(this ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandlerDelegate, ILEmitter strongEventHandler) { return new EmitFindWeak(preceedingCode, closedHandlerType, eventHandlerDelegate, strongEventHandler); }
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); }
public EmptyEmitter(ILEmitter template) : this(template.Method, template.Importer) { }
// Code is linear: each emitter must have a preceeding emitter protected IlEmitterBase(ILEmitter preceedingCode) { _preceedingCode = preceedingCode; }
public EmitLoadMethod(ILEmitter preceedingCode, MethodReference targetMethod) : base(preceedingCode) { _targetMethod = targetMethod; }
public static ILEmitter MakeWeak(this ILEmitter preceedingCode, GenericInstanceType closedHandlerType, ILEmitter eventHandler, ILEmitter unsubscribe) { return new EmitMakeWeak(preceedingCode, closedHandlerType, eventHandler, unsubscribe); }
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); }
public EmitLdToken(ILEmitter preceedingCode, TypeReference targetType) : base(preceedingCode) { _targetType = targetType; }
public static ILEmitter StoreField(this ILEmitter preceedingCode, ILEmitter fieldValue, FieldReference field) { return new EmitFieldStore(preceedingCode, field, fieldValue); }
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); }
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); }