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