Commit 339bb225 authored by Florian Sattler's avatar Florian Sattler Committed by Commit Bot

[parser] Remove explicit ok status tracking.

Replace the explicit ok tracing by setting the scanner to fail, allowing us to
return automatically. RETURN_IF_PARSE_ERROR is now used instead of CHECK_OK to
verify if the parser failed.

In a follow-up CL we'll merge RETURN_IF_PARSE_ERROR after Expect* into an
EXPECT* macro. We'll keep (for now) RETURN_IF_PARSE_ERROR that guard uses of
possible NullExpression (e.g., impl()->IsIdentifier(...)). All other RETURN_IF*
will be removed. Uses after failure can likely later be fixed too by introducing
a FailureExpression.

Bug: v8:8363 ,v8:7926

Change-Id: I9896449eb9be476c453da4417a0bfd17c169ff38
Reviewed-on: https://chromium-review.googlesource.com/c/1294649
Commit-Queue: Florian Sattler <sattlerf@google.com>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56972}
parent 9929a238
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -137,27 +137,23 @@ void Parser::GetUnexpectedTokenMessage(Token::Value token, ...@@ -137,27 +137,23 @@ void Parser::GetUnexpectedTokenMessage(Token::Value token,
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error // The RETURN_IF_PARSE_ERROR macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok). // handling for functions that may fail (by returning if there was an parser
// error scanner()->has_parser_error_set).
// //
// CAUTION: This macro appends extra statements after a call, // Usage:
// thus it must never be used where only a single statement // foo = ParseFoo(); // may fail
// is correct (e.g. an if statement branch w/o braces)! // RETURN_IF_PARSE_ERROR
//
#define CHECK_OK_VALUE(x) ok); \ // SAFE_USE(foo);
if (!*ok) return x; \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_OK CHECK_OK_VALUE(nullptr) #define RETURN_IF_PARSE_ERROR_VALUE(x) \
#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void()) if (scanner()->has_parser_error_set()) { \
return x; \
}
#define CHECK_FAILED /**/); \ #define RETURN_IF_PARSE_ERROR RETURN_IF_PARSE_ERROR_VALUE(nullptr)
if (failed_) return nullptr; \ #define RETURN_IF_PARSE_ERROR_VOID RETURN_IF_PARSE_ERROR_VALUE(this->Void())
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of Parser // Implementation of Parser
...@@ -362,7 +358,7 @@ Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) { ...@@ -362,7 +358,7 @@ Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
Expression* Parser::NewV8Intrinsic(const AstRawString* name, Expression* Parser::NewV8Intrinsic(const AstRawString* name,
const ScopedPtrList<Expression>& args, const ScopedPtrList<Expression>& args,
int pos, bool* ok) { int pos) {
if (extension_ != nullptr) { if (extension_ != nullptr) {
// The extension structures are only accessible while parsing the // The extension structures are only accessible while parsing the
// very first time, not when reparsing because of lazy compilation. // very first time, not when reparsing because of lazy compilation.
...@@ -387,7 +383,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name, ...@@ -387,7 +383,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
return args.at(0); return args.at(0);
} else { } else {
ReportMessage(MessageTemplate::kNotIsvar); ReportMessage(MessageTemplate::kNotIsvar);
*ok = false;
return nullptr; return nullptr;
} }
} }
...@@ -395,7 +390,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name, ...@@ -395,7 +390,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
// Check that the expected number of arguments are being passed. // Check that the expected number of arguments are being passed.
if (function->nargs != -1 && function->nargs != args.length()) { if (function->nargs != -1 && function->nargs != args.length()) {
ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
*ok = false;
return nullptr; return nullptr;
} }
...@@ -408,7 +402,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name, ...@@ -408,7 +402,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
// Check that the function is defined. // Check that the function is defined.
if (context_index == Context::kNotFound) { if (context_index == Context::kNotFound) {
ReportMessage(MessageTemplate::kNotDefined, name); ReportMessage(MessageTemplate::kNotDefined, name);
*ok = false;
return nullptr; return nullptr;
} }
...@@ -595,8 +588,9 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { ...@@ -595,8 +588,9 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
zone()); zone());
ParseModuleItemList(body, &ok); ParseModuleItemList(body);
ok = ok && module()->Validate(this->scope()->AsModuleScope(), ok = !scanner_.has_parser_error_set() &&
module()->Validate(this->scope()->AsModuleScope(),
pending_error_handler(), zone()); pending_error_handler(), zone());
} else if (info->is_wrapped_as_function()) { } else if (info->is_wrapped_as_function()) {
ParseWrapped(isolate, info, body, scope, zone(), &ok); ParseWrapped(isolate, info, body, scope, zone(), &ok);
...@@ -604,15 +598,17 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { ...@@ -604,15 +598,17 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
// Don't count the mode in the use counters--give the program a chance // Don't count the mode in the use counters--give the program a chance
// to enable script-wide strict mode below. // to enable script-wide strict mode below.
this->scope()->SetLanguageMode(info->language_mode()); this->scope()->SetLanguageMode(info->language_mode());
ParseStatementList(body, Token::EOS, &ok); ParseStatementList(body, Token::EOS);
} }
ok = ok && !scanner_.has_parser_error_set();
// The parser will peek but not consume EOS. Our scope logically goes all // The parser will peek but not consume EOS. Our scope logically goes all
// the way to the EOS, though. // the way to the EOS, though.
scope->set_end_position(scanner()->peek_location().beg_pos); scope->set_end_position(scanner()->peek_location().beg_pos);
if (ok && is_strict(language_mode())) { if (ok && is_strict(language_mode())) {
CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos);
ok = !scanner_.has_parser_error_set();
} }
if (ok && is_sloppy(language_mode())) { if (ok && is_sloppy(language_mode())) {
// TODO(littledan): Function bindings on the global object that modify // TODO(littledan): Function bindings on the global object that modify
...@@ -622,7 +618,8 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { ...@@ -622,7 +618,8 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
InsertSloppyBlockFunctionVarBindings(scope); InsertSloppyBlockFunctionVarBindings(scope);
} }
if (ok) { if (ok) {
CheckConflictingVarDeclarations(scope, &ok); CheckConflictingVarDeclarations(scope);
ok = !scanner_.has_parser_error_set();
} }
if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
...@@ -689,7 +686,8 @@ void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info, ...@@ -689,7 +686,8 @@ void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
FunctionLiteral* function_literal = ParseFunctionLiteral( FunctionLiteral* function_literal = ParseFunctionLiteral(
function_name, location, kSkipFunctionNameCheck, kNormalFunction, function_name, location, kSkipFunctionNameCheck, kNormalFunction,
kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy, kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
arguments_for_wrapped_function, CHECK_OK_VOID); arguments_for_wrapped_function);
RETURN_IF_PARSE_ERROR_VOID;
Statement* return_statement = factory()->NewReturnStatement( Statement* return_statement = factory()->NewReturnStatement(
function_literal, kNoSourcePosition, kNoSourcePosition); function_literal, kNoSourcePosition, kNoSourcePosition);
...@@ -817,11 +815,13 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -817,11 +815,13 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
BlockState block_state(&scope_, scope); BlockState block_state(&scope_, scope);
if (Check(Token::LPAREN)) { if (Check(Token::LPAREN)) {
// '(' StrictFormalParameters ')' // '(' StrictFormalParameters ')'
ParseFormalParameterList(&formals, &ok); ParseFormalParameterList(&formals);
ok = !scanner_.has_parser_error_set();
if (ok) ok = Check(Token::RPAREN); if (ok) ok = Check(Token::RPAREN);
} else { } else {
// BindingIdentifier // BindingIdentifier
ParseFormalParameter(&formals, &ok); ParseFormalParameter(&formals);
ok = !scanner_.has_parser_error_set();
if (ok) { if (ok) {
DeclareFormalParameters(&formals); DeclareFormalParameters(&formals);
} }
...@@ -852,8 +852,9 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -852,8 +852,9 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
// Any destructuring assignments in the current FunctionState // Any destructuring assignments in the current FunctionState
// actually belong to the arrow function itself. // actually belong to the arrow function itself.
const int rewritable_length = 0; const int rewritable_length = 0;
Expression* expression = ParseArrowFunctionLiteral( Expression* expression =
accept_IN, formals, rewritable_length, &ok); ParseArrowFunctionLiteral(accept_IN, formals, rewritable_length);
ok = !scanner_.has_parser_error_set();
if (ok) { if (ok) {
// Scanning must end at the same position that was recorded // Scanning must end at the same position that was recorded
// previously. If not, parsing has been interrupted due to a stack // previously. If not, parsing has been interrupted due to a stack
...@@ -883,9 +884,11 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -883,9 +884,11 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
result = ParseFunctionLiteral( result = ParseFunctionLiteral(
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind, raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
kNoSourcePosition, function_type, info->language_mode(), kNoSourcePosition, function_type, info->language_mode(),
arguments_for_wrapped_function, &ok); arguments_for_wrapped_function);
ok = !scanner_.has_parser_error_set();
} }
DCHECK_EQ(ok, !scanner_.has_parser_error_set());
if (ok) { if (ok) {
result->set_requires_instance_fields_initializer( result->set_requires_instance_fields_initializer(
info->requires_instance_fields_initializer()); info->requires_instance_fields_initializer());
...@@ -901,7 +904,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, ...@@ -901,7 +904,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
return result; return result;
} }
Statement* Parser::ParseModuleItem(bool* ok) { Statement* Parser::ParseModuleItem() {
// ecma262/#prod-ModuleItem // ecma262/#prod-ModuleItem
// ModuleItem : // ModuleItem :
// ImportDeclaration // ImportDeclaration
...@@ -911,7 +914,7 @@ Statement* Parser::ParseModuleItem(bool* ok) { ...@@ -911,7 +914,7 @@ Statement* Parser::ParseModuleItem(bool* ok) {
Token::Value next = peek(); Token::Value next = peek();
if (next == Token::EXPORT) { if (next == Token::EXPORT) {
return ParseExportDeclaration(ok); return ParseExportDeclaration();
} }
if (next == Token::IMPORT) { if (next == Token::IMPORT) {
...@@ -920,15 +923,16 @@ Statement* Parser::ParseModuleItem(bool* ok) { ...@@ -920,15 +923,16 @@ Statement* Parser::ParseModuleItem(bool* ok) {
Token::Value peek_ahead = PeekAhead(); Token::Value peek_ahead = PeekAhead();
if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) && if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
(!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) { (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
ParseImportDeclaration(CHECK_OK); ParseImportDeclaration();
RETURN_IF_PARSE_ERROR;
return factory()->NewEmptyStatement(kNoSourcePosition); return factory()->NewEmptyStatement(kNoSourcePosition);
} }
} }
return ParseStatementListItem(ok); return ParseStatementListItem();
} }
void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) { void Parser::ParseModuleItemList(ZonePtrList<Statement>* body) {
// ecma262/#prod-Module // ecma262/#prod-Module
// Module : // Module :
// ModuleBody? // ModuleBody?
...@@ -939,24 +943,25 @@ void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) { ...@@ -939,24 +943,25 @@ void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) {
DCHECK(scope()->is_module_scope()); DCHECK(scope()->is_module_scope());
while (peek() != Token::EOS) { while (peek() != Token::EOS) {
Statement* stat = ParseModuleItem(CHECK_OK_VOID); Statement* stat = ParseModuleItem();
RETURN_IF_PARSE_ERROR_VOID;
if (stat && !stat->IsEmpty()) { if (stat && !stat->IsEmpty()) {
body->Add(stat, zone()); body->Add(stat, zone());
} }
} }
} }
const AstRawString* Parser::ParseModuleSpecifier() {
const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
// ModuleSpecifier : // ModuleSpecifier :
// StringLiteral // StringLiteral
Expect(Token::STRING, CHECK_OK); Expect(Token::STRING);
RETURN_IF_PARSE_ERROR;
return GetSymbol(); return GetSymbol();
} }
ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause( ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
Scanner::Location* reserved_loc, bool* ok) { Scanner::Location* reserved_loc) {
// ExportClause : // ExportClause :
// '{' '}' // '{' '}'
// '{' ExportsList '}' // '{' ExportsList '}'
...@@ -972,7 +977,8 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause( ...@@ -972,7 +977,8 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
ZoneChunkList<ExportClauseData>* export_data = ZoneChunkList<ExportClauseData>* export_data =
new (zone()) ZoneChunkList<ExportClauseData>(zone()); new (zone()) ZoneChunkList<ExportClauseData>(zone());
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE);
RETURN_IF_PARSE_ERROR;
Token::Value name_tok; Token::Value name_tok;
while ((name_tok = peek()) != Token::RBRACE) { while ((name_tok = peek()) != Token::RBRACE) {
...@@ -983,11 +989,13 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause( ...@@ -983,11 +989,13 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
parsing_module_)) { parsing_module_)) {
*reserved_loc = scanner()->location(); *reserved_loc = scanner()->location();
} }
const AstRawString* local_name = ParseIdentifierName(CHECK_OK); const AstRawString* local_name = ParseIdentifierName();
RETURN_IF_PARSE_ERROR;
const AstRawString* export_name = nullptr; const AstRawString* export_name = nullptr;
Scanner::Location location = scanner()->location(); Scanner::Location location = scanner()->location();
if (CheckContextualKeyword(Token::AS)) { if (CheckContextualKeyword(Token::AS)) {
export_name = ParseIdentifierName(CHECK_OK); export_name = ParseIdentifierName();
RETURN_IF_PARSE_ERROR;
// Set the location to the whole "a as b" string, so that it makes sense // Set the location to the whole "a as b" string, so that it makes sense
// both for errors due to "a" and for errors due to "b". // both for errors due to "a" and for errors due to "b".
location.end_pos = scanner()->location().end_pos; location.end_pos = scanner()->location().end_pos;
...@@ -997,15 +1005,16 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause( ...@@ -997,15 +1005,16 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
} }
export_data->push_back({export_name, local_name, location}); export_data->push_back({export_name, local_name, location});
if (peek() == Token::RBRACE) break; if (peek() == Token::RBRACE) break;
Expect(Token::COMMA, CHECK_OK); Expect(Token::COMMA);
RETURN_IF_PARSE_ERROR;
} }
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE);
RETURN_IF_PARSE_ERROR;
return export_data; return export_data;
} }
ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos, ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
bool* ok) {
// NamedImports : // NamedImports :
// '{' '}' // '{' '}'
// '{' ImportsList '}' // '{' ImportsList '}'
...@@ -1019,47 +1028,50 @@ ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos, ...@@ -1019,47 +1028,50 @@ ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos,
// BindingIdentifier // BindingIdentifier
// IdentifierName 'as' BindingIdentifier // IdentifierName 'as' BindingIdentifier
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE);
RETURN_IF_PARSE_ERROR;
auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone()); auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
const AstRawString* import_name = ParseIdentifierName(CHECK_OK); const AstRawString* import_name = ParseIdentifierName();
RETURN_IF_PARSE_ERROR;
const AstRawString* local_name = import_name; const AstRawString* local_name = import_name;
Scanner::Location location = scanner()->location(); Scanner::Location location = scanner()->location();
// In the presence of 'as', the left-side of the 'as' can // In the presence of 'as', the left-side of the 'as' can
// be any IdentifierName. But without 'as', it must be a valid // be any IdentifierName. But without 'as', it must be a valid
// BindingIdentifier. // BindingIdentifier.
if (CheckContextualKeyword(Token::AS)) { if (CheckContextualKeyword(Token::AS)) {
local_name = ParseIdentifierName(CHECK_OK); local_name = ParseIdentifierName();
RETURN_IF_PARSE_ERROR;
} }
if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict, if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
false, parsing_module_)) { false, parsing_module_)) {
*ok = false;
ReportMessage(MessageTemplate::kUnexpectedReserved); ReportMessage(MessageTemplate::kUnexpectedReserved);
return nullptr; return nullptr;
} else if (IsEvalOrArguments(local_name)) { } else if (IsEvalOrArguments(local_name)) {
*ok = false;
ReportMessage(MessageTemplate::kStrictEvalArguments); ReportMessage(MessageTemplate::kStrictEvalArguments);
return nullptr; return nullptr;
} }
DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization, DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization,
position(), CHECK_OK); position());
RETURN_IF_PARSE_ERROR;
NamedImport* import = NamedImport* import =
new (zone()) NamedImport(import_name, local_name, location); new (zone()) NamedImport(import_name, local_name, location);
result->Add(import, zone()); result->Add(import, zone());
if (peek() == Token::RBRACE) break; if (peek() == Token::RBRACE) break;
Expect(Token::COMMA, CHECK_OK); Expect(Token::COMMA);
RETURN_IF_PARSE_ERROR;
} }
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE);
RETURN_IF_PARSE_ERROR;
return result; return result;
} }
void Parser::ParseImportDeclaration() {
void Parser::ParseImportDeclaration(bool* ok) {
// ImportDeclaration : // ImportDeclaration :
// 'import' ImportClause 'from' ModuleSpecifier ';' // 'import' ImportClause 'from' ModuleSpecifier ';'
// 'import' ModuleSpecifier ';' // 'import' ModuleSpecifier ';'
...@@ -1075,15 +1087,18 @@ void Parser::ParseImportDeclaration(bool* ok) { ...@@ -1075,15 +1087,18 @@ void Parser::ParseImportDeclaration(bool* ok) {
// '*' 'as' ImportedBinding // '*' 'as' ImportedBinding
int pos = peek_position(); int pos = peek_position();
Expect(Token::IMPORT, CHECK_OK_VOID); Expect(Token::IMPORT);
RETURN_IF_PARSE_ERROR_VOID;
Token::Value tok = peek(); Token::Value tok = peek();
// 'import' ModuleSpecifier ';' // 'import' ModuleSpecifier ';'
if (tok == Token::STRING) { if (tok == Token::STRING) {
Scanner::Location specifier_loc = scanner()->peek_location(); Scanner::Location specifier_loc = scanner()->peek_location();
const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); const AstRawString* module_specifier = ParseModuleSpecifier();
ExpectSemicolon(CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
ExpectSemicolon();
RETURN_IF_PARSE_ERROR_VOID;
module()->AddEmptyImport(module_specifier, specifier_loc); module()->AddEmptyImport(module_specifier, specifier_loc);
return; return;
} }
...@@ -1092,11 +1107,12 @@ void Parser::ParseImportDeclaration(bool* ok) { ...@@ -1092,11 +1107,12 @@ void Parser::ParseImportDeclaration(bool* ok) {
const AstRawString* import_default_binding = nullptr; const AstRawString* import_default_binding = nullptr;
Scanner::Location import_default_binding_loc; Scanner::Location import_default_binding_loc;
if (tok != Token::MUL && tok != Token::LBRACE) { if (tok != Token::MUL && tok != Token::LBRACE) {
import_default_binding = import_default_binding = ParseIdentifier(kDontAllowRestrictedIdentifiers);
ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
import_default_binding_loc = scanner()->location(); import_default_binding_loc = scanner()->location();
DeclareVariable(import_default_binding, VariableMode::kConst, DeclareVariable(import_default_binding, VariableMode::kConst,
kNeedsInitialization, pos, CHECK_OK_VOID); kNeedsInitialization, pos);
RETURN_IF_PARSE_ERROR_VOID;
} }
// Parse NameSpaceImport or NamedImports if present. // Parse NameSpaceImport or NamedImports if present.
...@@ -1107,30 +1123,36 @@ void Parser::ParseImportDeclaration(bool* ok) { ...@@ -1107,30 +1123,36 @@ void Parser::ParseImportDeclaration(bool* ok) {
switch (peek()) { switch (peek()) {
case Token::MUL: { case Token::MUL: {
Consume(Token::MUL); Consume(Token::MUL);
ExpectContextualKeyword(Token::AS, CHECK_OK_VOID); ExpectContextualKeyword(Token::AS);
RETURN_IF_PARSE_ERROR_VOID;
module_namespace_binding = module_namespace_binding =
ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); ParseIdentifier(kDontAllowRestrictedIdentifiers);
RETURN_IF_PARSE_ERROR_VOID;
module_namespace_binding_loc = scanner()->location(); module_namespace_binding_loc = scanner()->location();
DeclareVariable(module_namespace_binding, VariableMode::kConst, DeclareVariable(module_namespace_binding, VariableMode::kConst,
kCreatedInitialized, pos, CHECK_OK_VOID); kCreatedInitialized, pos);
RETURN_IF_PARSE_ERROR_VOID;
break; break;
} }
case Token::LBRACE: case Token::LBRACE:
named_imports = ParseNamedImports(pos, CHECK_OK_VOID); named_imports = ParseNamedImports(pos);
RETURN_IF_PARSE_ERROR_VOID;
break; break;
default: default:
*ok = false;
ReportUnexpectedToken(scanner()->current_token()); ReportUnexpectedToken(scanner()->current_token());
return; return;
} }
} }
ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID); ExpectContextualKeyword(Token::FROM);
RETURN_IF_PARSE_ERROR_VOID;
Scanner::Location specifier_loc = scanner()->peek_location(); Scanner::Location specifier_loc = scanner()->peek_location();
const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); const AstRawString* module_specifier = ParseModuleSpecifier();
ExpectSemicolon(CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
ExpectSemicolon();
RETURN_IF_PARSE_ERROR_VOID;
// Now that we have all the information, we can make the appropriate // Now that we have all the information, we can make the appropriate
// declarations. // declarations.
...@@ -1166,33 +1188,36 @@ void Parser::ParseImportDeclaration(bool* ok) { ...@@ -1166,33 +1188,36 @@ void Parser::ParseImportDeclaration(bool* ok) {
} }
} }
Statement* Parser::ParseExportDefault() {
Statement* Parser::ParseExportDefault(bool* ok) {
// Supports the following productions, starting after the 'default' token: // Supports the following productions, starting after the 'default' token:
// 'export' 'default' HoistableDeclaration // 'export' 'default' HoistableDeclaration
// 'export' 'default' ClassDeclaration // 'export' 'default' ClassDeclaration
// 'export' 'default' AssignmentExpression[In] ';' // 'export' 'default' AssignmentExpression[In] ';'
Expect(Token::DEFAULT, CHECK_OK); Expect(Token::DEFAULT);
RETURN_IF_PARSE_ERROR;
Scanner::Location default_loc = scanner()->location(); Scanner::Location default_loc = scanner()->location();
ZonePtrList<const AstRawString> local_names(1, zone()); ZonePtrList<const AstRawString> local_names(1, zone());
Statement* result = nullptr; Statement* result = nullptr;
switch (peek()) { switch (peek()) {
case Token::FUNCTION: case Token::FUNCTION:
result = ParseHoistableDeclaration(&local_names, true, CHECK_OK); result = ParseHoistableDeclaration(&local_names, true);
RETURN_IF_PARSE_ERROR;
break; break;
case Token::CLASS: case Token::CLASS:
Consume(Token::CLASS); Consume(Token::CLASS);
result = ParseClassDeclaration(&local_names, true, CHECK_OK); result = ParseClassDeclaration(&local_names, true);
RETURN_IF_PARSE_ERROR;
break; break;
case Token::ASYNC: case Token::ASYNC:
if (PeekAhead() == Token::FUNCTION && if (PeekAhead() == Token::FUNCTION &&
!scanner()->HasLineTerminatorAfterNext()) { !scanner()->HasLineTerminatorAfterNext()) {
Consume(Token::ASYNC); Consume(Token::ASYNC);
result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK); result = ParseAsyncFunctionDeclaration(&local_names, true);
RETURN_IF_PARSE_ERROR;
break; break;
} }
V8_FALLTHROUGH; V8_FALLTHROUGH;
...@@ -1200,8 +1225,10 @@ Statement* Parser::ParseExportDefault(bool* ok) { ...@@ -1200,8 +1225,10 @@ Statement* Parser::ParseExportDefault(bool* ok) {
default: { default: {
int pos = position(); int pos = position();
ExpressionClassifier classifier(this); ExpressionClassifier classifier(this);
Expression* value = ParseAssignmentExpression(true, CHECK_OK); Expression* value = ParseAssignmentExpression(true);
ValidateExpression(CHECK_OK); RETURN_IF_PARSE_ERROR;
ValidateExpression();
RETURN_IF_PARSE_ERROR;
SetFunctionName(value, ast_value_factory()->default_string()); SetFunctionName(value, ast_value_factory()->default_string());
const AstRawString* local_name = const AstRawString* local_name =
...@@ -1211,7 +1238,8 @@ Statement* Parser::ParseExportDefault(bool* ok) { ...@@ -1211,7 +1238,8 @@ Statement* Parser::ParseExportDefault(bool* ok) {
// It's fine to declare this as VariableMode::kConst because the user has // It's fine to declare this as VariableMode::kConst because the user has
// no way of writing to it. // no way of writing to it.
Declaration* decl = Declaration* decl =
DeclareVariable(local_name, VariableMode::kConst, pos, CHECK_OK); DeclareVariable(local_name, VariableMode::kConst, pos);
RETURN_IF_PARSE_ERROR;
decl->proxy()->var()->set_initializer_position(position()); decl->proxy()->var()->set_initializer_position(position());
Assignment* assignment = factory()->NewAssignment( Assignment* assignment = factory()->NewAssignment(
...@@ -1219,7 +1247,8 @@ Statement* Parser::ParseExportDefault(bool* ok) { ...@@ -1219,7 +1247,8 @@ Statement* Parser::ParseExportDefault(bool* ok) {
result = IgnoreCompletion( result = IgnoreCompletion(
factory()->NewExpressionStatement(assignment, kNoSourcePosition)); factory()->NewExpressionStatement(assignment, kNoSourcePosition));
ExpectSemicolon(CHECK_OK); ExpectSemicolon();
RETURN_IF_PARSE_ERROR;
break; break;
} }
} }
...@@ -1240,17 +1269,20 @@ const AstRawString* Parser::NextInternalNamespaceExportName() { ...@@ -1240,17 +1269,20 @@ const AstRawString* Parser::NextInternalNamespaceExportName() {
return ast_value_factory()->GetOneByteString(s.c_str()); return ast_value_factory()->GetOneByteString(s.c_str());
} }
void Parser::ParseExportStar(bool* ok) { void Parser::ParseExportStar() {
int pos = position(); int pos = position();
Consume(Token::MUL); Consume(Token::MUL);
if (!FLAG_harmony_namespace_exports || !PeekContextualKeyword(Token::AS)) { if (!FLAG_harmony_namespace_exports || !PeekContextualKeyword(Token::AS)) {
// 'export' '*' 'from' ModuleSpecifier ';' // 'export' '*' 'from' ModuleSpecifier ';'
Scanner::Location loc = scanner()->location(); Scanner::Location loc = scanner()->location();
ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID); ExpectContextualKeyword(Token::FROM);
RETURN_IF_PARSE_ERROR_VOID;
Scanner::Location specifier_loc = scanner()->peek_location(); Scanner::Location specifier_loc = scanner()->peek_location();
const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); const AstRawString* module_specifier = ParseModuleSpecifier();
ExpectSemicolon(CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
ExpectSemicolon();
RETURN_IF_PARSE_ERROR_VOID;
module()->AddStarExport(module_specifier, loc, specifier_loc, zone()); module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
return; return;
} }
...@@ -1263,25 +1295,30 @@ void Parser::ParseExportStar(bool* ok) { ...@@ -1263,25 +1295,30 @@ void Parser::ParseExportStar(bool* ok) {
// ~> // ~>
// import * as .x from "..."; export {.x as x}; // import * as .x from "..."; export {.x as x};
ExpectContextualKeyword(Token::AS, CHECK_OK_VOID); ExpectContextualKeyword(Token::AS);
const AstRawString* export_name = ParseIdentifierName(CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
const AstRawString* export_name = ParseIdentifierName();
RETURN_IF_PARSE_ERROR_VOID;
Scanner::Location export_name_loc = scanner()->location(); Scanner::Location export_name_loc = scanner()->location();
const AstRawString* local_name = NextInternalNamespaceExportName(); const AstRawString* local_name = NextInternalNamespaceExportName();
Scanner::Location local_name_loc = Scanner::Location::invalid(); Scanner::Location local_name_loc = Scanner::Location::invalid();
DeclareVariable(local_name, VariableMode::kConst, kCreatedInitialized, pos, DeclareVariable(local_name, VariableMode::kConst, kCreatedInitialized, pos);
CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID); ExpectContextualKeyword(Token::FROM);
RETURN_IF_PARSE_ERROR_VOID;
Scanner::Location specifier_loc = scanner()->peek_location(); Scanner::Location specifier_loc = scanner()->peek_location();
const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); const AstRawString* module_specifier = ParseModuleSpecifier();
ExpectSemicolon(CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
ExpectSemicolon();
RETURN_IF_PARSE_ERROR_VOID;
module()->AddStarImport(local_name, module_specifier, local_name_loc, module()->AddStarImport(local_name, module_specifier, local_name_loc,
specifier_loc, zone()); specifier_loc, zone());
module()->AddExport(local_name, export_name, export_name_loc, zone()); module()->AddExport(local_name, export_name, export_name_loc, zone());
} }
Statement* Parser::ParseExportDeclaration(bool* ok) { Statement* Parser::ParseExportDeclaration() {
// ExportDeclaration: // ExportDeclaration:
// 'export' '*' 'from' ModuleSpecifier ';' // 'export' '*' 'from' ModuleSpecifier ';'
// 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';' // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
...@@ -1290,16 +1327,18 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { ...@@ -1290,16 +1327,18 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
// 'export' Declaration // 'export' Declaration
// 'export' 'default' ... (handled in ParseExportDefault) // 'export' 'default' ... (handled in ParseExportDefault)
Expect(Token::EXPORT, CHECK_OK); Expect(Token::EXPORT);
RETURN_IF_PARSE_ERROR;
Statement* result = nullptr; Statement* result = nullptr;
ZonePtrList<const AstRawString> names(1, zone()); ZonePtrList<const AstRawString> names(1, zone());
Scanner::Location loc = scanner()->peek_location(); Scanner::Location loc = scanner()->peek_location();
switch (peek()) { switch (peek()) {
case Token::DEFAULT: case Token::DEFAULT:
return ParseExportDefault(ok); return ParseExportDefault();
case Token::MUL: case Token::MUL:
ParseExportStar(CHECK_OK); ParseExportStar();
RETURN_IF_PARSE_ERROR;
return factory()->NewEmptyStatement(position()); return factory()->NewEmptyStatement(position());
case Token::LBRACE: { case Token::LBRACE: {
...@@ -1317,19 +1356,21 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { ...@@ -1317,19 +1356,21 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
int pos = position(); int pos = position();
Scanner::Location reserved_loc = Scanner::Location::invalid(); Scanner::Location reserved_loc = Scanner::Location::invalid();
ZoneChunkList<ExportClauseData>* export_data = ZoneChunkList<ExportClauseData>* export_data =
ParseExportClause(&reserved_loc, CHECK_OK); ParseExportClause(&reserved_loc);
RETURN_IF_PARSE_ERROR;
const AstRawString* module_specifier = nullptr; const AstRawString* module_specifier = nullptr;
Scanner::Location specifier_loc; Scanner::Location specifier_loc;
if (CheckContextualKeyword(Token::FROM)) { if (CheckContextualKeyword(Token::FROM)) {
specifier_loc = scanner()->peek_location(); specifier_loc = scanner()->peek_location();
module_specifier = ParseModuleSpecifier(CHECK_OK); module_specifier = ParseModuleSpecifier();
RETURN_IF_PARSE_ERROR;
} else if (reserved_loc.IsValid()) { } else if (reserved_loc.IsValid()) {
// No FromClause, so reserved words are invalid in ExportClause. // No FromClause, so reserved words are invalid in ExportClause.
*ok = false;
ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
return nullptr; return nullptr;
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon();
RETURN_IF_PARSE_ERROR;
if (module_specifier == nullptr) { if (module_specifier == nullptr) {
for (const ExportClauseData& data : *export_data) { for (const ExportClauseData& data : *export_data) {
module()->AddExport(data.local_name, data.export_name, data.location, module()->AddExport(data.local_name, data.export_name, data.location,
...@@ -1348,31 +1389,34 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { ...@@ -1348,31 +1389,34 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
} }
case Token::FUNCTION: case Token::FUNCTION:
result = ParseHoistableDeclaration(&names, false, CHECK_OK); result = ParseHoistableDeclaration(&names, false);
RETURN_IF_PARSE_ERROR;
break; break;
case Token::CLASS: case Token::CLASS:
Consume(Token::CLASS); Consume(Token::CLASS);
result = ParseClassDeclaration(&names, false, CHECK_OK); result = ParseClassDeclaration(&names, false);
RETURN_IF_PARSE_ERROR;
break; break;
case Token::VAR: case Token::VAR:
case Token::LET: case Token::LET:
case Token::CONST: case Token::CONST:
result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); result = ParseVariableStatement(kStatementListItem, &names);
RETURN_IF_PARSE_ERROR;
break; break;
case Token::ASYNC: case Token::ASYNC:
Consume(Token::ASYNC); Consume(Token::ASYNC);
if (peek() == Token::FUNCTION && if (peek() == Token::FUNCTION &&
!scanner()->HasLineTerminatorBeforeNext()) { !scanner()->HasLineTerminatorBeforeNext()) {
result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); result = ParseAsyncFunctionDeclaration(&names, false);
RETURN_IF_PARSE_ERROR;
break; break;
} }
V8_FALLTHROUGH; V8_FALLTHROUGH;
default: default:
*ok = false;
ReportUnexpectedToken(scanner()->current_token()); ReportUnexpectedToken(scanner()->current_token());
return nullptr; return nullptr;
} }
...@@ -1397,14 +1441,14 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name) { ...@@ -1397,14 +1441,14 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
} }
Declaration* Parser::DeclareVariable(const AstRawString* name, Declaration* Parser::DeclareVariable(const AstRawString* name,
VariableMode mode, int pos, bool* ok) { VariableMode mode, int pos) {
return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode), return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
pos, ok); pos);
} }
Declaration* Parser::DeclareVariable(const AstRawString* name, Declaration* Parser::DeclareVariable(const AstRawString* name,
VariableMode mode, InitializationFlag init, VariableMode mode, InitializationFlag init,
int pos, bool* ok) { int pos) {
DCHECK_NOT_NULL(name); DCHECK_NOT_NULL(name);
VariableProxy* proxy = factory()->NewVariableProxy( VariableProxy* proxy = factory()->NewVariableProxy(
name, NORMAL_VARIABLE, scanner()->location().beg_pos); name, NORMAL_VARIABLE, scanner()->location().beg_pos);
...@@ -1415,24 +1459,25 @@ Declaration* Parser::DeclareVariable(const AstRawString* name, ...@@ -1415,24 +1459,25 @@ Declaration* Parser::DeclareVariable(const AstRawString* name,
} else { } else {
declaration = factory()->NewVariableDeclaration(proxy, pos); declaration = factory()->NewVariableDeclaration(proxy, pos);
} }
Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr, Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, nullptr,
scanner()->location().end_pos); scanner()->location().end_pos);
if (!*ok) return nullptr; if (scanner()->has_parser_error_set()) return nullptr;
return declaration; return declaration;
} }
Variable* Parser::Declare(Declaration* declaration, Variable* Parser::Declare(Declaration* declaration,
DeclarationDescriptor::Kind declaration_kind, DeclarationDescriptor::Kind declaration_kind,
VariableMode mode, InitializationFlag init, bool* ok, VariableMode mode, InitializationFlag init,
Scope* scope, int var_end_pos) { Scope* scope, int var_end_pos) {
bool local_ok = true;
if (scope == nullptr) { if (scope == nullptr) {
scope = this->scope(); scope = this->scope();
} }
bool sloppy_mode_block_scope_function_redefinition = false; bool sloppy_mode_block_scope_function_redefinition = false;
Variable* variable = scope->DeclareVariable( Variable* variable = scope->DeclareVariable(
declaration, mode, init, &sloppy_mode_block_scope_function_redefinition, declaration, mode, init, &sloppy_mode_block_scope_function_redefinition,
ok); &local_ok);
if (!*ok) { if (!local_ok | scanner()->has_parser_error_set()) {
// If we only have the start position of a proxy, we can't highlight the // If we only have the start position of a proxy, we can't highlight the
// whole variable name. Pretend its length is 1 so that we highlight at // whole variable name. Pretend its length is 1 so that we highlight at
// least the first character. // least the first character.
...@@ -1456,11 +1501,12 @@ Variable* Parser::Declare(Declaration* declaration, ...@@ -1456,11 +1501,12 @@ Variable* Parser::Declare(Declaration* declaration,
Block* Parser::BuildInitializationBlock( Block* Parser::BuildInitializationBlock(
DeclarationParsingResult* parsing_result, DeclarationParsingResult* parsing_result,
ZonePtrList<const AstRawString>* names, bool* ok) { ZonePtrList<const AstRawString>* names) {
Block* result = factory()->NewBlock(1, true); Block* result = factory()->NewBlock(1, true);
for (const auto& declaration : parsing_result->declarations) { for (const auto& declaration : parsing_result->declarations) {
DeclareAndInitializeVariables(result, &(parsing_result->descriptor), DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
&declaration, names, CHECK_OK); &declaration, names);
RETURN_IF_PARSE_ERROR;
} }
return result; return result;
} }
...@@ -1468,14 +1514,14 @@ Block* Parser::BuildInitializationBlock( ...@@ -1468,14 +1514,14 @@ Block* Parser::BuildInitializationBlock(
Statement* Parser::DeclareFunction(const AstRawString* variable_name, Statement* Parser::DeclareFunction(const AstRawString* variable_name,
FunctionLiteral* function, VariableMode mode, FunctionLiteral* function, VariableMode mode,
int pos, bool is_sloppy_block_function, int pos, bool is_sloppy_block_function,
ZonePtrList<const AstRawString>* names, ZonePtrList<const AstRawString>* names) {
bool* ok) {
VariableProxy* proxy = VariableProxy* proxy =
factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos); factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos);
Declaration* declaration = Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, function, pos); factory()->NewFunctionDeclaration(proxy, function, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized, Declare(declaration, DeclarationDescriptor::NORMAL, mode,
CHECK_OK); kCreatedInitialized);
RETURN_IF_PARSE_ERROR;
if (names) names->Add(variable_name, zone()); if (names) names->Add(variable_name, zone());
if (is_sloppy_block_function) { if (is_sloppy_block_function) {
SloppyBlockFunctionStatement* statement = SloppyBlockFunctionStatement* statement =
...@@ -1490,9 +1536,10 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name, ...@@ -1490,9 +1536,10 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
Statement* Parser::DeclareClass(const AstRawString* variable_name, Statement* Parser::DeclareClass(const AstRawString* variable_name,
Expression* value, Expression* value,
ZonePtrList<const AstRawString>* names, ZonePtrList<const AstRawString>* names,
int class_token_pos, int end_pos, bool* ok) { int class_token_pos, int end_pos) {
Declaration* decl = DeclareVariable(variable_name, VariableMode::kLet, Declaration* decl =
class_token_pos, CHECK_OK); DeclareVariable(variable_name, VariableMode::kLet, class_token_pos);
RETURN_IF_PARSE_ERROR;
decl->proxy()->var()->set_initializer_position(end_pos); decl->proxy()->var()->set_initializer_position(end_pos);
if (names) names->Add(variable_name, zone()); if (names) names->Add(variable_name, zone());
...@@ -1502,7 +1549,7 @@ Statement* Parser::DeclareClass(const AstRawString* variable_name, ...@@ -1502,7 +1549,7 @@ Statement* Parser::DeclareClass(const AstRawString* variable_name,
factory()->NewExpressionStatement(assignment, kNoSourcePosition)); factory()->NewExpressionStatement(assignment, kNoSourcePosition));
} }
Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) { Statement* Parser::DeclareNative(const AstRawString* name, int pos) {
// Make sure that the function containing the native declaration // Make sure that the function containing the native declaration
// isn't lazily compiled. The extension structures are only // isn't lazily compiled. The extension structures are only
// accessible while parsing the first time not when reparsing // accessible while parsing the first time not when reparsing
...@@ -1512,7 +1559,8 @@ Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) { ...@@ -1512,7 +1559,8 @@ Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
// TODO(1240846): It's weird that native function declarations are // TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas // introduced dynamically when we meet their declarations, whereas
// other functions are set up when entering the surrounding scope. // other functions are set up when entering the surrounding scope.
Declaration* decl = DeclareVariable(name, VariableMode::kVar, pos, CHECK_OK); Declaration* decl = DeclareVariable(name, VariableMode::kVar, pos);
RETURN_IF_PARSE_ERROR;
NativeFunctionLiteral* lit = NativeFunctionLiteral* lit =
factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
return factory()->NewExpressionStatement( return factory()->NewExpressionStatement(
...@@ -1523,7 +1571,7 @@ Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) { ...@@ -1523,7 +1571,7 @@ Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels, void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
ZonePtrList<const AstRawString>** own_labels, ZonePtrList<const AstRawString>** own_labels,
VariableProxy* var, bool* ok) { VariableProxy* var) {
DCHECK(IsIdentifier(var)); DCHECK(IsIdentifier(var));
const AstRawString* label = var->raw_name(); const AstRawString* label = var->raw_name();
...@@ -1534,7 +1582,6 @@ void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels, ...@@ -1534,7 +1582,6 @@ void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels,
// make later anyway so we should go back and fix this then. // make later anyway so we should go back and fix this then.
if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) { if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
ReportMessage(MessageTemplate::kLabelRedeclaration, label); ReportMessage(MessageTemplate::kLabelRedeclaration, label);
*ok = false;
return; return;
} }
...@@ -1603,11 +1650,10 @@ Expression* Parser::RewriteReturn(Expression* return_value, int pos) { ...@@ -1603,11 +1650,10 @@ Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
return return_value; return return_value;
} }
Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { Expression* Parser::RewriteDoExpression(Block* body, int pos) {
Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
DoExpression* expr = factory()->NewDoExpression(body, result, pos); DoExpression* expr = factory()->NewDoExpression(body, result, pos);
if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
*ok = false;
return nullptr; return nullptr;
} }
return expr; return expr;
...@@ -1651,7 +1697,7 @@ Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement, ...@@ -1651,7 +1697,7 @@ Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
return switch_block; return switch_block;
} }
void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { void Parser::RewriteCatchPattern(CatchInfo* catch_info) {
if (catch_info->name == nullptr) { if (catch_info->name == nullptr) {
DCHECK_NOT_NULL(catch_info->pattern); DCHECK_NOT_NULL(catch_info->pattern);
catch_info->name = ast_value_factory()->dot_catch_string(); catch_info->name = ast_value_factory()->dot_catch_string();
...@@ -1675,13 +1721,13 @@ void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { ...@@ -1675,13 +1721,13 @@ void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
catch_info->init_block = factory()->NewBlock(8, true); catch_info->init_block = factory()->NewBlock(8, true);
DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl, DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
&catch_info->bound_names, ok); &catch_info->bound_names);
} else { } else {
catch_info->bound_names.Add(catch_info->name, zone()); catch_info->bound_names.Add(catch_info->name, zone());
} }
} }
void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { void Parser::ValidateCatchBlock(const CatchInfo& catch_info) {
// Check for `catch(e) { let e; }` and similar errors. // Check for `catch(e) { let e; }` and similar errors.
Scope* inner_block_scope = catch_info.inner_block->scope(); Scope* inner_block_scope = catch_info.inner_block->scope();
if (inner_block_scope != nullptr) { if (inner_block_scope != nullptr) {
...@@ -1695,7 +1741,6 @@ void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { ...@@ -1695,7 +1741,6 @@ void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
? Scanner::Location::invalid() ? Scanner::Location::invalid()
: Scanner::Location(position, position + 1); : Scanner::Location(position, position + 1);
ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
*ok = false;
} }
} }
} }
...@@ -1737,18 +1782,17 @@ Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block, ...@@ -1737,18 +1782,17 @@ Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
} }
} }
void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, void Parser::ParseAndRewriteGeneratorFunctionBody(
ZonePtrList<Statement>* body, int pos, FunctionKind kind, ZonePtrList<Statement>* body) {
bool* ok) {
// For ES6 Generators, we just prepend the initial yield. // For ES6 Generators, we just prepend the initial yield.
Expression* initial_yield = BuildInitialYield(pos, kind); Expression* initial_yield = BuildInitialYield(pos, kind);
body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
zone()); zone());
ParseStatementList(body, Token::RBRACE, ok); ParseStatementList(body, Token::RBRACE, !scanner()->has_parser_error_set());
} }
void Parser::ParseAndRewriteAsyncGeneratorFunctionBody( void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
int pos, FunctionKind kind, ZonePtrList<Statement>* body, bool* ok) { int pos, FunctionKind kind, ZonePtrList<Statement>* body) {
// For ES2017 Async Generators, we produce: // For ES2017 Async Generators, we produce:
// //
// try { // try {
...@@ -1776,8 +1820,9 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody( ...@@ -1776,8 +1820,9 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
try_block->statements()->Add( try_block->statements()->Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
zone()); zone());
ParseStatementList(try_block->statements(), Token::RBRACE, ok); ParseStatementList(try_block->statements(), Token::RBRACE,
if (!*ok) return; !scanner()->has_parser_error_set());
RETURN_IF_PARSE_ERROR_VOID;
// Don't create iterator result for async generators, as the resume methods // Don't create iterator result for async generators, as the resume methods
// will create it. // will create it.
...@@ -1955,8 +2000,7 @@ Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) { ...@@ -1955,8 +2000,7 @@ Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
// } // }
void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
Block** body_block, Block** body_block,
Expression** each_variable, Expression** each_variable) {
bool* ok) {
DCHECK_EQ(1, for_info->parsing_result.declarations.size()); DCHECK_EQ(1, for_info->parsing_result.declarations.size());
DeclarationParsingResult::Declaration& decl = DeclarationParsingResult::Declaration& decl =
for_info->parsing_result.declarations[0]; for_info->parsing_result.declarations[0];
...@@ -1978,7 +2022,8 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, ...@@ -1978,7 +2022,8 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
DeclareAndInitializeVariables( DeclareAndInitializeVariables(
each_initialization_block, &descriptor, &decl, each_initialization_block, &descriptor, &decl,
collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID); collect_names ? &for_info->bound_names : nullptr);
RETURN_IF_PARSE_ERROR_VOID;
// Annex B.3.5 prohibits the form // Annex B.3.5 prohibits the form
// `try {} catch(e) { for (var e of {}); }` // `try {} catch(e) { for (var e of {}); }`
...@@ -1997,7 +2042,6 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, ...@@ -1997,7 +2042,6 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
for_info->bound_names.Contains(name)) { for_info->bound_names.Contains(name)) {
ReportMessageAt(for_info->parsing_result.bindings_loc, ReportMessageAt(for_info->parsing_result.bindings_loc,
MessageTemplate::kVarRedeclaration, name); MessageTemplate::kVarRedeclaration, name);
*ok = false;
return; return;
} }
} }
...@@ -2013,7 +2057,7 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, ...@@ -2013,7 +2057,7 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
// Create a TDZ for any lexically-bound names in for in/of statements. // Create a TDZ for any lexically-bound names in for in/of statements.
Block* Parser::CreateForEachStatementTDZ(Block* init_block, Block* Parser::CreateForEachStatementTDZ(Block* init_block,
const ForInfo& for_info, bool* ok) { const ForInfo& for_info) {
if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
DCHECK_NULL(init_block); DCHECK_NULL(init_block);
...@@ -2023,9 +2067,9 @@ Block* Parser::CreateForEachStatementTDZ(Block* init_block, ...@@ -2023,9 +2067,9 @@ Block* Parser::CreateForEachStatementTDZ(Block* init_block,
// TODO(adamk): This needs to be some sort of special // TODO(adamk): This needs to be some sort of special
// INTERNAL variable that's invisible to the debugger // INTERNAL variable that's invisible to the debugger
// but visible to everything else. // but visible to everything else.
Declaration* tdz_decl = Declaration* tdz_decl = DeclareVariable(
DeclareVariable(for_info.bound_names[i], VariableMode::kLet, for_info.bound_names[i], VariableMode::kLet, kNoSourcePosition);
kNoSourcePosition, CHECK_OK); RETURN_IF_PARSE_ERROR;
tdz_decl->proxy()->var()->set_initializer_position(position()); tdz_decl->proxy()->var()->set_initializer_position(position());
} }
} }
...@@ -2262,7 +2306,8 @@ Statement* Parser::DesugarLexicalBindingsInForStatement( ...@@ -2262,7 +2306,8 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
for (int i = 0; i < for_info.bound_names.length(); i++) { for (int i = 0; i < for_info.bound_names.length(); i++) {
Declaration* decl = DeclareVariable( Declaration* decl = DeclareVariable(
for_info.bound_names[i], for_info.parsing_result.descriptor.mode, for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
kNoSourcePosition, CHECK_OK); kNoSourcePosition);
RETURN_IF_PARSE_ERROR;
inner_vars.Add(decl->proxy()->var(), zone()); inner_vars.Add(decl->proxy()->var(), zone());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
Assignment* assignment = factory()->NewAssignment( Assignment* assignment = factory()->NewAssignment(
...@@ -2395,8 +2440,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement( ...@@ -2395,8 +2440,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
} }
void Parser::AddArrowFunctionFormalParameters( void Parser::AddArrowFunctionFormalParameters(
ParserFormalParameters* parameters, Expression* expr, int end_pos, ParserFormalParameters* parameters, Expression* expr, int end_pos) {
bool* ok) {
// ArrowFunctionFormals :: // ArrowFunctionFormals ::
// Nary(Token::COMMA, VariableProxy*, Tail) // Nary(Token::COMMA, VariableProxy*, Tail)
// Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
...@@ -2422,11 +2466,13 @@ void Parser::AddArrowFunctionFormalParameters( ...@@ -2422,11 +2466,13 @@ void Parser::AddArrowFunctionFormalParameters(
// the first child expression. // the first child expression.
Expression* next = nary->first(); Expression* next = nary->first();
for (size_t i = 0; i < nary->subsequent_length(); ++i) { for (size_t i = 0; i < nary->subsequent_length(); ++i) {
AddArrowFunctionFormalParameters( AddArrowFunctionFormalParameters(parameters, next,
parameters, next, nary->subsequent_op_position(i), CHECK_OK_VOID); nary->subsequent_op_position(i));
RETURN_IF_PARSE_ERROR_VOID;
next = nary->subsequent(i); next = nary->subsequent(i);
} }
AddArrowFunctionFormalParameters(parameters, next, end_pos, CHECK_OK_VOID); AddArrowFunctionFormalParameters(parameters, next, end_pos);
RETURN_IF_PARSE_ERROR_VOID;
return; return;
} }
...@@ -2440,8 +2486,8 @@ void Parser::AddArrowFunctionFormalParameters( ...@@ -2440,8 +2486,8 @@ void Parser::AddArrowFunctionFormalParameters(
Expression* left = binop->left(); Expression* left = binop->left();
Expression* right = binop->right(); Expression* right = binop->right();
int comma_pos = binop->position(); int comma_pos = binop->position();
AddArrowFunctionFormalParameters(parameters, left, comma_pos, AddArrowFunctionFormalParameters(parameters, left, comma_pos);
CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
// LHS of comma expression should be unparenthesized. // LHS of comma expression should be unparenthesized.
expr = right; expr = right;
} }
...@@ -2476,15 +2522,14 @@ void Parser::AddArrowFunctionFormalParameters( ...@@ -2476,15 +2522,14 @@ void Parser::AddArrowFunctionFormalParameters(
void Parser::DeclareArrowFunctionFormalParameters( void Parser::DeclareArrowFunctionFormalParameters(
ParserFormalParameters* parameters, Expression* expr, ParserFormalParameters* parameters, Expression* expr,
const Scanner::Location& params_loc, bool* ok) { const Scanner::Location& params_loc) {
if (expr->IsEmptyParentheses()) return; if (expr->IsEmptyParentheses()) return;
AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
if (parameters->arity > Code::kMaxArguments) { if (parameters->arity > Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
*ok = false;
return; return;
} }
...@@ -2505,7 +2550,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2505,7 +2550,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
LanguageMode language_mode, LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) { ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
// Function :: // Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}' // '(' FormalParameterList? ')' '{' FunctionBody '}'
// //
...@@ -2637,7 +2682,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2637,7 +2682,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
scope->SetScopeName(function_name); scope->SetScopeName(function_name);
#endif #endif
if (!is_wrapped) Expect(Token::LPAREN, CHECK_OK); if (!is_wrapped) {
Expect(Token::LPAREN);
RETURN_IF_PARSE_ERROR;
}
scope->set_start_position(position()); scope->set_start_position(position());
// Eager or lazy parse? If is_lazy_top_level_function, we'll parse // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
...@@ -2649,13 +2697,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2649,13 +2697,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
should_preparse && should_preparse &&
SkipFunction(function_name, kind, function_type, scope, &num_parameters, SkipFunction(function_name, kind, function_type, scope, &num_parameters,
&produced_preparsed_scope_data, is_lazy_top_level_function, &produced_preparsed_scope_data, is_lazy_top_level_function,
&eager_compile_hint, CHECK_OK); &eager_compile_hint);
RETURN_IF_PARSE_ERROR;
if (!did_preparse_successfully) { if (!did_preparse_successfully) {
should_post_parallel_task = false; should_post_parallel_task = false;
body = ParseFunction( body = ParseFunction(function_name, pos, kind, function_type, scope,
function_name, pos, kind, function_type, scope, &num_parameters, &num_parameters, &function_length,
&function_length, &has_duplicate_parameters, &expected_property_count, &has_duplicate_parameters, &expected_property_count,
&suspend_count, arguments_for_wrapped_function, CHECK_OK); &suspend_count, arguments_for_wrapped_function);
RETURN_IF_PARSE_ERROR;
} }
if (V8_UNLIKELY(FLAG_log_function_events)) { if (V8_UNLIKELY(FLAG_log_function_events)) {
...@@ -2684,13 +2734,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2684,13 +2734,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// since the function can declare itself strict. // since the function can declare itself strict.
language_mode = scope->language_mode(); language_mode = scope->language_mode();
CheckFunctionName(language_mode, function_name, function_name_validity, CheckFunctionName(language_mode, function_name, function_name_validity,
function_name_location, CHECK_OK); function_name_location);
RETURN_IF_PARSE_ERROR;
if (is_strict(language_mode)) { if (is_strict(language_mode)) {
CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
CHECK_OK); RETURN_IF_PARSE_ERROR;
} }
CheckConflictingVarDeclarations(scope, CHECK_OK); CheckConflictingVarDeclarations(scope);
RETURN_IF_PARSE_ERROR;
FunctionLiteral::ParameterFlag duplicate_parameters = FunctionLiteral::ParameterFlag duplicate_parameters =
has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
...@@ -2720,7 +2772,7 @@ bool Parser::SkipFunction( ...@@ -2720,7 +2772,7 @@ bool Parser::SkipFunction(
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters, DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data, bool may_abort, ProducedPreParsedScopeData** produced_preparsed_scope_data, bool may_abort,
FunctionLiteral::EagerCompileHint* hint, bool* ok) { FunctionLiteral::EagerCompileHint* hint) {
FunctionState function_state(&function_state_, &scope_, function_scope); FunctionState function_state(&function_state_, &scope_, function_scope);
function_scope->set_zone(&preparser_zone_); function_scope->set_zone(&preparser_zone_);
...@@ -2737,7 +2789,6 @@ bool Parser::SkipFunction( ...@@ -2737,7 +2789,6 @@ bool Parser::SkipFunction(
int num_inner_functions; int num_inner_functions;
bool uses_super_property; bool uses_super_property;
if (stack_overflow()) { if (stack_overflow()) {
*ok = false;
return true; return true;
} }
*produced_preparsed_scope_data = *produced_preparsed_scope_data =
...@@ -2750,7 +2801,8 @@ bool Parser::SkipFunction( ...@@ -2750,7 +2801,8 @@ bool Parser::SkipFunction(
function_scope->set_is_skipped_function(true); function_scope->set_is_skipped_function(true);
function_scope->set_end_position(end_position); function_scope->set_end_position(end_position);
scanner()->SeekForward(end_position - 1); scanner()->SeekForward(end_position - 1);
Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); Expect(Token::RBRACE);
RETURN_IF_PARSE_ERROR_VALUE(kLazyParsingComplete);
SetLanguageMode(function_scope, language_mode); SetLanguageMode(function_scope, language_mode);
if (uses_super_property) { if (uses_super_property) {
function_scope->RecordSuperPropertyUsage(); function_scope->RecordSuperPropertyUsage();
...@@ -2782,7 +2834,6 @@ bool Parser::SkipFunction( ...@@ -2782,7 +2834,6 @@ bool Parser::SkipFunction(
if (result == PreParser::kPreParseStackOverflow) { if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow. // Propagate stack overflow.
set_stack_overflow(); set_stack_overflow();
*ok = false;
} else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) { } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
// If we encounter an error that the preparser can not identify we reset to // If we encounter an error that the preparser can not identify we reset to
// the state before preparsing. The caller may then fully parse the function // the state before preparsing. The caller may then fully parse the function
...@@ -2792,13 +2843,14 @@ bool Parser::SkipFunction( ...@@ -2792,13 +2843,14 @@ bool Parser::SkipFunction(
pending_error_handler()->clear_unidentifiable_error(); pending_error_handler()->clear_unidentifiable_error();
return false; return false;
} else if (pending_error_handler()->has_pending_error()) { } else if (pending_error_handler()->has_pending_error()) {
*ok = false; DCHECK(scanner()->has_parser_error_set());
} else { } else {
set_allow_eval_cache(reusable_preparser()->allow_eval_cache()); set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
PreParserLogger* logger = reusable_preparser()->logger(); PreParserLogger* logger = reusable_preparser()->logger();
function_scope->set_end_position(logger->end()); function_scope->set_end_position(logger->end());
Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); Expect(Token::RBRACE);
RETURN_IF_PARSE_ERROR_VALUE(kLazyParsingComplete);
total_preparse_skipped_ += total_preparse_skipped_ +=
function_scope->end_position() - function_scope->start_position(); function_scope->end_position() - function_scope->start_position();
*num_parameters = logger->num_parameters(); *num_parameters = logger->num_parameters();
...@@ -2874,9 +2926,8 @@ void Parser::RewriteParameterInitializer(Expression* expr) { ...@@ -2874,9 +2926,8 @@ void Parser::RewriteParameterInitializer(Expression* expr) {
rewriter.Run(); rewriter.Run();
} }
Block* Parser::BuildParameterInitializationBlock( Block* Parser::BuildParameterInitializationBlock(
const ParserFormalParameters& parameters, bool* ok) { const ParserFormalParameters& parameters) {
DCHECK(!parameters.is_simple); DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope()); DCHECK(scope()->is_function_scope());
DCHECK_EQ(scope(), parameters.scope); DCHECK_EQ(scope(), parameters.scope);
...@@ -2932,13 +2983,14 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2932,13 +2983,14 @@ Block* Parser::BuildParameterInitializationBlock(
BlockState block_state(&scope_, param_scope); BlockState block_state(&scope_, param_scope);
DeclarationParsingResult::Declaration decl( DeclarationParsingResult::Declaration decl(
parameter->pattern, parameter->initializer_end_position, initial_value); parameter->pattern, parameter->initializer_end_position, initial_value);
DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr, DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr);
CHECK_OK); RETURN_IF_PARSE_ERROR;
if (param_block != init_block) { if (param_block != init_block) {
param_scope = param_scope->FinalizeBlockScope(); param_scope = param_scope->FinalizeBlockScope();
if (param_scope != nullptr) { if (param_scope != nullptr) {
CheckConflictingVarDeclarations(param_scope, CHECK_OK); CheckConflictingVarDeclarations(param_scope);
RETURN_IF_PARSE_ERROR;
} }
init_block->statements()->Add(param_block, zone()); init_block->statements()->Add(param_block, zone());
} }
...@@ -3006,7 +3058,7 @@ ZonePtrList<Statement>* Parser::ParseFunction( ...@@ -3006,7 +3058,7 @@ ZonePtrList<Statement>* Parser::ParseFunction(
DeclarationScope* function_scope, int* num_parameters, int* function_length, DeclarationScope* function_scope, int* num_parameters, int* function_length,
bool* has_duplicate_parameters, int* expected_property_count, bool* has_duplicate_parameters, int* expected_property_count,
int* suspend_count, int* suspend_count,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) { ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
FunctionState function_state(&function_state_, &scope_, function_scope); FunctionState function_state(&function_state_, &scope_, function_scope);
...@@ -3043,7 +3095,8 @@ ZonePtrList<Statement>* Parser::ParseFunction( ...@@ -3043,7 +3095,8 @@ ZonePtrList<Statement>* Parser::ParseFunction(
} else { } else {
// For a regular function, the function arguments are parsed from source. // For a regular function, the function arguments are parsed from source.
DCHECK_NULL(arguments_for_wrapped_function); DCHECK_NULL(arguments_for_wrapped_function);
ParseFormalParameterList(&formals, CHECK_OK); ParseFormalParameterList(&formals);
RETURN_IF_PARSE_ERROR;
if (expected_parameters_end_pos != kNoSourcePosition) { if (expected_parameters_end_pos != kNoSourcePosition) {
// Check for '(' or ')' shenanigans in the parameter string for dynamic // Check for '(' or ')' shenanigans in the parameter string for dynamic
// functions. // functions.
...@@ -3051,30 +3104,31 @@ ZonePtrList<Statement>* Parser::ParseFunction( ...@@ -3051,30 +3104,31 @@ ZonePtrList<Statement>* Parser::ParseFunction(
if (position < expected_parameters_end_pos) { if (position < expected_parameters_end_pos) {
ReportMessageAt(Scanner::Location(position, position + 1), ReportMessageAt(Scanner::Location(position, position + 1),
MessageTemplate::kArgStringTerminatesParametersEarly); MessageTemplate::kArgStringTerminatesParametersEarly);
*ok = false;
return nullptr; return nullptr;
} else if (position > expected_parameters_end_pos) { } else if (position > expected_parameters_end_pos) {
ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2, ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
expected_parameters_end_pos), expected_parameters_end_pos),
MessageTemplate::kUnexpectedEndOfArgString); MessageTemplate::kUnexpectedEndOfArgString);
*ok = false;
return nullptr; return nullptr;
} }
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN);
RETURN_IF_PARSE_ERROR;
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions(formals.arity, kind, formals.has_rest, CheckArityRestrictions(formals.arity, kind, formals.has_rest,
function_scope->start_position(), function_scope->start_position(),
formals_end_position, CHECK_OK); formals_end_position);
Expect(Token::LBRACE, CHECK_OK); RETURN_IF_PARSE_ERROR;
Expect(Token::LBRACE);
RETURN_IF_PARSE_ERROR;
} }
*num_parameters = formals.num_parameters(); *num_parameters = formals.num_parameters();
*function_length = formals.function_length; *function_length = formals.function_length;
ZonePtrList<Statement>* body = new (zone()) ZonePtrList<Statement>(8, zone()); ZonePtrList<Statement>* body = new (zone()) ZonePtrList<Statement>(8, zone());
ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
FunctionBodyType::kBlock, true, ok); FunctionBodyType::kBlock, true);
RewriteDestructuringAssignments(); RewriteDestructuringAssignments();
...@@ -3087,8 +3141,7 @@ ZonePtrList<Statement>* Parser::ParseFunction( ...@@ -3087,8 +3141,7 @@ ZonePtrList<Statement>* Parser::ParseFunction(
} }
void Parser::DeclareClassVariable(const AstRawString* name, void Parser::DeclareClassVariable(const AstRawString* name,
ClassInfo* class_info, int class_token_pos, ClassInfo* class_info, int class_token_pos) {
bool* ok) {
#ifdef DEBUG #ifdef DEBUG
scope()->SetScopeName(name); scope()->SetScopeName(name);
#endif #endif
...@@ -3099,21 +3152,21 @@ void Parser::DeclareClassVariable(const AstRawString* name, ...@@ -3099,21 +3152,21 @@ void Parser::DeclareClassVariable(const AstRawString* name,
factory()->NewVariableDeclaration(proxy, class_token_pos); factory()->NewVariableDeclaration(proxy, class_token_pos);
class_info->variable = Declare( class_info->variable = Declare(
declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst, declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
Variable::DefaultInitializationFlag(VariableMode::kConst), ok); Variable::DefaultInitializationFlag(VariableMode::kConst));
} }
} }
// TODO(gsathya): Ideally, this should just bypass scope analysis and // TODO(gsathya): Ideally, this should just bypass scope analysis and
// allocate a slot directly on the context. We should just store this // allocate a slot directly on the context. We should just store this
// index in the AST, instead of storing the variable. // index in the AST, instead of storing the variable.
Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name, Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
bool* ok) {
VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
Declaration* declaration = Declaration* declaration =
factory()->NewVariableDeclaration(proxy, kNoSourcePosition); factory()->NewVariableDeclaration(proxy, kNoSourcePosition);
Variable* var = Declare( Variable* var =
declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst, Declare(declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst,
Variable::DefaultInitializationFlag(VariableMode::kConst), CHECK_OK); Variable::DefaultInitializationFlag(VariableMode::kConst));
RETURN_IF_PARSE_ERROR;
var->ForceContextAllocation(); var->ForceContextAllocation();
return var; return var;
} }
...@@ -3128,7 +3181,7 @@ void Parser::DeclareClassProperty(const AstRawString* class_name, ...@@ -3128,7 +3181,7 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
ClassLiteralProperty::Kind kind, ClassLiteralProperty::Kind kind,
bool is_static, bool is_constructor, bool is_static, bool is_constructor,
bool is_computed_name, bool is_private, bool is_computed_name, bool is_private,
ClassInfo* class_info, bool* ok) { ClassInfo* class_info) {
if (is_constructor) { if (is_constructor) {
DCHECK(!class_info->constructor); DCHECK(!class_info->constructor);
class_info->constructor = property->value()->AsFunctionLiteral(); class_info->constructor = property->value()->AsFunctionLiteral();
...@@ -3160,17 +3213,18 @@ void Parser::DeclareClassProperty(const AstRawString* class_name, ...@@ -3160,17 +3213,18 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
DCHECK(!is_private); DCHECK(!is_private);
// We create a synthetic variable name here so that scope // We create a synthetic variable name here so that scope
// analysis doesn't dedupe the vars. // analysis doesn't dedupe the vars.
Variable* computed_name_var = CreateSyntheticContextVariable( Variable* computed_name_var =
ClassFieldVariableName(ast_value_factory(), CreateSyntheticContextVariable(ClassFieldVariableName(
class_info->computed_field_count), ast_value_factory(), class_info->computed_field_count));
CHECK_OK_VOID); RETURN_IF_PARSE_ERROR_VOID;
property->set_computed_name_var(computed_name_var); property->set_computed_name_var(computed_name_var);
class_info->properties->Add(property, zone()); class_info->properties->Add(property, zone());
} }
if (kind == ClassLiteralProperty::FIELD && is_private) { if (kind == ClassLiteralProperty::FIELD && is_private) {
Variable* private_field_name_var = Variable* private_field_name_var =
CreateSyntheticContextVariable(property_name, CHECK_OK_VOID); CreateSyntheticContextVariable(property_name);
RETURN_IF_PARSE_ERROR_VOID;
property->set_private_field_name_var(private_field_name_var); property->set_private_field_name_var(private_field_name_var);
class_info->properties->Add(property, zone()); class_info->properties->Add(property, zone());
} }
...@@ -3205,7 +3259,7 @@ FunctionLiteral* Parser::CreateInitializerFunction( ...@@ -3205,7 +3259,7 @@ FunctionLiteral* Parser::CreateInitializerFunction(
Expression* Parser::RewriteClassLiteral(Scope* block_scope, Expression* Parser::RewriteClassLiteral(Scope* block_scope,
const AstRawString* name, const AstRawString* name,
ClassInfo* class_info, int pos, ClassInfo* class_info, int pos,
int end_pos, bool* ok) { int end_pos) {
DCHECK_NOT_NULL(block_scope); DCHECK_NOT_NULL(block_scope);
DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE); DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict); DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
...@@ -3248,7 +3302,7 @@ Expression* Parser::RewriteClassLiteral(Scope* block_scope, ...@@ -3248,7 +3302,7 @@ Expression* Parser::RewriteClassLiteral(Scope* block_scope,
return class_literal; return class_literal;
} }
void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { void Parser::CheckConflictingVarDeclarations(Scope* scope) {
Declaration* decl = scope->CheckConflictingVarDeclarations(); Declaration* decl = scope->CheckConflictingVarDeclarations();
if (decl != nullptr) { if (decl != nullptr) {
// In ES6, conflicting variable bindings are early errors. // In ES6, conflicting variable bindings are early errors.
...@@ -3259,7 +3313,6 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { ...@@ -3259,7 +3313,6 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
? Scanner::Location::invalid() ? Scanner::Location::invalid()
: Scanner::Location(position, position + 1); : Scanner::Location(position, position + 1);
ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
*ok = false;
} }
} }
...@@ -3320,9 +3373,7 @@ bool Parser::TargetStackContainsLabel(const AstRawString* label) { ...@@ -3320,9 +3373,7 @@ bool Parser::TargetStackContainsLabel(const AstRawString* label) {
return false; return false;
} }
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label) {
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
bool* ok) {
bool anonymous = label == nullptr; bool anonymous = label == nullptr;
for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) { for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
BreakableStatement* stat = t->statement(); BreakableStatement* stat = t->statement();
...@@ -3334,9 +3385,7 @@ BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, ...@@ -3334,9 +3385,7 @@ BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
return nullptr; return nullptr;
} }
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label) {
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
bool* ok) {
bool anonymous = label == nullptr; bool anonymous = label == nullptr;
for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) { for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
IterationStatement* stat = t->statement()->AsIterationStatement(); IterationStatement* stat = t->statement()->AsIterationStatement();
...@@ -3351,7 +3400,6 @@ IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, ...@@ -3351,7 +3400,6 @@ IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
return nullptr; return nullptr;
} }
void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
Handle<String> source_url = scanner_.SourceUrl(isolate); Handle<String> source_url = scanner_.SourceUrl(isolate);
if (!source_url.is_null()) { if (!source_url.is_null()) {
...@@ -3583,8 +3631,7 @@ Expression* Parser::ExpressionListToExpression( ...@@ -3583,8 +3631,7 @@ Expression* Parser::ExpressionListToExpression(
// This method completes the desugaring of the body of async_function. // This method completes the desugaring of the body of async_function.
void Parser::RewriteAsyncFunctionBody(ZonePtrList<Statement>* body, void Parser::RewriteAsyncFunctionBody(ZonePtrList<Statement>* body,
Block* block, Expression* return_value, Block* block, Expression* return_value) {
bool* ok) {
// function async_function() { // function async_function() {
// .generator_object = %_AsyncFunctionEnter(); // .generator_object = %_AsyncFunctionEnter();
// BuildRejectPromiseOnException({ // BuildRejectPromiseOnException({
...@@ -4141,9 +4188,8 @@ Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, ...@@ -4141,9 +4188,8 @@ Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
return final_loop; return final_loop;
} }
#undef CHECK_OK #undef RETURN_IF_PARSE_ERROR_VOID
#undef CHECK_OK_VOID #undef RETURN_IF_PARSE_ERROR
#undef CHECK_FAILED #undef RETURN_IF_PARSE_ERROR_VALUE
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -270,20 +270,20 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -270,20 +270,20 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return reusable_preparser_; return reusable_preparser_;
} }
void ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok); void ParseModuleItemList(ZonePtrList<Statement>* body);
Statement* ParseModuleItem(bool* ok); Statement* ParseModuleItem();
const AstRawString* ParseModuleSpecifier(bool* ok); const AstRawString* ParseModuleSpecifier();
void ParseImportDeclaration(bool* ok); void ParseImportDeclaration();
Statement* ParseExportDeclaration(bool* ok); Statement* ParseExportDeclaration();
Statement* ParseExportDefault(bool* ok); Statement* ParseExportDefault();
void ParseExportStar(bool* ok); void ParseExportStar();
struct ExportClauseData { struct ExportClauseData {
const AstRawString* export_name; const AstRawString* export_name;
const AstRawString* local_name; const AstRawString* local_name;
Scanner::Location location; Scanner::Location location;
}; };
ZoneChunkList<ExportClauseData>* ParseExportClause( ZoneChunkList<ExportClauseData>* ParseExportClause(
Scanner::Location* reserved_loc, bool* ok); Scanner::Location* reserved_loc);
struct NamedImport : public ZoneObject { struct NamedImport : public ZoneObject {
const AstRawString* import_name; const AstRawString* import_name;
const AstRawString* local_name; const AstRawString* local_name;
...@@ -294,20 +294,19 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -294,20 +294,19 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
local_name(local_name), local_name(local_name),
location(location) {} location(location) {}
}; };
ZonePtrList<const NamedImport>* ParseNamedImports(int pos, bool* ok); ZonePtrList<const NamedImport>* ParseNamedImports(int pos);
Block* BuildInitializationBlock(DeclarationParsingResult* parsing_result, Block* BuildInitializationBlock(DeclarationParsingResult* parsing_result,
ZonePtrList<const AstRawString>* names, ZonePtrList<const AstRawString>* names);
bool* ok);
void DeclareLabel(ZonePtrList<const AstRawString>** labels, void DeclareLabel(ZonePtrList<const AstRawString>** labels,
ZonePtrList<const AstRawString>** own_labels, ZonePtrList<const AstRawString>** own_labels,
VariableProxy* expr, bool* ok); VariableProxy* expr);
bool ContainsLabel(ZonePtrList<const AstRawString>* labels, bool ContainsLabel(ZonePtrList<const AstRawString>* labels,
const AstRawString* label); const AstRawString* label);
Expression* RewriteReturn(Expression* return_value, int pos); Expression* RewriteReturn(Expression* return_value, int pos);
Statement* RewriteSwitchStatement(SwitchStatement* switch_statement, Statement* RewriteSwitchStatement(SwitchStatement* switch_statement,
Scope* scope); Scope* scope);
void RewriteCatchPattern(CatchInfo* catch_info, bool* ok); void RewriteCatchPattern(CatchInfo* catch_info);
void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok); void ValidateCatchBlock(const CatchInfo& catch_info);
Statement* RewriteTryStatement(Block* try_block, Block* catch_block, Statement* RewriteTryStatement(Block* try_block, Block* catch_block,
const SourceRange& catch_range, const SourceRange& catch_range,
Block* finally_block, Block* finally_block,
...@@ -316,11 +315,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -316,11 +315,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void GetUnexpectedTokenMessage(Token::Value token, MessageTemplate* message, void GetUnexpectedTokenMessage(Token::Value token, MessageTemplate* message,
Scanner::Location* location, const char** arg); Scanner::Location* location, const char** arg);
void ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, void ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
ZonePtrList<Statement>* body, ZonePtrList<Statement>* body);
bool* ok);
void ParseAndRewriteAsyncGeneratorFunctionBody(int pos, FunctionKind kind, void ParseAndRewriteAsyncGeneratorFunctionBody(int pos, FunctionKind kind,
ZonePtrList<Statement>* body, ZonePtrList<Statement>* body);
bool* ok);
void DeclareFunctionNameVar(const AstRawString* function_name, void DeclareFunctionNameVar(const AstRawString* function_name,
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope); DeclarationScope* function_scope);
...@@ -328,32 +325,30 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -328,32 +325,30 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Statement* DeclareFunction(const AstRawString* variable_name, Statement* DeclareFunction(const AstRawString* variable_name,
FunctionLiteral* function, VariableMode mode, FunctionLiteral* function, VariableMode mode,
int pos, bool is_sloppy_block_function, int pos, bool is_sloppy_block_function,
ZonePtrList<const AstRawString>* names, bool* ok); ZonePtrList<const AstRawString>* names);
Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name, Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name);
bool* ok);
FunctionLiteral* CreateInitializerFunction( FunctionLiteral* CreateInitializerFunction(
const char* name, DeclarationScope* scope, const char* name, DeclarationScope* scope,
ZonePtrList<ClassLiteral::Property>* fields); ZonePtrList<ClassLiteral::Property>* fields);
V8_INLINE Statement* DeclareClass(const AstRawString* variable_name, V8_INLINE Statement* DeclareClass(const AstRawString* variable_name,
Expression* value, Expression* value,
ZonePtrList<const AstRawString>* names, ZonePtrList<const AstRawString>* names,
int class_token_pos, int end_pos, bool* ok); int class_token_pos, int end_pos);
V8_INLINE void DeclareClassVariable(const AstRawString* name, V8_INLINE void DeclareClassVariable(const AstRawString* name,
ClassInfo* class_info, ClassInfo* class_info,
int class_token_pos, bool* ok); int class_token_pos);
V8_INLINE void DeclareClassProperty(const AstRawString* class_name, V8_INLINE void DeclareClassProperty(const AstRawString* class_name,
ClassLiteralProperty* property, ClassLiteralProperty* property,
const AstRawString* property_name, const AstRawString* property_name,
ClassLiteralProperty::Kind kind, ClassLiteralProperty::Kind kind,
bool is_static, bool is_constructor, bool is_static, bool is_constructor,
bool is_computed_name, bool is_private, bool is_computed_name, bool is_private,
ClassInfo* class_info, bool* ok); ClassInfo* class_info);
V8_INLINE Expression* RewriteClassLiteral(Scope* block_scope, V8_INLINE Expression* RewriteClassLiteral(Scope* block_scope,
const AstRawString* name, const AstRawString* name,
ClassInfo* class_info, int pos, ClassInfo* class_info, int pos,
int end_pos, bool* ok); int end_pos);
V8_INLINE Statement* DeclareNative(const AstRawString* name, int pos, V8_INLINE Statement* DeclareNative(const AstRawString* name, int pos);
bool* ok);
V8_INLINE Block* IgnoreCompletion(Statement* statement); V8_INLINE Block* IgnoreCompletion(Statement* statement);
...@@ -364,7 +359,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -364,7 +359,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void DeclareAndInitializeVariables( void DeclareAndInitializeVariables(
Block* block, const DeclarationDescriptor* declaration_descriptor, Block* block, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok); ZonePtrList<const AstRawString>* names);
void RewriteDestructuringAssignment(RewritableExpression* expr); void RewriteDestructuringAssignment(RewritableExpression* expr);
Expression* RewriteDestructuringAssignment(Assignment* assignment); Expression* RewriteDestructuringAssignment(Assignment* assignment);
...@@ -390,23 +385,21 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -390,23 +385,21 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Block* RewriteForVarInLegacy(const ForInfo& for_info); Block* RewriteForVarInLegacy(const ForInfo& for_info);
void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block, void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
Expression** each_variable, bool* ok); Expression** each_variable);
Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info, Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info);
bool* ok);
Statement* DesugarLexicalBindingsInForStatement( Statement* DesugarLexicalBindingsInForStatement(
ForStatement* loop, Statement* init, Expression* cond, Statement* next, ForStatement* loop, Statement* init, Expression* cond, Statement* next,
Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok); Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok);
Expression* RewriteDoExpression(Block* body, int pos, bool* ok); Expression* RewriteDoExpression(Block* body, int pos);
FunctionLiteral* ParseFunctionLiteral( FunctionLiteral* ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location, const AstRawString* name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
bool* ok);
ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) { ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) {
object_literal->CalculateEmitStore(main_zone()); object_literal->CalculateEmitStore(main_zone());
...@@ -422,7 +415,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -422,7 +415,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// The var declarations are hoisted to the function scope, but originate from // The var declarations are hoisted to the function scope, but originate from
// a scope where the name has also been let bound or the var declaration is // a scope where the name has also been let bound or the var declaration is
// hoisted over such a scope. // hoisted over such a scope.
void CheckConflictingVarDeclarations(Scope* scope, bool* ok); void CheckConflictingVarDeclarations(Scope* scope);
bool IsPropertyWithPrivateFieldKey(Expression* property); bool IsPropertyWithPrivateFieldKey(Expression* property);
...@@ -438,17 +431,17 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -438,17 +431,17 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
VariableProxy* NewUnresolved(const AstRawString* name); VariableProxy* NewUnresolved(const AstRawString* name);
Variable* Declare(Declaration* declaration, Variable* Declare(Declaration* declaration,
DeclarationDescriptor::Kind declaration_kind, DeclarationDescriptor::Kind declaration_kind,
VariableMode mode, InitializationFlag init, bool* ok, VariableMode mode, InitializationFlag init,
Scope* declaration_scope = nullptr, Scope* declaration_scope = nullptr,
int var_end_pos = kNoSourcePosition); int var_end_pos = kNoSourcePosition);
Declaration* DeclareVariable(const AstRawString* name, VariableMode mode, Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
int pos, bool* ok); int pos);
Declaration* DeclareVariable(const AstRawString* name, VariableMode mode, Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
InitializationFlag init, int pos, bool* ok); InitializationFlag init, int pos);
bool TargetStackContainsLabel(const AstRawString* label); bool TargetStackContainsLabel(const AstRawString* label);
BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok); BreakableStatement* LookupBreakTarget(const AstRawString* label);
IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok); IterationStatement* LookupContinueTarget(const AstRawString* label);
Statement* BuildAssertIsCoercible(Variable* var, ObjectLiteral* pattern); Statement* BuildAssertIsCoercible(Variable* var, ObjectLiteral* pattern);
...@@ -471,11 +464,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -471,11 +464,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters, DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data, ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool may_abort, FunctionLiteral::EagerCompileHint* hint, bool may_abort, FunctionLiteral::EagerCompileHint* hint);
bool* ok);
Block* BuildParameterInitializationBlock( Block* BuildParameterInitializationBlock(
const ParserFormalParameters& parameters, bool* ok); const ParserFormalParameters& parameters);
Block* BuildRejectPromiseOnException(Block* block); Block* BuildRejectPromiseOnException(Block* block);
ZonePtrList<Statement>* ParseFunction( ZonePtrList<Statement>* ParseFunction(
...@@ -484,8 +476,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -484,8 +476,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
DeclarationScope* function_scope, int* num_parameters, DeclarationScope* function_scope, int* num_parameters,
int* function_length, bool* has_duplicate_parameters, int* function_length, bool* has_duplicate_parameters,
int* expected_property_count, int* suspend_count, int* expected_property_count, int* suspend_count,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
bool* ok);
void ThrowPendingError(Isolate* isolate, Handle<Script> script); void ThrowPendingError(Isolate* isolate, Handle<Script> script);
...@@ -583,11 +574,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -583,11 +574,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
V8_INLINE void RewriteAsyncFunctionBody(ZonePtrList<Statement>* body, V8_INLINE void RewriteAsyncFunctionBody(ZonePtrList<Statement>* body,
Block* block, Block* block,
Expression* return_value, bool* ok); Expression* return_value);
void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters, void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
Expression* params, int end_pos, Expression* params, int end_pos);
bool* ok);
void SetFunctionName(Expression* value, const AstRawString* name, void SetFunctionName(Expression* value, const AstRawString* name,
const AstRawString* prefix = nullptr); const AstRawString* prefix = nullptr);
...@@ -802,6 +792,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -802,6 +792,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
pending_error_handler()->ReportMessageAt(source_location.beg_pos, pending_error_handler()->ReportMessageAt(source_location.beg_pos,
source_location.end_pos, message, source_location.end_pos, message,
arg, error_type); arg, error_type);
scanner_.set_parser_error();
} }
// Dummy implementation. The parser should never have a unidentifiable // Dummy implementation. The parser should never have a unidentifiable
...@@ -821,6 +812,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -821,6 +812,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
pending_error_handler()->ReportMessageAt(source_location.beg_pos, pending_error_handler()->ReportMessageAt(source_location.beg_pos,
source_location.end_pos, message, source_location.end_pos, message,
arg, error_type); arg, error_type);
scanner_.set_parser_error();
} }
// "null" return type creators. // "null" return type creators.
...@@ -901,7 +893,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -901,7 +893,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
V8_INLINE Expression* NewV8Intrinsic(const AstRawString* name, V8_INLINE Expression* NewV8Intrinsic(const AstRawString* name,
const ScopedPtrList<Expression>& args, const ScopedPtrList<Expression>& args,
int pos, bool* ok); int pos);
V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) { V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
return factory()->NewExpressionStatement( return factory()->NewExpressionStatement(
...@@ -950,10 +942,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -950,10 +942,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
} }
} }
void DeclareArrowFunctionFormalParameters(ParserFormalParameters* parameters, void DeclareArrowFunctionFormalParameters(
Expression* params, ParserFormalParameters* parameters, Expression* params,
const Scanner::Location& params_loc, const Scanner::Location& params_loc);
bool* ok);
Expression* ExpressionListToExpression(const ScopedPtrList<Expression>& args); Expression* ExpressionListToExpression(const ScopedPtrList<Expression>& args);
......
...@@ -29,7 +29,7 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -29,7 +29,7 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
Parser* parser, Block* block, Parser* parser, Block* block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const Parser::DeclarationParsingResult::Declaration* declaration, const Parser::DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok); ZonePtrList<const AstRawString>* names);
static Expression* RewriteDestructuringAssignment(Parser* parser, static Expression* RewriteDestructuringAssignment(Parser* parser,
Assignment* to_rewrite, Assignment* to_rewrite,
...@@ -50,7 +50,6 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -50,7 +50,6 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
descriptor_(descriptor), descriptor_(descriptor),
names_(names), names_(names),
current_value_(nullptr), current_value_(nullptr),
ok_(nullptr),
initializer_position_(initializer_position), initializer_position_(initializer_position),
value_beg_position_(value_beg_position), value_beg_position_(value_beg_position),
context_(context), context_(context),
...@@ -122,7 +121,6 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -122,7 +121,6 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
const DeclarationDescriptor* descriptor_; const DeclarationDescriptor* descriptor_;
ZonePtrList<const AstRawString>* names_; ZonePtrList<const AstRawString>* names_;
Expression* current_value_; Expression* current_value_;
bool* ok_;
const int initializer_position_; const int initializer_position_;
const int value_beg_position_; const int value_beg_position_;
PatternContext context_; PatternContext context_;
...@@ -135,9 +133,9 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -135,9 +133,9 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
void Parser::DeclareAndInitializeVariables( void Parser::DeclareAndInitializeVariables(
Block* block, const DeclarationDescriptor* declaration_descriptor, Block* block, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok) { ZonePtrList<const AstRawString>* names) {
PatternRewriter::DeclareAndInitializeVariables( PatternRewriter::DeclareAndInitializeVariables(
this, block, declaration_descriptor, declaration, names, ok); this, block, declaration_descriptor, declaration, names);
} }
void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) { void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) {
...@@ -159,7 +157,7 @@ void PatternRewriter::DeclareAndInitializeVariables( ...@@ -159,7 +157,7 @@ void PatternRewriter::DeclareAndInitializeVariables(
Parser* parser, Block* block, Parser* parser, Block* block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const Parser::DeclarationParsingResult::Declaration* declaration, const Parser::DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok) { ZonePtrList<const AstRawString>* names) {
DCHECK(block->ignore_completion_value()); DCHECK(block->ignore_completion_value());
Scope* scope = declaration_descriptor->scope; Scope* scope = declaration_descriptor->scope;
...@@ -170,7 +168,6 @@ void PatternRewriter::DeclareAndInitializeVariables( ...@@ -170,7 +168,6 @@ void PatternRewriter::DeclareAndInitializeVariables(
DeclarationDescriptor::PARAMETER && DeclarationDescriptor::PARAMETER &&
scope->is_block_scope()); scope->is_block_scope());
rewriter.block_ = block; rewriter.block_ = block;
rewriter.ok_ = ok;
rewriter.RecurseIntoSubpattern(declaration->pattern, rewriter.RecurseIntoSubpattern(declaration->pattern,
declaration->initializer); declaration->initializer);
...@@ -199,7 +196,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { ...@@ -199,7 +196,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
DCHECK_NOT_NULL(block_); DCHECK_NOT_NULL(block_);
DCHECK_NOT_NULL(descriptor_); DCHECK_NOT_NULL(descriptor_);
DCHECK_NOT_NULL(ok_);
Scope* outer_function_scope = nullptr; Scope* outer_function_scope = nullptr;
bool success; bool success;
...@@ -239,9 +235,9 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { ...@@ -239,9 +235,9 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
// scope which will be used for the initializer expression. // scope which will be used for the initializer expression.
Variable* var = parser_->Declare( Variable* var = parser_->Declare(
declaration, descriptor_->declaration_kind, descriptor_->mode, declaration, descriptor_->declaration_kind, descriptor_->mode,
Variable::DefaultInitializationFlag(descriptor_->mode), ok_, Variable::DefaultInitializationFlag(descriptor_->mode),
outer_function_scope); outer_function_scope);
if (!*ok_) return; if (parser_->scanner_.has_parser_error_set()) return;
DCHECK_NOT_NULL(var); DCHECK_NOT_NULL(var);
DCHECK(proxy->is_resolved()); DCHECK(proxy->is_resolved());
DCHECK_NE(initializer_position_, kNoSourcePosition); DCHECK_NE(initializer_position_, kNoSourcePosition);
...@@ -254,7 +250,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { ...@@ -254,7 +250,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
: scope()->GetDeclarationScope()); : scope()->GetDeclarationScope());
if (declaration_scope->num_var() > kMaxNumFunctionLocals) { if (declaration_scope->num_var() > kMaxNumFunctionLocals) {
parser_->ReportMessage(MessageTemplate::kTooManyVariables); parser_->ReportMessage(MessageTemplate::kTooManyVariables);
*ok_ = false;
return; return;
} }
if (names_) { if (names_) {
......
...@@ -19,21 +19,23 @@ namespace v8 { ...@@ -19,21 +19,23 @@ namespace v8 {
namespace internal { namespace internal {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error // The RETURN_IF_PARSE_ERROR macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok). // handling for functions that may fail (by returning if there was an parser
// error scanner()->has_parser_error_set).
// //
// CAUTION: This macro appends extra statements after a call, // Usage:
// thus it must never be used where only a single statement // foo = ParseFoo(); // may fail
// is correct (e.g. an if statement branch w/o braces)! // RETURN_IF_PARSE_ERROR
//
// SAFE_USE(foo);
#define CHECK_OK_VALUE(x) ok); \ #define RETURN_IF_PARSE_ERROR_VALUE(x) \
if (!*ok) return x; \ if (scanner()->has_parser_error_set()) { \
((void)0 return x; \
#define DUMMY ) // to make indentation work }
#undef DUMMY
#define CHECK_OK CHECK_OK_VALUE(Expression::Default()) #define RETURN_IF_PARSE_ERROR RETURN_IF_PARSE_ERROR_VALUE(Expression::Default())
#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void()) #define RETURN_IF_PARSE_ERROR_VOID RETURN_IF_PARSE_ERROR_VALUE(this->Void())
namespace { namespace {
...@@ -101,13 +103,14 @@ PreParser::PreParseResult PreParser::PreParseProgram() { ...@@ -101,13 +103,14 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
bool ok = true; bool ok = true;
int start_position = scanner()->peek_location().beg_pos; int start_position = scanner()->peek_location().beg_pos;
PreParserStatementList body; PreParserStatementList body;
ParseStatementList(body, Token::EOS, &ok); ParseStatementList(body, Token::EOS);
ok = !scanner()->has_parser_error_set();
original_scope_ = nullptr; original_scope_ = nullptr;
if (stack_overflow()) return kPreParseStackOverflow; if (stack_overflow()) return kPreParseStackOverflow;
if (!ok) { if (!ok) {
ReportUnexpectedToken(scanner()->current_token()); ReportUnexpectedToken(scanner()->current_token());
} else if (is_strict(language_mode())) { } else if (is_strict(language_mode())) {
CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, &ok); CheckStrictOctalLiteral(start_position, scanner()->location().end_pos);
} }
return kPreParseSuccess; return kPreParseSuccess;
} }
...@@ -145,9 +148,6 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -145,9 +148,6 @@ PreParser::PreParseResult PreParser::PreParseFunction(
DCHECK_NULL(function_state_); DCHECK_NULL(function_state_);
DCHECK_NULL(scope_); DCHECK_NULL(scope_);
FunctionState function_state(&function_state_, &scope_, function_scope); FunctionState function_state(&function_state_, &scope_, function_scope);
// This indirection is needed so that we can use the CHECK_OK macros.
bool ok_holder = true;
bool* ok = &ok_holder;
PreParserFormalParameters formals(function_scope); PreParserFormalParameters formals(function_scope);
std::unique_ptr<ExpressionClassifier> formals_classifier; std::unique_ptr<ExpressionClassifier> formals_classifier;
...@@ -158,21 +158,23 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -158,21 +158,23 @@ PreParser::PreParseResult PreParser::PreParseFunction(
formals_classifier.reset(new ExpressionClassifier(this)); formals_classifier.reset(new ExpressionClassifier(this));
// We return kPreParseSuccess in failure cases too - errors are retrieved // We return kPreParseSuccess in failure cases too - errors are retrieved
// separately by Parser::SkipLazyFunctionBody. // separately by Parser::SkipLazyFunctionBody.
ParseFormalParameterList( ParseFormalParameterList(&formals);
&formals, RETURN_IF_PARSE_ERROR_VALUE(
CHECK_OK_VALUE(
pending_error_handler()->has_error_unidentifiable_by_preparser() pending_error_handler()->has_error_unidentifiable_by_preparser()
? kPreParseNotIdentifiableError ? kPreParseNotIdentifiableError
: kPreParseSuccess)); : kPreParseSuccess);
Expect(Token::RPAREN, CHECK_OK_VALUE(kPreParseSuccess)); Expect(Token::RPAREN);
RETURN_IF_PARSE_ERROR_VALUE(kPreParseSuccess);
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions( CheckArityRestrictions(formals.arity, kind, formals.has_rest,
formals.arity, kind, formals.has_rest, function_scope->start_position(), function_scope->start_position(),
formals_end_position, CHECK_OK_VALUE(kPreParseSuccess)); formals_end_position);
RETURN_IF_PARSE_ERROR_VALUE(kPreParseSuccess);
} }
Expect(Token::LBRACE, CHECK_OK_VALUE(kPreParseSuccess)); Expect(Token::LBRACE);
RETURN_IF_PARSE_ERROR_VALUE(kPreParseSuccess);
DeclarationScope* inner_scope = function_scope; DeclarationScope* inner_scope = function_scope;
LazyParsingResult result; LazyParsingResult result;
...@@ -183,7 +185,7 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -183,7 +185,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
{ {
BlockState block_state(&scope_, inner_scope); BlockState block_state(&scope_, inner_scope);
result = ParseStatementListAndLogFunction(&formals, may_abort, ok); result = ParseStatementListAndLogFunction(&formals, may_abort);
} }
bool allow_duplicate_parameters = false; bool allow_duplicate_parameters = false;
...@@ -197,7 +199,7 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -197,7 +199,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
!IsConciseMethod(kind) && !IsConciseMethod(kind) &&
!IsArrowFunction(kind); !IsArrowFunction(kind);
} else { } else {
BuildParameterInitializationBlock(formals, ok); BuildParameterInitializationBlock(formals);
if (is_sloppy(inner_scope->language_mode())) { if (is_sloppy(inner_scope->language_mode())) {
inner_scope->HoistSloppyBlockFunctions(nullptr); inner_scope->HoistSloppyBlockFunctions(nullptr);
...@@ -216,9 +218,8 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -216,9 +218,8 @@ PreParser::PreParseResult PreParser::PreParseFunction(
} else if (stack_overflow()) { } else if (stack_overflow()) {
return kPreParseStackOverflow; return kPreParseStackOverflow;
} else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) { } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
DCHECK(!*ok);
return kPreParseNotIdentifiableError; return kPreParseNotIdentifiableError;
} else if (!*ok) { } else if (scanner()->has_parser_error_set()) {
DCHECK(pending_error_handler()->has_pending_error()); DCHECK(pending_error_handler()->has_pending_error());
} else { } else {
DCHECK_EQ(Token::RBRACE, scanner()->peek()); DCHECK_EQ(Token::RBRACE, scanner()->peek());
...@@ -227,8 +228,8 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -227,8 +228,8 @@ PreParser::PreParseResult PreParser::PreParseFunction(
if (!IsArrowFunction(kind)) { if (!IsArrowFunction(kind)) {
// Validate parameter names. We can do this only after parsing the // Validate parameter names. We can do this only after parsing the
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
ValidateFormalParameters(language_mode(), allow_duplicate_parameters, ok); ValidateFormalParameters(language_mode(), allow_duplicate_parameters);
if (!*ok) { if (scanner()->has_parser_error_set()) {
if (pending_error_handler()->has_error_unidentifiable_by_preparser()) { if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
return kPreParseNotIdentifiableError; return kPreParseNotIdentifiableError;
} else { } else {
...@@ -247,11 +248,14 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -247,11 +248,14 @@ PreParser::PreParseResult PreParser::PreParseFunction(
*produced_preparsed_scope_data = ProducedPreParsedScopeData::For( *produced_preparsed_scope_data = ProducedPreParsedScopeData::For(
preparsed_scope_data_builder_, main_zone()); preparsed_scope_data_builder_, main_zone());
} }
DCHECK(!pending_error_handler()->has_error_unidentifiable_by_preparser());
if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
return kPreParseNotIdentifiableError;
}
if (is_strict(function_scope->language_mode())) { if (is_strict(function_scope->language_mode())) {
int end_pos = scanner()->location().end_pos; int end_pos = scanner()->location().end_pos;
CheckStrictOctalLiteral(function_scope->start_position(), end_pos, ok); CheckStrictOctalLiteral(function_scope->start_position(), end_pos);
} }
} }
...@@ -278,7 +282,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -278,7 +282,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
LanguageMode language_mode, LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) { ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
// Wrapped functions are not parsed in the preparser. // Wrapped functions are not parsed in the preparser.
DCHECK_NULL(arguments_for_wrapped_function); DCHECK_NULL(arguments_for_wrapped_function);
DCHECK_NE(FunctionLiteral::kWrapped, function_type); DCHECK_NE(FunctionLiteral::kWrapped, function_type);
...@@ -311,25 +315,31 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -311,25 +315,31 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
ExpressionClassifier formals_classifier(this); ExpressionClassifier formals_classifier(this);
int func_id = GetNextFunctionLiteralId(); int func_id = GetNextFunctionLiteralId();
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN);
RETURN_IF_PARSE_ERROR;
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
function_scope->set_start_position(start_position); function_scope->set_start_position(start_position);
PreParserFormalParameters formals(function_scope); PreParserFormalParameters formals(function_scope);
ParseFormalParameterList(&formals, CHECK_OK); ParseFormalParameterList(&formals);
Expect(Token::RPAREN, CHECK_OK); RETURN_IF_PARSE_ERROR;
Expect(Token::RPAREN);
RETURN_IF_PARSE_ERROR;
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
formals_end_position, CHECK_OK); formals_end_position);
RETURN_IF_PARSE_ERROR;
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE);
RETURN_IF_PARSE_ERROR;
// Parse function body. // Parse function body.
PreParserStatementList body; PreParserStatementList body;
int pos = function_token_pos == kNoSourcePosition ? peek_position() int pos = function_token_pos == kNoSourcePosition ? peek_position()
: function_token_pos; : function_token_pos;
ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
FunctionBodyType::kBlock, true, CHECK_OK); FunctionBodyType::kBlock, true);
RETURN_IF_PARSE_ERROR;
// Parsing the body may change the language mode in our scope. // Parsing the body may change the language mode in our scope.
language_mode = function_scope->language_mode(); language_mode = function_scope->language_mode();
...@@ -341,11 +351,13 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -341,11 +351,13 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Validate name and parameter names. We can do this only after parsing the // Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
CheckFunctionName(language_mode, function_name, function_name_validity, CheckFunctionName(language_mode, function_name, function_name_validity,
function_name_location, CHECK_OK); function_name_location);
RETURN_IF_PARSE_ERROR;
int end_position = scanner()->location().end_pos; int end_position = scanner()->location().end_pos;
if (is_strict(language_mode)) { if (is_strict(language_mode)) {
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); CheckStrictOctalLiteral(start_position, end_position);
RETURN_IF_PARSE_ERROR;
} }
if (preparsed_scope_data_builder_scope) { if (preparsed_scope_data_builder_scope) {
...@@ -373,10 +385,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -373,10 +385,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
} }
PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
PreParserFormalParameters* formals, bool may_abort, bool* ok) { PreParserFormalParameters* formals, bool may_abort) {
PreParserStatementList body; PreParserStatementList body;
LazyParsingResult result = ParseStatementList( LazyParsingResult result = ParseStatementList(body, Token::RBRACE, may_abort);
body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); RETURN_IF_PARSE_ERROR_VALUE(kLazyParsingComplete);
if (result == kLazyParsingAborted) return result; if (result == kLazyParsingAborted) return result;
// Position right after terminal '}'. // Position right after terminal '}'.
...@@ -389,7 +401,7 @@ PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( ...@@ -389,7 +401,7 @@ PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
} }
PreParserStatement PreParser::BuildParameterInitializationBlock( PreParserStatement PreParser::BuildParameterInitializationBlock(
const PreParserFormalParameters& parameters, bool* ok) { const PreParserFormalParameters& parameters) {
DCHECK(!parameters.is_simple); DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope()); DCHECK(scope()->is_function_scope());
if (scope()->AsDeclarationScope()->calls_sloppy_eval() && if (scope()->AsDeclarationScope()->calls_sloppy_eval() &&
...@@ -425,7 +437,7 @@ void PreParser::DeclareAndInitializeVariables( ...@@ -425,7 +437,7 @@ void PreParser::DeclareAndInitializeVariables(
PreParserStatement block, PreParserStatement block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok) { ZonePtrList<const AstRawString>* names) {
if (declaration->pattern.variables_ != nullptr) { if (declaration->pattern.variables_ != nullptr) {
for (auto variable : *(declaration->pattern.variables_)) { for (auto variable : *(declaration->pattern.variables_)) {
declaration_descriptor->scope->RemoveUnresolved(variable); declaration_descriptor->scope->RemoveUnresolved(variable);
...@@ -443,9 +455,8 @@ void PreParser::DeclareAndInitializeVariables( ...@@ -443,9 +455,8 @@ void PreParser::DeclareAndInitializeVariables(
} }
} }
#undef CHECK_OK #undef RETURN_IF_PARSE_ERROR_VOID
#undef CHECK_OK_CUSTOM #undef RETURN_IF_PARSE_ERROR
#undef RETURN_IF_PARSE_ERROR_VALUE
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -1031,7 +1031,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1031,7 +1031,7 @@ class PreParser : public ParserBase<PreParser> {
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters, DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data, ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool may_abort, FunctionLiteral::EagerCompileHint* hint, bool* ok) { bool may_abort, FunctionLiteral::EagerCompileHint* hint) {
UNREACHABLE(); UNREACHABLE();
} }
...@@ -1040,15 +1040,14 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1040,15 +1040,14 @@ class PreParser : public ParserBase<PreParser> {
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type, int function_token_pos, FunctionLiteral::FunctionType function_type,
LanguageMode language_mode, LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function, ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
bool* ok);
PreParserExpression InitializeObjectLiteral(PreParserExpression literal) { PreParserExpression InitializeObjectLiteral(PreParserExpression literal) {
return literal; return literal;
} }
LazyParsingResult ParseStatementListAndLogFunction( LazyParsingResult ParseStatementListAndLogFunction(
PreParserFormalParameters* formals, bool maybe_abort, bool* ok); PreParserFormalParameters* formals, bool maybe_abort);
struct TemplateLiteralState {}; struct TemplateLiteralState {};
...@@ -1067,7 +1066,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1067,7 +1066,7 @@ class PreParser : public ParserBase<PreParser> {
const PreParserExpression& expression) { const PreParserExpression& expression) {
return expression.IsPropertyWithPrivateFieldKey(); return expression.IsPropertyWithPrivateFieldKey();
} }
V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} V8_INLINE void CheckConflictingVarDeclarations(Scope* scope) {}
V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) { V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) {
scope->SetLanguageMode(mode); scope->SetLanguageMode(mode);
...@@ -1087,17 +1086,17 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1087,17 +1086,17 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void PrepareGeneratorVariables() {} V8_INLINE void PrepareGeneratorVariables() {}
V8_INLINE void RewriteAsyncFunctionBody( V8_INLINE void RewriteAsyncFunctionBody(
PreParserStatementList body, PreParserStatement block, PreParserStatementList body, PreParserStatement block,
const PreParserExpression& return_value, bool* ok) {} const PreParserExpression& return_value) {}
void DeclareAndInitializeVariables( void DeclareAndInitializeVariables(
PreParserStatement block, PreParserStatement block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok); ZonePtrList<const AstRawString>* names);
V8_INLINE void DeclareLabel(ZonePtrList<const AstRawString>** labels, V8_INLINE void DeclareLabel(ZonePtrList<const AstRawString>** labels,
ZonePtrList<const AstRawString>** own_labels, ZonePtrList<const AstRawString>** own_labels,
const PreParserExpression& expr, bool* ok) { const PreParserExpression& expr) {
DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait()); DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
DCHECK(IsIdentifier(expr)); DCHECK(IsIdentifier(expr));
} }
...@@ -1117,7 +1116,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1117,7 +1116,7 @@ class PreParser : public ParserBase<PreParser> {
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info) {
const AstRawString* catch_name = catch_info->name.string_; const AstRawString* catch_name = catch_info->name.string_;
if (catch_name == nullptr) { if (catch_name == nullptr) {
catch_name = ast_value_factory()->dot_catch_string(); catch_name = ast_value_factory()->dot_catch_string();
...@@ -1131,7 +1130,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1131,7 +1130,7 @@ class PreParser : public ParserBase<PreParser> {
} }
} }
V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {} V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info) {}
V8_INLINE PreParserStatement RewriteTryStatement( V8_INLINE PreParserStatement RewriteTryStatement(
PreParserStatement try_block, PreParserStatement catch_block, PreParserStatement try_block, PreParserStatement catch_block,
const SourceRange& catch_range, PreParserStatement finally_block, const SourceRange& catch_range, PreParserStatement finally_block,
...@@ -1144,12 +1143,12 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1144,12 +1143,12 @@ class PreParser : public ParserBase<PreParser> {
Scanner::Location* location, Scanner::Location* location,
const char** arg) {} const char** arg) {}
V8_INLINE void ParseAndRewriteGeneratorFunctionBody( V8_INLINE void ParseAndRewriteGeneratorFunctionBody(
int pos, FunctionKind kind, PreParserStatementList body, bool* ok) { int pos, FunctionKind kind, PreParserStatementList body) {
ParseStatementList(body, Token::RBRACE, ok); ParseStatementList(body, Token::RBRACE);
} }
V8_INLINE void ParseAndRewriteAsyncGeneratorFunctionBody( V8_INLINE void ParseAndRewriteAsyncGeneratorFunctionBody(
int pos, FunctionKind kind, PreParserStatementList body, bool* ok) { int pos, FunctionKind kind, PreParserStatementList body) {
ParseStatementList(body, Token::RBRACE, ok); ParseStatementList(body, Token::RBRACE);
} }
V8_INLINE void DeclareFunctionNameVar( V8_INLINE void DeclareFunctionNameVar(
const AstRawString* function_name, const AstRawString* function_name,
...@@ -1171,26 +1170,25 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1171,26 +1170,25 @@ class PreParser : public ParserBase<PreParser> {
} }
V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body, V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body,
int pos, bool* ok) { int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
// TODO(nikolaos): The preparser currently does not keep track of labels // TODO(nikolaos): The preparser currently does not keep track of labels
// and targets. // and targets.
V8_INLINE PreParserStatement V8_INLINE PreParserStatement
LookupBreakTarget(const PreParserIdentifier& label, bool* ok) { LookupBreakTarget(const PreParserIdentifier& label) {
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
V8_INLINE PreParserStatement V8_INLINE PreParserStatement
LookupContinueTarget(const PreParserIdentifier& label, bool* ok) { LookupContinueTarget(const PreParserIdentifier& label) {
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
V8_INLINE PreParserStatement V8_INLINE PreParserStatement DeclareFunction(
DeclareFunction(const PreParserIdentifier& variable_name, const PreParserIdentifier& variable_name,
const PreParserExpression& function, VariableMode mode, const PreParserExpression& function, VariableMode mode, int pos,
int pos, bool is_sloppy_block_function, bool is_sloppy_block_function, ZonePtrList<const AstRawString>* names) {
ZonePtrList<const AstRawString>* names, bool* ok) {
DCHECK_NULL(names); DCHECK_NULL(names);
if (variable_name.string_ != nullptr) { if (variable_name.string_ != nullptr) {
scope()->DeclareVariableName(variable_name.string_, mode); scope()->DeclareVariableName(variable_name.string_, mode);
...@@ -1205,7 +1203,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1205,7 +1203,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserStatement DeclareClass( V8_INLINE PreParserStatement DeclareClass(
const PreParserIdentifier& variable_name, const PreParserIdentifier& variable_name,
const PreParserExpression& value, ZonePtrList<const AstRawString>* names, const PreParserExpression& value, ZonePtrList<const AstRawString>* names,
int class_token_pos, int end_pos, bool* ok) { int class_token_pos, int end_pos) {
// Preparser shouldn't be used in contexts where we need to track the names. // Preparser shouldn't be used in contexts where we need to track the names.
DCHECK_NULL(names); DCHECK_NULL(names);
if (variable_name.string_ != nullptr) { if (variable_name.string_ != nullptr) {
...@@ -1215,7 +1213,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1215,7 +1213,7 @@ class PreParser : public ParserBase<PreParser> {
} }
V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name, V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name,
ClassInfo* class_info, ClassInfo* class_info,
int class_token_pos, bool* ok) { int class_token_pos) {
if (name.string_ != nullptr) { if (name.string_ != nullptr) {
scope()->DeclareVariableName(name.string_, VariableMode::kConst); scope()->DeclareVariableName(name.string_, VariableMode::kConst);
} }
...@@ -1226,7 +1224,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1226,7 +1224,7 @@ class PreParser : public ParserBase<PreParser> {
ClassLiteralProperty::Kind kind, ClassLiteralProperty::Kind kind,
bool is_static, bool is_constructor, bool is_static, bool is_constructor,
bool is_computed_name, bool is_private, bool is_computed_name, bool is_private,
ClassInfo* class_info, bool* ok) { ClassInfo* class_info) {
if (kind == ClassLiteralProperty::FIELD && !is_private && if (kind == ClassLiteralProperty::FIELD && !is_private &&
is_computed_name) { is_computed_name) {
scope()->DeclareVariableName( scope()->DeclareVariableName(
...@@ -1243,7 +1241,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1243,7 +1241,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserExpression V8_INLINE PreParserExpression
RewriteClassLiteral(Scope* scope, const PreParserIdentifier& name, RewriteClassLiteral(Scope* scope, const PreParserIdentifier& name,
ClassInfo* class_info, int pos, int end_pos, bool* ok) { ClassInfo* class_info, int pos, int end_pos) {
bool has_default_constructor = !class_info->has_seen_constructor; bool has_default_constructor = !class_info->has_seen_constructor;
// Account for the default constructor. // Account for the default constructor.
if (has_default_constructor) { if (has_default_constructor) {
...@@ -1272,7 +1270,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1272,7 +1270,7 @@ class PreParser : public ParserBase<PreParser> {
} }
V8_INLINE PreParserStatement DeclareNative(const PreParserIdentifier& name, V8_INLINE PreParserStatement DeclareNative(const PreParserIdentifier& name,
int pos, bool* ok) { int pos) {
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
...@@ -1415,11 +1413,11 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1415,11 +1413,11 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserStatement V8_INLINE PreParserStatement
BuildInitializationBlock(DeclarationParsingResult* parsing_result, BuildInitializationBlock(DeclarationParsingResult* parsing_result,
ZonePtrList<const AstRawString>* names, bool* ok) { ZonePtrList<const AstRawString>* names) {
for (auto declaration : parsing_result->declarations) { for (auto declaration : parsing_result->declarations) {
DeclareAndInitializeVariables(PreParserStatement::Default(), DeclareAndInitializeVariables(PreParserStatement::Default(),
&(parsing_result->descriptor), &declaration, &(parsing_result->descriptor), &declaration,
names, ok); names);
} }
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
...@@ -1446,7 +1444,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1446,7 +1444,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void DesugarBindingInForEachStatement( V8_INLINE void DesugarBindingInForEachStatement(
ForInfo* for_info, PreParserStatement* body_block, ForInfo* for_info, PreParserStatement* body_block,
PreParserExpression* each_variable, bool* ok) { PreParserExpression* each_variable) {
DCHECK_EQ(1, for_info->parsing_result.declarations.size()); DCHECK_EQ(1, for_info->parsing_result.declarations.size());
bool is_for_var_of = bool is_for_var_of =
for_info->mode == ForEachStatement::ITERATE && for_info->mode == ForEachStatement::ITERATE &&
...@@ -1458,11 +1456,11 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1458,11 +1456,11 @@ class PreParser : public ParserBase<PreParser> {
DeclareAndInitializeVariables( DeclareAndInitializeVariables(
PreParserStatement::Default(), &for_info->parsing_result.descriptor, PreParserStatement::Default(), &for_info->parsing_result.descriptor,
&for_info->parsing_result.declarations[0], &for_info->parsing_result.declarations[0],
collect_names ? &for_info->bound_names : nullptr, ok); collect_names ? &for_info->bound_names : nullptr);
} }
V8_INLINE PreParserStatement CreateForEachStatementTDZ( V8_INLINE PreParserStatement CreateForEachStatementTDZ(
PreParserStatement init_block, const ForInfo& for_info, bool* ok) { PreParserStatement init_block, const ForInfo& for_info) {
if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
for (auto name : for_info.bound_names) { for (auto name : for_info.bound_names) {
scope()->DeclareVariableName(name, VariableMode::kLet); scope()->DeclareVariableName(name, VariableMode::kLet);
...@@ -1486,7 +1484,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1486,7 +1484,7 @@ class PreParser : public ParserBase<PreParser> {
} }
PreParserStatement BuildParameterInitializationBlock( PreParserStatement BuildParameterInitializationBlock(
const PreParserFormalParameters& parameters, bool* ok); const PreParserFormalParameters& parameters);
V8_INLINE PreParserStatement V8_INLINE PreParserStatement
BuildRejectPromiseOnException(PreParserStatement init_block) { BuildRejectPromiseOnException(PreParserStatement init_block) {
...@@ -1522,10 +1520,12 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1522,10 +1520,12 @@ class PreParser : public ParserBase<PreParser> {
pending_error_handler()->ReportMessageAt(source_location.beg_pos, pending_error_handler()->ReportMessageAt(source_location.beg_pos,
source_location.end_pos, message, source_location.end_pos, message,
arg, error_type); arg, error_type);
scanner()->set_parser_error();
} }
V8_INLINE void ReportUnidentifiableError() { V8_INLINE void ReportUnidentifiableError() {
pending_error_handler()->set_unidentifiable_error(); pending_error_handler()->set_unidentifiable_error();
scanner()->set_parser_error();
} }
V8_INLINE void ReportMessageAt(Scanner::Location source_location, V8_INLINE void ReportMessageAt(Scanner::Location source_location,
...@@ -1633,7 +1633,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1633,7 +1633,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserExpression V8_INLINE PreParserExpression
NewV8Intrinsic(const PreParserIdentifier& name, NewV8Intrinsic(const PreParserIdentifier& name,
const PreParserExpressionList& arguments, int pos, bool* ok) { const PreParserExpressionList& arguments, int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
...@@ -1680,7 +1680,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1680,7 +1680,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void DeclareArrowFunctionFormalParameters( V8_INLINE void DeclareArrowFunctionFormalParameters(
PreParserFormalParameters* parameters, const PreParserExpression& params, PreParserFormalParameters* parameters, const PreParserExpression& params,
const Scanner::Location& params_loc, bool* ok) { const Scanner::Location& params_loc) {
if (params.variables_ != nullptr) { if (params.variables_ != nullptr) {
Scope* scope = parameters->scope; Scope* scope = parameters->scope;
for (auto variable : *params.variables_) { for (auto variable : *params.variables_) {
......
...@@ -42,12 +42,12 @@ class Utf16CharacterStream { ...@@ -42,12 +42,12 @@ class Utf16CharacterStream {
virtual ~Utf16CharacterStream() = default; virtual ~Utf16CharacterStream() = default;
void set_parser_error() { V8_INLINE void set_parser_error() {
buffer_cursor_ = buffer_end_; buffer_cursor_ = buffer_end_;
has_parser_error_ = true; has_parser_error_ = true;
} }
void reset_parser_error_flag() { has_parser_error_ = false; } V8_INLINE void reset_parser_error_flag() { has_parser_error_ = false; }
bool has_parser_error() const { return has_parser_error_; } V8_INLINE bool has_parser_error() const { return has_parser_error_; }
inline uc32 Peek() { inline uc32 Peek() {
if (V8_LIKELY(buffer_cursor_ < buffer_end_)) { if (V8_LIKELY(buffer_cursor_ < buffer_end_)) {
...@@ -238,9 +238,13 @@ class Scanner { ...@@ -238,9 +238,13 @@ class Scanner {
// Sets the Scanner into an error state to stop further scanning and terminate // Sets the Scanner into an error state to stop further scanning and terminate
// the parsing by only returning ILLEGAL tokens after that. // the parsing by only returning ILLEGAL tokens after that.
void set_parser_error() { source_->set_parser_error(); } V8_INLINE void set_parser_error() { source_->set_parser_error(); }
void reset_parser_error_flag() { source_->reset_parser_error_flag(); } V8_INLINE void reset_parser_error_flag() {
bool has_parser_error_set() { return source_->has_parser_error(); } source_->reset_parser_error_flag();
}
V8_INLINE bool has_parser_error_set() const {
return source_->has_parser_error();
}
// Representation of an interval of source positions. // Representation of an interval of source positions.
struct Location { struct Location {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment