protected virtual void WriteInterceptorInvocationMethod(MethodInfo method, EasyMethod builder) { ArgumentReference[] arguments = builder.Arguments; TypeReference[] args = IndirectReference.WrapIfByRef(builder.Arguments); LocalReference target = builder.CodeBuilder.DeclareLocal(this.Context.Invocation); EasyCallable callable = this._method2Delegate[method] as EasyCallable; FieldReference reference2 = this.ObtainCallableFieldBuilderDelegate(callable); builder.CodeBuilder.AddStatement(new AssignStatement(target, new MethodInvocationExpression(this._method2Invocation, new Expression[] { reference2.ToExpression(), new MethodTokenExpression(this.GetCorrectMethod(method)), this.GetPseudoInvocationTarget(method) }))); LocalReference reference3 = builder.CodeBuilder.DeclareLocal(typeof(object)); LocalReference reference4 = builder.CodeBuilder.DeclareLocal(typeof(object[])); builder.CodeBuilder.AddStatement(new AssignStatement(reference4, new ReferencesToObjectArrayExpression(args))); builder.CodeBuilder.AddStatement(new AssignStatement(reference3, new VirtualMethodInvocationExpression(this.InterceptorField, this.Context.Interceptor.GetMethod("Intercept"), new Expression[] { target.ToExpression(), reference4.ToExpression() }))); for (int i = 0; i < arguments.Length; i++) { if (arguments[i].Type.IsByRef) { builder.CodeBuilder.AddStatement(new AssignStatement(args[i], new ConvertExpression(args[i].Type, new LoadRefArrayElementExpression(i, reference4)))); } } if (builder.ReturnType == typeof(void)) { builder.CodeBuilder.AddStatement(new ReturnStatement()); } else { builder.CodeBuilder.AddStatement(new ReturnStatement(new ConvertExpression(builder.ReturnType, reference3.ToExpression()))); } }
private void GenerateCall() { ArgumentReference arrayReference = new ArgumentReference(typeof(object[])); this._callmethod = base.CreateMethod("Call", new ReturnReferenceExpression(typeof(object)), new ArgumentReference[] { arrayReference }); TypeReference[] referenceArray = IndirectReference.WrapIfByRef(this._args); LocalReference[] referenceArray2 = new LocalReference[this._args.Length]; Expression[] args = new Expression[this._args.Length]; for (int i = 0; i < this._args.Length; i++) { if (this._args[i].Type.IsByRef) { referenceArray2[i] = this._callmethod.CodeBuilder.DeclareLocal(referenceArray[i].Type); this._callmethod.CodeBuilder.AddStatement(new AssignStatement(referenceArray2[i], new ConvertExpression(referenceArray[i].Type, new LoadRefArrayElementExpression(i, arrayReference)))); args[i] = referenceArray2[i].ToAddressOfExpression(); } else { args[i] = new ConvertExpression(referenceArray[i].Type, new LoadRefArrayElementExpression(i, arrayReference)); } } MethodInvocationExpression expression = new MethodInvocationExpression(this._invokeMethod, args); Expression instance = null; if (this._returnType.Type == typeof(void)) { this._callmethod.CodeBuilder.AddStatement(new ExpressionStatement(expression)); instance = NullExpression.Instance; } else { LocalReference target = this._callmethod.CodeBuilder.DeclareLocal(typeof(object)); this._callmethod.CodeBuilder.AddStatement(new AssignStatement(target, new ConvertExpression(typeof(object), this._returnType.Type, expression))); instance = target.ToExpression(); } for (int j = 0; j < this._args.Length; j++) { if (this._args[j].Type.IsByRef) { this._callmethod.CodeBuilder.AddStatement(new AssignArrayStatement(arrayReference, j, new ConvertExpression(typeof(object), referenceArray[j].Type, referenceArray2[j].ToExpression()))); } } this._callmethod.CodeBuilder.AddStatement(new ReturnStatement(instance)); }