Inheritance: Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST.TypeReference
Beispiel #1
0
        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;
 }