Box() public static method

Returns an expression that boxes a given value. Uses boxed objects cache for Int32 and Boolean types.
public static Box ( Expression expression ) : Expression
expression Expression
return Expression
示例#1
0
        // see Ruby Language.doc/Runtime/Control Flow Implementation/Next
        internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
        {
            MSA.Expression transformedReturnValue = TransformReturnValue(gen);

            // eval:
            if (gen.CompilerOptions.IsEval)
            {
                return(Methods.EvalNext.OpCall(gen.CurrentScopeVariable, AstUtils.Box(transformedReturnValue)));
            }

            // loop:
            if (gen.CurrentLoop != null)
            {
                return(Ast.Block(
                           transformedReturnValue, // evaluate for side-effects
                           Ast.Continue(gen.CurrentLoop.ContinueLabel),
                           AstUtils.Empty()
                           ));
            }

            // block:
            if (gen.CurrentBlock != null)
            {
                return(gen.Return(transformedReturnValue));
            }

            // method:
            return(Methods.MethodNext.OpCall(gen.CurrentScopeVariable, AstUtils.Box(transformedReturnValue)));
        }
 internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
 {
     if (_value != null)
     {
         return(Ast.Block(
                    AstUtils.IfThen(
                        _condition.TransformReadBoolean(gen, !_negateCondition),
                        _jumpStatement.Transform(gen)
                        ),
                    _value.TransformRead(gen)
                    ));
     }
     else
     {
         MSA.Expression tmpVariable = gen.CurrentScope.DefineHiddenVariable("#tmp_cond", typeof(object));
         return(Ast.Block(
                    Ast.Assign(tmpVariable, AstUtils.Box(_condition.TransformRead(gen))),
                    AstUtils.IfThen(
                        (_negateCondition ? Methods.IsFalse : Methods.IsTrue).OpCall(tmpVariable),
                        _jumpStatement.Transform(gen)
                        ),
                    tmpVariable
                    ));
     }
 }
        // see Ruby Language.doc/Runtime/Control Flow Implementation/Break
        internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
        {
            MSA.Expression transformedReturnValue = TransformReturnValue(gen);

            // eval:
            if (gen.CompilerOptions.IsEval)
            {
                return(Methods.EvalBreak.OpCall(gen.CurrentScopeVariable, AstUtils.Box(transformedReturnValue)));
            }

            // loop:
            if (gen.CurrentLoop != null)
            {
                return(Ast.Block(
                           Ast.Assign(
                               gen.CurrentLoop.ResultVariable,
                               Ast.Convert(transformedReturnValue, gen.CurrentLoop.ResultVariable.Type)
                               ),
                           Ast.Break(gen.CurrentLoop.BreakLabel),
                           AstUtils.Empty()
                           ));
            }

            // block:
            if (gen.CurrentBlock != null)
            {
                return(gen.Return(Methods.BlockBreak.OpCall(gen.CurrentBlock.BfcVariable, AstUtils.Box(transformedReturnValue))));
            }

            // primary frame:
            return(Methods.MethodBreak.OpCall(AstUtils.Box(transformedReturnValue)));
        }
示例#4
0
        private MSA.Expression /*!*/ MakeExpressionQualifiedRead(AstGenerator /*!*/ gen, int opKind, string /*!*/[] /*!*/ names)
        {
            Debug.Assert(_qualifier != null && !(_qualifier is ConstantVariable));

            object     siteCache;
            MethodInfo op;

            if (opKind == OpIsDefined)
            {
                siteCache = new ExpressionQualifiedIsDefinedConstantSiteCache();
                op        = Methods.IsDefinedExpressionQualifiedConstant;
            }
            else
            {
                siteCache = new ExpressionQualifiedConstantSiteCache();
                op        = Methods.GetExpressionQualifiedConstant;
            }

            var result = op.OpCall(
                AstUtils.Box(_qualifier.TransformRead(gen)),
                gen.CurrentScopeVariable,
                Ast.Constant(siteCache),
                Ast.Constant(names)
                );

            return(opKind == OpIsDefined?Ast.TryCatch(result, Ast.Catch(typeof(Exception), AstFactory.False)) : result);
        }
示例#5
0
 // when [<expr>, ...] *<array>
 private static MSA.Expression /*!*/ MakeArrayTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ array, MSA.Expression value)
 {
     return(Methods.ExistsUnsplat.OpCall(
                Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create(
                                 RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2))
                                 )),
                AstUtils.LightDynamic(ConvertToArraySplatAction.Make(gen.Context), array),
                AstUtils.Box(value)
                ));
 }
示例#6
0
 public static MSA.Expression /*!*/ IsFalse(MSA.Expression /*!*/ expression)
 {
     if (expression.Type == typeof(bool))
     {
         return(Ast.Not(expression));
     }
     else
     {
         return(Methods.IsFalse.OpCall(AstUtils.Box(expression)));
     }
 }
示例#7
0
 internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue)
 {
     if (_definitionLexicalDepth >= 0)
     {
         // static lookup:
         return(Ast.Assign(gen.CurrentScope.GetVariableAccessor(_definitionLexicalDepth, _closureIndex), AstUtils.Box(rightValue)));
     }
     else
     {
         // dynamic lookup:
         return(Methods.SetLocalVariable.OpCall(AstUtils.Box(rightValue), gen.CurrentScopeVariable, AstUtils.Constant(Name)));
     }
 }
示例#8
0
        internal static MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen, MSA.Expression /*!*/ left, MSA.Expression /*!*/ right)
        {
            MSA.ParameterExpression temp;
            MSA.Expression          result = AstUtils.CoalesceTrue(
                AstUtils.Box(left),
                AstUtils.Box(right),
                Methods.IsTrue,
                out temp
                );

            gen.CurrentScope.AddHidden(temp);
            return(result);
        }
示例#9
0
 private static RuleGenerator /*!*/ CreateSetter(int index)
 {
     return(delegate(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name) {
         var actualArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 1, 1);
         if (!metaBuilder.Error)
         {
             metaBuilder.Result = Methods.RubyStruct_SetValue.OpCall(
                 Ast.Convert(args.TargetExpression, typeof(RubyStruct)),
                 AstUtils.Constant(index),
                 AstUtils.Box(actualArgs[0].Expression)
                 );
         }
     });
 }
示例#10
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)
                );
        }
示例#11
0
        internal static MSA.Expression /*!*/ YieldExpression(
            RubyContext /*!*/ context,
            ICollection <MSA.Expression> /*!*/ arguments,
            MSA.Expression splattedArgument,
            MSA.Expression rhsArgument,
            MSA.Expression blockArgument,
            MSA.Expression /*!*/ bfcVariable,
            MSA.Expression /*!*/ selfArgument)
        {
            Assert.NotNull(arguments, bfcVariable, selfArgument);

            bool hasArgumentArray;
            var  opMethod = Methods.Yield(arguments.Count, splattedArgument != null, rhsArgument != null, out hasArgumentArray);

            var args = new AstExpressions();

            foreach (var arg in arguments)
            {
                args.Add(AstUtils.Box(arg));
            }

            if (hasArgumentArray)
            {
                args = new AstExpressions {
                    Ast.NewArrayInit(typeof(object), args)
                };
            }

            if (splattedArgument != null)
            {
                args.Add(AstUtils.LightDynamic(ExplicitSplatAction.Make(context), typeof(IList), splattedArgument));
            }

            if (rhsArgument != null)
            {
                args.Add(AstUtils.Box(rhsArgument));
            }

            args.Add(blockArgument != null ? AstUtils.Convert(blockArgument, typeof(Proc)) : AstFactory.NullOfProc);

            args.Add(AstUtils.Box(selfArgument));
            args.Add(bfcVariable);

            return(Ast.Call(opMethod, args));
        }
示例#12
0
        internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue)
        {
            MSA.Expression transformedName = TransformName(gen);
            MSA.Expression transformedQualifier;

            switch (TransformQualifier(gen, out transformedQualifier))
            {
            case StaticScopeKind.Global:
                return(Methods.SetGlobalConstant.OpCall(AstUtils.Box(rightValue), gen.CurrentScopeVariable, transformedName));

            case StaticScopeKind.EnclosingModule:
                return(Methods.SetUnqualifiedConstant.OpCall(AstUtils.Box(rightValue), gen.CurrentScopeVariable, transformedName));

            case StaticScopeKind.Explicit:
                return(Methods.SetQualifiedConstant.OpCall(AstUtils.Box(rightValue), transformedQualifier, gen.CurrentScopeVariable, transformedName));
            }

            throw Assert.Unreachable;
        }
示例#13
0
        /// <code>
        /// End-exclusive range:
        ///   if state
        ///     state = IsFalse({end})
        ///     true
        ///   else
        ///     state = IsTrue({begin})
        ///   end
        ///
        /// End-inclusive range:
        ///   if state || IsTrue({begin})
        ///     state = IsFalse({end})
        ///     true
        ///   else
        ///     false
        ///   end
        /// </code>
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            var begin = AstUtils.Box(_range.Begin.TransformRead(gen));
            var end   = AstUtils.Box(_range.End.TransformRead(gen));

            // state:
            // false <=> null
            // true <=> non-null
            if (_range.IsExclusive)
            {
                return(Ast.Condition(
                           Ast.ReferenceNotEqual(
                               _stateVariable.TransformReadVariable(gen, false),
                               AstUtils.Constant(null)
                               ),
                           Ast.Block(
                               _stateVariable.TransformWriteVariable(gen, Methods.NullIfTrue.OpCall(end)),
                               AstUtils.Constant(true)
                               ),
                           Ast.ReferenceNotEqual(
                               _stateVariable.TransformWriteVariable(gen, Methods.NullIfFalse.OpCall(begin)),
                               AstUtils.Constant(null)
                               )
                           ));
            }
            else
            {
                return(Ast.Condition(
                           Ast.OrElse(
                               Ast.ReferenceNotEqual(
                                   _stateVariable.TransformReadVariable(gen, false),
                                   AstUtils.Constant(null)
                                   ),
                               Methods.IsTrue.OpCall(begin)
                               ),
                           Ast.Block(
                               _stateVariable.TransformWriteVariable(gen, Methods.NullIfTrue.OpCall(end)),
                               AstUtils.Constant(true)
                               ),
                           AstUtils.Constant(false)
                           ));
            }
        }
示例#14
0
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            int intBegin, intEnd;

            if (IsIntegerRange(out intBegin, out intEnd))
            {
                return((_isExclusive ? Methods.CreateExclusiveIntegerRange : Methods.CreateInclusiveIntegerRange).OpCall(
                           AstUtils.Constant(intBegin), AstUtils.Constant(intEnd)
                           ));
            }
            else
            {
                return((_isExclusive ? Methods.CreateExclusiveRange : Methods.CreateInclusiveRange).OpCall(
                           AstUtils.Box(_begin.TransformRead(gen)),
                           AstUtils.Box(_end.TransformRead(gen)),
                           gen.CurrentScopeVariable,
                           AstUtils.Constant(new BinaryOpStorage(gen.Context))
                           ));
            }
        }
示例#15
0
        internal override MSA.Expression /*!*/ MakeDefinitionExpression(AstGenerator /*!*/ gen)
        {
            MSA.Expression transformedQualifier;
            MSA.Expression name             = QualifiedName.TransformName(gen);
            MSA.Expression transformedSuper = (_superClass != null) ? AstUtils.Box(_superClass.TransformRead(gen)) : AstUtils.Constant(null);

            switch (QualifiedName.TransformQualifier(gen, out transformedQualifier))
            {
            case StaticScopeKind.Global:
                return(Methods.DefineGlobalClass.OpCall(gen.CurrentScopeVariable, name, transformedSuper));

            case StaticScopeKind.EnclosingModule:
                return(Methods.DefineNestedClass.OpCall(gen.CurrentScopeVariable, name, transformedSuper));

            case StaticScopeKind.Explicit:
                return(Methods.DefineClass.OpCall(gen.CurrentScopeVariable, transformedQualifier, name, transformedSuper));
            }

            throw Assert.Unreachable;
        }
示例#16
0
        internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            Assert.NotNull(metaBuilder, args, name);

            // 2 implicit args: self, block
            var argsBuilder = new ArgsBuilder(2, Parameters.Mandatory.Length, Parameters.LeadingMandatoryCount, Parameters.Optional.Length, Parameters.Unsplat != null);

            argsBuilder.SetImplicit(0, AstUtils.Box(args.TargetExpression));
            argsBuilder.SetImplicit(1, args.Signature.HasBlock ? AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)) : AstFactory.NullOfProc);
            argsBuilder.AddCallArguments(metaBuilder, args);

            if (metaBuilder.Error)
            {
                return;
            }

            // box explicit arguments:
            var boxedArguments = argsBuilder.GetArguments();

            for (int i = 2; i < boxedArguments.Length; i++)
            {
                boxedArguments[i] = AstUtils.Box(boxedArguments[i]);
            }

            var method = GetDelegate();

            if (method.GetType() == ParamsArrayDelegateType)
            {
                // Func<object, Proc, object[], object>
                metaBuilder.Result = AstFactory.CallDelegate(method, new[] {
                    boxedArguments[0],
                    boxedArguments[1],
                    Ast.NewArrayInit(typeof(object), ArrayUtils.ShiftLeft(boxedArguments, 2))
                });
            }
            else
            {
                metaBuilder.Result = AstFactory.CallDelegate(method, boxedArguments);
            }
        }
示例#17
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(Call("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, Expression /*!*/ expr, MSA.Expression value)
 {
     MSA.Expression transformedExpr = expr.TransformRead(gen);
     if (expr is SplattedArgument)
     {
         if (value != null)
         {
             return(Methods.ExistsUnsplatCompare.OpCall(
                        Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create(
                                         RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2))
                                         )),
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr),
                        AstUtils.Box(value)
                        ));
         }
         else
         {
             return(Methods.ExistsUnsplat.OpCall(
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr)
                        ));
         }
     }
     else
     {
         if (value != null)
         {
             return(AstFactory.IsTrue(
                        CallSiteBuilder.InvokeMethod(gen.Context, "===", RubyCallSignature.WithScope(1),
                                                     gen.CurrentScopeVariable,
                                                     transformedExpr,
                                                     value
                                                     )
                        ));
         }
         else
         {
             return(AstFactory.IsTrue(transformedExpr));
         }
     }
 }
示例#18
0
        internal MSA.Expression UnsplatArguments(AstGenerator /*!*/ gen, int start)
        {
            // [*array] == array, [*item] = [item]
            if (start == _expressions.Length - 1)
            {
                return(Methods.Unsplat.OpCall(AstUtils.Box(_expressions[start].TransformRead(gen))));
            }

            MSA.Expression array = Methods.MakeArray0.OpCall();
            for (int i = start; i < _expressions.Length; i++)
            {
                if (_expressions[i] is SplattedArgument)
                {
                    array = Methods.AddRange.OpCall(array, _expressions[i].TransformRead(gen));
                }
                else
                {
                    array = Methods.AddItem.OpCall(array, AstUtils.Box(_expressions[i].TransformRead(gen)));
                }
            }
            return(array);
        }
示例#19
0
        public static MSA.Expression /*!*/ Condition(MSA.Expression /*!*/ test, MSA.Expression /*!*/ ifTrue, MSA.Expression /*!*/ ifFalse)
        {
            Assert.NotNull(test, ifTrue, ifFalse);
            Debug.Assert(test.Type == typeof(bool));

            if (ifTrue.Type != ifFalse.Type)
            {
                if (ifTrue.Type.IsAssignableFrom(ifFalse.Type))
                {
                    ifFalse = Ast.Convert(ifFalse, ifTrue.Type);
                }
                else if (ifFalse.Type.IsAssignableFrom(ifTrue.Type))
                {
                    ifTrue = Ast.Convert(ifTrue, ifFalse.Type);
                }
                else
                {
                    ifTrue  = AstUtils.Box(ifTrue);
                    ifFalse = AstUtils.Box(ifFalse);
                }
            }

            return(Ast.Condition(test, ifTrue, ifFalse));
        }
示例#20
0
 private MSA.Expression /*!*/ MakeCompareException(AstGenerator /*!*/ gen, MSA.Expression /*!*/ comparisonSiteStorage, MSA.Expression /*!*/ expression, bool isSplatted)
 {
     if (isSplatted)
     {
         return(Methods.CompareSplattedExceptions.OpCall(comparisonSiteStorage, gen.CurrentScopeVariable, expression));
     }
     else
     {
         return(Methods.CompareException.OpCall(comparisonSiteStorage, gen.CurrentScopeVariable, AstUtils.Box(expression)));
     }
 }
示例#21
0
 private MSA.Expression /*!*/ MakeCompareException(AstGenerator /*!*/ gen, MSA.Expression /*!*/ comparisonSiteStorage, MSA.Expression /*!*/ expression)
 {
     return(Methods.CompareException.OpCall(comparisonSiteStorage, gen.CurrentScopeVariable, AstUtils.Box(expression)));
 }
示例#22
0
        public void AddCallArguments(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            _callArguments = args;

            // calculate actual argument count:
            _actualArgumentCount = args.SimpleArgumentCount;
            if (args.Signature.HasSplattedArgument)
            {
                var splattedArg = args.GetSplattedMetaArgument();
                metaBuilder.AddSplattedArgumentTest((IList)splattedArg.Value, splattedArg.Expression, out _listLength, out _listVariable);
                _actualArgumentCount += _listLength;
            }
            if (args.Signature.HasRhsArgument)
            {
                _actualArgumentCount++;
            }

            // check:
            if (HasTooFewArguments)
            {
                metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount);
                return;
            }

            if (HasTooManyArguments)
            {
                metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount);
                return;
            }

            bool isSplatted;

            // leading mandatory:
            for (int i = 0; i < _leadingMandatoryParamCount; i++)
            {
                _arguments[LeadingMandatoryIndex + i] = GetArgument(i, out isSplatted);
            }

            // trailing mandatory:
            for (int i = 0; i < TrailingMandatoryCount; i++)
            {
                _arguments[TrailingMandatoryIndex + i] = GetArgument(_actualArgumentCount - TrailingMandatoryCount + i, out isSplatted);
            }

            int start = _leadingMandatoryParamCount;
            int end   = _actualArgumentCount - TrailingMandatoryCount;

            // optional:
            for (int i = 0; i < _optionalParamCount; i++)
            {
                _arguments[OptionalParameterIndex + i] = (start < end) ? GetArgument(start++, out isSplatted) : Ast.Field(null, Fields.DefaultArgument);
            }

            // unsplat:
            if (_hasUnsplatParameter)
            {
                Expression array;
                if (args.Signature.HasSplattedArgument)
                {
                    // simple:
                    var argsToUnsplat = new List <Expression>();
                    while (start < end)
                    {
                        var arg = GetArgument(start, out isSplatted);
                        if (isSplatted)
                        {
                            break;
                        }
                        argsToUnsplat.Add(AstUtils.Box(arg));
                        start++;
                    }
                    array = Methods.MakeArrayOpCall(argsToUnsplat);

                    int rangeStart  = start - args.SimpleArgumentCount;
                    int rangeLength = Math.Min(end - start, _listLength - rangeStart);

                    // splatted:
                    if (rangeLength > 0)
                    {
                        array  = Methods.AddSubRange.OpCall(array, _listVariable, Ast.Constant(rangeStart), Ast.Constant(rangeLength));
                        start += rangeLength;
                    }

                    // rhs:
                    while (start < end)
                    {
                        array = Methods.AddItem.OpCall(array, AstUtils.Box(GetArgument(start, out isSplatted)));
                        start++;
                    }
                }
                else
                {
                    var argsToUnsplat = new List <Expression>(end - start);
                    while (start < end)
                    {
                        argsToUnsplat.Add(AstUtils.Box(GetArgument(start++, out isSplatted)));
                    }
                    array = Methods.MakeArrayOpCall(argsToUnsplat);
                }

                _arguments[UnsplatParameterIndex] = array;
            }

            _callArguments = null;
            _listVariable  = null;
            Debug.Assert(CollectionUtils.TrueForAll(_arguments, (e) => e != null));
        }
示例#23
0
 /// <summary>
 /// Transform as expression whose value is read as Boolean.
 /// </summary>
 internal virtual MSA.Expression /*!*/ TransformReadBoolean(AstGenerator /*!*/ gen, bool positive)
 {
     return((positive ? Methods.IsTrue : Methods.IsFalse).OpCall(AstUtils.Box(TransformRead(gen))));
 }
示例#24
0
 internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue)
 {
     return(Methods.SetInstanceVariable.OpCall(gen.CurrentSelfVariable, AstUtils.Box(rightValue), gen.CurrentScopeVariable, AstUtils.Constant(Name)));
 }