Exemple #1
0
 internal void Load()
 {
     _il.Emit(OpCodes.Ldloc, _lb);
 }
Exemple #2
0
 public static void EmitMarkLabel(this ILProcessor processor, VariableDefinition label)
 {
     processor.Emit(OpCodes.Ldloc, label);
     processor.Emit(OpCodes.Callvirt, Program.MethodReferences["MarkLabel"]);
 }
Exemple #3
0
 private static void EmitCall(ILProcessor il, MethodReference reference)
 {
     il.Emit(OpCodes.Call, reference);
 }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        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);
        }
Exemple #7
0
 public static void EmitPushConst(this ILProcessor ilg, float value)
 {
     ilg.Emit(OpCodes.Ldc_R4, value);
 }
Exemple #8
0
        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;
        }
Exemple #9
0
        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);
        }
Exemple #10
0
 public override void EmitSetCodeAfterValue(ILProcessor il, TypeReference type)
 {
     il.Emit(OpCodes.Callvirt, ilistSetItem);
 }
Exemple #11
0
        /// <summary>
        /// Replaces a method body with the signature:
        /// <code>
        /// public static unsafe void WriteArray&lt;T&gt;(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);
        }
Exemple #12
0
 public override void EmitSetCodeBeforeValue(ILProcessor il, TypeReference type)
 {
     il.Emit(OpCodes.Ldarg_0);
     il.Emit(OpCodes.Ldfld, indexField);
 }
Exemple #13
0
 public override void EmitGetCode(ILProcessor il, TypeReference type)
 {
     il.Emit(OpCodes.Ldarg_0);
     il.Emit(OpCodes.Ldfld, indexField);
     il.Emit(OpCodes.Callvirt, ilistGetItem);
 }
Exemple #14
0
    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);
 }
Exemple #16
0
        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;
            }
        }
Exemple #17
0
        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);
                }
            }
        }
Exemple #18
0
 public static void LoadType(this ILProcessor il, TypeReference type)
 {
     il.Emit(OpCodes.Ldtoken, type);
     il.Emit(OpCodes.Call, getTypeFromRuntimeHandleMethod);
 }
Exemple #19
0
 public static void EmitPushConst(this ILProcessor ilg, long value)
 {
     ilg.Emit(OpCodes.Ldc_I8, value);
 }
Exemple #20
0
        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);
        }
Exemple #21
0
 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);
    }
Exemple #25
0
 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);
    }
Exemple #27
0
 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);
 }
Exemple #28
0
        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 });
        }
Exemple #29
0
        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);
        }
Exemple #30
0
 internal void Get(int i)
 {
     _il.Emit(OpCodes.Ldarg, i + 1);
 }