예제 #1
0
        public override MSAst.Expression Reduce() {
            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            for (int i = 0; i < _names.Length; i++) {
                statements.Add(
                    // _references[i] = PythonOps.Import(<code context>, _names[i])
                    GlobalParent.AddDebugInfoAndVoid(
                        AssignValue(
                            Parent.GetVariableExpression(_variables[i]),
                            LightExceptions.CheckAndThrow(
                                Expression.Call(
                                    _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom,
                                    Parent.LocalContext,                                     // 1st arg - code context
                                    AstUtils.Constant(_names[i].MakeString()),                   // 2nd arg - module name
                                    AstUtils.Constant(_forceAbsolute ? 0 : -1)                   // 3rd arg - absolute or relative imports
                                )
                            )
                        ),
                        _names[i].Span
                    )
                );
            }

            statements.Add(AstUtils.Empty());
            return GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span);
        }
예제 #2
0
        public ICollection <CuratorTransactionResult> commit()
        {
            CheckAlreadyCommited();
            isCommitted = true;

            AtomicBoolean   firstTime  = new AtomicBoolean(true);
            List <OpResult> resultList = RetryLoop.callWithRetry
                                         (
                client.getZookeeperClient(),
                CallableUtils.FromFunc(() => doOperation(firstTime)));

            if (resultList.Count != transaction.metadataSize())
            {
                throw new InvalidOperationException(String.Format("Result size ({0}) doesn't match input size ({1})",
                                                                  resultList.Count,
                                                                  transaction.metadataSize()));
            }

            var builder = new ReadOnlyCollectionBuilder <CuratorTransactionResult>();

            for (int i = 0; i < resultList.Count; ++i)
            {
                OpResult opResult = resultList[i];
                CuratorMultiTransactionRecord.TypeAndPath metadata = transaction.getMetadata(i);
                CuratorTransactionResult curatorResult             = makeCuratorResult(opResult, metadata);
                builder.Add(curatorResult);
            }

            return(builder.ToReadOnlyCollection());
        }
예제 #3
0
        public TotemArgs(TotemContext context, string[] names, IList<object> args, Dictionary<string, object> kwargs)
            : base(context.GetType<Types.Arguments>())
        {
            _names = new ReadOnlyCollectionBuilder<string>(names).ToReadOnlyCollection();
            var vb = new ReadOnlyCollectionBuilder<object>();
            var nvb = new Dictionary<string, object>();
            var snb = new ReadOnlyCollectionBuilder<string>();

            for (var i = 0; i < args.Count; i++)
            {
                vb.Add(args[i]);
                if (i < names.Length)
                    nvb.Add(names[i], args[i]);
            }

            foreach (var arg in kwargs)
            {
                nvb.Add(arg.Key, arg.Value);
                snb.Add(arg.Key);
            }

            _values = vb.ToReadOnlyCollection();
            _namedValues = new ReadOnlyDictionary<string, object>(nvb);
            _named = snb.ToReadOnlyCollection();
        }
예제 #4
0
        public override System.Linq.Expressions.Expression Reduce()
        {
            if (_statements.Length == 0)
                return GlobalParent.AddDebugInfoAndVoid(Utils.Empty(), Span);

            ReadOnlyCollectionBuilder<ParameterExpression> locals = new ReadOnlyCollectionBuilder<ParameterExpression>();
            List<Expression> init = new List<Expression>();

            init.Add(Expression.ClearDebugInfo(GlobalParent.Document));

            CreateVariables(locals, init);

            foreach (var statement in _statements)
            {
                int newline = GlobalParent.IndexToLocation(statement.StartIndex).Line;
                if (statement.CanThrow && newline != -1)
                    init.Add(UpdateLineNumber(newline));

                init.Add(statement);
            }

            return GlobalParent.AddDebugInfoAndVoid(
                Expression.Block(
                    locals.ToReadOnlyCollection(),
                    init
                ),
                Span
            );
        }
예제 #5
0
        public override MSAst.Expression Reduce()
        {
            ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>();

            for (int i = 0; i < _names.Length; i++)
            {
                statements.Add(
                    // _references[i] = PythonOps.Import(<code context>, _names[i])
                    GlobalParent.AddDebugInfoAndVoid(
                        AssignValue(
                            Parent.GetVariableExpression(_variables[i]),
                            LightExceptions.CheckAndThrow(
                                Expression.Call(
                                    _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom,
                                    Parent.LocalContext,                                     // 1st arg - code context
                                    AstUtils.Constant(_names[i].MakeString()),               // 2nd arg - module name
                                    AstUtils.Constant(_forceAbsolute ? 0 : -1)               // 3rd arg - absolute or relative imports
                                    )
                                )
                            ),
                        _names[i].Span
                        )
                    );
            }

            statements.Add(AstUtils.Empty());
            return(GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span));
        }
예제 #6
0
        internal override MSAst.Expression Transform(AstGenerator ag) {
            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            for (int i = 0; i < _names.Length; i++) {
                statements.Add(
                    // _references[i] = PythonOps.Import(<code context>, _names[i])
                    ag.AddDebugInfoAndVoid(
                        GlobalAllocator.Assign(
                            ag.Globals.GetVariable(ag, _variables[i]), 
                            Ast.Call(
                                AstGenerator.GetHelperMethod(                           // helper
                                    _asNames[i] == null ? "ImportTop" : "ImportBottom"
                                ),
                                ag.LocalContext,                                        // 1st arg - code context
                                AstUtils.Constant(_names[i].MakeString()),                   // 2nd arg - module name
                                AstUtils.Constant(_forceAbsolute ? 0 : -1)                   // 3rd arg - absolute or relative imports
                            )
                        ),
                        _names[i].Span
                    )
                );
            }

            statements.Add(AstUtils.Empty());
            return ag.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span);
        }
예제 #7
0
            private LambdaSignature()
            {
                Type target = typeof(T);

                if (!typeof(Delegate).IsAssignableFrom(target))
                {
                    throw new InvalidOperationException();
                }

                MethodInfo invoke = target.GetMethod("Invoke");

                ParameterInfo[] pis = invoke.GetParameters();
                if (pis[0].ParameterType != typeof(CallSite))
                {
                    throw new InvalidOperationException();
                }

                var @params = new ReadOnlyCollectionBuilder <ParameterExpression>(pis.Length - 1);

                for (int i = 0; i < pis.Length - 1; i++)
                {
                    @params.Add(Expression.Parameter(pis[i + 1].ParameterType, "$arg" + i));
                }

                Parameters  = @params.ToReadOnlyCollection();
                ReturnLabel = Expression.Label(invoke.GetReturnType());
            }
예제 #8
0
        public override MSAst.Expression Reduce() {
            if (_statements.Length == 0) {
                return GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span);
            }

            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            int curStart = -1;
            foreach (var statement in _statements) {
                // CPython debugging treats multiple statements on the same line as a single step, we
                // match that behavior here.
                if (statement.Start.Line == curStart) {
                    statements.Add(new DebugInfoRemovalExpression(statement, curStart));
                } else {
                    if (statement.CanThrow && statement.Start.IsValid) {
                        statements.Add(UpdateLineNumber(statement.Start.Line));
                    }

                    statements.Add(statement);
                }
                curStart = statement.Start.Line;
            }
            
            return Ast.Block(statements.ToReadOnlyCollection());
        }
예제 #9
0
            private GenericInterpretedBinder()
            {
                var invokeMethod = typeof(T).GetMethod("Invoke");
                var methodParams = invokeMethod.GetParameters();

                ReadOnlyCollectionBuilder <ParameterExpression> prms       = new ReadOnlyCollectionBuilder <ParameterExpression>(methodParams.Length);
                ReadOnlyCollectionBuilder <Expression>          invokePrms = new ReadOnlyCollectionBuilder <Expression>(methodParams.Length);

                for (int i = 0; i < methodParams.Length; i++)
                {
                    var param = Expression.Parameter(methodParams[i].ParameterType);
                    if (i == 0)
                    {
                        invokePrms.Add(Expression.Convert(param, typeof(CallSite <T>)));
                    }
                    else
                    {
                        invokePrms.Add(param);
                    }
                    prms.Add(param);
                }

                _parameters = prms.ToReadOnlyCollection();

                _updateExpression = Expression.Block(
                    Expression.Label(CallSiteBinder.UpdateLabel),
                    Expression.Invoke(
                        Expression.Property(
                            invokePrms[0],
                            typeof(CallSite <T>).GetDeclaredProperty("Update")
                            ),
                        invokePrms.ToReadOnlyCollection()
                        )
                    );
            }
        internal static ReadOnlyCollection <T> ToReadOnly <T>(this IEnumerable <T> enumerable)
        {
            if (enumerable == null)
            {
                return(EmptyReadOnlyCollection <T> .Instance);
            }
            TrueReadOnlyCollection <T> onlys = enumerable as TrueReadOnlyCollection <T>;

            if (onlys != null)
            {
                return(onlys);
            }
            ReadOnlyCollectionBuilder <T> builder = enumerable as ReadOnlyCollectionBuilder <T>;

            if (builder != null)
            {
                return(builder.ToReadOnlyCollection());
            }
            ICollection <T> is2 = enumerable as ICollection <T>;

            if (is2 == null)
            {
                return(new TrueReadOnlyCollection <T>(new List <T>(enumerable).ToArray()));
            }
            int count = is2.Count;

            if (count == 0)
            {
                return(EmptyReadOnlyCollection <T> .Instance);
            }
            T[] array = new T[count];
            is2.CopyTo(array, 0);
            return(new TrueReadOnlyCollection <T>(array));
        }
예제 #11
0
        public override MSAst.Expression Reduce()
        {
            if (_statements.Length == 0)
            {
                return(GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span));
            }

            ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>();

            int curStart = -1;

            foreach (var statement in _statements)
            {
                // CPython debugging treats multiple statements on the same line as a single step, we
                // match that behavior here.
                int newline = GlobalParent.IndexToLocation(statement.StartIndex).Line;
                if (newline == curStart)
                {
                    statements.Add(new DebugInfoRemovalExpression(statement, curStart));
                }
                else
                {
                    if (statement.CanThrow && newline != -1)
                    {
                        statements.Add(UpdateLineNumber(newline));
                    }

                    statements.Add(statement);
                }
                curStart = newline;
            }

            return(Ast.Block(statements.ToReadOnlyCollection()));
        }
예제 #12
0
        internal LoopFunc CreateDelegate()
        {
            var loop          = (LoopExpression)Visit(_loop);
            var body          = new ReadOnlyCollectionBuilder <Expression>();
            var finallyClause = new ReadOnlyCollectionBuilder <Expression>();

            foreach (var variable in _loopVariables)
            {
                LocalVariable local;
                if (!_outerVariables.TryGetValue(variable.Key, out local))
                {
                    local = _closureVariables[variable.Key];
                }
                Expression elemRef = local.LoadFromArray(_frameDataVar, _frameClosureVar);

                if (local.InClosureOrBoxed)
                {
                    var box = variable.Value.BoxStorage;
                    Debug.Assert(box != null);
                    body.Add(Expression.Assign(box, elemRef));
                    AddTemp(box);
                }
                else
                {
                    // Always initialize the variable even if it is only written to.
                    // If a write-only variable is actually not assigned during execution of the loop we will still write some value back.
                    // This value must be the original value, which we assign at entry.
                    body.Add(Expression.Assign(variable.Key, AstUtils.Convert(elemRef, variable.Key.Type)));

                    if ((variable.Value.Access & ExpressionAccess.Write) != 0)
                    {
                        finallyClause.Add(Expression.Assign(elemRef, AstUtils.Box(variable.Key)));
                    }

                    AddTemp(variable.Key);
                }
            }

            if (finallyClause.Count > 0)
            {
                body.Add(Expression.TryFinally(loop, Expression.Block(finallyClause)));
            }
            else
            {
                body.Add(loop);
            }

            body.Add(Expression.Label(_returnLabel, Expression.Constant(_loopEndInstructionIndex - _loopStartInstructionIndex)));

            var lambda = Expression.Lambda <LoopFunc>(
                _temps != null ? Expression.Block(_temps.ToReadOnlyCollection(), body) : Expression.Block(body),
                new[] { _frameDataVar, _frameClosureVar, _frameVar }
                );

            return(lambda.Compile());
        }
예제 #13
0
        private ReadOnlyCollection <Expression> ToTemp(ReadOnlyCollectionBuilder <Expression> block, ICollection <Expression> args)
        {
            var spilledArgs = new ReadOnlyCollectionBuilder <Expression>(args.Count);

            foreach (var arg in args)
            {
                spilledArgs.Add(ToTemp(block, arg));
            }
            return(spilledArgs.ToReadOnlyCollection());
        }
예제 #14
0
        internal MSAst.Expression ReduceWorker()
        {
            ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>();

            if (_body is ReturnStatement && (_languageFeatures == ModuleOptions.None || _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret)))
            {
                // for simple eval's we can construct a simple tree which just
                // leaves the value on the stack.  Return's can't exist in modules
                // so this is always safe.
                Debug.Assert(!_isModule);

                var ret = (ReturnStatement)_body;
                return(Ast.Block(
                           Ast.DebugInfo(
                               _document,
                               ret.Expression.Start.Line,
                               ret.Expression.Start.Column,
                               ret.Expression.End.Line,
                               ret.Expression.End.Column
                               ),
                           AstUtils.Convert(
                               ret.Expression.Reduce(),
                               typeof(object)
                               )
                           ));
            }

            AddInitialiation(block);

            if (_isModule)
            {
                block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body))));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());

            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));
            if (body.Type == typeof(void))
            {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return(body);
        }
예제 #15
0
        public void ReadOnlyCollectionBuilder_ToReadOnlyCollection(int length)
        {
            var rocb = new ReadOnlyCollectionBuilder <int>();

            for (int i = 0; i < length; i++)
            {
                rocb.Add(i);
            }

            ReadOnlyCollection <int> collection = rocb.ToReadOnlyCollection();

            Assert.Equal(length, collection.Count);

            Assert.True(Enumerable.Range(0, length).SequenceEqual(collection));

            AssertEmpty(rocb);
        }
예제 #16
0
        public void ReadOnlyCollectionBuilder_Ctor_Collection(IEnumerable <int> collection)
        {
            var rocb = new ReadOnlyCollectionBuilder <int>(collection);

            Assert.Equal(collection.Count(), rocb.Count);
            Assert.True(collection.SequenceEqual(rocb));

            int[] array = rocb.ToArray();

            Assert.Equal(collection.Count(), array.Length);
            Assert.True(collection.SequenceEqual(array));

            ReadOnlyCollection <int> roc = rocb.ToReadOnlyCollection();

            Assert.Equal(collection.Count(), roc.Count);
            Assert.True(collection.SequenceEqual(roc));

            AssertEmpty(rocb); // ToReadOnlyCollection behavior is to empty the builder
        }
예제 #17
0
        public override System.Linq.Expressions.Expression Reduce()
        {
            if (_statements.Length == 0)
                return GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span);

            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            foreach (var stmt in _statements)
            {
                var line = GlobalParent.IndexToLocation(stmt.StartIndex).Line;
                if (stmt.CanThrow && line != -1)
                {
                    statements.Add(UpdateLineNumber(line));
                }

                statements.Add(stmt);
            }

            return Ast.Block(statements.ToReadOnlyCollection());
        }
예제 #18
0
        internal override void FinishBind(TotemNameBinder binder)
        {
            if (_freeVars != null && _freeVars.Count > 0)
            {
                ReadOnlyCollectionBuilder<TotemVariable> closureVariables = new ReadOnlyCollectionBuilder<TotemVariable>();
                _closureType = MutableTuple.MakeTupleType(_freeVars.Select(v => typeof(ClosureCell)).ToArray());
                _localClosureTuple = Expression.Parameter(_closureType, "$closure");
                for (var i = 0; i < _freeVars.Count; i++)
                {
                    var variable = _freeVars[i];
                    _variableMapping[variable] = new ClosureExpression(variable, Expression.Property(_localClosureTuple, String.Format("Item{0:D3}", i)), null);
                    closureVariables.Add(variable);
                }
                _closureVariables = closureVariables.ToReadOnlyCollection();
            }

            if (_scopeVars != null)
                foreach (var local in _scopeVars)
                {
                    if (local.Kind == VariableKind.Parameter) // handled in subclass
                        continue;

                    // scope variables, defined in this scope
                    Debug.Assert(local.Kind == VariableKind.Local);
                    Debug.Assert(local.Scope == this);

                    if (local.AccessedInNestedScope)
                    {
                        // Closure variable
                        _variableMapping[local] = new ClosureExpression(local, Expression.Parameter(typeof(ClosureCell), local.Name), null);
                    }
                    else
                    {
                        // Not used in nested function-scopes
                        _variableMapping[local] = Expression.Parameter(typeof(object), local.Name);
                    }
                }
        }
예제 #19
0
        /// <summary>
        /// Creates the LambdaExpression which implements the body of the function.
        /// 
        /// The functions signature is either "object Function(PythonFunction, ...)"
        /// where there is one object parameter for each user defined parameter or
        /// object Function(PythonFunction, object[]) for functions which take more
        /// than PythonCallTargets.MaxArgs arguments.
        /// </summary>
        private MSAst.LambdaExpression CreateFunctionLambda() {
            bool needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs;
            Delegate originalDelegate;
            Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate);

            MSAst.ParameterExpression localContext = null;
            ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>();
            if (NeedsLocalsDictionary || ContainsNestedFreeVariables) {
                localContext = LocalCodeContextVariable;
                locals.Add(localContext);
            }

            MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals);

            List<MSAst.Expression> init = new List<MSAst.Expression>();

            foreach (var param in _parameters) {
                IPythonVariableExpression pyVar = GetVariableExpression(param.PythonVariable) as IPythonVariableExpression;
                if (pyVar != null) {
                    var varInit = pyVar.Create();
                    if (varInit != null) {
                        init.Add(varInit);
                    }
                }
            }

            // Transform the parameters.
            init.Add(Ast.ClearDebugInfo(GlobalParent.Document));

            locals.Add(PythonAst._globalContext);
            init.Add(Ast.Assign(PythonAst._globalContext, Ast.Call(_GetGlobalContext, _parentContext)));

            GlobalParent.PrepareScope(locals, init);

            // Create variables and references. Since references refer to
            // parameters, do this after parameters have been created.

            CreateFunctionVariables(locals, init);

            // Initialize parameters - unpack tuples.
            // Since tuples unpack into locals, this must be done after locals have been created.
            InitializeParameters(init, needsWrapperMethod, parameters);

            List<MSAst.Expression> statements = new List<MSAst.Expression>();
            // add beginning sequence point
            statements.Add(GlobalParent.AddDebugInfo(
                AstUtils.Empty(),
                new SourceSpan(new SourceLocation(0, Start.Line, Start.Column), new SourceLocation(0, Start.Line, Int32.MaxValue))));


            // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close().
            // The exception traceback needs to come from the generator's method body, and so we must do the check and throw
            // from inside the generator.
            if (IsGenerator) {
                MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None);
                statements.Add(s1);
            }

            MSAst.ParameterExpression extracted = null;
            if (!IsGenerator && _canSetSysExcInfo) {
                // need to allocate the exception here so we don't share w/ exceptions made & freed
                // during the body.
                extracted = Ast.Parameter(typeof(Exception), "$ex");
                locals.Add(extracted);
            }

            if (_body.CanThrow && !(_body is SuiteStatement) && _body.Start.IsValid) {
                statements.Add(UpdateLineNumber(_body.Start.Line));
            }

            statements.Add(Body);
            MSAst.Expression body = Ast.Block(statements);

            // If this function can modify sys.exc_info() (_canSetSysExcInfo), then it must restore the result on finish.
            // 
            // Wrap in 
            //   $temp = PythonOps.SaveCurrentException()
            //   <body>
            //   PythonOps.RestoreCurrentException($temp)
            // Skip this if we're a generator. For generators, the try finally is handled by the PythonGenerator class 
            //  before it's invoked. This is because the restoration must occur at every place the function returns from 
            //  a yield point. That's different than the finally semantics in a generator.
            if (extracted != null) {
                MSAst.Expression s = AstUtils.Try(
                    Ast.Assign(
                        extracted,
                        Ast.Call(AstMethods.SaveCurrentException)
                    ),
                    body
                ).Finally(
                    Ast.Call(
                        AstMethods.RestoreCurrentException, extracted
                    )
                );
                body = s;
            }

            if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) {
                body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty("__code__")), body);
                locals.Add(FunctionStackVariable);
            }

            body = AddProfiling(body);
            body = WrapScopeStatements(body, _body.CanThrow);
            body = Ast.Block(body, AstUtils.Empty());
            body = AddReturnTarget(body);


            MSAst.Expression bodyStmt = body;
            if (localContext != null) {
                var createLocal = CreateLocalContext(_parentContext);

                init.Add(
                    Ast.Assign(
                        localContext,
                        createLocal
                    )
                );
            }

            init.Add(bodyStmt);

            bodyStmt = Ast.Block(init);

            // wrap a scope if needed
            bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt);

            return Ast.Lambda(
                delegateType,
                AddDefaultReturn(bodyStmt, typeof(object)),
                Name + "$" + Interlocked.Increment(ref _lambdaId),
                parameters
            );
        }
예제 #20
0
        public override MSAst.Expression Reduce() {
            MSAst.Expression destination = _dest;

            if (_expressions.Length == 0) {
                MSAst.Expression result;
                if (destination != null) {
                    result = Ast.Call(
                        AstMethods.PrintNewlineWithDest,
                        Parent.LocalContext,
                        destination
                    );
                } else {
                    result = Ast.Call(
                        AstMethods.PrintNewline,
                        Parent.LocalContext
                    );
                }
                return GlobalParent.AddDebugInfo(result, Span);
            } else {
                // Create list for the individual statements
                ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

                // Store destination in a temp, if we have one
                MSAst.ParameterExpression temp = null;
                if (destination != null) {
                    temp = Ast.Variable(typeof(object), "destination");

                    statements.Add(MakeAssignment(temp, destination));

                    destination = temp;
                }
                for (int i = 0; i < _expressions.Length; i++) {
                    bool withComma = (i < _expressions.Length - 1 || _trailingComma);// ? "PrintComma" : "Print";
                    Expression current = _expressions[i];
                    MSAst.MethodCallExpression mce;

                    if (destination != null) {
                        mce = Ast.Call(
                            withComma ? AstMethods.PrintCommaWithDest : AstMethods.PrintWithDest,
                            Parent.LocalContext,
                            destination,
                            AstUtils.Convert(current, typeof(object))
                        );
                    } else {
                        mce = Ast.Call(
                            withComma ? AstMethods.PrintComma : AstMethods.Print,
                            Parent.LocalContext,
                            AstUtils.Convert(current, typeof(object))
                        );
                    }

                    statements.Add(mce);
                }

                statements.Add(AstUtils.Empty());
                MSAst.Expression res;
                if (temp != null) {
                    res = Ast.Block(new[] { temp }, statements.ToReadOnlyCollection());
                } else {
                    res = Ast.Block(statements.ToReadOnlyCollection());
                }
                return GlobalParent.AddDebugInfo(res, Span);
            }
        }
예제 #21
0
        /// <summary>
        /// Creates the LambdaExpression which implements the body of the function.
        ///
        /// The functions signature is either "object Function(PythonFunction, ...)"
        /// where there is one object parameter for each user defined parameter or
        /// object Function(PythonFunction, object[]) for functions which take more
        /// than PythonCallTargets.MaxArgs arguments.
        /// </summary>
        private LightLambdaExpression CreateFunctionLambda()
        {
            bool needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs;
            Type delegateType       = GetDelegateType(_parameters, needsWrapperMethod, out _);

            MSAst.ParameterExpression localContext = null;
            ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>();

            if (NeedsLocalContext)
            {
                localContext = LocalCodeContextVariable;
                locals.Add(localContext);
            }

            MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals);

            List <MSAst.Expression> init = new List <MSAst.Expression>();

            foreach (var param in _parameters)
            {
                if (GetVariableExpression(param.PythonVariable) is IPythonVariableExpression pyVar)
                {
                    var varInit = pyVar.Create();
                    if (varInit != null)
                    {
                        init.Add(varInit);
                    }
                }
            }

            // Transform the parameters.
            init.Add(Ast.ClearDebugInfo(GlobalParent.Document));

            locals.Add(PythonAst._globalContext);
            init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContext)));

            GlobalParent.PrepareScope(locals, init);

            // Create variables and references. Since references refer to
            // parameters, do this after parameters have been created.

            CreateFunctionVariables(locals, init);

            // Initialize parameters - unpack tuples.
            // Since tuples unpack into locals, this must be done after locals have been created.
            InitializeParameters(init, needsWrapperMethod, parameters);

            List <MSAst.Expression> statements = new List <MSAst.Expression>();
            // add beginning sequence point
            var start = GlobalParent.IndexToLocation(StartIndex);

            statements.Add(GlobalParent.AddDebugInfo(
                               AstUtils.Empty(),
                               new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, int.MaxValue))));


            // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close().
            // The exception traceback needs to come from the generator's method body, and so we must do the check and throw
            // from inside the generator.
            if (IsGenerator)
            {
                MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None);
                statements.Add(s1);
            }

            if (Body.CanThrow && !(Body is SuiteStatement) && Body.StartIndex != -1)
            {
                statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(Body.StartIndex).Line));
            }

            statements.Add(Body);
            MSAst.Expression body = Ast.Block(statements);

            if (Body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames)
            {
                body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty(nameof(PythonFunction.__code__))), body);
                locals.Add(FunctionStackVariable);
            }

            body = AddProfiling(body);
            body = WrapScopeStatements(body, Body.CanThrow);
            body = Ast.Block(body, AstUtils.Empty());
            body = AddReturnTarget(body);

            MSAst.Expression bodyStmt = body;
            if (localContext != null)
            {
                var createLocal = CreateLocalContext(_parentContext);

                init.Add(
                    Ast.Assign(
                        localContext,
                        createLocal
                        )
                    );
            }

            init.Add(bodyStmt);

            bodyStmt = Ast.Block(init);

            // wrap a scope if needed
            bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt);

            return(AstUtils.LightLambda(
                       typeof(object),
                       delegateType,
                       AddDefaultReturn(bodyStmt, typeof(object)),
                       Name + "$" + Interlocked.Increment(ref _lambdaId),
                       parameters
                       ));
        }
예제 #22
0
        public override MSAst.Expression Reduce()
        {
            MSAst.Expression destination = _dest;

            if (_expressions.Length == 0)
            {
                MSAst.Expression result;
                if (destination != null)
                {
                    result = Ast.Call(
                        AstMethods.PrintNewlineWithDest,
                        Parent.LocalContext,
                        destination
                        );
                }
                else
                {
                    result = Ast.Call(
                        AstMethods.PrintNewline,
                        Parent.LocalContext
                        );
                }
                return(GlobalParent.AddDebugInfo(result, Span));
            }
            else
            {
                // Create list for the individual statements
                ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>();

                // Store destination in a temp, if we have one
                MSAst.ParameterExpression temp = null;
                if (destination != null)
                {
                    temp = Ast.Variable(typeof(object), "destination");

                    statements.Add(MakeAssignment(temp, destination));

                    destination = temp;
                }
                for (int i = 0; i < _expressions.Length; i++)
                {
                    bool       withComma = (i < _expressions.Length - 1 || _trailingComma);// ? "PrintComma" : "Print";
                    Expression current   = _expressions[i];
                    MSAst.MethodCallExpression mce;

                    if (destination != null)
                    {
                        mce = Ast.Call(
                            withComma ? AstMethods.PrintCommaWithDest : AstMethods.PrintWithDest,
                            Parent.LocalContext,
                            destination,
                            AstUtils.Convert(current, typeof(object))
                            );
                    }
                    else
                    {
                        mce = Ast.Call(
                            withComma ? AstMethods.PrintComma : AstMethods.Print,
                            Parent.LocalContext,
                            AstUtils.Convert(current, typeof(object))
                            );
                    }

                    statements.Add(mce);
                }

                statements.Add(AstUtils.Empty());
                MSAst.Expression res;
                if (temp != null)
                {
                    res = Ast.Block(new[] { temp }, statements.ToReadOnlyCollection());
                }
                else
                {
                    res = Ast.Block(statements.ToReadOnlyCollection());
                }
                return(GlobalParent.AddDebugInfo(res, Span));
            }
        }
예제 #23
0
        /// <summary>
        /// WithStatement is translated to the DLR AST equivalent to
        /// the following Python code snippet (from with statement spec):
        /// 
        /// mgr = (EXPR)
        /// exit = mgr.__exit__  # Not calling it yet
        /// value = mgr.__enter__()
        /// exc = True
        /// try:
        ///     VAR = value  # Only if "as VAR" is present
        ///     BLOCK
        /// except:
        ///     # The exceptional case is handled here
        ///     exc = False
        ///     if not exit(*sys.exc_info()):
        ///         raise
        ///     # The exception is swallowed if exit() returns true
        /// finally:
        ///     # The normal and non-local-goto cases are handled here
        ///     if exc:
        ///         exit(None, None, None)
        /// 
        /// </summary>
        public override MSAst.Expression Reduce() {
            // Five statements in the result...
            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(6);
            ReadOnlyCollectionBuilder<MSAst.ParameterExpression> variables = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>(6);
            MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with");
            variables.Add(lineUpdated);

            //******************************************************************
            // 1. mgr = (EXPR)
            //******************************************************************
            MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager");
            variables.Add(manager);
            statements.Add(
                GlobalParent.AddDebugInfo(
                    Ast.Assign(
                        manager,
                        _contextManager
                    ),
                    new SourceSpan(Start, _header)
                )
            );

            //******************************************************************
            // 2. exit = mgr.__exit__  # Not calling it yet
            //******************************************************************
            MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit");
            variables.Add(exit);
            statements.Add(
                MakeAssignment(
                    exit,
                    GlobalParent.Get(
                        "__exit__",
                        manager
                    )
                )
            );

            //******************************************************************
            // 3. value = mgr.__enter__()
            //******************************************************************
            MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value");
            variables.Add(value);
            statements.Add(
                GlobalParent.AddDebugInfoAndVoid(
                    MakeAssignment(
                        value,
                        Parent.Invoke(
                            new CallSignature(0),
                            Parent.LocalContext,
                            GlobalParent.Get(
                                "__enter__",
                                manager
                            )
                        )
                    ),
                    new SourceSpan(Start, _header)
                )
            );

            //******************************************************************
            // 4. exc = True
            //******************************************************************
            MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc");
            variables.Add(exc);
            statements.Add(
                MakeAssignment(
                    exc,
                    AstUtils.Constant(true)
                )
            );

            //******************************************************************
            //  5. The final try statement:
            //
            //  try:
            //      VAR = value  # Only if "as VAR" is present
            //      BLOCK
            //  except:
            //      # The exceptional case is handled here
            //      exc = False
            //      if not exit(*sys.exc_info()):
            //          raise
            //      # The exception is swallowed if exit() returns true
            //  finally:
            //      # The normal and non-local-goto cases are handled here
            //      if exc:
            //          exit(None, None, None)
            //******************************************************************

            MSAst.ParameterExpression exception;
            MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List<DynamicStackFrame>), "$nestedFrames");
            variables.Add(nestedFrames);
            statements.Add(
                // try:
                AstUtils.Try(
                    AstUtils.Try(// try statement body
                        PushLineUpdated(false, lineUpdated),
                        _var != null ?
                            (MSAst.Expression)Ast.Block(
                // VAR = value
                                _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None),
                // BLOCK
                                _body,
                                AstUtils.Empty()
                            ) :
                // BLOCK
                            (MSAst.Expression)_body // except:, // try statement location
                    ).Catch(exception = Ast.Variable(typeof(Exception), "exception"),
                // Python specific exception handling code
                        TryStatement.GetTracebackHeader(
                            this,
                            exception,
                            GlobalParent.AddDebugInfoAndVoid(
                                Ast.Block(
                // exc = False
                                    MakeAssignment(
                                        exc,
                                        AstUtils.Constant(false)
                                    ),
                                    Ast.Assign(
                                        nestedFrames,
                                        Ast.Call(AstMethods.GetAndClearDynamicStackFrames)
                                    ),
                //  if not exit(*sys.exc_info()):
                //      raise
                                    AstUtils.IfThen(
                                        GlobalParent.Convert(
                                            typeof(bool),
                                            ConversionResultKind.ExplicitCast,
                                            GlobalParent.Operation(
                                                typeof(bool),
                                                PythonOperationKind.IsFalse,
                                                MakeExitCall(exit, exception)
                                            )
                                        ),
                                        UpdateLineUpdated(true),
                                        Ast.Call(
                                            AstMethods.SetDynamicStackFrames,
                                            nestedFrames
                                        ),
                                        Ast.Throw(
                                            Ast.Call(
                                                AstMethods.MakeRethrowExceptionWorker,
                                                exception
                                            )
                                        )
                                    )
                                ),
                                _body.Span
                            )
                        ),
                        Ast.Call(
                            AstMethods.SetDynamicStackFrames,
                            nestedFrames
                        ),
                        PopLineUpdated(lineUpdated),
                        Ast.Empty()
                    )
                // finally:                    
                ).Finally(
                //  if exc:
                //      exit(None, None, None)
                    AstUtils.IfThen(
                        exc,
                        GlobalParent.AddDebugInfoAndVoid(
                            Ast.Block(
                                Ast.Dynamic(
                                    GlobalParent.PyContext.Invoke(
                                        new CallSignature(3)        // signature doesn't include function
                                    ),
                                    typeof(object),
                                    new MSAst.Expression[] {
                                        Parent.LocalContext,
                                        exit,
                                        AstUtils.Constant(null),
                                        AstUtils.Constant(null),
                                        AstUtils.Constant(null)
                                    }
                                ),
                                Ast.Empty()
                            ),
                            _contextManager.Span
                        )
                    )
                )
            );

            statements.Add(AstUtils.Empty());
            return Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection());
        }
예제 #24
0
        internal MSAst.Expression ReduceWorker()
        {
            var retStmt = _body as ReturnStatement;

            if (retStmt != null)
            {
                var ret = (ReturnStatement)_body;
                Ast simpleBody;
                simpleBody = retStmt.Expression.Reduce();

                var start = IndexToLocation(ret.Expression.StartIndex);
                var end = IndexToLocation(ret.Expression.EndIndex);

                return Ast.Block(
                    Ast.DebugInfo(
                        _document,
                        start.Line,
                        start.Column,
                        end.Line,
                        end.Column
                    ),
                    AstUtils.Convert(simpleBody, typeof(object))
                );
            }

            ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            if (!(_body is SuiteStatement) && _body.CanThrow)
            {
                // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement
                // at the top level we can miss some line number updates.
                block.Add(UpdateLineNumber(_body.Start.Line));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());

            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddProfiling(body);

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));

            if (body.Type == typeof(void))
            {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return body;
        }
예제 #25
0
        public void TestReadOnlyCollectionBuilder()
        {
            int cnt = 0;

            // Empty
            ReadOnlyCollectionBuilder <int> a = new ReadOnlyCollectionBuilder <int>();

            AreEqual(0, a.Count);
            AreEqual(0, a.Capacity);
            AreEqual(a.ToReadOnlyCollection().Count, 0);
            AreEqual(a.ToReadOnlyCollection().Count, 0);

            // Simple case
            a.Add(5);
            AreEqual(1, a.Count);
            AreEqual(4, a.Capacity);
            AreEqual(a.ToReadOnlyCollection()[0], 5);
            AreEqual(a.ToReadOnlyCollection().Count, 0);  // Will reset

            a = new ReadOnlyCollectionBuilder <int>(0);
            AreEqual(0, a.Count);
            AssertError <ArgumentException>(() => a = new ReadOnlyCollectionBuilder <int>(-1));

            a = new ReadOnlyCollectionBuilder <int>(5);
            for (int i = 1; i <= 10; i++)
            {
                a.Add(i);
            }

            AreEqual(10, a.Capacity);
            System.Collections.ObjectModel.ReadOnlyCollection <int> readonlyCollection = a.ToReadOnlyCollection();
            AreEqual(0, a.Capacity);
            AreEqual(readonlyCollection.Count, 10);

            ReadOnlyCollectionBuilder <int> b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);

            b.Add(11);
            AreEqual(b.Count, 11);

            AssertError <ArgumentException>(() => a = new ReadOnlyCollectionBuilder <int>(null));

            // Capacity tests
            b.Capacity = 11;
            AssertError <ArgumentException>(() => b.Capacity = 10);
            b.Capacity = 50;
            AreEqual(b.Count, 11);
            AreEqual(b.Capacity, 50);

            // IndexOf cases
            AreEqual(b.IndexOf(5), 4);
            AreEqual(b[4], 5);
            a = new ReadOnlyCollectionBuilder <int>();
            AreEqual(a.IndexOf(5), -1);

            // Insert cases
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            AssertError <ArgumentException>(() => b.Insert(11, 11));
            b.Insert(2, 24);
            AreEqual(b.Count, 11);
            AreEqual(b[1], 2);
            AreEqual(b[2], 24);
            AreEqual(b[3], 3);
            b.Insert(11, 1234);
            AssertError <ArgumentException>(() => b.Insert(-1, 55));
            AreEqual(b[11], 1234);
            AreEqual(b.ToReadOnlyCollection().Count, 12);

            // Remove
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            AreEqual(b.Remove(2), true);
            AreEqual(b[0], 1);
            AreEqual(b[1], 3);
            AreEqual(b[2], 4);
            AreEqual(b.Remove(2), false);

            // RemoveAt
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            b.RemoveAt(2);
            AreEqual(b[1], 2);
            AreEqual(b[2], 4);
            AreEqual(b[3], 5);
            AssertError <ArgumentException>(() => b.RemoveAt(-5));
            AssertError <ArgumentException>(() => b.RemoveAt(9));

            // Clear
            b.Clear();
            AreEqual(b.Count, 0);
            AreEqual(b.ToReadOnlyCollection().Count, 0);
            b = new ReadOnlyCollectionBuilder <int>();
            b.Clear();
            AreEqual(b.Count, 0);

            // Contains
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            AreEqual(b.Contains(5), true);
            AreEqual(b.Contains(-3), false);

            ReadOnlyCollectionBuilder <object> c = new ReadOnlyCollectionBuilder <object>();

            c.Add("HI");
            AreEqual(c.Contains("HI"), true);
            AreEqual(c.Contains(null), false);
            c.Add(null);
            AreEqual(c.Contains(null), true);

            // CopyTo
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            int[] ary = new int[10];
            b.CopyTo(ary, 0);

            AreEqual(ary[0], 1);
            AreEqual(ary[9], 10);

            // Reverse
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            b.Reverse();
            // 1..10
            cnt = 10;
            for (int i = 0; i < 10; i++)
            {
                AreEqual(b[i], cnt--);
            }

            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            AssertError <ArgumentException>(() => b.Reverse(-1, 5));
            AssertError <ArgumentException>(() => b.Reverse(5, -1));
            b.Reverse(3, 3);
            // 1,2,3,4,5,6,7,8,9.10
            // 1,2,3,6,5,4,7,8,9,10
            AreEqual(b[1], 2);
            AreEqual(b[2], 3);
            AreEqual(b[3], 6);
            AreEqual(b[4], 5);
            AreEqual(b[5], 4);
            AreEqual(b[6], 7);

            // ToArray
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            int[] intAry = b.ToArray();
            AreEqual(intAry[0], 1);
            AreEqual(intAry[9], 10);

            b      = new ReadOnlyCollectionBuilder <int>();
            intAry = b.ToArray();
            AreEqual(intAry.Length, 0);

            // IEnumerable cases
            b   = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            cnt = 0;
            foreach (int i in b)
            {
                cnt++;
            }
            AreEqual(cnt, 10);

            b   = new ReadOnlyCollectionBuilder <int>();
            cnt = 0;
            foreach (int i in b)
            {
                cnt++;
            }
            AreEqual(cnt, 0);

            // Error case
            AssertError <InvalidOperationException>(() => ChangeWhileEnumeratingAdd());
            AssertError <InvalidOperationException>(() => ChangeWhileEnumeratingRemove());

            // IList members
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            System.Collections.IList lst = b;

            // IsReadOnly
            AreEqual(lst.IsReadOnly, false);

            // Add
            AreEqual(lst.Add(11), 10);
            AreEqual(lst.Count, 11);
            AssertError <ArgumentException>(() => lst.Add("MOM"));
            AssertError <ArgumentException>(() => lst.Add(null));

            c = new ReadOnlyCollectionBuilder <object>();

            c.Add("HI");
            c.Add(null);
            lst = c;
            lst.Add(null);
            AreEqual(lst.Count, 3);

            // Contains
            lst = b;
            AreEqual(lst.Contains(5), true);
            AreEqual(lst.Contains(null), false);

            lst = c;
            AreEqual(lst.Contains("HI"), true);
            AreEqual(lst.Contains("hi"), false);
            AreEqual(lst.Contains(null), true);

            // IndexOf
            lst = b;
            AreEqual(lst.IndexOf(null), -1);
            AreEqual(lst.IndexOf(1234), -1);
            AreEqual(lst.IndexOf(5), 4);

            // Insert
            b   = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            lst = b;
            AssertError <ArgumentException>(() => lst.Insert(11, 11));
            lst.Insert(2, 24);
            AreEqual(lst.Count, 11);
            AreEqual(lst[1], 2);
            AreEqual(lst[2], 24);
            AreEqual(lst[3], 3);
            lst.Insert(11, 1234);
            AssertError <ArgumentException>(() => lst.Insert(-1, 55));
            AreEqual(lst[11], 1234);

            AssertError <ArgumentException>(() => lst.Insert(3, "MOM"));

            // IsFixedSize
            AreEqual(lst.IsFixedSize, false);

            // Remove
            b   = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            lst = b;
            lst.Remove(2);
            AreEqual(lst[0], 1);
            AreEqual(lst[1], 3);
            AreEqual(lst[2], 4);
            lst.Remove(2);

            // Indexing
            lst[3] = 234;
            AreEqual(lst[3], 234);
            AssertError <ArgumentException>(() => lst[3] = null);
            AssertError <ArgumentException>(() => lst[3] = "HI");

            // ICollection<T>

            // IsReadOnly
            System.Collections.Generic.ICollection <int> col = b;
            AreEqual(col.IsReadOnly, false);

            // ICollection
            b = new ReadOnlyCollectionBuilder <int>(readonlyCollection);
            System.Collections.ICollection col2 = b;
            AreEqual(col2.IsSynchronized, false);
            Assert(col2.SyncRoot != null);
            intAry = new int[10];
            col2.CopyTo(intAry, 0);
            AreEqual(intAry[0], 1);
            AreEqual(intAry[9], 10);

            string[] str = new string[50];
            AssertError <ArrayTypeMismatchException>(() => col2.CopyTo(str, 0));
        }
예제 #26
0
        internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) {
            // if we just have a simple named multi-assignment  (e.g. a, b = 1,2)
            // then go ahead and step over the entire statement at once.  If we have a 
            // more complex statement (e.g. a.b, c.d = 1, 2) then we'll step over the
            // sets individually as they could be property sets the user wants to step
            // into.  TODO: Enable stepping of the right hand side?
            bool emitIndividualSets = false;
            foreach (Expression e in _items) {
                if (IsComplexAssignment(e)) {
                    emitIndividualSets = true;
                    break;
                }
            }

            SourceSpan rightSpan = SourceSpan.None;
            SourceSpan leftSpan =
                (Span.Start.IsValid && span.IsValid) ?
                    new SourceSpan(Span.Start, span.End) :
                    SourceSpan.None;

            SourceSpan totalSpan = SourceSpan.None;
            if (emitIndividualSets) {
                rightSpan = span;
                leftSpan = SourceSpan.None;
                totalSpan = (Span.Start.IsValid && span.IsValid) ?
                    new SourceSpan(Span.Start, span.End) :
                    SourceSpan.None;
            }

            // 1. Evaluate the expression and assign the value to the temp.
            MSAst.ParameterExpression right_temp = Ast.Variable(typeof(object), "unpacking");

            // 2. Add the assignment "right_temp = right" into the suite/block
            MSAst.Expression assignStmt1 = MakeAssignment(right_temp, right);

            // 3. Call GetEnumeratorValues on the right side (stored in temp)
            MSAst.Expression enumeratorValues = Expression.Convert(LightExceptions.CheckAndThrow(
                Expression.Call(
                    emitIndividualSets ? 
                        AstMethods.GetEnumeratorValues : 
                        AstMethods.GetEnumeratorValuesNoComplexSets,    // method
                    // arguments
                    Parent.LocalContext,
                    right_temp,
                    AstUtils.Constant(_items.Length)
                )
            ), typeof(object[]));

            // 4. Create temporary variable for the array
            MSAst.ParameterExpression array_temp = Ast.Variable(typeof(object[]), "array");

            // 5. Assign the value of the method call (mce) into the array temp
            // And add the assignment "array_temp = Ops.GetEnumeratorValues(...)" into the block
            MSAst.Expression assignStmt2 = MakeAssignment(
                array_temp,
                enumeratorValues,
                rightSpan
            );

            ReadOnlyCollectionBuilder<MSAst.Expression> sets = new ReadOnlyCollectionBuilder<MSAst.Expression>(_items.Length + 1);
            for (int i = 0; i < _items.Length; i++) {
                // target = array_temp[i]

                Expression target = _items[i];
                if (target == null) {
                    continue;
                }

                // 6. array_temp[i]
                MSAst.Expression element = Ast.ArrayAccess(
                    array_temp,                             // array expression
                    AstUtils.Constant(i)                         // index
                );

                // 7. target = array_temp[i], and add the transformed assignment into the list of sets
                MSAst.Expression set = target.TransformSet(
                    emitIndividualSets ?                    // span
                        target.Span :
                        SourceSpan.None,
                    element,
                    PythonOperationKind.None
                );
                sets.Add(set);
            }
            // 9. add the sets as their own block so they can be marked as a single span, if necessary.
            sets.Add(AstUtils.Empty());
            MSAst.Expression itemSet = GlobalParent.AddDebugInfo(Ast.Block(sets.ToReadOnlyCollection()), leftSpan);

            // 10. Return the suite statement (block)
            return GlobalParent.AddDebugInfo(Ast.Block(new[] { array_temp, right_temp }, assignStmt1, assignStmt2, itemSet, AstUtils.Empty()), totalSpan);
        }
예제 #27
0
        /// <summary>
        /// WithStatement is translated to the DLR AST equivalent to
        /// the following Python code snippet (from with statement spec):
        ///
        /// mgr = (EXPR)
        /// exit = mgr.__exit__  # Not calling it yet
        /// value = mgr.__enter__()
        /// exc = True
        /// try:
        ///     VAR = value  # Only if "as VAR" is present
        ///     BLOCK
        /// except:
        ///     # The exceptional case is handled here
        ///     exc = False
        ///     if not exit(*sys.exc_info()):
        ///         raise
        ///     # The exception is swallowed if exit() returns true
        /// finally:
        ///     # The normal and non-local-goto cases are handled here
        ///     if exc:
        ///         exit(None, None, None)
        ///
        /// </summary>
        public override MSAst.Expression Reduce()
        {
            // Five statements in the result...
            ReadOnlyCollectionBuilder <MSAst.Expression>          statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(6);
            ReadOnlyCollectionBuilder <MSAst.ParameterExpression> variables  = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(6);

            MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with");
            variables.Add(lineUpdated);

            //******************************************************************
            // 1. mgr = (EXPR)
            //******************************************************************
            MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager");
            variables.Add(manager);
            statements.Add(
                GlobalParent.AddDebugInfo(
                    Ast.Assign(
                        manager,
                        _contextManager
                        ),
                    new SourceSpan(Start, _header)
                    )
                );

            //******************************************************************
            // 2. exit = mgr.__exit__  # Not calling it yet
            //******************************************************************
            MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit");
            variables.Add(exit);
            statements.Add(
                MakeAssignment(
                    exit,
                    GlobalParent.Get(
                        "__exit__",
                        manager
                        )
                    )
                );

            //******************************************************************
            // 3. value = mgr.__enter__()
            //******************************************************************
            MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value");
            variables.Add(value);
            statements.Add(
                GlobalParent.AddDebugInfoAndVoid(
                    MakeAssignment(
                        value,
                        Parent.Invoke(
                            new CallSignature(0),
                            Parent.LocalContext,
                            GlobalParent.Get(
                                "__enter__",
                                manager
                                )
                            )
                        ),
                    new SourceSpan(Start, _header)
                    )
                );

            //******************************************************************
            // 4. exc = True
            //******************************************************************
            MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc");
            variables.Add(exc);
            statements.Add(
                MakeAssignment(
                    exc,
                    AstUtils.Constant(true)
                    )
                );

            //******************************************************************
            //  5. The final try statement:
            //
            //  try:
            //      VAR = value  # Only if "as VAR" is present
            //      BLOCK
            //  except:
            //      # The exceptional case is handled here
            //      exc = False
            //      if not exit(*sys.exc_info()):
            //          raise
            //      # The exception is swallowed if exit() returns true
            //  finally:
            //      # The normal and non-local-goto cases are handled here
            //      if exc:
            //          exit(None, None, None)
            //******************************************************************

            MSAst.ParameterExpression exception;
            MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List <DynamicStackFrame>), "$nestedFrames");
            variables.Add(nestedFrames);
            statements.Add(
                // try:
                AstUtils.Try(
                    AstUtils.Try(// try statement body
                        PushLineUpdated(false, lineUpdated),
                        _var != null ?
                        (MSAst.Expression)Ast.Block(
                            // VAR = value
                            _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None),
                            // BLOCK
                            _body,
                            AstUtils.Empty()
                            ) :
                        // BLOCK
                        (MSAst.Expression)_body // except:, // try statement location
                        ).Catch(exception = Ast.Variable(typeof(Exception), "exception"),
                                                // Python specific exception handling code
                                TryStatement.GetTracebackHeader(
                                    this,
                                    exception,
                                    GlobalParent.AddDebugInfoAndVoid(
                                        Ast.Block(
                                            // exc = False
                                            MakeAssignment(
                                                exc,
                                                AstUtils.Constant(false)
                                                ),
                                            Ast.Assign(
                                                nestedFrames,
                                                Ast.Call(AstMethods.GetAndClearDynamicStackFrames)
                                                ),
                                            //  if not exit(*sys.exc_info()):
                                            //      raise
                                            AstUtils.IfThen(
                                                GlobalParent.Convert(
                                                    typeof(bool),
                                                    ConversionResultKind.ExplicitCast,
                                                    GlobalParent.Operation(
                                                        typeof(bool),
                                                        PythonOperationKind.IsFalse,
                                                        MakeExitCall(exit, exception)
                                                        )
                                                    ),
                                                UpdateLineUpdated(true),
                                                Ast.Call(
                                                    AstMethods.SetDynamicStackFrames,
                                                    nestedFrames
                                                    ),
                                                Ast.Throw(
                                                    Ast.Call(
                                                        AstMethods.MakeRethrowExceptionWorker,
                                                        exception
                                                        )
                                                    )
                                                )
                                            ),
                                        _body.Span
                                        )
                                    ),
                                Ast.Call(
                                    AstMethods.SetDynamicStackFrames,
                                    nestedFrames
                                    ),
                                PopLineUpdated(lineUpdated),
                                Ast.Empty()
                                )
                    // finally:
                    ).Finally(
                    //  if exc:
                    //      exit(None, None, None)
                    AstUtils.IfThen(
                        exc,
                        GlobalParent.AddDebugInfoAndVoid(
                            Ast.Block(
                                Ast.Dynamic(
                                    GlobalParent.PyContext.Invoke(
                                        new CallSignature(3)        // signature doesn't include function
                                        ),
                                    typeof(object),
                                    new MSAst.Expression[] {
                Parent.LocalContext,
                exit,
                AstUtils.Constant(null),
                AstUtils.Constant(null),
                AstUtils.Constant(null)
            }
                                    ),
                                Ast.Empty()
                                ),
                            _contextManager.Span
                            )
                        )
                    )
                );

            statements.Add(AstUtils.Empty());
            return(Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection()));
        }
예제 #28
0
 public void CompleteLoading()
 {
     _tcs.TrySetResult(_bufferBuilder.ToReadOnlyCollection());
     _navigationManager.LocationChanged += OnLocationChanged;
 }
예제 #29
0
        internal Expression ReduceWorker()
        {
            var retStmt = _body as ReturnStmt;

            ReadOnlyCollectionBuilder<Expression> block = new ReadOnlyCollectionBuilder<Expression>();
            AddInitialization(block);

            if (!(_body is BlockStmt) && _body.CanThrow)
            {
                // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement
                // at the top level we can miss some line number updates.  
                block.Add(UpdateLineNumber(_body.Start.Line));
            }

            block.Add(_body);

            Expression body = Expression.Block(block.ToReadOnlyCollection());

            body = WrapScopeStatements(body, _body.CanThrow);

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            if ((((TotemCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0)
            {
                body = LightExceptions.Rewrite(body);
            }

            body = Expression.Label(FunctionDefinition._returnLabel, Utils.Convert(body, typeof(object)));
            if (body.Type == typeof(void))
                body = Expression.Block(body, Expression.Constant(null));

            return body;
        }
예제 #30
0
        private static ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>> GetOperators(TotemType type)
        {
            Debug.Assert(type.IsSystemType, "Should only be called for system types as totem types should populate operators by themselves");
            if(!type.IsTotemType)
                return new ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>(
                    new Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>());

            Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>> ops = new Dictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>();
            var t = TotemBinder.GetProxyType(type.UnderlyingSystemType) ?? type.UnderlyingSystemType;

            var methods = t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)
                .GroupBy(m => m.Name);
            var names = Enum.GetNames(typeof(TotemOperationKind));

            foreach (var methodGroup in methods)
            {
                var builder = new ReadOnlyCollectionBuilder<MethodOrFunction>();
                foreach (var method in methodGroup)
                {
                    if(method.IsSpecialName)
                        builder.Add(new MethodOrFunction(method));
                }

                if (builder.Count > 0)
                {
                    TotemOperationKind kind;
                    if (Enum.TryParse<TotemOperationKind>(methodGroup.Key, out kind))
                        ops.Add(kind, builder.ToReadOnlyCollection());
                }
            }

            return new ReadOnlyDictionary<TotemOperationKind, ReadOnlyCollection<MethodOrFunction>>(ops);
        }
예제 #31
0
        private LightLambdaExpression CreateFunctionLambda()
        {
            bool needsWrapperMethod = _parameters.Length > TotemCallTargets.MAX_ARGS;
            Delegate originalDelegate;
            Type delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate);

            ReadOnlyCollectionBuilder<ParameterExpression> locals = new ReadOnlyCollectionBuilder<ParameterExpression>();

            ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals);

            List<Expression> init = new List<Expression>();
            foreach (var param in _parameters)
            {
                ITotemVariableExpression toVar = GetVariableExpression(param.TotemVariable) as ITotemVariableExpression;
                if (toVar != null)
                {
                    var varInit = toVar.Create();
                    if (varInit != null)
                        init.Add(varInit);
                }
            }

            // Transform the parameters.
            init.Add(Expression.ClearDebugInfo(GlobalParent.Document));

            locals.Add(TotemAst._globalContext);
            init.Add(Expression.Assign(TotemAst._globalContext, new GetGlobalContextExpression(_parentContext)));
            if (IsClosure)
            {
                locals.Add(LocalClosureTuple);
                init.Add(
                    Expression.Assign(
                        LocalClosureTuple,
                        Utils.Convert(
                            _localClosure,
                            LocalClosureTupleType
                        )
                    )
                );
            }

            GlobalParent.PrepareScope(locals, init);

            // Create variables and references. Since references refer to
            // parameters, do this after parameters have been created.

            CreateFunctionVariables(locals, init);

            // Initialize parameters - unpack tuples.
            // Since tuples unpack into locals, this must be done after locals have been created.
            InitializeParameters(init, needsWrapperMethod, parameters);

            List<Expression> statements = new List<Expression>();
            // Add beginning sequence point
            var start = GlobalParent.IndexToLocation(StartIndex);
            statements.Add(
                GlobalParent.AddDebugInfo(
                    Utils.Empty(),
                    new SourceSpan(
                        new SourceLocation(0, start.Line, start.Column),
                        new SourceLocation(0, start.Line, Int32.MaxValue)
                    )
                )
            );

            // For generators, we need to do a check before the first statement for Generator.Throw / Generator.Close.
            // The exception traceback needs to come from the generator's method body, and so we must do the check and throw
            // from inside the generator.
            if (IsGenerator)
            {
                //Expression s1 = YieldExpr.CreateCheckThrowExpression(SourceSpan.None);
                //statements.Add(s1);
                throw new NotImplementedException("Generators");
            }

            if (_body.CanThrow && !(_body is BlockStmt) && _body.StartIndex != -1)
            {
                statements.Add(
                    UpdateLineNumber(
                        GlobalParent.IndexToLocation(_body.StartIndex).Line
                    )
                );
            }

            statements.Add(Body);
            Expression body = Expression.Block(statements);

            body = AddProfiling(body);
            body = WrapScopeStatements(body, _body.CanThrow);
            body = Expression.Block(body, Utils.Empty());
            body = AddReturnTarget(body);

            Expression bodyStmt = body;
            init.Add(bodyStmt);
            bodyStmt = Expression.Block(init);

            // wrap a scope if needed
            bodyStmt = Expression.Block(locals.ToReadOnlyCollection(), bodyStmt);

            return Utils.LightLambda(
                typeof(object),
                delegateType,
                AddDefaultReturn(bodyStmt, typeof(object)),
                Name + "$" + Interlocked.Increment(ref _lambdaId),
                parameters
            );
        }
예제 #32
0
        internal ReadOnlyCollection<MSAst.Expression> Transform(Statement/*!*/[]/*!*/ from) {
            Debug.Assert(from != null);
            var to = new ReadOnlyCollectionBuilder<MSAst.Expression>(from.Length + 1);

            SourceLocation start = SourceLocation.Invalid;

            for (int i = 0; i < from.Length; i++) {
                Debug.Assert(from[i] != null);

                to.Add(TransformMaybeSingleLineSuite(from[i], start));
                start = from[i].Start;
            }
            to.Add(AstUtils.Empty());
            return to.ToReadOnlyCollection();
        }
예제 #33
0
 public static LightDynamicExpression LightDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollectionBuilder<Expression> arguments) {
     ContractUtils.RequiresNotNull(arguments, "arguments");
     return new LightTypedDynamicExpressionN(binder, returnType, arguments.ToReadOnlyCollection());
 }
예제 #34
0
        /// <summary>
        /// Creates the LambdaExpression which implements the body of the function.
        ///
        /// The functions signature is either "object Function(PythonFunction, ...)"
        /// where there is one object parameter for each user defined parameter or
        /// object Function(PythonFunction, object[]) for functions which take more
        /// than PythonCallTargets.MaxArgs arguments.
        /// </summary>
        private LightLambdaExpression CreateFunctionLambda()
        {
            bool     needsWrapperMethod = _parameters.Length > PythonCallTargets.MaxArgs;
            Delegate originalDelegate;
            Type     delegateType = GetDelegateType(_parameters, needsWrapperMethod, out originalDelegate);

            MSAst.ParameterExpression localContext = null;
            ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>();

            if (NeedsLocalContext)
            {
                localContext = LocalCodeContextVariable;
                locals.Add(localContext);
            }

            MSAst.ParameterExpression[] parameters = CreateParameters(needsWrapperMethod, locals);

            List <MSAst.Expression> init = new List <MSAst.Expression>();

            foreach (var param in _parameters)
            {
                IPythonVariableExpression pyVar = GetVariableExpression(param.PythonVariable) as IPythonVariableExpression;
                if (pyVar != null)
                {
                    var varInit = pyVar.Create();
                    if (varInit != null)
                    {
                        init.Add(varInit);
                    }
                }
            }

            // Transform the parameters.
            init.Add(Ast.ClearDebugInfo(GlobalParent.Document));

            locals.Add(PythonAst._globalContext);
            init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContext)));

            GlobalParent.PrepareScope(locals, init);

            // Create variables and references. Since references refer to
            // parameters, do this after parameters have been created.

            CreateFunctionVariables(locals, init);

            // If the __class__ variable is used the a class method then we need to initialize it.
            // This must be done before parameter initialization (in case one of the parameters is called __class__).
            ClassDefinition parent = FindParentOfType <ClassDefinition>();
            PythonVariable  pVar;

            if (parent != null && TryGetVariable("__class__", out pVar))
            {
                init.Add(
                    AssignValue(
                        GetVariableExpression(pVar),
                        Ast.Call(AstMethods.LookupName, parent.Parent.LocalContext, Ast.Constant(parent.Name))
                        )
                    );
            }

            // Initialize parameters - unpack tuples.
            // Since tuples unpack into locals, this must be done after locals have been created.
            InitializeParameters(init, needsWrapperMethod, parameters);

            List <MSAst.Expression> statements = new List <MSAst.Expression>();
            // add beginning sequence point
            var start = GlobalParent.IndexToLocation(StartIndex);

            statements.Add(GlobalParent.AddDebugInfo(
                               AstUtils.Empty(),
                               new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, Int32.MaxValue))));


            // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close().
            // The exception traceback needs to come from the generator's method body, and so we must do the check and throw
            // from inside the generator.
            if (IsGenerator)
            {
                MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None);
                statements.Add(s1);
            }

            MSAst.ParameterExpression extracted = null;
            if (!IsGenerator && _canSetSysExcInfo)
            {
                // need to allocate the exception here so we don't share w/ exceptions made & freed
                // during the body.
                extracted = Ast.Parameter(typeof(Exception), "$ex");
                locals.Add(extracted);
            }

            if (_body.CanThrow && !(_body is SuiteStatement) && _body.StartIndex != -1)
            {
                statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(_body.StartIndex).Line));
            }

            statements.Add(Body);
            MSAst.Expression body = Ast.Block(statements);

            // If this function can modify sys.exc_info() (_canSetSysExcInfo), then it must restore the result on finish.
            //
            // Wrap in
            //   $temp = PythonOps.SaveCurrentException()
            //   <body>
            //   PythonOps.RestoreCurrentException($temp)
            // Skip this if we're a generator. For generators, the try finally is handled by the PythonGenerator class
            //  before it's invoked. This is because the restoration must occur at every place the function returns from
            //  a yield point. That's different than the finally semantics in a generator.
            if (extracted != null)
            {
                MSAst.Expression s = AstUtils.Try(
                    Ast.Assign(
                        extracted,
                        Ast.Call(AstMethods.SaveCurrentException)
                        ),
                    body
                    ).Finally(
                    Ast.Call(
                        AstMethods.RestoreCurrentException, extracted
                        )
                    );
                body = s;
            }

            if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames)
            {
                body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(PythonFunction).GetProperty("__code__")), body);
                locals.Add(FunctionStackVariable);
            }

            body = AddProfiling(body);
            body = WrapScopeStatements(body, _body.CanThrow);
            body = Ast.Block(body, AstUtils.Empty());
            body = AddReturnTarget(body);


            MSAst.Expression bodyStmt = body;
            if (localContext != null)
            {
                var createLocal = CreateLocalContext(_parentContext);

                init.Add(
                    Ast.Assign(
                        localContext,
                        createLocal
                        )
                    );
            }

            init.Add(bodyStmt);

            bodyStmt = Ast.Block(init);

            // wrap a scope if needed
            bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt);

            return(AstUtils.LightLambda(
                       typeof(object),
                       delegateType,
                       AddDefaultReturn(bodyStmt, typeof(object)),
                       Name + "$" + Interlocked.Increment(ref _lambdaId),
                       parameters
                       ));
        }
예제 #35
0
        internal override MSAst.Expression Transform(AstGenerator ag) {
            MSAst.Expression destination = ag.TransformAsObject(_dest);

            if (_expressions.Length == 0) {
                MSAst.Expression result;
                if (destination != null) {
                    result = Ast.Call(
                        AstGenerator.GetHelperMethod("PrintNewlineWithDest"),
                        ag.LocalContext,
                        destination
                    );
                } else {
                    result = Ast.Call(
                        AstGenerator.GetHelperMethod("PrintNewline"),
                        ag.LocalContext
                    );
                }
                return ag.AddDebugInfo(result, Span);
            } else {
                // Create list for the individual statements
                ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>();

                // Store destination in a temp, if we have one
                if (destination != null) {
                    MSAst.ParameterExpression temp = ag.GetTemporary("destination");

                    statements.Add(
                        AstGenerator.MakeAssignment(temp, destination)
                    );

                    destination = temp;
                }
                for (int i = 0; i < _expressions.Length; i++) {
                    string method = (i < _expressions.Length - 1 || _trailingComma) ? "PrintComma" : "Print";
                    Expression current = _expressions[i];
                    MSAst.MethodCallExpression mce;

                    if (destination != null) {
                        mce = Ast.Call(
                            AstGenerator.GetHelperMethod(method + "WithDest"),
                            ag.LocalContext,
                            destination,
                            ag.TransformAsObject(current)
                        );
                    } else {
                        mce = Ast.Call(
                            AstGenerator.GetHelperMethod(method),
                            ag.LocalContext,
                            ag.TransformAsObject(current)
                        );
                    }

                    statements.Add(mce);
                }

                statements.Add(AstUtils.Empty());
                return ag.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span);
            }
        }
예제 #36
0
        //internal static Func<TotemFunction, TotemArgs, object> FunctionDelegate = new Func<TotemFunction, TotemArgs, object>((fn, args) =>
        //{
        //    fn.Code.LazyCompileFirstTarget(fn);
        //    return ((Func<TotemFunction, TotemArgs, object>)fn.Code.Target)(fn, args);
        //});
        /// <summary>
        /// Creates the LambdaExpression which implements the body of the function.
        /// 
        /// The functions signature is either "object Function(PythonFunction, ...)"
        /// where there is one object parameter for each user defined parameter or
        /// object Function(PythonFunction, object[]) for functions which take more
        /// than PythonCallTargets.MaxArgs arguments.
        /// </summary>
        private LightLambdaExpression CreateFunctionLambda()
        {
            Type delegateType = typeof(Func<TotemFunction, TotemArgs, object>);

            MSAst.ParameterExpression localContext = null;
            ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>();
            if (NeedsLocalContext || CanThrow)
            {
                localContext = LocalCodeContextVariable;
                locals.Add(localContext);
            }

            MSAst.ParameterExpression[] parameters = CreateParameters(locals);

            List<MSAst.Expression> init = new List<Ast>();

            foreach (var param in _parameters)
            {
                ITotemVariableExpression toVar = GetVariableExpression(param.TotemVariable) as ITotemVariableExpression;
                if (toVar != null)
                {
                    var varInit = toVar.Create();
                    if (varInit != null)
                        init.Add(varInit);
                }
            }

            // Transform the parameters.
            init.Add(Ast.ClearDebugInfo(GlobalParent.Document));

            locals.Add(TotemAst._globalContext);
            init.Add(Ast.Assign(TotemAst._globalContext, new GetGlobalContextExpression(_parentContext)));

            GlobalParent.PrepareScope(locals, init);

            // Create variables and references. Since references refer to
            // parameters, do this after parameters have been created.
            CreateFunctionVariables(locals, init);

            // Initialize parameters - unpack tuples.
            // Since tuples unpack into locals, this must be done after locals have been created.
            InitializeParameters(init, parameters);

            List<MSAst.Expression> statements = new List<MSAst.Expression>();
            // add beginning sequence point
            var start = GlobalParent.IndexToLocation(StartIndex);
            statements.Add(
                GlobalParent.AddDebugInfo(
                    AstUtils.Empty(),
                    new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, Int32.MaxValue)) // TODO: augment, not correct for totem
                )
            );

            // For generators, we need to do a check before the first statement for Generator.Throw() / Generator.Close().
            // The exception traceback needs to come from the generator's method body, and so we must do the check and throw
            // from inside the generator.
            if (IsGenerator)
            {
                //throw new NotImplementedException();
                //MSAst.Expression s1 = YieldExpression.CreateCheckThrowExpression(SourceSpan.None);
                //statements.Add(s1);
            }

            if (_body.CanThrow && !(_body is SuiteStatement) && _body.StartIndex != -1)
            {
                statements.Add(UpdateLineNumber(GlobalParent.IndexToLocation(_body.StartIndex).Line));
            }

            statements.Add(Body);
            MSAst.Expression body = Ast.Block(statements);

            if (_body.CanThrow && GlobalParent.TotemContext.TotemOptions.Frames)
            {
                //body = AddFrame(LocalContext, Ast.Property(_functionParam, typeof(TotemFunction).GetProperty("Code")), body);
                locals.Add(FunctionStackVariable);
            }

            body = AddProfiling(body);
            body = WrapScopeStatements(body, _body.CanThrow);
            body = Ast.Block(body, Ast.Empty());
            body = AddReturnTarget(body);

            MSAst.Expression bodyStmt = body;
            if (localContext != null)
            {
                var createLocal = CreateLocalContext(_parentContext);

                init.Add(
                    Ast.Assign(
                        localContext,
                        createLocal
                    )
                );
            }

            init.Add(bodyStmt);

            bodyStmt = Ast.Block(init);

            // wrap a scope if needed
            bodyStmt = Ast.Block(locals.ToReadOnlyCollection(), bodyStmt);

            return AstUtils.LightLambda(
                typeof(object),
                delegateType,
                AddDefaultReturn(bodyStmt, typeof(object)),
                Name + "$" + Interlocked.Increment(ref _lambdaId),
                parameters
            );
        }
예제 #37
0
파일: PythonAst.cs 프로젝트: Xiaoqing/main
        internal MSAst.Expression ReduceWorker() {
            var retStmt = _body as ReturnStatement;
            
            if (retStmt != null && 
                (_languageFeatures == ModuleOptions.None || 
                _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) ||
                _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow))) {
                // for simple eval's we can construct a simple tree which just
                // leaves the value on the stack.  Return's can't exist in modules
                // so this is always safe.
                Debug.Assert(!_isModule);

                var ret = (ReturnStatement)_body;
                Ast simpleBody;
                if ((_languageFeatures & ModuleOptions.LightThrow) != 0) {
                    simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce());
                } else {
                    simpleBody = retStmt.Expression.Reduce();
                }

                var start = IndexToLocation(ret.Expression.StartIndex);
                var end = IndexToLocation(ret.Expression.EndIndex);

                return Ast.Block(
                    Ast.DebugInfo(
                        _document,
                        start.Line,
                        start.Column,
                        end.Line,
                        end.Column
                    ),
                    AstUtils.Convert(simpleBody, typeof(object))
                );
            }

            ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>();
            AddInitialiation(block);

            if (_isModule) {
                block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body))));
            }

            if (!(_body is SuiteStatement) && _body.CanThrow) {
                // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement
                // at the top level we can miss some line number updates.  
                block.Add(UpdateLineNumber(_body.Start.Line));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());
            
            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0) {
                body = LightExceptions.Rewrite(body);
            }

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));
            if (body.Type == typeof(void)) {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return body;
        }
예제 #38
0
        public ReadOnlyCollection <IWebElement> DownloadTimbratureCurrentMonth(string user, string pwd, DateTime targetDate, TimbratureBuilder builder, System.ComponentModel.BackgroundWorker worker)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            wait.Until(ExpectedConditions.ElementExists(By.Name("m_cUserName")));
            wait.Until(ExpectedConditions.ElementExists(By.Name("m_cPassword")));
            wait.Until(ExpectedConditions.ElementExists(By.CssSelector("input[class='buttonlogin Accedi_ctrl']")));

            try
            {
                worker.ReportProgress(5);
                // LOGIN
                driver.FindElement(By.Name("m_cUserName")).SendKeys(user);
                driver.FindElement(By.Name("m_cPassword")).SendKeys(pwd);

                driver.FindElement(By.CssSelector("input[class='buttonlogin Accedi_ctrl']")).Click();

                // TIMBRATURE

                wait.Until(ExpectedConditions.ElementExists(By.CssSelector("td[class='grid_title grid_cell_title']")));
                worker.ReportProgress(40);

                String          tableId = driver.FindElement(By.ClassName("hfpr_wcartellino2c_container")).GetAttribute("id");
                Regex           rx      = new Regex(@"^(.*?)_container", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                MatchCollection matches = rx.Matches(tableId);
                if (matches.Count > 0)
                {
                    ReadOnlyCollectionBuilder <IWebElement> collection = new ReadOnlyCollectionBuilder <IWebElement>(5);
                    String   randomId         = matches[0].Groups[1].Value;
                    DateTime currentPageMonth = DateTime.Now;
                    DateTime firstDayNumber   = Utils.getFirstWorkingDayOfWeekAsDate(targetDate);//todo check if first day is previous month
                    DateTime currDay          = firstDayNumber;
                    bool     bNewMonth        = false;
                    for (int i = 0; i < 5; ++i)
                    {
                        currDay   = firstDayNumber.AddDays(i);
                        bNewMonth = currDay.Month != currentPageMonth.Month;
                        if (!bNewMonth)
                        {
                            IWebElement elem = driver.FindElement(By.Id(randomId + "_Grid1_row" + (currDay.Day - 1)));
                            builder.addDate(elem, currDay.DayOfWeek);
                            collection.Add(elem);
                            worker.ReportProgress(52 + i * 12);
                        }
                        else
                        {
                            IWebElement currMonth = new SelectElement(driver.FindElement(By.ClassName("TxtMese_ctrl"))).SelectedOption;
                            if ((currDay.Month < currentPageMonth.Month && currDay.Year == currentPageMonth.Year) || currDay.Year < currentPageMonth.Year)
                            {
                                driver.FindElement(By.ClassName("BtnMesePrev_ctrl")).Click();
                                currentPageMonth = currentPageMonth.AddMonths(-1);
                            }
                            else
                            {
                                driver.FindElement(By.ClassName("BtnMeseNext_ctrl")).Click();
                                currentPageMonth = currentPageMonth.AddMonths(1);
                            }

                            wait.Until(ExpectedConditions.ElementSelectionStateToBe(currMonth, false));
                            wait.Until(ExpectedConditions.ElementExists(By.CssSelector("td[class='grid_title grid_cell_title']")));
                            i--;//redo current loop, we changed month
                        }
                    }
                    return(collection.ToReadOnlyCollection());
                }
                else
                {
                    //ReadOnlyCollection<IWebElement> selected = driver.FindElements(By.CssSelector("tr[class='grid_row grid_rowselected']")); // WTF ZUCCHETTI
                    ReadOnlyCollection <IWebElement> selected = driver.FindElements(By.XPath("//*[@class='grid_row grid_rowselected']"));           // WTF ZUCCHETTI

                    ReadOnlyCollection <IWebElement> selectedOdd = driver.FindElements(By.CssSelector("tr[class='grid_rowodd grid_rowselected']")); // WTF ZUCCHETTI

                    ReadOnlyCollection <IWebElement> pairRowsRO = driver.FindElements(By.XPath("//*[@class='grid_row']"));                          // REALLYYY. ZUCCHETTI PLZ
                    ReadOnlyCollection <IWebElement> oddRowsRO  = driver.FindElements(By.XPath("//*[@class='grid_rowodd']"));                       // REALLYYY. ZUCCHETTI PLZ

                    return(new ReadOnlyCollectionBuilder <IWebElement>(pairRowsRO.Concat(oddRowsRO)
                                                                       .Concat(selectedOdd)
                                                                       .Concat(selected))
                           .ToReadOnlyCollection());
                }
            }
            catch
            {
            }

            return(new ReadOnlyCollectionBuilder <IWebElement>().ToReadOnlyCollection());

#pragma warning restore CS0618 // Type or member is obsolete
        }
예제 #39
0
        internal MSAst.Expression ReduceWorker() {
            ReadOnlyCollectionBuilder<MSAst.Expression> block = new ReadOnlyCollectionBuilder<MSAst.Expression>();

            if (_body is ReturnStatement && (_languageFeatures == ModuleOptions.None || _languageFeatures == ModuleOptions.Interpret)) {
                // for simple eval's we can construct a simple tree which just
                // leaves the value on the stack.  Return's can't exist in modules
                // so this is always safe.
                Debug.Assert(!_isModule);

                return AstUtils.Convert(((ReturnStatement)_body).Expression.Reduce(), typeof(object));
            }

            AddInitialiation(block);

            if (_isModule) {
                block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body))));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());
            
            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));
            if (body.Type == typeof(void)) {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return body;
        }
예제 #40
0
        internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op)
        {
            // if we just have a simple named multi-assignment  (e.g. a, b = 1,2)
            // then go ahead and step over the entire statement at once.  If we have a
            // more complex statement (e.g. a.b, c.d = 1, 2) then we'll step over the
            // sets individually as they could be property sets the user wants to step
            // into.  TODO: Enable stepping of the right hand side?
            bool emitIndividualSets = false;

            foreach (Expression e in _items)
            {
                if (IsComplexAssignment(e))
                {
                    emitIndividualSets = true;
                    break;
                }
            }

            SourceSpan rightSpan = SourceSpan.None;
            SourceSpan leftSpan  =
                (Span.Start.IsValid && span.IsValid) ?
                new SourceSpan(Span.Start, span.End) :
                SourceSpan.None;

            SourceSpan totalSpan = SourceSpan.None;

            if (emitIndividualSets)
            {
                rightSpan = span;
                leftSpan  = SourceSpan.None;
                totalSpan = (Span.Start.IsValid && span.IsValid) ?
                            new SourceSpan(Span.Start, span.End) :
                            SourceSpan.None;
            }

            // 1. Evaluate the expression and assign the value to the temp.
            MSAst.ParameterExpression right_temp = Ast.Variable(typeof(object), "unpacking");

            // 2. Add the assignment "right_temp = right" into the suite/block
            MSAst.Expression assignStmt1 = MakeAssignment(right_temp, right);

            // 3. Call GetEnumeratorValues on the right side (stored in temp)
            MSAst.Expression enumeratorValues = Expression.Convert(LightExceptions.CheckAndThrow(
                                                                       Expression.Call(
                                                                           emitIndividualSets ?
                                                                           AstMethods.GetEnumeratorValues :
                                                                           AstMethods.GetEnumeratorValuesNoComplexSets, // method
                                                                           // arguments
                                                                           Parent.LocalContext,
                                                                           right_temp,
                                                                           AstUtils.Constant(_items.Length)
                                                                           )
                                                                       ), typeof(object[]));

            // 4. Create temporary variable for the array
            MSAst.ParameterExpression array_temp = Ast.Variable(typeof(object[]), "array");

            // 5. Assign the value of the method call (mce) into the array temp
            // And add the assignment "array_temp = Ops.GetEnumeratorValues(...)" into the block
            MSAst.Expression assignStmt2 = MakeAssignment(
                array_temp,
                enumeratorValues,
                rightSpan
                );

            ReadOnlyCollectionBuilder <MSAst.Expression> sets = new ReadOnlyCollectionBuilder <MSAst.Expression>(_items.Length + 1);

            for (int i = 0; i < _items.Length; i++)
            {
                // target = array_temp[i]

                Expression target = _items[i];
                if (target == null)
                {
                    continue;
                }

                // 6. array_temp[i]
                MSAst.Expression element = Ast.ArrayAccess(
                    array_temp,                             // array expression
                    AstUtils.Constant(i)                    // index
                    );

                // 7. target = array_temp[i], and add the transformed assignment into the list of sets
                MSAst.Expression set = target.TransformSet(
                    emitIndividualSets ?                    // span
                    target.Span :
                    SourceSpan.None,
                    element,
                    PythonOperationKind.None
                    );
                sets.Add(set);
            }
            // 9. add the sets as their own block so they can be marked as a single span, if necessary.
            sets.Add(AstUtils.Empty());
            MSAst.Expression itemSet = GlobalParent.AddDebugInfo(Ast.Block(sets.ToReadOnlyCollection()), leftSpan);

            // 10. Return the suite statement (block)
            return(GlobalParent.AddDebugInfo(Ast.Block(new[] { array_temp, right_temp }, assignStmt1, assignStmt2, itemSet, AstUtils.Empty()), totalSpan));
        }
예제 #41
0
 public static LightDynamicExpression LightDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollectionBuilder <Expression> arguments)
 {
     ContractUtils.RequiresNotNull(arguments, "arguments");
     return(new LightTypedDynamicExpressionN(binder, returnType, arguments.ToReadOnlyCollection()));
 }
예제 #42
0
        internal MSAst.Expression ReduceWorker()
        {
            var retStmt = _body as ReturnStatement;

            if (retStmt != null &&
                (_languageFeatures == ModuleOptions.None ||
                 _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) ||
                 _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow)))
            {
                // for simple eval's we can construct a simple tree which just
                // leaves the value on the stack.  Return's can't exist in modules
                // so this is always safe.
                Debug.Assert(!IsModule);

                var ret = (ReturnStatement)_body;
                Ast simpleBody;
                if ((_languageFeatures & ModuleOptions.LightThrow) != 0)
                {
                    simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce());
                }
                else
                {
                    simpleBody = retStmt.Expression.Reduce();
                }

                var start = IndexToLocation(ret.Expression.StartIndex);
                var end   = IndexToLocation(ret.Expression.EndIndex);

                return(Ast.Block(
                           Ast.DebugInfo(
                               _document,
                               start.Line,
                               start.Column,
                               end.Line,
                               end.Column
                               ),
                           AstUtils.Convert(simpleBody, typeof(object))
                           ));
            }

            ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>();

            AddInitialiation(block);

            if (IsModule)
            {
                block.Add(AssignValue(GetVariableExpression(DocVariable), Ast.Constant(GetDocumentation(_body))));
            }

            if (!(_body is SuiteStatement) && _body.CanThrow)
            {
                // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement
                // at the top level we can miss some line number updates.
                block.Add(UpdateLineNumber(_body.Start.Line));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());

            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0)
            {
                body = LightExceptions.Rewrite(body);
            }

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));
            if (body.Type == typeof(void))
            {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return(body);
        }
예제 #43
0
        /// <summary>
        /// WithStatement is translated to the DLR AST equivalent to
        /// the following Python code snippet (from with statement spec):
        /// 
        /// mgr = (EXPR)
        /// exit = mgr.__exit__  # Not calling it yet
        /// value = mgr.__enter__()
        /// exc = True
        /// try:
        ///     VAR = value  # Only if "as VAR" is present
        ///     BLOCK
        /// except:
        ///     # The exceptional case is handled here
        ///     exc = False
        ///     if not exit(*sys.exc_info()):
        ///         raise
        ///     # The exception is swallowed if exit() returns true
        /// finally:
        ///     # The normal and non-local-goto cases are handled here
        ///     if exc:
        ///         exit(None, None, None)
        /// 
        /// </summary>
        internal override MSAst.Expression Transform(AstGenerator ag) {            
            MSAst.ParameterExpression lineUpdated = ag.GetTemporary("$lineUpdated_with", typeof(bool));
            // Five statements in the result...
            ReadOnlyCollectionBuilder<MSAst.Expression> statements = new ReadOnlyCollectionBuilder<MSAst.Expression>(6);
            

            //******************************************************************
            // 1. mgr = (EXPR)
            //******************************************************************
            MSAst.ParameterExpression manager = ag.GetTemporary("with_manager");
            statements.Add(
                ag.MakeAssignment(
                    manager,
                    ag.Transform(_contextManager),
                    new SourceSpan(Start, _header)
                )
            );

            //******************************************************************
            // 2. exit = mgr.__exit__  # Not calling it yet
            //******************************************************************
            MSAst.ParameterExpression exit = ag.GetTemporary("with_exit");
            statements.Add(
                AstGenerator.MakeAssignment(
                    exit,
                    ag.Get(
                        typeof(object),
                        "__exit__",
                        manager
                    )
                )
            );

            //******************************************************************
            // 3. value = mgr.__enter__()
            //******************************************************************
            MSAst.ParameterExpression value = ag.GetTemporary("with_value");
            statements.Add(
                ag.AddDebugInfoAndVoid(
                    AstGenerator.MakeAssignment(
                        value,
                        ag.Invoke(
                            typeof(object),
                            new CallSignature(0),
                            ag.Get(
                                typeof(object),
                                "__enter__",
                                manager
                            )
                        )
                    ),
                    new SourceSpan(Start, _header)
                )
            );

            //******************************************************************
            // 4. exc = True
            //******************************************************************
            MSAst.ParameterExpression exc = ag.GetTemporary("with_exc", typeof(bool));
            statements.Add(
                AstGenerator.MakeAssignment(
                    exc,
                    AstUtils.Constant(true)
                )
            );

            //******************************************************************
            //  5. The final try statement:
            //
            //  try:
            //      VAR = value  # Only if "as VAR" is present
            //      BLOCK
            //  except:
            //      # The exceptional case is handled here
            //      exc = False
            //      if not exit(*sys.exc_info()):
            //          raise
            //      # The exception is swallowed if exit() returns true
            //  finally:
            //      # The normal and non-local-goto cases are handled here
            //      if exc:
            //          exit(None, None, None)
            //******************************************************************

            MSAst.ParameterExpression exception = ag.GetTemporary("exception", typeof(Exception));
            MSAst.ParameterExpression nestedFrames = ag.GetTemporary("$nestedFrames", typeof(List<DynamicStackFrame>));
            statements.Add(
                // try:
                AstUtils.Try(
                    AstUtils.Try(// try statement body
                        ag.PushLineUpdated(false, lineUpdated),
                        _var != null ?
                            Ast.Block(
                                // VAR = value
                                _var.TransformSet(ag, SourceSpan.None, value, PythonOperationKind.None),
                                // BLOCK
                                ag.Transform(_body),
                                AstUtils.Empty()
                            ) :
                            // BLOCK
                            ag.Transform(_body) // except:, // try statement location
                    ).Catch(exception,
                    // Python specific exception handling code
                        TryStatement.GetTracebackHeader(                        
                            ag,
                            exception,
                            ag.AddDebugInfoAndVoid(
                                Ast.Block(
                                    // exc = False
                                    AstGenerator.MakeAssignment(
                                        exc,
                                        AstUtils.Constant(false)
                                    ),
                                    Ast.Assign(
                                        nestedFrames,
                                        Ast.Call(AstGenerator.GetHelperMethod("GetAndClearDynamicStackFrames"))
                                    ),
                                    //  if not exit(*sys.exc_info()):
                                    //      raise
                                    AstUtils.IfThen(
                                        ag.Convert(
                                            typeof(bool),
                                            ConversionResultKind.ExplicitCast,
                                            ag.Operation(
                                                typeof(bool),
                                                PythonOperationKind.Not,
                                                MakeExitCall(ag, exit, exception)
                                            )
                                        ),
                                        ag.UpdateLineUpdated(true),
                                        Ast.Call(
                                            AstGenerator.GetHelperMethod("SetDynamicStackFrames"),
                                            nestedFrames
                                        ),
                                        Ast.Throw(
                                            Ast.Call(
                                                AstGenerator.GetHelperMethod("MakeRethrowExceptionWorker"),
                                                exception
                                            )
                                        )
                                    )
                                ),
                                _body.Span
                            )
                        ),
                        Ast.Call(
                            AstGenerator.GetHelperMethod("SetDynamicStackFrames"),
                            nestedFrames
                        ),
                        ag.PopLineUpdated(lineUpdated),
                        Ast.Empty()
                    )
                // finally:                    
                ).Finally(
                //  if exc:
                //      exit(None, None, None)
                    AstUtils.IfThen(
                        exc,
                        ag.AddDebugInfoAndVoid(
                            Ast.Block(
                                Ast.Dynamic(
                                    ag.PyContext.Invoke(
                                        new CallSignature(3)        // signature doesn't include function
                                    ),
                                    typeof(object),
                                    new MSAst.Expression[] {
                                        ag.LocalContext,
                                        exit,
                                        AstUtils.Constant(null),
                                        AstUtils.Constant(null),
                                        AstUtils.Constant(null)
                                    }
                                ),                                    
                                Ast.Empty()
                            ),
                            _contextManager.Span
                        )
                    )
                )
            );

            statements.Add(AstUtils.Empty());
            return Ast.Block(statements.ToReadOnlyCollection());
        }