Bug 1296814 - Inline Parser::checkFunctionDefinition into its sole caller. r=anba
authorJeff Walden <jwalden@mit.edu>
Sun, 13 Nov 2016 00:10:34 -0800
changeset 322557 4b4b6a642aeb2c5d6c8098e6c49d6d44ec550afb
parent 322556 2f6b90c78c4b43dfea9db1895eeb90fa6cfc3d26
child 322558 9ec9d6149b5e8bc091775e67aa921738f0b5624a
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
reviewersanba
bugs1296814
milestone52.0a1
Bug 1296814 - Inline Parser::checkFunctionDefinition into its sole caller. r=anba
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2964,71 +2964,16 @@ Parser<ParseHandler>::functionArguments(
     } else if (IsSetterKind(kind)) {
         error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
         return false;
     }
 
     return true;
 }
 
-template <typename ParseHandler>
-bool
-Parser<ParseHandler>::checkFunctionDefinition(HandlePropertyName funName, Node pn,
-                                              GeneratorKind generatorKind, bool* tryAnnexB)
-{
-    TokenPos pos = handler.getPosition(pn);
-
-    // In sloppy mode, Annex B.3.2 allows labelled function
-    // declarations. Otherwise it is a parse error.
-    ParseContext::Statement* declaredInStmt = pc->innermostStatement();
-    if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
-        MOZ_ASSERT(!pc->sc()->strict(),
-                   "labeled functions shouldn't be parsed in strict mode");
-
-        // Find the innermost non-label statement.  Report an error if it's
-        // unbraced: functions can't appear in it.  Otherwise the statement
-        // (or its absence) determines the scope the function's bound in.
-        while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label)
-            declaredInStmt = declaredInStmt->enclosing();
-
-        if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
-            reportWithOffset(ParseError, false, pos.begin, JSMSG_SLOPPY_FUNCTION_LABEL);
-            return false;
-        }
-    }
-
-    if (declaredInStmt) {
-        MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
-        MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
-
-        if (!pc->sc()->strict() && generatorKind == NotGenerator) {
-            // Under sloppy mode, try Annex B.3.3 semantics. If making an
-            // additional 'var' binding of the same name does not throw an
-            // early error, do so. This 'var' binding would be assigned
-            // the function object when its declaration is reached, not at
-            // the start of the block.
-
-            if (!tryDeclareVarForAnnexBLexicalFunction(funName, tryAnnexB))
-                return false;
-        }
-
-        if (!noteDeclaredName(funName, DeclarationKind::LexicalFunction, pos))
-            return false;
-    } else {
-        if (!noteDeclaredName(funName, DeclarationKind::BodyLevelFunction, pos))
-            return false;
-
-        // Body-level functions in modules are always closed over.
-        if (pc->atModuleLevel())
-            pc->varScope().lookupDeclaredName(funName)->value()->setClosedOver();
-    }
-
-    return true;
-}
-
 template <>
 bool
 Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, FunctionSyntaxKind kind,
                                                 bool tryAnnexB)
 {
     // When a lazily-parsed function is called, we only fully parse (and emit)
     // that function, not any of its nested children. The initial syntax-only
     // parse recorded the free variables of nested functions and their extents,
@@ -3546,54 +3491,95 @@ Parser<ParseHandler>::functionFormalPara
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling,
                                    FunctionAsyncKind asyncKind)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
 
-    RootedPropertyName name(context);
-    GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator;
+    // In sloppy mode, Annex B.3.2 allows labelled function declarations.
+    // Otherwise it's a parse error.
+    ParseContext::Statement* declaredInStmt = pc->innermostStatement();
+    if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
+        MOZ_ASSERT(!pc->sc()->strict(),
+                   "labeled functions shouldn't be parsed in strict mode");
+
+        // Find the innermost non-label statement.  Report an error if it's
+        // unbraced: functions can't appear in it.  Otherwise the statement
+        // (or its absence) determines the scope the function's bound in.
+        while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label)
+            declaredInStmt = declaredInStmt->enclosing();
+
+        if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
+            error(JSMSG_SLOPPY_FUNCTION_LABEL);
+            return null();
+        }
+    }
+
     TokenKind tt;
     if (!tokenStream.getToken(&tt))
         return null();
 
+    GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator;
     if (tt == TOK_MUL) {
         if (asyncKind != SyncFunction) {
             error(JSMSG_ASYNC_GENERATOR);
             return null();
         }
         generatorKind = StarGenerator;
         if (!tokenStream.getToken(&tt))
             return null();
     }
 
+    RootedPropertyName name(context);
     if (tt == TOK_NAME || tt == TOK_YIELD) {
         name = bindingIdentifier(yieldHandling);
         if (!name)
             return null();
     } else if (defaultHandling == AllowDefaultName) {
         name = context->names().starDefaultStar;
         tokenStream.ungetToken();
     } else {
         /* Unnamed function expressions are forbidden in statement context. */
         error(JSMSG_UNNAMED_FUNCTION_STMT);
         return null();
     }
 
+    // Note the declared name and check for early errors.
+    bool tryAnnexB = false;
+    if (declaredInStmt) {
+        MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
+        MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
+
+        if (!pc->sc()->strict() && generatorKind == NotGenerator) {
+            // Under sloppy mode, try Annex B.3.3 semantics. If making an
+            // additional 'var' binding of the same name does not throw an
+            // early error, do so. This 'var' binding would be assigned
+            // the function object when its declaration is reached, not at
+            // the start of the block.
+            if (!tryDeclareVarForAnnexBLexicalFunction(name, &tryAnnexB))
+                return null();
+        }
+
+        if (!noteDeclaredName(name, DeclarationKind::LexicalFunction, pos()))
+            return null();
+    } else {
+        if (!noteDeclaredName(name, DeclarationKind::BodyLevelFunction, pos()))
+            return null();
+
+        // Body-level functions in modules are always closed over.
+        if (pc->atModuleLevel())
+            pc->varScope().lookupDeclaredName(name)->value()->setClosedOver();
+    }
+
     Node pn = handler.newFunctionStatement();
     if (!pn)
         return null();
 
-    // Note the declared name and check for early errors.
-    bool tryAnnexB = false;
-    if (!checkFunctionDefinition(name, pn, generatorKind, &tryAnnexB))
-        return null();
-
     YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind);
     return functionDefinition(pn, InAllowed, newYieldHandling, name, Statement, generatorKind,
                               asyncKind, tryAnnexB);
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::functionExpr(InvokedPrediction invoked, FunctionAsyncKind asyncKind)
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1338,18 +1338,16 @@ class Parser final : private JS::AutoGCR
     bool hasUsedFunctionSpecialName(HandlePropertyName name);
     bool declareFunctionArgumentsObject();
     bool declareFunctionThis();
     Node newInternalDotName(HandlePropertyName name);
     Node newThisName();
     Node newDotGeneratorName();
     bool declareDotGeneratorName();
 
-    bool checkFunctionDefinition(HandlePropertyName funName, Node pn, GeneratorKind generatorKind,
-                                 bool* tryAnnexB);
     bool skipLazyInnerFunction(Node pn, FunctionSyntaxKind kind, bool tryAnnexB);
     bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
                        InHandling inHandling, YieldHandling yieldHandling,
                        FunctionSyntaxKind kind,
                        GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
                        Directives inheritedDirectives, Directives* newDirectives);
     bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, InHandling inHandling,
                                      YieldHandling yieldHandling, FunctionSyntaxKind kind,