private void GenerateCall() { ArgumentReference arg = new ArgumentReference( typeof(object[]) ); _callmethod = CreateMethod( "Call", new ReturnReferenceExpression(typeof(object)), arg ); // LocalReference localRef = method.CodeBuilder.DeclareLocal( typeof(object) ); TypeReference[] dereferencedArguments = IndirectReference.WrapIfByRef(_args); LocalReference[] localCopies = new LocalReference[_args.Length]; Expression[] invocationArguments = new Expression[_args.Length]; // Load arguments from the object array. for (int i = 0; i < _args.Length; i++) { if (_args[i].Type.IsByRef) { localCopies[i] = _callmethod.CodeBuilder.DeclareLocal(dereferencedArguments[i].Type); _callmethod.CodeBuilder.AddStatement(new AssignStatement(localCopies[i], new ConvertExpression(dereferencedArguments[i].Type, new LoadRefArrayElementExpression(i, arg)))); invocationArguments[i] = localCopies[i].ToAddressOfExpression(); } else { invocationArguments[i] = new ConvertExpression(dereferencedArguments[i].Type, new LoadRefArrayElementExpression(i, arg)); } } // Invoke the method. MethodInvocationExpression methodInv = new MethodInvocationExpression( _invokeMethod, invocationArguments ); Expression result = null; if (_returnType.Type == typeof(void)) { _callmethod.CodeBuilder.AddStatement(new ExpressionStatement(methodInv)); result = NullExpression.Instance; } else { LocalReference resultLocal = _callmethod.CodeBuilder.DeclareLocal(typeof(object)); _callmethod.CodeBuilder.AddStatement(new AssignStatement(resultLocal, new ConvertExpression(typeof(object), _returnType.Type, methodInv))); result = resultLocal.ToExpression(); } // Save ByRef arguments into the object array. for (int i = 0; i < _args.Length; i++) { if (_args[i].Type.IsByRef) { _callmethod.CodeBuilder.AddStatement(new AssignArrayStatement(arg, i, new ConvertExpression(typeof(object), dereferencedArguments[i].Type, localCopies[i].ToExpression()))); } } // Return. _callmethod.CodeBuilder.AddStatement( new ReturnStatement( result ) ); }
public LocalReference DeclareLocal( Type type ) { LocalReference local = new LocalReference(type); _ilmarkers.Add( local ); return local; }