Bug 1319416 - Consolidate all semicolon-matching into a single function, now that there's no quasi-bogus need for multiple variants. r=arai
☠☠ backed out by 963adce2ffbe ☠ ☠
authorJeff Walden <jwalden@mit.edu>
Wed, 11 Jan 2017 12:28:09 -0800
changeset 374151 c5c333fa977212477cdb8c0ac0edab3ce617c073
parent 374150 f12f1db4b4f1893076c90d184a99d36a91c69485
child 374152 4dbe893355f7096535a833eeb314267f4258933a
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1319416
milestone53.0a1
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 1319416 - Consolidate all semicolon-matching into a single function, now that there's no quasi-bogus need for multiple variants. r=arai
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2591,24 +2591,19 @@ Parser<ParseHandler>::newFunction(Handle
 #ifdef DEBUG
         if (isGlobalSelfHostedBuiltin)
             fun->setExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT, BooleanValue(false));
 #endif
     }
     return fun;
 }
 
-/*
- * WARNING: Do not call this function directly.
- * Call either matchOrInsertSemicolonAfterExpression or
- * matchOrInsertSemicolonAfterNonExpression instead, depending on context.
- */
 template <typename ParseHandler>
 bool
-Parser<ParseHandler>::matchOrInsertSemicolonHelper()
+Parser<ParseHandler>::matchOrInsertSemicolon()
 {
     TokenKind tt = TOK_EOF;
     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
         return false;
     if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
         /*
          * When current token is `await` and it's outside of async function,
          * it's possibly intended to be an await expression.
@@ -2636,30 +2631,16 @@ Parser<ParseHandler>::matchOrInsertSemic
     }
 
     bool matched;
     return tokenStream.matchToken(&matched, TOK_SEMI, TokenStream::Operand);
 }
 
 template <typename ParseHandler>
 bool
-Parser<ParseHandler>::matchOrInsertSemicolonAfterExpression()
-{
-    return matchOrInsertSemicolonHelper();
-}
-
-template <typename ParseHandler>
-bool
-Parser<ParseHandler>::matchOrInsertSemicolonAfterNonExpression()
-{
-    return matchOrInsertSemicolonHelper();
-}
-
-template <typename ParseHandler>
-bool
 Parser<ParseHandler>::leaveInnerFunction(ParseContext* outerpc)
 {
     MOZ_ASSERT(pc != outerpc);
 
     // If the current function allows super.property but cannot have a home
     // object, i.e., it is an arrow function, we need to propagate the flag to
     // the outer ParseContext.
     if (pc->superScopeNeedsHomeObject()) {
@@ -3008,17 +2989,17 @@ Parser<FullParseHandler>::skipLazyInnerF
     if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
         return false;
 
 #if JS_HAS_EXPR_CLOSURES
     // Only expression closure can be Statement kind.
     // If we remove expression closure, we can remove isExprBody flag from
     // LazyScript and JSScript.
     if (kind == Statement && funbox->isExprBody()) {
-        if (!matchOrInsertSemicolonAfterExpression())
+        if (!matchOrInsertSemicolon())
             return false;
     }
 #endif
 
     return true;
 }
 
 template <>
@@ -3487,17 +3468,17 @@ Parser<ParseHandler>::functionFormalPara
         funbox->bufEnd = pos().end;
     } else {
 #if !JS_HAS_EXPR_CLOSURES
         MOZ_ASSERT(kind == Arrow);
 #endif
         if (tokenStream.hadError())
             return false;
         funbox->bufEnd = pos().end;
-        if (kind == Statement && !matchOrInsertSemicolonAfterExpression())
+        if (kind == Statement && !matchOrInsertSemicolon())
             return false;
     }
 
     if (IsMethodDefinitionKind(kind) && pc->superScopeNeedsHomeObject())
         funbox->setNeedsHomeObject();
 
     if (!finishFunction(isStandaloneFunction))
         return false;
@@ -4559,17 +4540,17 @@ Parser<ParseHandler>::lexicalDeclaration
      * the same environment record as vars.
      *
      * However, they cannot be parsed exactly as vars, as ES6
      * requires that uninitialized lets throw ReferenceError on use.
      *
      * See 8.1.1.1.6 and the note in 13.2.1.
      */
     Node decl = declarationList(yieldHandling, isConst ? PNK_CONST : PNK_LET);
-    if (!decl || !matchOrInsertSemicolonAfterExpression())
+    if (!decl || !matchOrInsertSemicolon())
         return null();
 
     return decl;
 }
 
 template <>
 bool
 Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet)
@@ -4800,17 +4781,17 @@ Parser<FullParseHandler>::importDeclarat
         error(JSMSG_DECLARATION_AFTER_IMPORT);
         return null();
     }
 
     Node moduleSpec = stringLiteral();
     if (!moduleSpec)
         return null();
 
-    if (!matchOrInsertSemicolonAfterNonExpression())
+    if (!matchOrInsertSemicolon())
         return null();
 
     ParseNode* node =
         handler.newImportDeclaration(importSpecSet, moduleSpec, TokenPos(begin, pos().end));
     if (!node || !pc->sc()->asModuleContext()->builder.processImport(node))
         return null();
 
     return node;
@@ -4943,45 +4924,45 @@ Parser<FullParseHandler>::exportDeclarat
         //   from "foo"; // a single ExportDeclaration
         //
         // But if it doesn't, we might have an ASI opportunity in Operand
         // context, so simply matching a contextual keyword won't work:
         //
         //   export { x }   // ExportDeclaration, terminated by ASI
         //   fro\u006D      // ExpressionStatement, the name "from"
         //
-        // In that case let matchOrInsertSemicolonAfterNonExpression sort out
-        // ASI or any necessary error.
+        // In that case let matchOrInsertSemicolon sort out ASI or any
+        // necessary error.
         TokenKind tt;
         if (!tokenStream.getToken(&tt, TokenStream::Operand))
             return null();
 
         if (tt == TOK_NAME &&
             tokenStream.currentToken().name() == context->names().from &&
             !tokenStream.currentToken().nameContainsEscape())
         {
             MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
 
             Node moduleSpec = stringLiteral();
             if (!moduleSpec)
                 return null();
 
-            if (!matchOrInsertSemicolonAfterNonExpression())
+            if (!matchOrInsertSemicolon())
                 return null();
 
             ParseNode* node = handler.newExportFromDeclaration(begin, kid, moduleSpec);
             if (!node || !pc->sc()->asModuleContext()->builder.processExportFrom(node))
                 return null();
 
             return node;
         }
 
         tokenStream.ungetToken();
 
-        if (!matchOrInsertSemicolonAfterNonExpression())
+        if (!matchOrInsertSemicolon())
             return null();
         break;
       }
 
       case TOK_MUL: {
         kid = handler.newList(PNK_EXPORT_SPEC_LIST);
         if (!kid)
             return null();
@@ -5005,17 +4986,17 @@ Parser<FullParseHandler>::exportDeclarat
             return null();
 
         MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
 
         Node moduleSpec = stringLiteral();
         if (!moduleSpec)
             return null();
 
-        if (!matchOrInsertSemicolonAfterNonExpression())
+        if (!matchOrInsertSemicolon())
             return null();
 
         ParseNode* node = handler.newExportFromDeclaration(begin, kid, moduleSpec);
         if (!node || !pc->sc()->asModuleContext()->builder.processExportFrom(node))
             return null();
 
         return node;
 
@@ -5041,17 +5022,17 @@ Parser<FullParseHandler>::exportDeclarat
             return null();
         break;
       }
 
       case TOK_VAR:
         kid = declarationList(YieldIsName, PNK_VAR);
         if (!kid)
             return null();
-        if (!matchOrInsertSemicolonAfterExpression())
+        if (!matchOrInsertSemicolon())
             return null();
         if (!checkExportedNamesForDeclaration(kid))
             return null();
         break;
 
       case TOK_DEFAULT: {
         if (!tokenStream.getToken(&tt, TokenStream::Operand))
             return null();
@@ -5094,17 +5075,17 @@ Parser<FullParseHandler>::exportDeclarat
             nameNode = newName(name);
             if (!nameNode)
                 return null();
             if (!noteDeclaredName(name, DeclarationKind::Const, pos()))
                 return null();
             kid = assignExpr(InAllowed, YieldIsKeyword, TripledotProhibited);
             if (!kid)
                 return null();
-            if (!matchOrInsertSemicolonAfterExpression())
+            if (!matchOrInsertSemicolon())
                 return null();
             break;
           }
         }
 
         ParseNode* node = handler.newExportDefaultDeclaration(kid, nameNode,
                                                               TokenPos(begin, pos().end));
         if (!node || !pc->sc()->asModuleContext()->builder.processExport(node))
@@ -5159,17 +5140,17 @@ template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::expressionStatement(YieldHandling yieldHandling, InvokedPrediction invoked)
 {
     tokenStream.ungetToken();
     Node pnexpr = expr(InAllowed, yieldHandling, TripledotProhibited,
                        /* possibleError = */ nullptr, invoked);
     if (!pnexpr)
         return null();
-    if (!matchOrInsertSemicolonAfterExpression())
+    if (!matchOrInsertSemicolon())
         return null();
     return handler.newExprStatement(pnexpr, pos().end);
 }
 
 template <class ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::consequentOrAlternative(YieldHandling yieldHandling)
 {
@@ -5849,17 +5830,17 @@ Parser<ParseHandler>::continueStatement(
             if (foundTarget)
                 break;
         }
     } else if (!pc->findInnermostStatement(isLoop)) {
         error(JSMSG_BAD_CONTINUE);
         return null();
     }
 
-    if (!matchOrInsertSemicolonAfterNonExpression())
+    if (!matchOrInsertSemicolon())
         return null();
 
     return handler.newContinueStatement(label, TokenPos(begin, pos().end));
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
@@ -5889,17 +5870,17 @@ Parser<ParseHandler>::breakStatement(Yie
         };
 
         if (!pc->findInnermostStatement(isBreakTarget)) {
             errorAt(begin, JSMSG_TOUGH_BREAK);
             return null();
         }
     }
 
-    if (!matchOrInsertSemicolonAfterNonExpression())
+    if (!matchOrInsertSemicolon())
         return null();
 
     return handler.newBreakStatement(label, TokenPos(begin, pos().end));
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
@@ -5929,20 +5910,20 @@ Parser<ParseHandler>::returnStatement(Yi
         exprNode = expr(InAllowed, yieldHandling, TripledotProhibited);
         if (!exprNode)
             return null();
         pc->funHasReturnExpr = true;
       }
     }
 
     if (exprNode) {
-        if (!matchOrInsertSemicolonAfterExpression())
+        if (!matchOrInsertSemicolon())
             return null();
     } else {
-        if (!matchOrInsertSemicolonAfterNonExpression())
+        if (!matchOrInsertSemicolon())
             return null();
     }
 
     Node pn = handler.newReturnStatement(exprNode, TokenPos(begin, pos().end));
     if (!pn)
         return null();
 
     /* Disallow "return v;" in legacy generators. */
@@ -6230,17 +6211,17 @@ Parser<ParseHandler>::throwStatement(Yie
         error(JSMSG_LINE_BREAK_AFTER_THROW);
         return null();
     }
 
     Node throwExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
     if (!throwExpr)
         return null();
 
-    if (!matchOrInsertSemicolonAfterExpression())
+    if (!matchOrInsertSemicolon())
         return null();
 
     return handler.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
@@ -6457,17 +6438,17 @@ Parser<ParseHandler>::catchBlockStatemen
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::debuggerStatement()
 {
     TokenPos p;
     p.begin = pos().begin;
-    if (!matchOrInsertSemicolonAfterNonExpression())
+    if (!matchOrInsertSemicolon())
         return null();
     p.end = pos().end;
 
     pc->sc()->setBindingsAccessedDynamically();
     pc->sc()->setHasDebuggerStatement();
 
     return handler.newDebuggerStatement(p);
 }
@@ -6764,17 +6745,17 @@ Parser<ParseHandler>::nextTokenContinues
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::variableStatement(YieldHandling yieldHandling)
 {
     Node vars = declarationList(yieldHandling, PNK_VAR);
     if (!vars)
         return null();
-    if (!matchOrInsertSemicolonAfterExpression())
+    if (!matchOrInsertSemicolon())
         return null();
     return vars;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::statement(YieldHandling yieldHandling)
 {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1366,19 +1366,17 @@ class Parser final : public ParserBase, 
                                      YieldHandling yieldHandling, FunctionSyntaxKind kind,
                                      GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
                                      bool tryAnnexB,
                                      Directives inheritedDirectives, Directives* newDirectives);
     bool finishFunctionScopes(bool isStandaloneFunction);
     bool finishFunction(bool isStandaloneFunction = false);
     bool leaveInnerFunction(ParseContext* outerpc);
 
-    bool matchOrInsertSemicolonHelper();
-    bool matchOrInsertSemicolonAfterExpression();
-    bool matchOrInsertSemicolonAfterNonExpression();
+    bool matchOrInsertSemicolon();
 
   public:
     enum FunctionCallBehavior {
         PermitAssignmentToFunctionCalls,
         ForbidAssignmentToFunctionCalls
     };
 
     bool isValidSimpleAssignmentTarget(Node node,