Beispiel #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;
        }
Beispiel #2
0
        internal static void BuildConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            const string ToS = "to_s";

            if (TryImplicitConversion(metaBuilder, args))
            {
                metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
                return;
            }

            RubyMemberInfo conversionMethod, methodMissing = null;

            RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target);

            using (targetClass.Context.ClassHierarchyLocker()) {
                metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
                                              new[] { ToS, Symbols.MethodMissing }
                                              );

                conversionMethod = targetClass.ResolveMethodForSiteNoLock(ToS, VisibilityContext.AllVisible).Info;

                // find method_missing - we need to add "to_s" method to the missing methods table:
                if (conversionMethod == null)
                {
                    methodMissing = targetClass.ResolveMethodMissingForSite(ToS, RubyMethodVisibility.None);
                }
            }

            // invoke target.to_s and if successful convert the result to string unless it is already:
            if (conversionMethod != null)
            {
                conversionMethod.BuildCall(metaBuilder, args, ToS);
            }
            else
            {
                RubyCallAction.BuildMethodMissingCall(metaBuilder, args, ToS, methodMissing, RubyMethodVisibility.None, false, true);
            }

            if (metaBuilder.Error)
            {
                return;
            }

            metaBuilder.Result = Methods.ToSDefaultConversion.OpCall(
                AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)),
                AstUtils.Box(args.TargetExpression),
                AstUtils.Box(metaBuilder.Result)
                );
        }
Beispiel #3
0
        internal void BuildInvoke(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);

            var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(Proc));

            // test for target type:
            metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);

            BuildCall(
                metaBuilder,
                convertedTarget,                             // proc object
                Methods.GetProcSelf.OpCall(convertedTarget), // self captured by the block closure
                args
                );
        }
Beispiel #4
0
        /// <summary>
        /// OldCallAction on Proc target.
        /// From control flow perspective it "yields" to the proc.
        /// </summary>
        internal void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(!args.Signature.HasBlock);

            var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(BlockParam));

            // test for target type:
            metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);

            metaBuilder.Result = AstFactory.YieldExpression(
                args.GetSimpleArgumentExpressions(),
                args.GetSplattedArgumentExpression(),
                args.GetRhsArgumentExpression(),
                convertedTarget,                              // block param
                Ast.Property(convertedTarget, SelfProperty)   // self
                );
        }
Beispiel #5
0
        internal static void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, bool testTarget)
        {
            Assert.NotNull(metaBuilder, args);

            var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(Proc));

            // test for target type:
            if (testTarget)
            {
                metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
            }

            SetProcCallRule(
                metaBuilder,
                convertedTarget,                              // proc object
                Ast.Property(convertedTarget, SelfProperty),  // self captured by the block closure
                null,
                args
                );
        }