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"); } }
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; } }