internal void Load() { _il.Emit(OpCodes.Ldloc, _lb); }
public static void EmitMarkLabel(this ILProcessor processor, VariableDefinition label) { processor.Emit(OpCodes.Ldloc, label); processor.Emit(OpCodes.Callvirt, Program.MethodReferences["MarkLabel"]); }
private static void EmitCall(ILProcessor il, MethodReference reference) { il.Emit(OpCodes.Call, reference); }
public static void EmitPushConst(this ILProcessor ilg, int value) { switch (value) { case -1: ilg.Emit(OpCodes.Ldc_I4_M1); return; case 0: ilg.Emit(OpCodes.Ldc_I4_0); return; case 1: ilg.Emit(OpCodes.Ldc_I4_1); return; case 2: ilg.Emit(OpCodes.Ldc_I4_2); return; case 3: ilg.Emit(OpCodes.Ldc_I4_3); return; case 4: ilg.Emit(OpCodes.Ldc_I4_4); return; case 5: ilg.Emit(OpCodes.Ldc_I4_5); return; case 6: ilg.Emit(OpCodes.Ldc_I4_6); return; case 7: ilg.Emit(OpCodes.Ldc_I4_7); return; case 8: ilg.Emit(OpCodes.Ldc_I4_8); return; } if (value >= -128 && value <= 127) { ilg.Emit(OpCodes.Ldc_I4_S, (sbyte)value); return; } ilg.Emit(OpCodes.Ldc_I4, value); }
private void AddInsOfRemoveEvent(ILProcessor ilOfInit, List <Instruction> instructions, TypeDefinition typeDef) { MethodDefinition methodCall = typeDef.GetOrCreateMethod("Call", MethodAttributes.Public, typeof(void)); methodCall.Body.Instructions.Clear(); var fieldOfRemoveEvent = typeDef.DeclaringType.Fields.FirstOrDefault(a => a.Name == "___Info_Of_RemoveEvent___"); var il = methodCall.Body.GetILProcessor(); foreach (var ins in instructions) { if (ins.OpCode == OpCodes.Ldloc && ins.Operand is VariableDefinition variable) { var fieldName = "field" + variable.Index; var field = typeDef.GetOrCreateField(fieldName, FieldAttributes.Public, variable.VariableType); ilOfInit.Emit(OpCodes.Ldarg_0); ilOfInit.Emit(OpCodes.Ldfld, fieldOfRemoveEvent); ilOfInit.Emit(OpCodes.Ldloc, variable); ilOfInit.Emit(OpCodes.Stfld, field); methodCall.Body.Instructions.Add(Instruction.Create(Ldarg_0)); methodCall.Body.Instructions.Add(Instruction.Create(Ldfld, field)); } else { bool isReplaced = false; if (ins.OpCode == OpCodes.Callvirt && ins.Operand is MethodReference method) { if (method.Name.StartsWith("add_")) { var eventName = method.Name.Substring("add_".Length); TypeReference _; var typeOfEvent = method.DeclaringType.GetEvent(a => a.Name == eventName, out _); if (typeOfEvent is EventDefinition) { var methodOfRemoveEvent = typeDef.Module.ImportReference(method.DeclaringType.ResolveCached()?.Methods.FirstOrDefault(a => a.Name == "remove_" + eventName)); if (null != methodOfRemoveEvent) { var newIns = Instruction.Create(ins.OpCode, methodOfRemoveEvent); methodCall.Body.Instructions.Add(newIns); isReplaced = true; } } } } if (false == isReplaced) { methodCall.Body.Instructions.Add(ins); } } } methodCall.Body.Instructions.Add(Instruction.Create(Ret)); var removeEventMethod = typeDef.DeclaringType.Methods.FirstOrDefault(a => a.Name == "RemoveEventsInXaml"); if (null != removeEventMethod) { removeEventMethod.Body.Instructions.Clear(); var ilRemoveEvent = removeEventMethod.Body.GetILProcessor(); ilRemoveEvent.Emit(Ldarg_0); ilRemoveEvent.Emit(Ldfld, fieldOfRemoveEvent); ilRemoveEvent.Emit(Dup); var insOfCall = Instruction.Create(Call, methodCall.Resolve()); ilRemoveEvent.Emit(Brtrue_S, insOfCall); ilRemoveEvent.Emit(Pop); var endIns = Instruction.Create(Ret); ilRemoveEvent.Emit(Br_S, endIns); ilRemoveEvent.Append(insOfCall); ilRemoveEvent.Append(endIns); } }
static int EmitParameters(MethodDefinition method, MethodDefinition native, MethodBody body, ILProcessor il) { int i; for (i = 0; i < method.Parameters.Count; i++) { var parameter = method.Parameters[i]; var p = method.Module.Import(method.Parameters[i].ParameterType); il.Emit(OpCodes.Ldarg, i); if (p.Name.Contains("Int32") && native.Parameters[i].ParameterType.Name.Contains("IntPtr")) { // This is a convenience Int32 overload for an IntPtr (size_t) parameter. // We need to convert the loaded argument to IntPtr. il.Emit(OpCodes.Conv_I); } else if (p.Name == "StringBuilder") { EmitStringBuilderParameter(method, parameter, body, il); } else if (p.Name == "String" && !p.IsArray) { EmitStringParameter(method, parameter, body, il); } else if (p.IsByReference) { body.Variables.Add(new VariableDefinition(new PinnedType(p))); var index = body.Variables.Count - 1; il.Emit(OpCodes.Stloc, index); il.Emit(OpCodes.Ldloc, index); il.Emit(OpCodes.Conv_I); } else if (p.IsArray) { if (p.Name != method.Module.Import(typeof(string[])).Name) { // .Net treats 1d arrays differently than higher rank arrays. // 1d arrays are directly supported by instructions such as ldlen and ldelema. // Higher rank arrays must be accessed through System.Array methods such as get_Length. // 1d array: // check array is not null // check ldlen array > 0 // ldc.i4.0 // ldelema // 2d array: // check array is not null // check array.get_Length() > 0 // ldc.i4.0 // ldc.i4.0 // call instance T& T[0..., 0...]::Address(int32, int32) // Mono treats everything as a 1d array. // Interestingly, the .Net approach works on both Mono and .Net. // The Mono approach fails when using high-rank arrays on .Net. // We should report a bug to http://bugzilla.xamarin.com // Pin the array and pass the address // of its first element. var array = (ArrayType)p; var element_type = p.GetElementType(); body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type)))); int pinned_index = body.Variables.Count - 1; var empty = il.Create(OpCodes.Ldc_I4, 0); var pin = il.Create(OpCodes.Ldarg, i); var end = il.Create(OpCodes.Stloc, pinned_index); // if (array == null) goto empty il.Emit(OpCodes.Brfalse, empty); // else if (array.Length != 0) goto pin il.Emit(OpCodes.Ldarg, i); if (array.Rank == 1) { il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Conv_I4); } else { var get_length = method.Module.Import( mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length")); il.Emit(OpCodes.Callvirt, get_length); } il.Emit(OpCodes.Brtrue, pin); // empty: IntPtr ptr = IntPtr.Zero il.Append(empty); il.Emit(OpCodes.Conv_U); il.Emit(OpCodes.Br, end); // pin: &array[0] il.Append(pin); if (array.Rank == 1) { // 1d array (vector), address is taken by ldelema il.Emit(OpCodes.Ldc_I4, 0); il.Emit(OpCodes.Ldelema, element_type); } else { // 2d-3d array, address must be taken as follows: // call instance T& T[0..., 0..., 0...]::Address(int, int, int) ByReferenceType t_ref = array.ElementType.MakeByReferenceType(); MethodReference get_address = new MethodReference("Address", t_ref, array); for (int r = 0; r < array.Rank; r++) { get_address.Parameters.Add(new ParameterDefinition(TypeInt32)); } get_address.HasThis = true; // emit the get_address call for (int r = 0; r < array.Rank; r++) { il.Emit(OpCodes.Ldc_I4, 0); } il.Emit(OpCodes.Call, get_address); } // end: fixed (IntPtr ptr = &array[0]) il.Append(end); il.Emit(OpCodes.Ldloc, pinned_index); il.Emit(OpCodes.Conv_I); } else { EmitStringArrayParameter(method, parameter, body, il); } } } return(i); }
public static void EmitPushConst(this ILProcessor ilg, float value) { ilg.Emit(OpCodes.Ldc_R4, value); }
protected override void PackCore(out AssemblyDefinition asm, PackerParameter parameter) { ModuleDefinition originMain = parameter.Modules[0]; asm = AssemblyDefinition.CreateAssembly(originMain.Assembly.Name, originMain.Name, new ModuleParameters() { Architecture = originMain.Architecture, Kind = originMain.Kind, Runtime = originMain.Runtime }); ModuleDefinition mod = asm.MainModule; Random rand = new Random(); int key0 = rand.Next(0, 0xff); int key1 = rand.Next(0, 0xff); EmbeddedResource res = new EmbeddedResource(Encoding.UTF8.GetString(Guid.NewGuid().ToByteArray()), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[0], key0)); mod.Resources.Add(res); for (int i = 1; i < parameter.Modules.Length; i++) { if (parameter.Modules[i].IsMain) { mod.Resources.Add(new EmbeddedResource(GetNewName(parameter.Modules[i].Assembly.Name.FullName, key1), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[i], key0))); } else { mod.Resources.Add(new EmbeddedResource(GetNewName(parameter.Modules[i].Name, key1), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[i], key0))); //TODO: Support for multi-module asssembly } } AssemblyDefinition ldrC = AssemblyDefinition.ReadAssembly(typeof(Iid).Assembly.Location); TypeDefinition t = CecilHelper.Inject(mod, ldrC.MainModule.GetType("CompressShell")); foreach (Instruction inst in t.GetStaticConstructor().Body.Instructions) { if (inst.Operand is string) { inst.Operand = res.Name; } } foreach (Instruction inst in t.Methods.FirstOrDefault(mtd => mtd.Name == "Decrypt").Body.Instructions) { if (inst.Operand is int && (int)inst.Operand == 0x12345678) { inst.Operand = key0; } } foreach (Instruction inst in t.Methods.FirstOrDefault(mtd => mtd.Name == "DecryptAsm").Body.Instructions) { if (inst.Operand is int && (int)inst.Operand == 0x12345678) { inst.Operand = key1; } } t.Namespace = ""; t.DeclaringType = null; t.IsNestedPrivate = false; t.IsNotPublic = true; mod.Types.Add(t); MethodDefinition cctor = new MethodDefinition(".cctor", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static, mod.TypeSystem.Void); mod.GetType("<Module>").Methods.Add(cctor); MethodBody bdy = cctor.Body = new MethodBody(cctor); ILProcessor psr = bdy.GetILProcessor(); psr.Emit(OpCodes.Call, mod.Import(typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod())); psr.Emit(OpCodes.Ldnull); psr.Emit(OpCodes.Ldftn, t.Methods.FirstOrDefault(mtd => mtd.Name == "DecryptAsm")); psr.Emit(OpCodes.Newobj, mod.Import(typeof(ResolveEventHandler).GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }))); psr.Emit(OpCodes.Callvirt, mod.Import(typeof(AppDomain).GetEvent("AssemblyResolve").GetAddMethod())); psr.Emit(OpCodes.Ret); MethodDefinition main = t.Methods.FirstOrDefault(mtd => mtd.Name == "Main"); mod.EntryPoint = main; }
private static GeneratedVariableIdentifier EmitStringOutParameter(MethodDefinition method, ParameterDefinition parameter, MethodBody body, ILProcessor il) { // void GetShaderInfoLog(..., out String foo) // IntPtr foo_string_ptr; // try { // foo_string_ptr = Marshal.AllocHGlobal(count + 1); // glGetShaderInfoLog(..., foo_string_ptr); // foo = MarshalPtrToString(foo_string_ptr); // } // finally { // Marshal.FreeHGlobal(foo_string_ptr); // } // Pop off the string parameter that would of just been loaded il.Emit(OpCodes.Pop); // Make sure we have imported Marshal::AllocHGlobal var alloc_hglobal = method.Module.ImportReference(TypeMarshal.Methods.First(m => m.Name == "AllocHGlobal")); // IntPtr ptr; var variableDefinition = new VariableDefinition(TypeIntPtr); body.Variables.Add(variableDefinition); int stringPtrIndex = body.Variables.Count - 1; GeneratedVariableIdentifier stringPtrVar = new GeneratedVariableIdentifier(body, variableDefinition, parameter.Name + "_string_ptr"); // ptr = Marshal.AllocHGlobal(count + 1); var count = GetCountAttribute(parameter); if (count == null) { // We need a count attribute so we know what size to make the // string buffer. Currently every string out parameter has a // count attribute but this check is in place to make things // clearer if this case is ever hit. throw new InvalidOperationException(string.Format("{0}({1}) doesn't have a count attribute", method.Name, parameter.Name)); } if (count.Count != 0) { // Fixed size il.Emit(OpCodes.Ldc_I4, count.Count); } else if (count.Parameter != null) { // Parameter sized var countVariable = EmitCountVariable(method, body, il, count.Parameter); il.Emit(OpCodes.Ldloc, countVariable.Index); } else if (count.Computed != null) { if (method.Name == "GetActiveVarying") { // GetActiveVaryingNV's name parameter has a count of "COMPSIZE(program,index,bufSize)" but really it should be bufSize. var countVariable = EmitCountVariable(method, body, il, "bufSize"); il.Emit(OpCodes.Ldloc, countVariable.Index); } else { // Computed counts are hard and require manual reading of the specification for each one. throw new NotSupportedException(string.Format("{0}({1}) requires a computed count: {2}", method.Name, parameter.Name, count.Computed)); } } il.Emit(OpCodes.Ldc_I4, 1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Call, alloc_hglobal); il.Emit(OpCodes.Stloc, stringPtrIndex); il.Emit(OpCodes.Ldloc, stringPtrIndex); // We'll emit the try-finally block in the epilogue implementation, // because we haven't yet emitted all necessary instructions here. return(stringPtrVar); }
public override void EmitSetCodeAfterValue(ILProcessor il, TypeReference type) { il.Emit(OpCodes.Callvirt, ilistSetItem); }
/// <summary> /// Replaces a method body with the signature: /// <code> /// public static unsafe void WriteArray<T>(IntPtr pSrc, T[] data, int startIndexInArray, int count) where T : struct /// </code> /// </summary> /// <param name="method">Method which will have its body replaced</param> private static unsafe void CreateReadArrayMethod(MethodDefinition method) { //Make sure we import IntPtr::op_explicit(void*) MethodInfo opExplicitInfo = typeof(IntPtr).GetMethod("op_Explicit", new Type[] { typeof(void *) }); MethodReference opExplicitRef = method.Module.Import(opExplicitInfo); method.Body.Instructions.Clear(); method.Body.InitLocals = true; ILProcessor ilGen = method.Body.GetILProcessor(); TypeReference paramT = method.GenericParameters[0]; //local(0) Pinned T method.Body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(paramT)))); //fixed(void* pinnedData = &data[startIndexInArray]) ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Ldelema, paramT); ilGen.Emit(OpCodes.Stloc_0); //Push (0) pinnedData for memcpy ilGen.Emit(OpCodes.Ldloc_0); //Push (1) pSrc, explicitly convert to void* ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, opExplicitRef); //totalSize = sizeof(T) * count ilGen.Emit(OpCodes.Sizeof, paramT); ilGen.Emit(OpCodes.Conv_I4); ilGen.Emit(OpCodes.Ldarg_3); ilGen.Emit(OpCodes.Mul); //Memcpy ilGen.Emit(OpCodes.Unaligned, (byte)1); ilGen.Emit(OpCodes.Cpblk); //Return ilGen.Emit(OpCodes.Ret); }
public override void EmitSetCodeBeforeValue(ILProcessor il, TypeReference type) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, indexField); }
public override void EmitGetCode(ILProcessor il, TypeReference type) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, indexField); il.Emit(OpCodes.Callvirt, ilistGetItem); }
public List <Instruction> Convert(ILProcessor il, List <Instruction> opCodes, TypeReference source, TypeReference target, bool isAddress) { Debug.Assert(!target.IsByReference); if (target == source) { return(opCodes); } if (source.IsByReference) { Debug.Assert(!isAddress); TypeReference argType = source.GetElementType(); OpCode opCode = s_ldindOpCodes[GetTypeCode(argType)]; if (!opCode.Equals(OpCodes.Nop)) { opCodes.Add(il.Create(opCode)); } else { opCodes.Add(il.Create(OpCodes.Ldobj, argType)); } Convert(il, opCodes, argType, target, isAddress); return(opCodes); } if (target.IsValueType) { if (source.IsValueType) { OpCode opCode = s_convOpCodes[GetTypeCode(target)]; Debug.Assert(!opCode.Equals(OpCodes.Nop)); opCodes.Add(il.Create(opCode)); } else { Debug.Assert(IsAssignableFrom(source, target)); opCodes.Add(il.Create(OpCodes.Unbox_Any, ModuleDefinition.ImportReference(target))); if (!isAddress) { OpCode opCode = s_ldindOpCodes[GetTypeCode(target)]; if (!opCode.Equals(OpCodes.Nop)) { opCodes.Add(il.Create(opCode)); } else { opCodes.Add(il.Create(OpCodes.Ldobj, target)); } } } } else if (IsAssignableFrom(target, source)) { if (source.IsValueType) { if (isAddress) { OpCode opCode = s_ldindOpCodes[GetTypeCode(source)]; if (!opCode.Equals(OpCodes.Nop)) { il.Emit(opCode); } else { il.Emit(OpCodes.Ldobj, source); } } opCodes.Add(il.Create(OpCodes.Box, ModuleDefinition.ImportReference(source))); } } else { if (target.IsGenericParameter) { opCodes.Add(il.Create(OpCodes.Unbox_Any, ModuleDefinition.ImportReference(target))); } else { opCodes.Add(il.Create(OpCodes.Castclass, ModuleDefinition.ImportReference(target))); } } return(opCodes); }
public static void CreateArrayAndStoreToVariable(this ILProcessor processor, VariableDefinition variable, TypeReference elementType, sbyte arraySize) { processor.Emit(OpCodes.Ldc_I4_S, arraySize); processor.Emit(OpCodes.Newarr, elementType); processor.Emit(OpCodes.Stloc_S, variable); }
public static void EmitLdc_4(this ILProcessor processor, int val) { switch (val) { case 0: processor.Emit(OpCodes.Ldc_I4_0); break; case 1: processor.Emit(OpCodes.Ldc_I4_1); break; case 2: processor.Emit(OpCodes.Ldc_I4_2); break; case 3: processor.Emit(OpCodes.Ldc_I4_3); break; case 4: processor.Emit(OpCodes.Ldc_I4_4); break; case 5: processor.Emit(OpCodes.Ldc_I4_5); break; case 6: processor.Emit(OpCodes.Ldc_I4_6); break; case 7: processor.Emit(OpCodes.Ldc_I4_7); break; case 8: processor.Emit(OpCodes.Ldc_I4_8); break; default: if (val >= sbyte.MinValue && val <= sbyte.MaxValue) { processor.Emit(OpCodes.Ldc_I4_S, (sbyte)val); } else if (val >= byte.MinValue && val <= byte.MaxValue) { processor.Emit(OpCodes.Ldc_I4_S, (byte)val); } else { processor.Emit(OpCodes.Ldc_I4, val); } break; } }
static void EmitConvenienceWrapper(MethodDefinition wrapper, MethodDefinition native, int difference, MethodBody body, ILProcessor il) { if (wrapper.Parameters.Count > 2) { // Todo: emit all parameters bar the last two throw new NotImplementedException(); } if (wrapper.ReturnType.Name != "Void") { if (difference == 2) { // Convert sized out-array/reference to return value, for example: // void GenTextures(int n, int[] textures) -> int GenTexture() // { // const int n = 1; // int buffers; // calli GenTextures(n, &textures); // return result; // } body.Variables.Add(new VariableDefinition(wrapper.ReturnType)); il.Emit(OpCodes.Ldc_I4, 1); // const int n = 1 il.Emit(OpCodes.Ldloca, body.Variables.Count - 1); // &buffers } else if (difference == 1) { // Convert unsized out-array/reference to return value, for example: // void GetBoolean(GetPName pname, out bool data) -> bool GetBoolean(GetPName pname) // { // bool result; // GetBooleanv(pname, &result); // return result; // } body.Variables.Add(new VariableDefinition(wrapper.ReturnType)); EmitParameters(wrapper, native, body, il); il.Emit(OpCodes.Ldloca, body.Variables.Count - 1); } else { Console.Error.WriteLine("Unknown wrapper type for ({0})", native.Name); } } else { if (difference == 1) { // Convert in-array/reference to single element, for example: // void DeleteTextures(int n, ref int textures) -> void DeleteTexture(int texture) // { // const int n = 1; // calli DeleteTextures(n, &textures); // } il.Emit(OpCodes.Ldc_I4, 1); // const int n = 1 il.Emit(OpCodes.Ldarga, wrapper.Parameters.Last()); // &textures } else { Console.Error.WriteLine("Unknown wrapper type for ({0})", native.Name); } } }
public static void LoadType(this ILProcessor il, TypeReference type) { il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, getTypeFromRuntimeHandleMethod); }
public static void EmitPushConst(this ILProcessor ilg, long value) { ilg.Emit(OpCodes.Ldc_I8, value); }
public static void StoreMethodInfo(this ILProcessor il, FieldReference staticField, TypeReference declaringType, MethodDefinition method) { var parameterTypes = method.Parameters.Select(info => info.ParameterType).ToArray(); // The type we want to invoke GetMethod upon il.LoadType(declaringType); // Arg1: methodName il.Emit(OpCodes.Ldstr, method.Name); // Arg2: bindingFlags il.Emit(OpCodes.Ldc_I4, (int)(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)); // Arg3: binder il.Emit(OpCodes.Ldnull); // Arg4: parameterTypes il.Emit(OpCodes.Ldc_I4, parameterTypes.Length); il.Emit(OpCodes.Newarr, typeType); // Copy array for each element we are going to set for (int i = 0; i < parameterTypes.Length; i++) { il.Emit(OpCodes.Dup); } // Set each element for (int i = 0; i < parameterTypes.Length; i++) { il.Emit(OpCodes.Ldc_I4, i); il.LoadType(ModuleDefinition.Import(parameterTypes[i])); il.Emit(OpCodes.Stelem_Any, typeType); } // Arg5: parameterModifiers il.Emit(OpCodes.Ldnull); // Invoke method il.Emit(OpCodes.Call, typeGetMethod); // Store MethodInfo into the static field il.Emit(OpCodes.Stsfld, staticField); }
public static void EmitPushConst(this ILProcessor ilg, double value) { ilg.Emit(OpCodes.Ldc_R8, value); }
private MethodDefinition GenerateInitMethod(MethodDefinition configureMethod, FieldDefinition globalServiceProvider) { var initMethod = new MethodDefinition(nameof(DI.Init), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, ModuleDefinition.ImportReference(typeof(void))); var configureAction = new ParameterDefinition("configure", ParameterAttributes.None, ModuleDefinition.Get <Action <IApplicationBuilder> >()); initMethod.Parameters.Add(configureAction); var applicationBuilder = new VariableDefinition(ModuleDefinition.Get <IApplicationBuilder>()); initMethod.Body.Variables.Add(applicationBuilder); ILProcessor initProcessor = initMethod.Body.GetILProcessor(); Instruction createApplicationbuilder = Instruction.Create(OpCodes.Newobj, ModuleDefinition.GetDefaultConstructor <ApplicationBuilder>()); initProcessor.Emit(OpCodes.Ldsfld, globalServiceProvider); initProcessor.Emit(OpCodes.Brfalse_S, createApplicationbuilder); //Compare initProcessor.Emit(OpCodes.Newobj, ModuleDefinition.GetConstructor <AlreadyInitializedException>()); initProcessor.Emit(OpCodes.Throw); initProcessor.Append(createApplicationbuilder); initProcessor.Emit(OpCodes.Stloc_0); initProcessor.Emit(OpCodes.Ldloc_0); //applicationBuilder initProcessor.Emit(OpCodes.Ldnull); initProcessor.Emit(OpCodes.Ldftn, configureMethod); initProcessor.Emit(OpCodes.Newobj, ModuleDefinition.GetConstructor <Action <IServiceCollection> >()); initProcessor.Emit(OpCodes.Callvirt, ModuleDefinition.GetMethod <IApplicationBuilder>(nameof(IApplicationBuilder.ConfigureServices))); initProcessor.Emit(OpCodes.Pop); MethodDefinition setupMethod = FindSetupMethod(); if (setupMethod != null) { InternalLogDebug($"Found setup method '{setupMethod.FullName}'", DebugLogLevel.Default); initProcessor.Emit(OpCodes.Ldloc_0); //applicationBuilder initProcessor.Emit(OpCodes.Call, setupMethod); initProcessor.Emit(OpCodes.Nop); } else { InternalLogDebug("No setup method found", DebugLogLevel.Default); } Instruction loadForBuild = Instruction.Create(OpCodes.Ldloc_0); initProcessor.Emit(OpCodes.Ldarg_0); initProcessor.Emit(OpCodes.Brfalse_S, loadForBuild); initProcessor.Emit(OpCodes.Ldarg_0); initProcessor.Emit(OpCodes.Ldloc_0); initProcessor.Emit(OpCodes.Callvirt, ModuleDefinition.GetMethod <Action <IApplicationBuilder> >(nameof(Action <IApplicationBuilder> .Invoke))); initProcessor.Append(loadForBuild); var buildMethod = ModuleDefinition.GetMethod <IApplicationBuilder>(nameof(IApplicationBuilder.Build)); buildMethod.ReturnType = Import.IServiceProvider; //Must update the return type to handle .net core apps initProcessor.Emit(OpCodes.Callvirt, buildMethod); initProcessor.Emit(OpCodes.Stsfld, globalServiceProvider); initProcessor.Emit(OpCodes.Ldsfld, globalServiceProvider); initProcessor.Emit(OpCodes.Call, Import.GlobalDI_Register); initProcessor.Emit(OpCodes.Ret); return(initMethod); }
private void EmitLoad(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField, ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, VariableDefinition marshalerVar, VariableDefinition var) { EmitLoad(processor, loadBuffer, offsetField, nativePropertyField, typeInfo, propertyInfo, marshalerVar); processor.Emit(OpCodes.Stloc, var); }
private MethodDefinition GenerateDisposeMethod(FieldDefinition globalServiceProvider) { var disposeMethod = new MethodDefinition(nameof(DI.Dispose), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, ModuleDefinition.ImportReference(typeof(void))); VariableDefinition disposable = new VariableDefinition(ModuleDefinition.Get <IDisposable>()); disposeMethod.Body.Variables.Add(disposable); ILProcessor processor = disposeMethod.Body.GetILProcessor(); Instruction afterDispose = Instruction.Create(OpCodes.Nop); processor.Emit(OpCodes.Ldsfld, globalServiceProvider); processor.Emit(OpCodes.Isinst, ModuleDefinition.Get <IDisposable>()); processor.Emit(OpCodes.Dup); processor.Emit(OpCodes.Stloc_0); //disposable processor.Emit(OpCodes.Brfalse_S, afterDispose); processor.Emit(OpCodes.Ldloc_0); //disposable processor.Emit(OpCodes.Callvirt, ModuleDefinition.GetMethod <IDisposable>(nameof(IDisposable.Dispose))); processor.Append(afterDispose); processor.Emit(OpCodes.Ldsfld, globalServiceProvider); processor.Emit(OpCodes.Call, Import.GlobalDI_Unregister); processor.Emit(OpCodes.Pop); processor.Emit(OpCodes.Ldnull); processor.Emit(OpCodes.Stsfld, globalServiceProvider); processor.Emit(OpCodes.Ret); return(disposeMethod); }
public static void EmitType(this ILProcessor processor, TypeReference reference) { processor.Emit(OpCodes.Ldtoken, reference); processor.Emit(OpCodes.Call, Program.MethodReferences["GetTypeFromHandle"]); }
private MethodDefinition GenerateConfigureMethod(Mapping mapping, TypeDefinition containerType) { var method = new MethodDefinition(nameof(DI.AddServices), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, ModuleDefinition.ImportReference(typeof(void))); var serviceCollection = new ParameterDefinition("collection", ParameterAttributes.None, ModuleDefinition.Get <IServiceCollection>()); method.Parameters.Add(serviceCollection); ILProcessor processor = method.Body.GetILProcessor(); MethodDefinition funcCtor = ModuleDefinition.ResolveCoreConstructor(typeof(Func <,>)); if (mapping != null) { int factoryIndex = 0; foreach (TypeMap map in mapping) { try { InternalLogDebug($"Processing map for {map.TargetType.FullName}", DebugLogLevel.Verbose); MethodDefinition factoryMethod = GenerateFactoryMethod(map.TargetType, factoryIndex); if (factoryMethod == null) { InternalLogDebug($"No acceptable constructor for '{map.TargetType.FullName}', skipping map", DebugLogLevel.Verbose); continue; } containerType.Methods.Add(factoryMethod); factoryIndex++; foreach (TypeLifetime typeLifetime in map.Lifetimes) { processor.Emit(OpCodes.Ldarg_0); //collection parameter processor.Emit(OpCodes.Ldnull); processor.Emit(OpCodes.Ldftn, factoryMethod); processor.Emit(OpCodes.Newobj, ModuleDefinition.ImportReference( funcCtor.MakeGenericTypeConstructor(Import.IServiceProvider, map.TargetType))); processor.Emit(OpCodes.Ldc_I4, typeLifetime.Keys.Count); processor.Emit(OpCodes.Newarr, Import.System_Type); int arrayIndex = 0; foreach (TypeDefinition key in typeLifetime.Keys) { TypeReference importedKey = ModuleDefinition.ImportReference(key); InternalLogDebug( $"Mapping {importedKey.FullName} => {map.TargetType.FullName} ({typeLifetime.Lifetime})", DebugLogLevel.Default); processor.Emit(OpCodes.Dup); processor.Emit(OpCodes.Ldc_I4, arrayIndex++); processor.Emit(OpCodes.Ldtoken, importedKey); processor.Emit(OpCodes.Call, Import.Type_GetTypeFromHandle); processor.Emit(OpCodes.Stelem_Ref); } processor.Emit(OpCodes.Ldc_I4, (int)typeLifetime.Lifetime); var genericAddMethod = new GenericInstanceMethod(Import.ServiceCollectionMixins_AddAutoDIService); genericAddMethod.GenericArguments.Add(ModuleDefinition.ImportReference(map.TargetType)); processor.Emit(OpCodes.Call, genericAddMethod); processor.Emit(OpCodes.Pop); } } catch (MultipleConstructorAutoDIException e) { LogError($"Failed to create map for {map}\r\n{e}"); } catch (Exception e) { LogWarning($"Failed to create map for {map}\r\n{e}"); } } } processor.Emit(OpCodes.Ret); return(method); }
private static void EmitEntryPoint(FieldDefinition entry_points, ILProcessor il, int slot) { il.Emit(OpCodes.Ldsfld, entry_points); il.Emit(OpCodes.Ldc_I4, slot); il.Emit(OpCodes.Ldelem_I); }
public void should_find_call_arguments() { _il.Emit(OpCodes.Ldc_I4_0); var p0 = _il.Body.Instructions.Last(); _il.Emit(OpCodes.Nop); _il.Emit(OpCodes.Ldc_I4_1); var p1 = _il.Body.Instructions.Last(); _il.Emit(OpCodes.Ldc_I4_8); _il.Emit(OpCodes.Nop); _il.Emit(OpCodes.Nop); _il.Emit(OpCodes.Ldc_I4_8); _il.Emit(OpCodes.Add); var p2 = _il.Body.Instructions.Last(); _il.Emit(OpCodes.Call, _methodPop3Push0); var callInstruction = _il.Body.Instructions.Last(); var result = callInstruction.GetArgumentPushInstructions(); result.ShouldEqual(new[] { p0, p1, p2 }); }
private static DebugVariables EmitDebugPrologue(MethodDefinition wrapper, ILProcessor il) { DebugVariables vars = null; if (il.Body.Method.Name != "GetError") { // Pull out the namespace name, method fullname will look // something like "type namespace.class::method(type arg)" var module = il.Body.Method.FullName; module = module.Substring(module.IndexOf(' ') + 1); module = module.Substring(0, module.IndexOf("::", StringComparison.Ordinal)); module = module.Substring(0, module.LastIndexOf('.')); // Only works for Graphics modules due to hardcoded use of // osuTK.Graphics.GraphicsContext if (module == "osuTK.Graphics.OpenGL4" || module == "osuTK.Graphics.OpenGL" || module == "osuTK.Graphics.ES10" || module == "osuTK.Graphics.ES11" || module == "osuTK.Graphics.ES20" || module == "osuTK.Graphics.ES30") { var errorHelperType = wrapper.Module.GetType(module, "ErrorHelper"); if (errorHelperType != null) { vars = new DebugVariables(); vars.ErrorHelperType = errorHelperType; // GraphicsContext type var graphicsContext = wrapper.Module.Types.First( type => type.FullName == "osuTK.Graphics.GraphicsContext"); // IGraphicsContext type var iGraphicsContext = wrapper.Module.Types.First( type => type.FullName == "osuTK.Graphics.IGraphicsContext"); // Get the constructor that takes a GraphicsContext parameter var ctor = vars.ErrorHelperType.GetConstructors().FirstOrDefault( c => c.Parameters.Count == 1 && c.Parameters[0].ParameterType.FullName == iGraphicsContext.FullName); if (ctor == null) { throw new InvalidOperationException( String.Format( "{0} does needs a constructor taking {1}", errorHelperType, graphicsContext)); } // GraphicsContext.CurrentContext property getter vars.Get_CurrentContext = graphicsContext.Methods.First( method => method.Name == "get_CurrentContext"); vars.Set_ErrorChecking = graphicsContext.Methods.First( method => method.Name == "set_ErrorChecking"); vars.ErrorHelperLocal = new VariableDefinition(vars.ErrorHelperType); // using (new ErrorHelper(GraphicsContext.CurrentContext)) { ... il.Body.Variables.Add(vars.ErrorHelperLocal); il.Emit(OpCodes.Ldloca, vars.ErrorHelperLocal); il.Emit(OpCodes.Call, vars.Get_CurrentContext); il.Emit(OpCodes.Call, ctor); vars.BeginTry = Instruction.Create(OpCodes.Nop); il.Append(vars.BeginTry); // Special case Begin to turn off error checking. if (il.Body.Method.Name == "Begin") { il.Emit(OpCodes.Call, vars.Get_CurrentContext); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Conv_I1); il.Emit(OpCodes.Call, vars.Set_ErrorChecking); } } } } return(vars); }
internal void Get(int i) { _il.Emit(OpCodes.Ldarg, i + 1); }