Bug 594604: Various narcissus jsparse fixes. (r=taustin)
authorShu-yu Guo <shu@rfrn.org>
Thu, 09 Sep 2010 17:40:13 -0700
changeset 53633 fbaed38f2fb5ace823eb48b33b55730d699d2246
parent 53632 a3b16f1872a94e8340e699b16684b200c05a1279
child 53634 c70c6d647f239b316d938995add5bc820cfa099b
push id15660
push userrsayre@mozilla.com
push dateSat, 11 Sep 2010 19:16:24 +0000
treeherdermozilla-central@f1bd314e64ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaustin
bugs594604
milestone2.0b6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 594604: Various narcissus jsparse fixes. (r=taustin)
js/narcissus/jsparse.js
--- a/js/narcissus/jsparse.js
+++ b/js/narcissus/jsparse.js
@@ -591,17 +591,17 @@ Narcissus.parser = (function() {
             },
 
             finish: function(n) {
             }
         },
 
         LET_BLOCK: {
             build: function(t) {
-                var n = Node(t, LET_BLOCK);
+                var n = new Node(t, LET_BLOCK);
                 n.varDecls = [];
                 return n;
             },
 
             setVariables: function(n, n2) {
                 n.variables = n2;
             },
 
@@ -631,29 +631,16 @@ Narcissus.parser = (function() {
             addStatement: function(n, n2) {
                 n.push(n2);
             },
 
             finish: function(n) {
             }
         },
 
-        EXPRESSION: {
-            build: function(t, tt) {
-                return new Node(t, tt);
-            },
-
-            addOperand: function(n, n2) {
-                n.push(n2);
-            },
-
-            finish: function(n) {
-            }
-        },
-
         ASSIGN: {
             build: function(t) {
                 return new Node(t, ASSIGN);
             },
 
             addOperand: function(n, n2) {
                 n.push(n2);
             },
@@ -736,18 +723,18 @@ Narcissus.parser = (function() {
             },
 
             finish: function(n) {
             }
         },
 
         PRIMARY: {
             build: function(t, tt) {
-                // NB t.token.type must be NULL, THIS, TRUIE, FALSE, IDENTIFIER,
-                // NUMBER, STRING, or REGEXP.
+                // NULL | THIS | TRUE | FALSE | IDENTIFIER | NUMBER
+                // STRING | REGEXP.
                 return new Node(t, tt);
             },
 
             finish: function(n) {
             }
         },
 
         ARRAY_INIT: {
@@ -805,16 +792,25 @@ Narcissus.parser = (function() {
             addProperty: function(n, n2) {
                 n.push(n2);
             },
 
             finish: function(n) {
             }
         },
 
+        PROPERTY_NAME: {
+            build: function(t) {
+                return new Node(t, IDENTIFIER);
+            },
+
+            finish: function(n) {
+            }
+        },
+
         PROPERTY_INIT: {
             build: function(t) {
                 return new Node(t, PROPERTY_INIT);
             },
 
             addOperand: function(n, n2) {
                 n.push(n2);
             },
@@ -1135,16 +1131,17 @@ Narcissus.parser = (function() {
                     n2 = Expression(t, x);
                 }
                 x.inForLoopInit = false;
             }
             if (n2 && t.match(IN)) {
                 // for-ins always get a for block to help desugaring.
                 if (!forBlock) {
                     var forBlock = builder.BLOCK.build(t, x.blockId++);
+                    forBlock.isInternalForInBlock = true;
                     x.stmtStack.push(forBlock);
                 }
 
                 b.rebuildForIn(n);
                 b.setObject(n, Expression(t, x));
                 if (n2.type === VAR || n2.type === LET) {
                     // Destructuring turns one decl into multiples, so either
                     // there must be only one destructuring or only one
@@ -1245,16 +1242,19 @@ Narcissus.parser = (function() {
                  * a loop, then break targets its labeled statement. Labels can be
                  * nested so we skip all labels immediately enclosing the nearest
                  * non-label statement.
                  */
                 while (i < ss.length - 1 && ss[i+1].type === LABEL)
                     i++;
                 if (i < ss.length - 1 && ss[i+1].isLoop)
                     i++;
+                else if (i < ss.length - 1 && ss[i+1].isInternalForInBlock
+                                           && ss[i+2].isLoop)
+                    i++;
                 else if (tt === CONTINUE)
                     throw t.newSyntaxError("Invalid continue");
             } else {
                 do {
                     if (--i < 0) {
                         throw t.newSyntaxError("Invalid " + ((tt === BREAK)
                                                              ? "break"
                                                              : "continue"));
@@ -1404,26 +1404,27 @@ Narcissus.parser = (function() {
 
     function returnOrYield(t, x) {
         var n, b, tt = t.token.type, tt2;
 
         if (tt === RETURN) {
             if (!x.inFunction)
                 throw t.newSyntaxError("Return not in function");
             b = x.builder.RETURN;
-        } else /* (tt === YIELD) */ {
+        } else /* if (tt === YIELD) */ {
             if (!x.inFunction)
                 throw t.newSyntaxError("Yield not in function");
             x.isGenerator = true;
             b = x.builder.YIELD;
         }
         n = b.build(t);
 
         tt2 = t.peek(true);
-        if (tt2 !== END && tt2 !== NEWLINE && tt2 !== SEMICOLON && tt2 !== RIGHT_CURLY
+        if (tt2 !== END && tt2 !== NEWLINE &&
+            tt2 !== SEMICOLON && tt2 !== RIGHT_CURLY
             && (tt !== YIELD ||
                 (tt2 !== tt && tt2 !== RIGHT_BRACKET && tt2 !== RIGHT_PAREN &&
                  tt2 !== COLON && tt2 !== COMMA))) {
             if (tt === RETURN) {
                 b.setValue(n, Expression(t, x));
                 x.hasReturnWithValue = true;
             } else {
                 b.setValue(n, AssignExpression(t, x));
@@ -1545,20 +1546,18 @@ Narcissus.parser = (function() {
          *
          * The list of declarations can be tied to block ids to aid talking
          * about declarations of blocks that have not yet been fully parsed.
          *
          * Blocks are already uniquely numbered; see the comment in
          * Statements.
          */
         if (x2.needsHoisting) {
-            /*
-             * Order is important here! Builders expect funDecls to come after
-             * varDecls!
-             */
+            // Order is important here! Builders expect funDecls to come
+            // after varDecls!
             builder.setHoists(f.body.id, x2.varDecls.concat(x2.funDecls));
 
             if (x.inFunction) {
                 /*
                  * If an inner function needs hoisting, we need to propagate
                  * this flag up to the parent function.
                  */
                 x.needsHoisting = true;
@@ -1590,20 +1589,19 @@ Narcissus.parser = (function() {
 
     /*
      * Variables :: (tokenizer, compiler context) -> node
      *
      * Parses a comma-separated list of var declarations (and maybe
      * initializations).
      */
     function Variables(t, x, letBlock) {
-        var b, bDecl, bAssign, n, n2, n3, ss, i, s, tt, id, data;
+        var b, n, n2, ss, i, s, tt;
         var builder = x.builder;
         var bDecl = builder.DECL;
-        var bAssign = builder.ASSIGN;
 
         switch (t.token.type) {
           case VAR:
             b = builder.VAR;
             s = x;
             break;
           case CONST:
             b = builder.CONST;
@@ -1632,25 +1630,17 @@ Narcissus.parser = (function() {
             break;
         }
 
         n = b.build(t);
         n.destructurings = [];
 
         do {
             tt = t.get();
-            /*
-             * FIXME Should have a special DECLARATION node instead of overloading
-             * IDENTIFIER to mean both identifier declarations and destructured
-             * declarations.
-             */
             if (tt === LEFT_BRACKET || tt === LEFT_CURLY) {
-                // Pass in s if we need to add each pattern matched into
-                // its varDecls, else pass in x.
-                data = null;
                 // Need to unget to parse the full destructured expression.
                 t.unget();
 
                 var dexp = DestructuringExpressionNoHoist(t, x, true, s);
 
                 n2 = bDecl.build(t);
                 bDecl.setName(n2, dexp);
                 bDecl.setReadOnly(n2, n.type === CONST);
@@ -1839,21 +1829,19 @@ Narcissus.parser = (function() {
               case IDENTIFIER:
                 var n3 = bDecl.build(t);
                 bDecl.setName(n3, n3.value);
                 bDecl.finish(n3);
                 var n2 = bVar.build(t);
                 bVar.addDecl(n2, n3, x);
                 bVar.finish(n2);
                 bFor.setIterator(n, n3, n2);
-                /*
-                 * Don't add to varDecls since the semantics of comprehensions is
-                 * such that the variables are in their own function when
-                 * desugared.
-                 */
+                // Don't add to varDecls since the semantics of comprehensions is
+                // such that the variables are in their own function when
+                // desugared.
                 break;
 
               default:
                 throw t.newSyntaxError("missing identifier");
             }
             t.mustMatch(IN);
             bFor.setObject(n, Expression(t, x));
             t.mustMatch(RIGHT_PAREN);
@@ -2177,17 +2165,20 @@ Narcissus.parser = (function() {
             break;
         }
 
         b.finish(n);
         return n;
     }
 
     function MemberExpression(t, x, allowCallSyntax) {
-        var n, n2, tt, b = x.builder.MEMBER;
+        var n, n2, name, tt;
+        var builder = x.builder;
+        var b = builder.MEMBER
+        var b2 = builder.PROPERTY_NAME;
 
         if (t.match(NEW)) {
             n = b.build(t);
             b.addOperand(n, MemberExpression(t, x, false));
             if (t.match(LEFT_PAREN)) {
                 b.rebuildNewWithArgs(n);
                 b.addOperand(n, ArgumentList(t, x));
             }
@@ -2197,17 +2188,19 @@ Narcissus.parser = (function() {
         }
 
         while ((tt = t.get()) !== END) {
             switch (tt) {
               case DOT:
                 n2 = b.build(t);
                 b.addOperand(n2, n);
                 t.mustMatch(IDENTIFIER);
-                b.addOperand(n2, b.build(t));
+                name = b2.build(t);
+                b2.finish(name);
+                b.addOperand(n2, name);
                 break;
 
               case LEFT_BRACKET:
                 n2 = b.build(t, INDEX);
                 b.addOperand(n2, n);
                 b.addOperand(n2, Expression(t, x));
                 t.mustMatch(RIGHT_BRACKET);
                 break;
@@ -2258,16 +2251,17 @@ Narcissus.parser = (function() {
     }
 
     function PrimaryExpression(t, x) {
         var n, n2, n3, tt = t.get(true);
         var builder = x.builder;
         var bArrayInit = builder.ARRAY_INIT;
         var bArrayComp = builder.ARRAY_COMP;
         var bPrimary = builder.PRIMARY;
+        var bPropName = builder.PROPERTY_NAME;
         var bObjInit = builder.OBJECT_INIT;
         var bPropInit = builder.PROPERTY_INIT;
 
         switch (tt) {
           case FUNCTION:
             n = FunctionDefinition(t, x, false, EXPRESSED_FORM);
             break;
 
@@ -2288,17 +2282,17 @@ Narcissus.parser = (function() {
             // array comprehension.
             if (n.length === 1 && t.match(FOR)) {
                 n2 = bArrayComp.build(t);
                 bArrayComp.setExpression(n2, n[0]);
                 bArrayComp.setTail(n2, comprehensionTail(t, x));
                 n = n2;
             }
             t.mustMatch(RIGHT_BRACKET);
-            bPrimary.finish(n);
+            bArrayInit.finish(n);
             break;
 
           case LEFT_CURLY:
             var id, fd;
             n = bObjInit.build(t);
 
           object_init:
             if (!t.match(RIGHT_CURLY)) {
@@ -2308,27 +2302,27 @@ Narcissus.parser = (function() {
                         t.peek() === IDENTIFIER) {
                         if (x.ecma3OnlyMode)
                             throw t.newSyntaxError("Illegal property accessor");
                         fd = FunctionDefinition(t, x, true, EXPRESSED_FORM);
                         bObjInit.addProperty(n, fd);
                     } else {
                         switch (tt) {
                           case IDENTIFIER: case NUMBER: case STRING:
-                            id = bPrimary.build(t, IDENTIFIER);
-                            bPrimary.finish(id);
+                            id = bPropName.build(t);
+                            bPropName.finish(id);
                             break;
                           case RIGHT_CURLY:
                             if (x.ecma3OnlyMode)
                                 throw t.newSyntaxError("Illegal trailing ,");
                             break object_init;
                           default:
                             if (t.token.value in definitions.keywords) {
-                                id = bPrimary.build(t, IDENTIFIER);
-                                bPrimary.finish(id);
+                                id = bPropName.build(t);
+                                bPropName.finish(id);
                                 break;
                             }
                             throw t.newSyntaxError("Invalid property name");
                         }
                         if (t.match(COLON)) {
                             n2 = bPropInit.build(t);
                             bPropInit.addOperand(n2, id);
                             bPropInit.addOperand(n2, AssignExpression(t, x));