internal protected override Expression ToExpression(ParameterBinder parameterBinder, IList <Expression> parameters, bool[] hasBeenUsed)
        {
            if (_tmp == null)
            {
                _tmp = parameterBinder.GetTemporary(Type, "outParam");
            }

            return(Ast.Block(Ast.Assign(_tmp, base.ToExpression(parameterBinder, parameters, hasBeenUsed)), _tmp));
        }
Beispiel #2
0
 public Ast DeclareVariable(string name, Ast value)
 {
     System.Linq.Expressions.ParameterExpression param;
     if (!_variables.TryGetValue(name, out param))
     {
         _variables[name] = param = Ast.Variable(typeof(object), name);
     }
     return(Ast.Assign(param, value));
 }
Beispiel #3
0
        private MSAst.Expression AddFinally(MSAst.Expression /*!*/ body)
        {
            if (_finally != null)
            {
                MSAst.ParameterExpression tryThrows    = Ast.Variable(typeof(Exception), "$tryThrows");
                MSAst.ParameterExpression locException = Ast.Variable(typeof(Exception), "$localException");

                MSAst.Expression @finally = _finally;

                // lots is going on here.  We need to consider:
                //      1. Exceptions propagating out of try/except/finally.  Here we need to save the line #
                //          from the exception block and not save the # from the finally block later.
                //      2. Exceptions propagating out of the finally block.  Here we need to report the line number
                //          from the finally block and leave the existing stack traces cleared.
                //      3. Returning from the try block: Here we need to run the finally block and not update the
                //          line numbers.
                body = AstUtils.Try( // we use a fault to know when we have an exception and when control leaves normally (via
                    // either a return or the body completing successfully).
                    AstUtils.Try(
                        Parent.AddDebugInfo(AstUtils.Empty(), new SourceSpan(Span.Start, GlobalParent.IndexToLocation(_headerIndex))),
                        Ast.Assign(tryThrows, AstUtils.Constant(null, typeof(Exception))),
                        body,
                        AstUtils.Empty()
                        ).Catch(
                        locException,
                        Expression.Block(
                            Ast.Assign(tryThrows, locException),
                            Expression.Rethrow()
                            )
                        )
                    ).FinallyWithJumps(
                    // if we had an exception save the line # that was last executing during the try
                    AstUtils.If(
                        Expression.NotEqual(tryThrows, Expression.Default(typeof(Exception))),
                        Parent.GetSaveLineNumberExpression(tryThrows, false)
                        ),

                    // clear the frames incase thae finally throws, and allow line number
                    // updates to proceed
                    UpdateLineUpdated(false),

                    // run the finally code
                    @finally,

                    // if we took an exception in the try block we have saved the line number.  Otherwise
                    // we have no line number saved and will need to continue saving them if
                    // other exceptions are thrown.
                    AstUtils.If(
                        Expression.NotEqual(tryThrows, Expression.Default(typeof(Exception))),
                        UpdateLineUpdated(true)
                        )
                    );
                body = Ast.Block(new[] { tryThrows }, body);
            }

            return(body);
        }
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            // TODO:
            // {target}[{arguments}] op= rhs
            // we need to evaluate {arguments} once: http://ironruby.codeplex.com/workitem/4525

            // first, read target into a temp:
            MSA.Expression transformedLeftTarget = _left.TransformTargetRead(gen);
            MSA.Expression leftTargetTemp;

            if (transformedLeftTarget != null)
            {
                leftTargetTemp = gen.CurrentScope.DefineHiddenVariable(String.Empty, transformedLeftTarget.Type);
            }
            else
            {
                leftTargetTemp = null;
            }

            MSA.Expression transformedRight = _right.TransformRead(gen);

            // lhs &&= rhs  -->  lhs && (lhs = rhs)
            // lhs ||= rhs  -->  lhs || (lhs = rhs)
            if (Operation == Symbols.And || Operation == Symbols.Or)
            {
                MSA.Expression transformedLeftRead = _left.TransformRead(gen,
                                                                         (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
                                                                         true // tryRead
                                                                         );

                MSA.Expression transformedWrite = _left.TransformWrite(gen, leftTargetTemp, transformedRight);

                if (Operation == Symbols.And)
                {
                    return(AndExpression.TransformRead(gen, transformedLeftRead, transformedWrite));
                }
                else
                {
                    return(OrExpression.TransformRead(gen, transformedLeftRead, transformedWrite));
                }
            }
            else
            {
                // lhs op= rhs  -->  lhs = lhs op rhs
                if (Operation != null)
                {
                    MSA.Expression transformedLeftRead = _left.TransformRead(gen, leftTargetTemp, false);
                    transformedRight = MethodCall.TransformRead(this, gen, false, Operation, transformedLeftRead, null, null, transformedRight, null);
                }

                // transform lhs write assigning lhs-target temp:
                return(_left.TransformWrite(gen,
                                            (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
                                            transformedRight
                                            ));
            }
        }
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed)
        {
            if (_tmp == null)
            {
                _tmp = resolver.GetTemporary(Type, "outParam");
            }

            return(Ast.Block(Ast.Assign(_tmp, base.ToExpression(resolver, args, hasBeenUsed)), _tmp));
        }
Beispiel #6
0
        internal static MSAst.Expression /*!*/ Delete(MSAst.Expression /*!*/ expression)
        {
            if (expression is IPythonVariableExpression pyGlobal)
            {
                return(pyGlobal.Delete());
            }

            return(Ast.Assign(expression, Ast.Field(null, typeof(Uninitialized).GetField(nameof(Uninitialized.Instance)))));
        }
Beispiel #7
0
        internal sealed override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDefinition) ? "CLASS" : "MODULE") + " " + QualifiedName.Name;

            ScopeBuilder outerLocals = gen.CurrentScope;

            // definition needs to take place outside the defined lexical scope:
            var definition   = MakeDefinitionExpression(gen);
            var selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule));
            var parentScope  = gen.CurrentScopeVariable;

            // inner locals:
            ScopeBuilder scope         = DefineLocals();
            var          scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope));

            gen.EnterModuleDefinition(
                scope,
                selfVariable,
                scopeVariable,
                IsSingletonDeclaration
                );

            // transform body:
            MSA.Expression transformedBody = Body.TransformRead(gen);

            // outer local:
            MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type);

            // begin with new scope
            //   self = DefineModule/Class(... parent scope here ...)
            //   <body>
            // end
            MSA.Expression result = new AstBlock {
                gen.DebugMarker(debugString),
                Ast.Assign(selfVariable, definition),
                scope.CreateScope(
                    scopeVariable,
                    Methods.CreateModuleScope.OpCall(
                        scope.MakeLocalsStorage(),
                        scope.GetVariableNamesExpression(),
                        parentScope,
                        selfVariable
                        ),
                    Ast.Block(
                        Ast.Assign(resultVariable, transformedBody),
                        AstUtils.Empty()
                        )
                    ),
                gen.DebugMarker("END OF " + debugString),
                resultVariable
            };

            gen.LeaveModuleDefinition();

            return(result);
        }
Beispiel #8
0
        private DynamicMetaObject MakeMethodIndexRule(IndexType oper, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args)
        {
            MethodInfo[] defaults = GetMethodsFromDefaults(args[0].GetLimitType().GetDefaultMembers(), oper);
            if (defaults.Length != 0)
            {
                DynamicMetaObject[] selfWithArgs = args;
                ParameterExpression arg2         = null;

                if (oper == IndexType.Set)
                {
                    Debug.Assert(args.Length >= 2);

                    // need to save arg2 in a temp because it's also our result
                    arg2 = Ast.Variable(args[2].Expression.Type, "arg2Temp");

                    args[2] = new DynamicMetaObject(
                        Ast.Assign(arg2, args[2].Expression),
                        args[2].Restrictions
                        );
                }

                BindingRestrictions restrictions = BindingRestrictions.Combine(args);

                var           resolver = resolverFactory.CreateOverloadResolver(selfWithArgs, new CallSignature(selfWithArgs.Length), CallTypes.ImplicitInstance);
                BindingTarget target   = resolver.ResolveOverload(oper == IndexType.Get ? "get_Item" : "set_Item", defaults, NarrowingLevel.None, NarrowingLevel.All);
                if (target.Success)
                {
                    if (oper == IndexType.Get)
                    {
                        return(new DynamicMetaObject(
                                   target.MakeExpression(),
                                   restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                                   ));
                    }
                    else
                    {
                        return(new DynamicMetaObject(
                                   Ast.Block(
                                       new ParameterExpression[] { arg2 },
                                       target.MakeExpression(),
                                       arg2
                                       ),
                                   restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                                   ));
                    }
                }

                return(MakeError(
                           resolver.MakeInvalidParametersError(target),
                           restrictions,
                           typeof(object)
                           ));
            }

            return(null);
        }
Beispiel #9
0
        //
        // rescue stmts                     ... if (StandardError === $!) { stmts; }
        // rescue <types> stmts             ... temp1 = type1; ...; if (<temp1> === $! || ...) { stmts; }
        // rescue <types> => <lvalue> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { <lvalue> = $!; stmts; }
        //
        internal IfStatementTest /*!*/ Transform(AstGenerator /*!*/ gen, ResultOperation resultOperation)
        {
            Assert.NotNull(gen);

            MSA.Expression condition;
            if (_types.Length != 0)
            {
                var comparisonSiteStorage = Ast.Constant(new BinaryOpStorage(gen.Context));

                if (_types.Length == 1)
                {
                    condition = MakeCompareException(gen, comparisonSiteStorage, _types[0].TransformRead(gen), _types[0] is SplattedArgument);
                }
                else
                {
                    // forall{i}: <temps[i]> = evaluate type[i]
                    var temps = new MSA.Expression[_types.Length];
                    var exprs = new BlockBuilder();

                    for (int i = 0; i < _types.Length; i++)
                    {
                        var t   = _types[i].TransformRead(gen);
                        var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, t.Type);
                        temps[i] = tmp;
                        exprs.Add(Ast.Assign(tmp, t));
                    }

                    // CompareException(<temps[0]>) || ... CompareException(<temps[n]>) || CompareSplattedExceptions(<splatTypes>)
                    condition = MakeCompareException(gen, comparisonSiteStorage, temps[0], _types[0] is SplattedArgument);
                    for (int i = 1; i < _types.Length; i++)
                    {
                        condition = Ast.OrElse(condition, MakeCompareException(gen, comparisonSiteStorage, temps[i], _types[i] is SplattedArgument));
                    }

                    // (temps[0] = type[0], ..., temps[n] == type[n], condition)
                    exprs.Add(condition);
                    condition = exprs;
                }
            }
            else
            {
                condition = Methods.CompareDefaultException.OpCall(gen.CurrentScopeVariable);
            }

            return(AstUtils.IfCondition(condition,
                                        gen.TransformStatements(
                                            // <lvalue> = e;
                                            (_target != null) ? _target.TransformWrite(gen, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)) : null,

                                            // body:
                                            _statements,

                                            resultOperation
                                            )
                                        ));
        }
Beispiel #10
0
        private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ invoke, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke");

            DynamicMetaObject self = Restrict(typeof(OldInstance));

            Expression[] exprArgs = new Expression[args.Length + 1];
            for (int i = 0; i < args.Length; i++)
            {
                exprArgs[i + 1] = args[i].Expression;
            }

            ParameterExpression tmp = Ast.Variable(typeof(object), "callFunc");

            exprArgs[0] = tmp;
            return(new DynamicMetaObject(
                       // we could get better throughput w/ a more specific rule against our current custom old class but
                       // this favors less code generation.

                       Ast.Block(
                           new ParameterExpression[] { tmp },
                           Ast.Condition(
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("OldInstanceTryGetBoundCustomMember"),
                                   codeContext,
                                   self.Expression,
                                   AstUtils.Constant("__call__"),
                                   tmp
                                   ),
                               Ast.Block(
                                   Utils.Try(
                                       Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrameCodeContext"), codeContext),
                                       Ast.Assign(
                                           tmp,
                                           Ast.Dynamic(
                                               PythonContext.GetPythonContext(invoke).Invoke(
                                                   BindingHelpers.GetCallSignature(invoke)
                                                   ),
                                               typeof(object),
                                               ArrayUtils.Insert(codeContext, exprArgs)
                                               )
                                           )
                                       ).Finally(
                                       Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame"))
                                       ),
                                   tmp
                                   ),
                               Utils.Convert(
                                   BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression,
                                   typeof(object)
                                   )
                               )
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Beispiel #11
0
        internal static MSAst.Expression /*!*/ Delete(MSAst.Expression /*!*/ expression)
        {
            IPythonVariableExpression pyGlobal = expression as IPythonVariableExpression;

            if (pyGlobal != null)
            {
                return(pyGlobal.Delete());
            }

            return(Ast.Assign(expression, Ast.Field(null, typeof(Uninitialized).GetField("Instance"))));
        }
Beispiel #12
0
        public static MSAst.Expression /*!*/ Assign(MSAst.Expression /*!*/ expression, MSAst.Expression value)
        {
            IPythonVariableExpression pyGlobal = expression as IPythonVariableExpression;

            if (pyGlobal != null)
            {
                return(pyGlobal.Assign(value));
            }

            return(Ast.Assign(expression, value));
        }
        internal override Expression ToExpression(MethodBinderContext context, Expression[] parameters)
        {
#if FULL
            if (_tmp == null)
            {
                _tmp = context.GetTemporary(Type, "outParam");
            }
#endif


            return(Ast.Comma(Ast.Assign(_tmp, base.ToExpression(context, parameters)), Ast.Read(_tmp)));
        }
Beispiel #14
0
        internal static MSAst.Expression /*!*/ AssignValue(MSAst.Expression /*!*/ expression, MSAst.Expression value)
        {
            Debug.Assert(expression != null);
            Debug.Assert(value != null);

            if (expression is IPythonVariableExpression pyGlobal)
            {
                return(pyGlobal.Assign(value));
            }

            return(Ast.Assign(expression, value));
        }
Beispiel #15
0
        internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            Expression expr     = null;
            Expression instance = _fieldInfo.IsStatic ? null : Ast.Convert(args.TargetExpression, _fieldInfo.DeclaringType);

            if (_isSetter)
            {
                // parameters should be: instance/type, value
                if (args.SimpleArgumentCount == 0 && args.Signature.HasRhsArgument)
                {
                    expr = Ast.Assign(
                        Ast.Field(instance, _fieldInfo),
                        // TODO: remove
                        args.RubyContext.Binder.ConvertExpression(
                            args.GetRhsArgumentExpression(),
                            _fieldInfo.FieldType,
                            ConversionResultKind.ExplicitCast,
                            args.ScopeExpression
                            )
                        );
                }
            }
            else
            {
                // parameter should be: instance/type
                if (args.SimpleArgumentCount == 0)
                {
                    if (_fieldInfo.IsLiteral)
                    {
                        // TODO: seems like Compiler should correctly handle the literal field case
                        // (if you emit a read to a literal field, you get a NotSupportedExpception from
                        // FieldHandle when we try to emit)
                        expr = Ast.Constant(_fieldInfo.GetValue(null));
                    }
                    else
                    {
                        expr = Ast.Field(instance, _fieldInfo);
                    }
                }
            }

            if (expr != null)
            {
                metaBuilder.Result = expr;
            }
            else
            {
                metaBuilder.SetError(
                    Methods.MakeInvalidArgumentTypesError.OpCall(Ast.Constant(_isSetter ? name + "=" : name))
                    );
            }
        }
Beispiel #16
0
        // This is a compound comparison operator like: a < b < c.
        // That's represented as binary operators, but it's not the same as (a<b) < c, so we do special transformations.
        // We need to:
        // - return true iff (a<b) && (b<c), but ensure that b is only evaluated once.
        // - ensure evaluation order is correct (a,b,c)
        // - don't evaluate c if a<b is false.
        private MSAst.Expression FinishCompare(MSAst.Expression left)
        {
            Debug.Assert(_right is BinaryExpression);

            BinaryExpression bright = (BinaryExpression)_right;

            // Transform the left child of my right child (the next node in sequence)
            MSAst.Expression rleft = bright.Left;

            // Store it in the temp
            MSAst.ParameterExpression temp = Ast.Parameter(typeof(object), "chained_comparison");

            // Create binary operation: left <_op> (temp = rleft)
            MSAst.Expression comparison = MakeBinaryOperation(
                _op,
                left,
                Ast.Assign(temp, AstUtils.Convert(rleft, temp.Type)),
                Span
                );

            MSAst.Expression rright;

            // Transform rright, comparing to temp
            if (IsComparison(bright._right))
            {
                rright = bright.FinishCompare(temp);
            }
            else
            {
                MSAst.Expression transformedRight = bright.Right;
                rright = MakeBinaryOperation(
                    bright.Operator,
                    temp,
                    transformedRight,
                    bright.Span
                    );
            }

            // return (left (op) (temp = rleft)) and (rright)
            MSAst.ParameterExpression tmp;
            MSAst.Expression          res = AstUtils.CoalesceTrue(
                comparison,
                rright,
                AstMethods.IsTrue,
                out tmp
                );

            return(Ast.Block(
                       new[] { temp, tmp },
                       res
                       ));
        }
Beispiel #17
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)));
     }
 }
Beispiel #18
0
 internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue)
 {
     if (_transformed != null)
     {
         // static lookup:
         return(Ast.Assign(_transformed, AstUtils.Convert(rightValue, _transformed.Type)));
     }
     else
     {
         // dynamic lookup:
         return(Methods.SetLocalVariable.OpCall(AstFactory.Box(rightValue), gen.CurrentScopeVariable, AstUtils.Constant(Name)));
     }
 }
Beispiel #19
0
 public override MSAst.LambdaExpression ReduceAst(PythonAst instance, string name)
 {
     return(Ast.Lambda <Func <FunctionCode, object> >(
                Ast.Block(
                    new[] { PythonAst._globalArray, PythonAst._globalContext },
                    Ast.Assign(PythonAst._globalArray, instance.GlobalArrayInstance),
                    Ast.Assign(PythonAst._globalContext, Ast.Constant(instance.ModuleContext.GlobalContext)),
                    AstUtils.Convert(instance.ReduceWorker(), typeof(object))
                    ),
                name,
                new[] { PythonAst._functionCode }
                ));
 }
Beispiel #20
0
 public override void PrepareScope(PythonAst ast, System.Runtime.CompilerServices.ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals, List <MSAst.Expression> init)
 {
     locals.Add(PythonAst._globalArray);
     init.Add(
         Ast.Assign(
             PythonAst._globalArray,
             Ast.Call(
                 typeof(PythonOps).GetMethod(nameof(PythonOps.GetGlobalArrayFromContext)),
                 PythonAst._globalContext
                 )
             )
         );
 }
Beispiel #21
0
        internal static MSA.Expression /*!*/ MakeUserMethodBody(AstGenerator gen, int lastLine,
                                                                MSA.Expression /*!*/ blockParameter, MSA.Expression /*!*/ rfcVariable,
                                                                MSA.ParameterExpression /*!*/ methodUnwinder, MSA.Expression /*!*/ bodyStatement, ResultOperation resultOperation,
                                                                int profileTickIndex, MSA.ParameterExpression stampVariable, MSA.LabelTarget returnLabel)
        {
            Assert.NotNull(blockParameter, rfcVariable, bodyStatement, methodUnwinder);
            Debug.Assert(!resultOperation.IsIgnore, "return value should not be ignored");
            Debug.Assert(returnLabel != null || resultOperation.Variable != null, "return label needed");

            MSA.Expression resultExpression = Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField);
            if (resultOperation.Variable != null)
            {
                resultExpression = Ast.Assign(resultOperation.Variable, resultExpression);
            }
            else
            {
                resultExpression = Ast.Return(returnLabel, resultExpression);
            }

            // TODO: move this to the caller:
            MSA.Expression profileStart, profileEnd;
            if (stampVariable != null)
            {
                profileStart = Ast.Assign(stampVariable, Methods.Stopwatch_GetTimestamp.OpCall());
                profileEnd   = Methods.UpdateProfileTicks.OpCall(Ast.Constant(profileTickIndex), stampVariable);
            }
            else
            {
                profileStart = profileEnd = Ast.Empty();
            }

            return(AstUtils.Try(
                       // initialize frame (RFC):
                       profileStart,
                       Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(blockParameter, typeof(Proc)))),
                       bodyStatement
                       ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable),

                                // return unwinder.ReturnValue;
                                resultExpression

                                ).Finally(
                       Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false)),
                       profileEnd,
                       gen != null && gen.TraceEnabled ? Methods.TraceMethodReturn.OpCall(
                           gen.CurrentScopeVariable,
                           Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)),
                           Ast.Constant(lastLine)
                           ) : Ast.Empty()
                       ));
        }
Beispiel #22
0
        private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke");

            CallSignature signature = BindingHelpers.GetCallSignature(call);

            // TODO: If we know __init__ wasn't present we could construct the OldInstance directly.

            Expression[] exprArgs = new Expression[args.Length];
            for (int i = 0; i < args.Length; i++)
            {
                exprArgs[i] = args[i].Expression;
            }

            ParameterExpression init    = Ast.Variable(typeof(object), "init");
            ParameterExpression instTmp = Ast.Variable(typeof(object), "inst");
            DynamicMetaObject   self    = Restrict(typeof(OldClass));

            return(new DynamicMetaObject(
                       Ast.Block(
                           new ParameterExpression[] { init, instTmp },
                           Ast.Assign(
                               instTmp,
                               Ast.New(
                                   typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }),
                                   codeContext,
                                   self.Expression
                                   )
                               ),
                           Ast.Condition(
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("OldClassTryLookupInit"),
                                   self.Expression,
                                   instTmp,
                                   init
                                   ),
                               Ast.Dynamic(
                                   PythonContext.GetPythonContext(call).Invoke(
                                       signature
                                       ),
                                   typeof(object),
                                   ArrayUtils.Insert <Expression>(codeContext, init, exprArgs)
                                   ),
                               NoInitCheckNoArgs(signature, self, args)
                               ),
                           instTmp
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Beispiel #23
0
        // Function Body Code Generation
        //
        // object Func(object self, object[] args) {
        //     object p1 = ...;
        //     object p2 = ...;
        //     ...
        //     object pn = ...;
        //     (..Body..)
        // }
        //
        // <if has_default(p[i]) then>
        //     <p[i]> = <i> < args.Length ? (args[<i>] == void ? <default(p[i])> : args[<i>]) : <default(p[i])>;
        // <else if any_length_args(p[i]) then>
        //     <if has_name(p[i]) then>
        //         <p[i]> = new Array(args.Skip(<i>));
        //     <else>
        //         <p[i]> = new UnnamedSpreadArguments(args, <i>);
        //     <end if>
        // <else>
        //     <p[i]> = <i> < args.Length ? args[<i>] : void;
        // <end if>

        public System.Linq.Expressions.Expression <Func <object, object, object[], object> > TransformLambda()
        {
            List <Ast> body = new List <Ast>();

            for (int i = 0; i < Parameters.Count; i++)
            {
                var capCheck = Ast.LessThan(Ast.Constant(i), Ast.Property(_arguments, "Length"));
                Ast exp;
                if (Parameters[i].HasDefaultValue)
                {
                    exp = Ast.Condition(capCheck,
                                        Ast.Condition(Ast.TypeEqual(Ast.ArrayAccess(_arguments, Ast.Constant(i)), typeof(Builtins.Void)),
                                                      Ast.Constant(Parameters[i].DefaultValue, typeof(object)),
                                                      Ast.ArrayAccess(_arguments, Ast.Constant(i))
                                                      ),
                                        Ast.Constant(Parameters[i].DefaultValue, typeof(object))
                                        );
                }
                else if (Parameters[i].ExpandToArray)
                {
                    if (Parameters[i].ParameterVariable.Name != null)
                    {
                        exp = Ast.New((System.Reflection.ConstructorInfo)Utils.GetMember(() => new Builtins.Array(null)),
                                      Ast.Call(new Func <IEnumerable <object>, int, IEnumerable <object> >(Enumerable.Skip).Method, _arguments, Ast.Constant(i))
                                      );
                    }
                    else
                    {
                        exp = Ast.New((System.Reflection.ConstructorInfo)Utils.GetMember(() => new Runtime.UnnamedSpreadArguments(null, 0)),
                                      _arguments,
                                      Ast.Constant(i)
                                      );
                    }
                }
                else
                {
                    exp = Ast.Condition(capCheck,
                                        Ast.ArrayAccess(_arguments, Ast.Constant(i)),
                                        Ast.Constant(Builtins.Void.Value, typeof(object))
                                        );
                }
                body.Add(Ast.Assign(Parameters[i].ParameterVariable, exp));
            }
            foreach (var statement in Body)
            {
                body.Add(statement.Transform());
            }
            body.Add(Ast.Label(ReturnLabel, Ast.Constant(Builtins.Void.Value)));
            return(Ast.Lambda <Func <object, object, object[], object> >(Ast.Block(_variables.Values.Concat(Parameters.Select(x => x.ParameterVariable)), body), Name, new[] { _global, _context, _arguments }));
        }
Beispiel #24
0
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            MSA.Expression transformedCondition = AstFactory.Box(_condition.TransformRead(gen));
            MSA.Expression tmpVariable          = gen.CurrentScope.DefineHiddenVariable("#tmp_cond", transformedCondition.Type);

            return(AstFactory.Block(
                       Ast.Assign(tmpVariable, transformedCondition),
                       AstUtils.IfThen(
                           (_negateCondition ? AstFactory.IsFalse(tmpVariable) : AstFactory.IsTrue(tmpVariable)),
                           _jumpStatement.Transform(gen)
                           ),
                       (_value != null) ? _value.TransformRead(gen) : tmpVariable
                       ));
        }
Beispiel #25
0
        private MSAst.Expression AssignOne()
        {
            Debug.Assert(_left.Length == 1);

            SequenceExpression seLeft  = _left[0] as SequenceExpression;
            SequenceExpression seRight = _right as SequenceExpression;

            bool isStarred = seLeft != null && seLeft.Items.OfType <StarredExpression>().Any();

            if (!isStarred && seLeft != null && seRight != null && seLeft.Items.Count == seRight.Items.Count)
            {
                int cnt = seLeft.Items.Count;

                // a, b = 1, 2, or [a,b] = 1,2 - not something like a, b = range(2)
                // we can do a fast parallel assignment
                MSAst.ParameterExpression[] tmps = new MSAst.ParameterExpression[cnt];
                MSAst.Expression[]          body = new MSAst.Expression[cnt * 2 + 1];

                // generate the body, the 1st n are the temporary assigns, the
                // last n are the assignments to the left hand side
                // 0: tmp0 = right[0]
                // ...
                // n-1: tmpn-1 = right[n-1]
                // n: right[0] = tmp0
                // ...
                // n+n-1: right[n-1] = tmpn-1

                // allocate the temps first before transforming so we don't pick up a bad temp...
                for (int i = 0; i < cnt; i++)
                {
                    MSAst.Expression tmpVal = seRight.Items[i];
                    tmps[i] = Ast.Variable(tmpVal.Type, "parallelAssign");

                    body[i] = Ast.Assign(tmps[i], tmpVal);
                }

                // then transform which can allocate more temps
                for (int i = 0; i < cnt; i++)
                {
                    body[i + cnt] = seLeft.Items[i].TransformSet(SourceSpan.None, tmps[i], PythonOperationKind.None);
                }

                // 4. Create and return the resulting suite
                body[cnt * 2] = AstUtils.Empty();
                return(GlobalParent.AddDebugInfoAndVoid(Ast.Block(tmps, body), Span));
            }

            return(_left[0].TransformSet(Span, _right, PythonOperationKind.None));
        }
Beispiel #26
0
 private static BinaryExpression /*!*/ MakeOneConvert(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ self, string name, ParameterExpression /*!*/ tmp)
 {
     return(Ast.NotEqual(
                Ast.Assign(
                    tmp,
                    Ast.Call(
                        typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceConvertNonThrowing)),
                        AstUtils.Constant(PythonContext.GetPythonContext(conversion).SharedContext),
                        self.Expression,
                        AstUtils.Constant(name)
                        )
                    ),
                AstUtils.Constant(null)
                ));
 }
Beispiel #27
0
        internal MSA.Expression /*!*/ TryCatchAny(MSA.Expression /*!*/ tryBody, MSA.Expression /*!*/ catchBody)
        {
            var variable = CurrentScope.DefineHiddenVariable("#value", tryBody.Type);

            return
                (Ast.Block(
                     Ast.TryCatch(
                         Ast.Assign(variable, tryBody),
                         Ast.Catch(typeof(Exception),
                                   Ast.Assign(variable, catchBody)
                                   )
                         ),
                     variable
                     ));
        }
Beispiel #28
0
        /// <summary>
        /// Gets the expression for the actual updating of the line number for stack traces to be available
        /// </summary>
        internal MSAst.Expression GetSaveLineNumberExpression(bool preventAdditionalAdds)
        {
            MSAst.Expression res;
            if (preventAdditionalAdds)
            {
                res = _saveLineNumberNoAdds;
            }
            else
            {
                res = _saveLineNumberAdds;
            }

            if (res == null)
            {
                res = Ast.Block(
                    AstUtils.If(
                        Ast.Not(
                            LineNumberUpdated
                            ),
                        Ast.Call(
                            AstMethods.UpdateStackTrace,
                            LocalContext,
                            _funcCodeExpr,
                            _GetCurrentMethod,
                            AstUtils.Constant(Name),
                            AstUtils.Constant(GlobalParent.SourceUnit.Path ?? "<string>"),
                            new LastFaultingLineExpression(LineNumberExpression)
                            )
                        ),
                    Ast.Assign(
                        LineNumberUpdated,
                        AstUtils.Constant(preventAdditionalAdds)
                        ),
                    AstUtils.Empty()
                    );

                if (preventAdditionalAdds)
                {
                    _saveLineNumberNoAdds = res;
                }
                else
                {
                    _saveLineNumberAdds = res;
                }
            }

            return(res);
        }
Beispiel #29
0
        /// <summary>
        /// Transform and handle the result according to the specified result operation.
        /// </summary>
        internal virtual MSA.Expression /*!*/ TransformResult(AstGenerator /*!*/ gen, ResultOperation resultOperation)
        {
            MSA.Expression resultExpression = TransformRead(gen);
            MSA.Expression statement;

            if (resultOperation.Variable != null)
            {
                statement = Ast.Assign(resultOperation.Variable, Ast.Convert(resultExpression, resultOperation.Variable.Type));
            }
            else
            {
                statement = gen.Return(resultExpression);
            }

            return(gen.AddDebugInfo(statement, Location));
        }
Beispiel #30
0
 /// <summary>
 /// Gets the expression for the actual updating of the line number for stack traces to be available
 /// </summary>
 internal MSAst.Expression GetSaveLineNumberExpression(MSAst.ParameterExpression exception, bool preventAdditionalAdds) {
     Debug.Assert(exception.Type == typeof(Exception));
     return Ast.Block(
         AstUtils.If(
             Ast.Not(
                 LineNumberUpdated
             ),
             UpdateStackTrace(exception)
         ),
         Ast.Assign(
             LineNumberUpdated,
             AstUtils.Constant(preventAdditionalAdds)
         ),
         AstUtils.Empty()
     );
 }