示例#1
0
        /// <summary>
        /// Compiles a method into IL instructions.
        /// </summary>
        /// <param name="method">Method to compile.</param>
        /// <returns>
        /// List of ILInstructions.
        /// </returns>
        /// <remarks>
        /// Utilizes harmony library.
        /// </remarks>
        public static List <CodeInstruction> MethodToILInstructions(MethodBase method)
        {
            DynamicMethod dynamicMethod = DynamicTools.CreateDynamicMethod(method, "_ILParser");

            if (dynamicMethod == null)
            {
                return(null);
            }

            // Get il generato
            ILGenerator il = dynamicMethod.GetILGenerator();

            LocalBuilder[] existingVariables = DynamicTools.DeclareLocalVariables(method, il);
            Dictionary <string, LocalBuilder> privateVars = new Dictionary <string, LocalBuilder>();

            MethodBodyReader reader = new MethodBodyReader(method, il);

            reader.DeclareVariables(existingVariables);
            reader.ReadInstructions();

            List <ILInstruction> ilInstructions = (List <ILInstruction>)FIilInstructions.GetValue(reader);

            // Defines function start label
            il.DefineLabel();

            // Define labels
            foreach (ILInstruction ilInstruction in ilInstructions)
            {
                switch (ilInstruction.opcode.OperandType)
                {
                case OperandType.InlineSwitch:
                {
                    ILInstruction[] array = ilInstruction.operand as ILInstruction[];
                    if (array != null)
                    {
                        List <Label>    labels = new List <Label>();
                        ILInstruction[] array2 = array;
                        foreach (ILInstruction iLInstruction2 in array2)
                        {
                            Label item = il.DefineLabel();
                            iLInstruction2.labels.Add(item);
                            labels.Add(item);
                        }
                        ilInstruction.argument = labels.ToArray();
                    }
                    break;
                }

                case OperandType.InlineBrTarget:
                case OperandType.ShortInlineBrTarget:
                {
                    ILInstruction iLInstruction = ilInstruction.operand as ILInstruction;
                    if (iLInstruction != null)
                    {
                        Label label2 = il.DefineLabel();
                        iLInstruction.labels.Add(label2);
                        ilInstruction.argument = label2;
                    }
                    break;
                }
                }
            }

            // Transpile code
            CodeTranspiler         codeTranspiler = new CodeTranspiler(ilInstructions);
            List <CodeInstruction> result         = codeTranspiler.GetResult(il, method);

            // Replace debug commands with normal
            foreach (CodeInstruction codeInstruction in result)
            {
                OpCode opCode = codeInstruction.opcode;

                codeInstruction.opcode = ReplaceShortJumps(opCode);
            }

            return(result);
        }