Exemplo n.º 1
0
        private Expression /*!*/ MarshalArgument(MetaObjectBuilder /*!*/ metaBuilder, DynamicMetaObject /*!*/ arg, ArgType parameterType)
        {
            object value = arg.Value;

            if (value == null)
            {
                metaBuilder.AddRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null)));
            }
            else
            {
                metaBuilder.AddTypeRestriction(value.GetType(), arg.Expression);
            }

            switch (parameterType)
            {
            case ArgType.Buffer:
                if (value == null)
                {
                    return(AstUtils.Constant(null, typeof(byte[])));
                }

                if (value is int && (int)value == 0)
                {
                    metaBuilder.AddRestriction(Ast.Equal(AstUtils.Convert(arg.Expression, typeof(int)), AstUtils.Constant(0)));
                    return(AstUtils.Constant(null, typeof(byte[])));
                }

                if (value.GetType() == typeof(MutableString))
                {
                    return(Methods.GetMutableStringBytes.OpCall(
                               AstUtils.Convert(arg.Expression, typeof(MutableString))
                               ));
                }

                return(Methods.GetMutableStringBytes.OpCall(
                           AstUtils.LightDynamic(ConvertToStrAction.Make(_context), typeof(MutableString), arg.Expression)
                           ));

            case ArgType.Int32:
                if (value is int)
                {
                    return(AstUtils.Convert(arg.Expression, typeof(int)));
                }

                return(Ast.Convert(
                           Ast.Call(
                               AstUtils.LightDynamic(ConvertToIntAction.Make(_context), typeof(IntegerValue), arg.Expression),
                               Methods.IntegerValue_ToUInt32Unchecked
                               ),
                           typeof(int)
                           ));
            }
            throw Assert.Unreachable;
        }
Exemplo n.º 2
0
        internal virtual void BuildInvoke(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(args.Target == this);

            // first argument must be this method:
            metaBuilder.AddRestriction(Ast.Equal(args.TargetExpression, AstUtils.Constant(this)));

            // set the target (becomes self in the called method):
            args.SetTarget(AstUtils.Constant(_target, CompilerHelpers.GetVisibleType(_target)), _target);

            _info.BuildCall(metaBuilder, args, _name);
        }
Exemplo n.º 3
0
        internal void SetRuleForCall(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(args.Target == this);

            // TODO: we could compare infos here:
            // first argument must be this method:
            metaBuilder.AddRestriction(Ast.Equal(args.TargetExpression, Ast.Constant(this)));

            // set the target (becomes self in the called method):
            args.SetTarget(Ast.Constant(_target), _target);

            _info.BuildCall(metaBuilder, args, _name);
        }
Exemplo n.º 4
0
        private void BuildCall(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            var actualArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue);

            if (metaBuilder.Error)
            {
                return;
            }

            metaBuilder.AddRestriction(
                Ast.Equal(
                    Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), VersionProperty),
                    Ast.Constant(_version)
                    )
                );

            if (_function == IntPtr.Zero)
            {
                metaBuilder.SetError(Ast.Throw(new Func <Exception>(UninitializedFunctionError).Method.OpCall(), typeof(object)));
                return;
            }

            if (_signature.Length != actualArgs.Count)
            {
                metaBuilder.SetError(Ast.Throw(new Func <int, int, Exception>(InvalidParameterCountError).Method.OpCall(
                                                   Ast.Constant(_signature.Length), Ast.Constant(actualArgs.Count)), typeof(object)
                                               ));
                return;
            }

            var calliArgs = new AstExpressions();

            calliArgs.Add(Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), FunctionProperty));
            for (int i = 0; i < actualArgs.Count; i++)
            {
                calliArgs.Add(MarshalArgument(metaBuilder, actualArgs[i], _signature[i]));
            }

            metaBuilder.Result = Ast.Call(EmitCalliStub(), calliArgs);

            // MRI returns 0 if void return type is given:
            if (_returnType == ArgType.None)
            {
                metaBuilder.Result = Ast.Block(metaBuilder.Result, AstUtils.Constant(0));
            }
        }