Пример #1
0
        private void ProcessInvoke(RPContext ctx, int instrIndex, int argBeginIndex)
        {
            Tuple <FieldDef, MethodDef> tuple2;
            Instruction instruction  = ctx.Body.Instructions[instrIndex];
            IMethod     operand      = (IMethod)instruction.Operand;
            MethodSig   sig          = RPMode.CreateProxySignature(ctx, operand, instruction.OpCode.Code == Code.Newobj);
            TypeDef     delegateType = RPMode.GetDelegateType(ctx, sig);
            Tuple <Code, IMethod, IRPEncoding> key = Tuple.Create <Code, IMethod, IRPEncoding>(instruction.OpCode.Code, operand, ctx.EncodingHandler);

            if (!this.fields.TryGetValue(key, out tuple2))
            {
                tuple2           = new Tuple <FieldDef, MethodDef>(this.CreateField(ctx, delegateType), null);
                this.fields[key] = tuple2;
            }
            if (argBeginIndex == instrIndex)
            {
                ctx.Body.Instructions.Insert(instrIndex + 1, new Instruction(OpCodes.Call, delegateType.FindMethod("Invoke")));
                instruction.OpCode  = OpCodes.Ldsfld;
                instruction.Operand = tuple2.Item1;
            }
            else
            {
                Instruction instruction2 = ctx.Body.Instructions[argBeginIndex];
                ctx.Body.Instructions.Insert(argBeginIndex + 1, new Instruction(instruction2.OpCode, instruction2.Operand));
                instruction2.OpCode  = OpCodes.Ldsfld;
                instruction2.Operand = tuple2.Item1;
                instruction.OpCode   = OpCodes.Call;
                instruction.Operand  = delegateType.FindMethod("Invoke");
            }
        }
Пример #2
0
        private void ProcessBridge(RPContext ctx, int instrIndex)
        {
            Instruction instruction = ctx.Body.Instructions[instrIndex];
            IMethod     operand     = (IMethod)instruction.Operand;
            TypeDef     def         = operand.DeclaringType.ResolveTypeDefThrow();

            if (def.Module.IsILOnly && !def.IsGlobalModuleType)
            {
                Tuple <FieldDef, MethodDef>        tuple2;
                Tuple <Code, IMethod, IRPEncoding> key = Tuple.Create <Code, IMethod, IRPEncoding>(instruction.OpCode.Code, operand, ctx.EncodingHandler);
                if (this.fields.TryGetValue(key, out tuple2))
                {
                    if (tuple2.Item2 != null)
                    {
                        instruction.OpCode  = OpCodes.Call;
                        instruction.Operand = tuple2.Item2;
                        return;
                    }
                }
                else
                {
                    tuple2 = new Tuple <FieldDef, MethodDef>(null, null);
                }
                MethodSig sig          = RPMode.CreateProxySignature(ctx, operand, instruction.OpCode.Code == Code.Newobj);
                TypeDef   delegateType = RPMode.GetDelegateType(ctx, sig);
                if (tuple2.Item1 == null)
                {
                    tuple2 = new Tuple <FieldDef, MethodDef>(this.CreateField(ctx, delegateType), tuple2.Item2);
                }
                tuple2              = new Tuple <FieldDef, MethodDef>(tuple2.Item1, this.CreateBridge(ctx, delegateType, tuple2.Item1, sig));
                this.fields[key]    = tuple2;
                instruction.OpCode  = OpCodes.Call;
                instruction.Operand = tuple2.Item2;
            }
        }