From 987d6726f3c64d1cc510acba1de08deb5e0a7702 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 14:34:29 -0400 Subject: 1296814 - Move FunctionDeclaration-as-consequent/alternative handling out of Parser::functionStmt into Parser::consequentOrAlternative. --- js/src/frontend/Parser.cpp | 56 ++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 3c509465f..8f52f1d27 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -3550,21 +3550,6 @@ Parser::functionStmt(uint32_t preludeStart, YieldHandling yieldHan { MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION)); - // Annex B.3.4 says we can parse function declarations unbraced under if - // or else as if it were braced. That is, |if (x) function f() {}| is - // parsed as |if (x) { function f() {} }|. - Maybe synthesizedStmtForAnnexB; - Maybe synthesizedScopeForAnnexB; - if (!pc->sc()->strict()) { - ParseContext::Statement* stmt = pc->innermostStatement(); - if (stmt && stmt->kind() == StatementKind::If) { - synthesizedStmtForAnnexB.emplace(pc, StatementKind::Block); - synthesizedScopeForAnnexB.emplace(this); - if (!synthesizedScopeForAnnexB->init(pc)) - return null(); - } - } - // In sloppy mode, Annex B.3.2 allows labelled function declarations. // Otherwise it's a parse error. ParseContext::Statement* declaredInStmt = pc->innermostStatement(); @@ -3645,20 +3630,8 @@ Parser::functionStmt(uint32_t preludeStart, YieldHandling yieldHan return null(); YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind); - Node fun = functionDefinition(preludeStart, pn, InAllowed, newYieldHandling, + return functionDefinition(preludeStart, pn, InAllowed, newYieldHandling, name, Statement, generatorKind, asyncKind, tryAnnexB); - if (!fun) - return null(); - - if (synthesizedStmtForAnnexB) { - Node synthesizedStmtList = handler.newStatementList(handler.getPosition(fun)); - if (!synthesizedStmtList) - return null(); - handler.addStatementToList(synthesizedStmtList, fun); - return finishLexicalScope(*synthesizedScopeForAnnexB, synthesizedStmtList); - } - - return fun; } template @@ -5276,13 +5249,32 @@ Parser::consequentOrAlternative(YieldHandling yieldHandling) return null(); if (next == TOK_FUNCTION) { - // Apply Annex B.3.4 in non-strict code to allow FunctionDeclaration as - // the consequent/alternative of an |if| or |else|. Parser::statement - // will report the strict mode error. + // Annex B.3.4 says that unbraced function declarations under if/else + // in non-strict code act as if they were braced. That is, + // |if (x) function f() {}| is parsed as |if (x) { function f() {} }|. if (!pc->sc()->strict()) { tokenStream.consumeKnownToken(next, TokenStream::Operand); - return functionStmt(pos().begin, yieldHandling, NameRequired); + + ParseContext::Statement stmt(pc, StatementKind::Block); + ParseContext::Scope scope(this); + if (!scope.init(pc)) + return null(); + + TokenPos funcPos = pos(); + Node fun = functionStmt(pos().begin, yieldHandling, NameRequired); + if (!fun) + return null(); + + Node block = handler.newStatementList(funcPos); + if (!block) + return null(); + + handler.addStatementToList(block, fun); + return finishLexicalScope(scope, block); } + + // Function declarations are a syntax error in strict mode code. + // Parser::statement reports that error. } return statement(yieldHandling); -- cgit v1.2.3