Exemplo n.º 1
0
        public void HoistLabel(JSStatement parentBlock, JSStatement labelledStatement)
        {
            HoistedALabel = true;

            parentBlock.Label       = labelledStatement.Label;
            labelledStatement.Label = null;
        }
Exemplo n.º 2
0
 protected void WriteLabel(JSStatement stmt)
 {
     if (!String.IsNullOrWhiteSpace(stmt.Label))
     {
         Output.Label(stmt.Label);
     }
 }
Exemplo n.º 3
0
 protected void PushBlock(JSStatement s)
 {
     BlockStack.Push(new EnclosingBlockEntry {
         Block      = s,
         ParentNode = ParentNode,
         Depth      = BlockStack.Count
     });
 }
Exemplo n.º 4
0
 protected void CheckLabel(JSStatement s)
 {
     if (s.Label != null)
     {
         Labels.Add(s.Label, new LabelEntry {
             LabelledStatement = s,
             ParentNode        = ParentNode,
             EnclosingBlock    = BlockStack.Peek()
         });
     }
 }
Exemplo n.º 5
0
        public void VisitNode(JSIfStatement ifs)
        {
            Output.WriteRaw("if");
            Output.Space();

            Output.LPar();
            Visit(ifs.Condition);
            Output.RPar();
            Output.Space();

            Output.OpenBrace();
            Visit(ifs.TrueClause);

            JSStatement falseClause = ifs.FalseClause;

            while (falseClause != null)
            {
                var nestedBlock = falseClause as JSBlockStatement;
                var nestedIf    = falseClause as JSIfStatement;
                if ((nestedBlock != null) && (nestedBlock.Statements.Count == 1))
                {
                    nestedIf = nestedBlock.Statements[0] as JSIfStatement;
                }

                if (nestedIf != null)
                {
                    Output.CloseAndReopenBrace((o) => {
                        if (o != this.Output)
                        {
                            throw new InvalidOperationException("Output mismatch");
                        }

                        o.WriteRaw("else if");
                        o.Space();
                        o.LPar();
                        Visit(nestedIf.Condition);
                        o.RPar();
                    });

                    Visit(nestedIf.TrueClause);

                    falseClause = nestedIf.FalseClause;
                }
                else
                {
                    Output.CloseAndReopenBrace("else");
                    Visit(falseClause);
                    falseClause = null;
                }
            }

            Output.CloseBrace();
        }
Exemplo n.º 6
0
        public bool InsertNearChildRecursive (JSStatement relativeTo, JSStatement newChild, int offset = 0) {
            for (int i = 0, c = Statements.Count; i < c; i++) {
                if (
                    (Statements[i] == relativeTo) ||
                    Statements[i].AllChildrenRecursive.Any((n) => n == relativeTo)
                ) {
                    Statements.Insert(i + offset, newChild);
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 7
0
        public void VisitNode(JSStatement s)
        {
            VisitChildren(s);

            BarrierFlags flags = GetStatementFlags();

            var rb = GenerateSubtreeBarrier(0, flags);

            if ((rb.Flags != BarrierFlags.None) || (rb.Slots.Length > 0))
            {
                Result.Add(rb);
            }
        }
Exemplo n.º 8
0
        protected void MaybeHoist(JSStatement enclosingStatement, IEnumerable <JSStatement> children)
        {
            var firstChildStatement = children.FirstOrDefault();

            if (firstChildStatement == null)
            {
                return;
            }

            if (firstChildStatement.Label == null)
            {
                return;
            }

            if (enclosingStatement.Label == null)
            {
                HoistLabel(enclosingStatement, firstChildStatement);
            }
        }
Exemplo n.º 9
0
        public void VisitNode(JSWhileLoop whileLoop)
        {
            JSVariable       initVariable = null, lastVariable = null;
            JSBinaryOperator initOperator = null;
            JSExpression     initValue    = null;

            var prevEStmt = PreviousSibling as JSExpressionStatement;
            var prevVDS   = PreviousSibling as JSVariableDeclarationStatement;

            if (prevEStmt != null)
            {
                var boe = prevEStmt.Expression as JSBinaryOperatorExpression;
                if (
                    (boe != null) &&
                    (boe.Operator is JSAssignmentOperator) &&
                    (boe.Left is JSVariable)
                    )
                {
                    initVariable = (JSVariable)boe.Left;
                    initOperator = boe.Operator;
                    initValue    = boe.Right;
                }
            }
            else if (prevVDS != null)
            {
                var decl = prevVDS.Declarations.FirstOrDefault(
                    (d) => !d.IsNull
                    );
                if (decl != null)
                {
                    initVariable = (JSVariable)decl.Left;
                    initOperator = decl.Operator;
                    initValue    = decl.Right;
                }
            }

            var lastStatement = whileLoop.Statements.LastOrDefault();

            while ((lastStatement != null) && (lastStatement.GetType() == typeof(JSBlockStatement)))
            {
                lastStatement = ((JSBlockStatement)lastStatement).Statements.LastOrDefault();
            }

            var lastExpressionStatement = lastStatement as JSExpressionStatement;

            if (lastExpressionStatement != null)
            {
                var lastUoe = lastExpressionStatement.Expression as JSUnaryOperatorExpression;
                var lastBoe = lastExpressionStatement.Expression as JSBinaryOperatorExpression;

                if ((lastUoe != null) && (lastUoe.Operator is JSUnaryMutationOperator))
                {
                    lastVariable = lastUoe.Expression as JSVariable;
                }
                else if ((lastBoe != null) && (lastBoe.Operator is JSAssignmentOperator))
                {
                    lastVariable = lastBoe.Left as JSVariable;
                    if (
                        (lastVariable != null) &&
                        !lastBoe.Right.SelfAndChildrenRecursive.Any(
                            (n) => lastVariable.Equals(n)
                            )
                        )
                    {
                        lastVariable = null;
                    }
                }
            }

            var lastIfStatement = lastStatement as JSIfStatement;

            if (
                (lastIfStatement != null) &&
                whileLoop.Condition is JSBooleanLiteral &&
                ((JSBooleanLiteral)whileLoop.Condition).Value
                )
            {
                var innerStatement = lastIfStatement.TrueClause;
                while (innerStatement is JSBlockStatement)
                {
                    var bs = (JSBlockStatement)innerStatement;
                    if (bs.Statements.Count != 1)
                    {
                        innerStatement = null;
                        break;
                    }

                    innerStatement = bs.Statements[0];
                }

                var eStmt = innerStatement as JSExpressionStatement;

                if (eStmt != null)
                {
                    var breakExpr = eStmt.Expression as JSBreakExpression;
                    if ((breakExpr != null) && (breakExpr.TargetLoop == whileLoop.Index))
                    {
                        whileLoop.ReplaceChildRecursive(lastIfStatement, new JSNullStatement());

                        var doLoop = new JSDoLoop(
                            new JSUnaryOperatorExpression(JSOperator.LogicalNot, lastIfStatement.Condition, TypeSystem.Boolean),
                            whileLoop.Statements.ToArray()
                            );
                        doLoop.Index = whileLoop.Index;

                        ParentNode.ReplaceChild(whileLoop, doLoop);
                        VisitChildren(doLoop);
                        return;
                    }
                }
            }

            bool cantBeFor = false;

            if ((initVariable != null) && (lastVariable != null) &&
                !initVariable.Equals(lastVariable)
                )
            {
                cantBeFor = true;
            }
            else if ((initVariable ?? lastVariable) == null)
            {
                cantBeFor = true;
            }
            else if (!whileLoop.Condition.SelfAndChildrenRecursive.Any(
                         (n) => (initVariable ?? lastVariable).Equals(n)
                         ))
            {
                cantBeFor = true;
            }
            else if (
                !PostSwitchTransform && (
                    (lastStatement is JSSwitchStatement) ||
                    (lastStatement is JSLabelGroupStatement)
                    )
                )
            {
                cantBeFor = true;
            }

            if (!cantBeFor)
            {
                JSStatement initializer = null, increment = null;

                if (initVariable != null)
                {
                    initializer = PreviousSibling as JSStatement;

                    ParentNode.ReplaceChild(PreviousSibling, new JSNullStatement());
                }

                if (lastVariable != null)
                {
                    increment = lastExpressionStatement;

                    whileLoop.ReplaceChildRecursive(lastExpressionStatement, new JSNullStatement());
                }

                var forLoop = new JSForLoop(
                    initializer, whileLoop.Condition, increment,
                    whileLoop.Statements.ToArray()
                    );
                forLoop.Index = whileLoop.Index;

                ParentNode.ReplaceChild(whileLoop, forLoop);
                VisitChildren(forLoop);
            }
            else
            {
                VisitChildren(whileLoop);
            }
        }
Exemplo n.º 10
0
        public void HoistLabel(JSStatement parentBlock, JSStatement labelledStatement)
        {
            HoistedALabel = true;

            parentBlock.Label = labelledStatement.Label;
            labelledStatement.Label = null;
        }
Exemplo n.º 11
0
 private void MarkAsControlFlow(JSStatement s)
 {
     s.IsControlFlow = true;
 }
Exemplo n.º 12
0
        public JSLabelGroupStatement(int index, JSStatement entryLabel, JSStatement exitLabel)
        {
            GroupIndex = index;

            MarkAsControlFlow(entryLabel);
            MarkAsControlFlow(exitLabel);

            EntryLabelNode = Labels.Enqueue(entryLabel.Label, entryLabel);
            ExitLabelNode = Labels.Enqueue(exitLabel.Label, exitLabel);
        }
Exemplo n.º 13
0
        public JSIfStatement(JSExpression condition, JSStatement trueClause, JSStatement falseClause = null)
        {
            _Condition = condition;
            _TrueClause = trueClause;
            _FalseClause = falseClause;

            if (_TrueClause != null)
                _TrueClause.IsControlFlow = true;
            if (_FalseClause != null)
                _FalseClause.IsControlFlow = true;
        }
Exemplo n.º 14
0
        public void VisitNode(JSStatement statement)
        {
            Console.WriteLine("AstEmitter Unhandled statement type {0}", statement.GetType());

            Formatter.WriteSExpr("untranslatable." + statement.GetType().Name, lineBreakAfter: true);
        }
Exemplo n.º 15
0
 private void MarkAsControlFlow(JSStatement s)
 {
     var bs = s as JSBlockStatement;
     if (bs != null)
         bs.IsControlFlow = true;
 }
Exemplo n.º 16
0
        public JSIfStatement(JSExpression condition, JSStatement trueClause, JSStatement falseClause = null)
        {
            _Condition = condition;
            _TrueClause = trueClause;
            _FalseClause = falseClause;

            var trueBlock = _TrueClause as JSBlockStatement;
            if (trueBlock != null)
                trueBlock.IsControlFlow = true;

            var falseBlock = _FalseClause as JSBlockStatement;
            if (falseBlock != null)
                falseBlock.IsControlFlow = true;
        }
Exemplo n.º 17
0
        public void Add(JSStatement statement)
        {
            if (statement.Label == null)
                throw new InvalidOperationException("Cannot add an unlabeled statement to a label group");

            Labels.Enqueue(statement.Label, statement);
        }
Exemplo n.º 18
0
 public JSForLoop(JSStatement initializer, JSExpression condition, JSStatement increment, params JSStatement[] body)
 {
     _Initializer = initializer;
     _Condition = condition;
     _Increment = increment;
     Statements.AddRange(body);
 }
Exemplo n.º 19
0
        public override void ReplaceChild(JSNode oldChild, JSNode newChild)
        {
            if (oldChild == null)
                throw new ArgumentNullException("oldChild");

            if (_Initializer == oldChild)
                _Initializer = (JSStatement)newChild;

            if (_Condition == oldChild)
                _Condition = (JSExpression)newChild;

            if (_Increment == oldChild)
                _Increment = (JSStatement)newChild;

            if (newChild is JSStatement)
                base.ReplaceChild(oldChild, newChild);
        }
Exemplo n.º 20
0
        public void VisitNode(JSStatement s)
        {
            CheckLabel(s);

            VisitChildren(s);
        }
Exemplo n.º 21
0
        public override void ReplaceChild(JSNode oldChild, JSNode newChild)
        {
            if (oldChild == null)
                throw new ArgumentNullException("oldChild");

            if (_Condition == oldChild)
                _Condition = (JSExpression)newChild;

            if (_TrueClause == oldChild)
                _TrueClause = (JSStatement)newChild;

            if (_FalseClause == oldChild)
                _FalseClause = (JSStatement)newChild;
        }
Exemplo n.º 22
0
        public override void ReplaceChild(JSNode oldChild, JSNode newChild)
        {
            if (oldChild == null)
                throw new ArgumentNullException("oldChild");

            if (CatchVariable == oldChild)
                CatchVariable = (JSVariable)newChild;

            if (Catch == oldChild)
                Catch = (JSStatement)newChild;

            if (Finally == oldChild)
                Finally = (JSStatement)newChild;

            Body.ReplaceChild(oldChild, newChild);
        }
Exemplo n.º 23
0
        public void Add(JSStatement statement)
        {
            if (statement.Label == null)
                throw new InvalidOperationException("Cannot add an unlabeled statement to a label group");

            MarkAsControlFlow(statement);

            Labels.EnqueueBefore(ExitLabelNode, statement.Label, statement);
        }
Exemplo n.º 24
0
 protected void CheckLabel(JSStatement s)
 {
     if (s.Label != null)
         Labels.Add(s.Label, new LabelEntry {
             LabelledStatement = s,
             ParentNode = ParentNode,
             EnclosingBlock = BlockStack.Peek()
         });
 }
Exemplo n.º 25
0
 public JSTryCatchBlock(JSStatement body, JSVariable catchVariable = null, JSStatement @catch = null, JSStatement @finally = null)
 {
     Body = body;
     CatchVariable = catchVariable;
     Catch = @catch;
     Finally = @finally;
 }
Exemplo n.º 26
0
 public JSStatement AddStatement(JSStatement statement)
 {
     Statements.Add(statement);
     return statement;
 }
Exemplo n.º 27
0
        public void VisitNode(JSStatement s)
        {
            CheckLabel(s);

            VisitChildren(s);
        }
Exemplo n.º 28
0
        private void CheckForFallthrough(JSStatement statement)
        {
            if (String.IsNullOrWhiteSpace(statement.Label))
            {
                return;
            }

            bool failed = true;

            PreviousLabelledStatement = CurrentLabelledStatement;
            CurrentLabelledStatement  = statement;

            if (PreviousLabelledStatement == null)
            {
                return;
            }

            if (PreviousLabelledStatement.Label == null)
            {
                PreviousLabelledStatement = null;
                return;
            }

            var lastChildStatement = PreviousLabelledStatement.AllChildrenRecursive
                                     .OfType <JSStatement>()
                                     .LastOrDefault((s) => !s.IsNull);

            var lastEs = lastChildStatement as JSExpressionStatement;

            if ((lastEs != null) &&
                (
                    (lastEs.Expression is JSGotoExpression) ||
                    (lastEs.Expression is JSBreakExpression) ||
                    (lastEs.Expression is JSContinueExpression)
                )
                )
            {
                if (TraceLevel >= 3)
                {
                    Console.WriteLine("// Not recording fallthrough from {0} to {1} because {0} ends with control flow ({2})", PreviousLabelledStatement.Label, CurrentLabelledStatement.Label, lastEs.Expression);
                }

                return;
            }

            if (LabelGroupStack.Count > 0)
            {
                foreach (var lg in LabelGroupStack)
                {
                    LabelGroupLabelData labelData;

                    if (lg.TryGetValue(PreviousLabelledStatement.Label, out labelData))
                    {
                        failed = false;

                        if (TraceLevel >= 2)
                        {
                            Console.WriteLine("// Recording fallthrough from {0} to {1}", PreviousLabelledStatement.Label, CurrentLabelledStatement.Label);
                        }

                        labelData.ExitTargetLabels.Add(CurrentLabelledStatement.Label);
                    }
                }
            }

            if ((TraceLevel >= 2) && failed)
            {
                Console.WriteLine("// Failed to record fallthrough from {0} to {1}", PreviousLabelledStatement.Label, CurrentLabelledStatement.Label);
            }
        }
Exemplo n.º 29
0
 protected void PushBlock(JSStatement s)
 {
     BlockStack.Push(new EnclosingBlockEntry {
         Block = s,
         ParentNode = ParentNode,
         Depth = BlockStack.Count
     });
 }
Exemplo n.º 30
0
        public void VisitNode(JSStatement jss)
        {
            CheckForFallthrough(jss);

            VisitChildren(jss);
        }
Exemplo n.º 31
0
        protected void MaybeHoist(JSStatement enclosingStatement, IEnumerable<JSStatement> children)
        {
            var firstChildStatement = children.FirstOrDefault();

            if (firstChildStatement == null)
                return;

            if (firstChildStatement.Label == null)
                return;

            if (enclosingStatement.Label == null) {
                HoistLabel(enclosingStatement, firstChildStatement);
            }
        }
Exemplo n.º 32
0
        protected bool TranslateCallSiteConstruction(ILCondition condition, out JSStatement result)
        {
            var cond = condition.Condition;
            if (
                (cond.Code == ILCode.LogicNot) &&
                (cond.Arguments.Count > 0) &&
                (cond.Arguments[0].Code == ILCode.GetCallSite) &&
                (condition.TrueBlock != null) &&
                (condition.TrueBlock.Body.Count == 1) &&
                (condition.TrueBlock.Body[0] is ILExpression)
            ) {
                var callSiteExpression = (ILExpression)condition.TrueBlock.Body[0];
                var callSiteType = callSiteExpression.Arguments[0].ExpectedType;
                var binderExpression = callSiteExpression.Arguments[0].Arguments[0];
                var binderMethod = (MethodReference)binderExpression.Operand;
                var arguments = Translate(binderExpression.Arguments);
                var targetType = ((IGenericInstance)callSiteType).GenericArguments[0];

                DynamicCallSites.InitializeCallSite(
                    (FieldReference)cond.Arguments[0].Operand,
                    binderMethod.Name,
                    targetType,
                    arguments
                );

                result = new JSNullStatement();
                return true;
            }

            result = null;
            return false;
        }