Index: src/parsing/preparser.cc |
diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc |
index d335c8bdcd29433337d1173c9e17b3a1e116a999..c0dc9846465cf655271f9640b9f6964ccacee807 100644 |
--- a/src/parsing/preparser.cc |
+++ b/src/parsing/preparser.cc |
@@ -323,6 +323,14 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) { |
return ParseSubStatement(ok); |
} |
+PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { |
+ if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
+ (legacy && allow_harmony_restrictive_declarations())) { |
+ return ParseSubStatement(ok); |
+ } else { |
+ return ParseFunctionDeclaration(CHECK_OK); |
+ } |
+} |
PreParser::Statement PreParser::ParseSubStatement(bool* ok) { |
// Statement :: |
@@ -397,20 +405,18 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) { |
case Token::TRY: |
return ParseTryStatement(ok); |
- case Token::FUNCTION: { |
- Scanner::Location start_location = scanner()->peek_location(); |
- Statement statement = ParseFunctionDeclaration(CHECK_OK); |
- Scanner::Location end_location = scanner()->location(); |
- if (is_strict(language_mode())) { |
- PreParserTraits::ReportMessageAt(start_location.beg_pos, |
- end_location.end_pos, |
- MessageTemplate::kStrictFunction); |
- *ok = false; |
- return Statement::Default(); |
- } else { |
- return statement; |
- } |
- } |
+ case Token::FUNCTION: |
+ // FunctionDeclaration only allowed as a StatementListItem, not in |
+ // an arbitrary Statement position. Exceptions such as |
+ // ES#sec-functiondeclarations-in-ifstatement-statement-clauses |
+ // are handled by calling ParseScopedStatement rather than |
+ // ParseSubStatement directly. |
+ ReportMessageAt(scanner()->peek_location(), |
+ is_strict(language_mode()) |
+ ? MessageTemplate::kStrictFunction |
+ : MessageTemplate::kSloppyFunction); |
+ *ok = false; |
+ return Statement::Default(); |
case Token::DEBUGGER: |
return ParseDebuggerStatement(ok); |
@@ -698,6 +704,10 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
DCHECK(is_sloppy(language_mode()) || |
!IsFutureStrictReserved(expr.AsIdentifier())); |
Consume(Token::COLON); |
+ // ES#sec-labelled-function-declarations Labelled Function Declarations |
+ if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { |
+ return ParseFunctionDeclaration(ok); |
+ } |
Statement statement = ParseStatement(ok); |
return statement.IsJumpStatement() ? Statement::Default() : statement; |
// Preparsing is disabled for extensions (because the extension details |
@@ -726,10 +736,10 @@ PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
Expect(Token::LPAREN, CHECK_OK); |
ParseExpression(true, CHECK_OK); |
Expect(Token::RPAREN, CHECK_OK); |
- Statement stat = ParseSubStatement(CHECK_OK); |
+ Statement stat = ParseScopedStatement(false, CHECK_OK); |
if (peek() == Token::ELSE) { |
Next(); |
- Statement else_stat = ParseSubStatement(CHECK_OK); |
+ Statement else_stat = ParseScopedStatement(false, CHECK_OK); |
stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ? |
Statement::Jump() : Statement::Default(); |
} else { |
@@ -825,7 +835,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
BlockState block_state(&scope_, with_scope); |
- ParseSubStatement(CHECK_OK); |
+ ParseScopedStatement(true, CHECK_OK); |
return Statement::Default(); |
} |
@@ -875,7 +885,7 @@ PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
// 'do' Statement 'while' '(' Expression ')' ';' |
Expect(Token::DO, CHECK_OK); |
- ParseSubStatement(CHECK_OK); |
+ ParseScopedStatement(true, CHECK_OK); |
Expect(Token::WHILE, CHECK_OK); |
Expect(Token::LPAREN, CHECK_OK); |
ParseExpression(true, CHECK_OK); |
@@ -893,7 +903,7 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { |
Expect(Token::LPAREN, CHECK_OK); |
ParseExpression(true, CHECK_OK); |
Expect(Token::RPAREN, CHECK_OK); |
- ParseSubStatement(ok); |
+ ParseScopedStatement(true, ok); |
return Statement::Default(); |
} |
@@ -945,7 +955,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
} |
Expect(Token::RPAREN, CHECK_OK); |
- ParseSubStatement(CHECK_OK); |
+ ParseScopedStatement(true, CHECK_OK); |
return Statement::Default(); |
} |
} else { |
@@ -983,7 +993,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
} |
Expect(Token::RPAREN, CHECK_OK); |
- ParseSubStatement(CHECK_OK); |
+ ParseScopedStatement(true, CHECK_OK); |
return Statement::Default(); |
} |
} |
@@ -1009,7 +1019,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
} |
Expect(Token::RPAREN, CHECK_OK); |
- ParseSubStatement(ok); |
+ ParseScopedStatement(true, ok); |
return Statement::Default(); |
} |