示例#1
0
        private static void EmitILForConstructor(ILGenerator ilGenerator, OperandInstruction <MethodBase> instruction,
                                                 ConstructorInfo constructorInfo, int contextParamIndex)
        {
            /*if (PoseContext.StubCache.TryGetValue(constructorInfo, out DynamicMethod stub))
             * {
             *  ilGenerator.Emit(OpCodes.Ldtoken, constructorInfo);
             *  ilGenerator.Emit(OpCodes.Ldtoken, constructorInfo.DeclaringType);
             *  ilGenerator.Emit(OpCodes.Call, stub);
             *  return;
             * }*/

            var methodBody = constructorInfo.GetMethodBody();

            if (methodBody == null)
            {
                ilGenerator.Emit(instruction.OpCode, constructorInfo);
                return;
            }

            if (instruction.OpCode != OpCodes.Newobj && instruction.OpCode != OpCodes.Call)
            {
                ilGenerator.Emit(instruction.OpCode, constructorInfo);
                return;
            }

            var stub = StubGenerator.GenerateStub(constructorInfo, instruction.OpCode == OpCodes.Newobj);

            ilGenerator.Emit(OpCodes.Ldarg, contextParamIndex);
            ilGenerator.Emit(OpCodes.Call, stub);

            //PoseContext.StubCache.TryAdd(constructorInfo, stub);
        }
示例#2
0
        private static void EmitILForMethod(ILGenerator ilGenerator, OperandInstruction <MethodBase> instruction, MethodInfo methodInfo, ShimContext context, int contextParamIndex)
        {
            /*if (context.StubCache.TryGetValue(methodInfo, out DynamicMethod stub))
             * {
             *  ilGenerator.Emit(OpCodes.Ldtoken, methodInfo);
             *  ilGenerator.Emit(OpCodes.Ldtoken, methodInfo.DeclaringType);
             *  ilGenerator.Emit(OpCodes.Call, stub);
             *  return;
             * }*/

            var methodBody = methodInfo.GetMethodBody();

            if (methodBody == null)
            {
                ilGenerator.Emit(instruction.OpCode, methodInfo);
                return;
            }

            MethodInfo stub;

            if (instruction.OpCode == OpCodes.Call)
            {
                stub = StubGenerator.GenerateStubForMethod(methodInfo);
            }
            else if (instruction.OpCode == OpCodes.Callvirt)
            {
                stub = StubGenerator.GenerateStubForVirtualMethod(methodInfo);
            }

            /*else if (instruction.OpCode == OpCodes.Ldftn)
             * {
             *  stub = StubGenerator.GenerateStubForMethodPointer(methodInfo);
             * }
             * else if (instruction.OpCode == OpCodes.Ldvirtftn)
             * {
             *  stub = StubGenerator.GenerateStubForMethodPointer(methodInfo);
             * }*/
            else
            {
                ilGenerator.Emit(instruction.OpCode, methodInfo);
                return;
            }

            ilGenerator.Emit(OpCodes.Ldarg, contextParamIndex);
            ilGenerator.Emit(OpCodes.Call, stub);
            //PoseContext.StubCache.TryAdd(methodInfo, stub);
        }
示例#3
0
        private static List <ILProcessorInstruction> TranslateInstructions(IReadOnlyList <ILInstruction> instructions)
        {
            //Convert all instructions into processor instructions
            var offsetMap       = new Dictionary <int, ILProcessorInstruction>();
            var newInstructions = new List <ILProcessorInstruction>();

            ILProcessorInstruction lastInstruction = null;

            foreach (var instruction in instructions)
            {
                var processorInstruction = TranslateInstruction(instruction);
                newInstructions.Add(processorInstruction);
                offsetMap.Add(instruction.Offset, processorInstruction);

                if (lastInstruction != null)
                {
                    lastInstruction.Next = processorInstruction;
                }
                processorInstruction.Prev = lastInstruction;
                lastInstruction           = processorInstruction;
            }

            //Set the correct TargetInstruction for Branch and Switches
            foreach (var(instruction, oldInstruction) in newInstructions.Zip(instructions,
                                                                             (i, oi) => (Instruction: i, OldInstruction:oi)))
            {
                switch (instruction)
                {
                case OperandInstruction <ILProcessorInstruction> branchInstruction:
                    var targetOffset = (oldInstruction as InlineBrTargetInstruction)?.TargetOffset ??
                                       (oldInstruction as ShortInlineBrTargetInstruction)?.TargetOffset ??
                                       throw new ArgumentException();
                    branchInstruction.Operand = offsetMap[targetOffset];
                    break;

                case OperandInstruction <IReadOnlyList <ILProcessorInstruction> > switchInstruction:
                    var targetOffsets = (oldInstruction as InlineSwitchInstruction)?.TargetOffsets ??
                                        throw new ArgumentException();
                    switchInstruction.Operand = targetOffsets.Select(o => offsetMap[o]).ToList();
                    break;
                }
            }
            return(newInstructions);

            ILProcessorInstruction TranslateInstruction(ILInstruction instruction)
            {
                var opCode = instruction.OpCode;

                switch (instruction)
                {
                case InlineNoneInstruction _:
                    return(new NoneInstruction(opCode));

                case ShortInlineBrTargetInstruction _:
                case InlineBrTargetInstruction _:
                    return(OperandInstruction.Create(opCode, (ILProcessorInstruction)null));

                case InlineSwitchInstruction _:
                    return(OperandInstruction.Create(opCode, (IReadOnlyList <ILProcessorInstruction>)null));

                case InlineFieldInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case InlineI8Instruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case InlineIInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case InlineMethodInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Method));

                case InlineRInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case InlineSigInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Signature));

                case InlineStringInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case InlineTokInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Member));

                case InlineTypeInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case ShortInlineVarInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Ordinal));

                case InlineVarInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Ordinal));

                case ShortInlineIInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                case ShortInlineRInstruction matched:
                    return(OperandInstruction.Create(opCode, matched.Operand));

                default:
                    throw new ArgumentException("Unknown instruction!", nameof(instruction));
                }
            }
        }