summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--js/src/frontend/Parser.cpp112
-rw-r--r--js/src/frontend/Parser.h2
2 files changed, 49 insertions, 65 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 5a42b75b0..34d87528f 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1307,7 +1307,7 @@ Parser<ParseHandler>::noteDeclaredName(HandlePropertyName name, DeclarationKind
// Functions in block have complex allowances in sloppy mode for being
// labelled that other lexical declarations do not have. Those checks
// are more complex than calling checkLexicalDeclarationDirectlyWithin-
- // Block and are done in checkFunctionDefinition.
+ // Block and are done inline in callers.
ParseContext::Scope* scope = pc->innermostScope();
if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
@@ -3008,61 +3008,6 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
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) {
- // In 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, uint32_t preludeStart,
@@ -3618,12 +3563,30 @@ Parser<ParseHandler>::functionStmt(uint32_t preludeStart, YieldHandling yieldHan
}
}
- 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);
@@ -3634,6 +3597,7 @@ Parser<ParseHandler>::functionStmt(uint32_t preludeStart, YieldHandling yieldHan
return null();
}
+ RootedPropertyName name(context);
if (tt == TOK_NAME || tt == TOK_YIELD) {
name = bindingIdentifier(yieldHandling);
if (!name)
@@ -3647,13 +3611,35 @@ Parser<ParseHandler>::functionStmt(uint32_t preludeStart, YieldHandling yieldHan
return null();
}
- 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))
+ if (declaredInStmt) {
+ MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
+ MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
+
+ if (!pc->sc()->strict() && generatorKind == NotGenerator) {
+ // In 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();
YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind);
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index dc9c16adb..13580846b 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1349,8 +1349,6 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
Node newDotGeneratorName();
bool declareDotGeneratorName();
- bool checkFunctionDefinition(HandlePropertyName funName, Node pn,
- GeneratorKind generatorKind, bool* tryAnnexB);
bool skipLazyInnerFunction(Node pn, uint32_t preludeStart, FunctionSyntaxKind kind,
bool tryAnnexB);
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, uint32_t preludeStart,