Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index 72508c1cc9a5256f0392b04ee6c0d7caebed5147..9753595e4d9ffc9a3487b1f100abdccf25b2ff26 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -277,17 +277,14 @@ class TargetScope BASE_EMBEDDED { |
// 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 ok); \ |
- if (!*ok) return nullptr; \ |
+#define CHECK_OK_VALUE(x) ok); \ |
+ if (!*ok) return x; \ |
((void)0 |
#define DUMMY ) // to make indentation work |
#undef DUMMY |
-#define CHECK_OK_VOID ok); \ |
- if (!*ok) return; \ |
- ((void)0 |
-#define DUMMY ) // to make indentation work |
-#undef DUMMY |
+#define CHECK_OK CHECK_OK_VALUE(nullptr) |
+#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void()) |
#define CHECK_FAILED /**/); \ |
if (failed_) return nullptr; \ |
@@ -3255,8 +3252,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
int each_beg_pos = scanner()->location().beg_pos; |
int each_end_pos = scanner()->location().end_pos; |
- if (CheckInOrOf(&mode, ok)) { |
- if (!*ok) return nullptr; |
+ if (CheckInOrOf(&mode)) { |
if (parsing_result.declarations.length() != 1) { |
ReportMessageAt(parsing_result.bindings_loc, |
MessageTemplate::kForInOfLoopMultiBindings, |
@@ -3450,7 +3446,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
int lhs_end_pos = scanner()->location().end_pos; |
ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
- bool is_for_each = CheckInOrOf(&mode, CHECK_OK); |
+ bool is_for_each = CheckInOrOf(&mode); |
bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || |
expression->IsObjectLiteral()); |
@@ -3964,22 +3960,23 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
if (formals.has_rest) arity--; |
// Eager or lazy parse? |
- // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll |
- // pass it to SkipLazyFunctionBody, which may use it to abort lazy |
- // parsing if it suspect that wasn't a good idea. If so, or if we didn't |
- // try to lazy parse in the first place, we'll have to parse eagerly. |
- Scanner::BookmarkScope bookmark(scanner()); |
+ // If is_lazily_parsed, we'll parse lazily. We'll call SkipLazyFunctionBody, |
+ // which may decide to abort lazy parsing if it suspects that wasn't a good |
+ // idea. If so (in which case the parser is expected to have backtracked), |
+ // or if we didn't try to lazy parse in the first place, we'll have to parse |
+ // eagerly. |
if (is_lazily_parsed) { |
- Scanner::BookmarkScope* maybe_bookmark = |
- bookmark.Set() ? &bookmark : nullptr; |
- SkipLazyFunctionBody(&materialized_literal_count, |
- &expected_property_count, /*CHECK_OK*/ ok, |
- maybe_bookmark); |
+ Scanner::BookmarkScope bookmark(scanner()); |
+ bool may_abort = bookmark.Set(); |
+ LazyParsingResult result = |
+ SkipLazyFunctionBody(&materialized_literal_count, |
+ &expected_property_count, may_abort, CHECK_OK); |
materialized_literal_count += formals.materialized_literals_count + |
function_state.materialized_literal_count(); |
- if (bookmark.HasBeenReset()) { |
+ if (result == kLazyParsingAborted) { |
+ bookmark.Reset(); |
// Trigger eager (re-)parsing, just below this block. |
is_lazily_parsed = false; |
@@ -4079,10 +4076,9 @@ Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { |
language_mode(), CHECK_OK); |
} |
-void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
- int* expected_property_count, bool* ok, |
- Scanner::BookmarkScope* bookmark) { |
- DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
+Parser::LazyParsingResult Parser::SkipLazyFunctionBody( |
+ int* materialized_literal_count, int* expected_property_count, |
+ bool may_abort, bool* ok) { |
if (produce_cached_parse_data()) CHECK(log_); |
int function_block_pos = position(); |
@@ -4100,14 +4096,14 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
scanner()->SeekForward(entry.end_pos() - 1); |
scope->set_end_position(entry.end_pos()); |
- Expect(Token::RBRACE, CHECK_OK_VOID); |
+ Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); |
total_preparse_skipped_ += scope->end_position() - function_block_pos; |
*materialized_literal_count = entry.literal_count(); |
*expected_property_count = entry.property_count(); |
SetLanguageMode(scope, entry.language_mode()); |
if (entry.uses_super_property()) scope->RecordSuperPropertyUsage(); |
if (entry.calls_eval()) scope->RecordEvalCall(); |
- return; |
+ return kLazyParsingComplete; |
} |
cached_parse_data_->Reject(); |
} |
@@ -4115,25 +4111,26 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
// AST. This gathers the data needed to build a lazy function. |
SingletonLogger logger; |
PreParser::PreParseResult result = |
- ParseLazyFunctionBodyWithPreParser(&logger, bookmark); |
- if (bookmark && bookmark->HasBeenReset()) { |
- return; // Return immediately if pre-parser devided to abort parsing. |
+ ParseLazyFunctionBodyWithPreParser(&logger, may_abort); |
+ // Return immediately if pre-parser decided to abort parsing. |
+ if (result == PreParser::kPreParseAbort) { |
+ return kLazyParsingAborted; |
} |
if (result == PreParser::kPreParseStackOverflow) { |
// Propagate stack overflow. |
set_stack_overflow(); |
*ok = false; |
- return; |
+ return kLazyParsingComplete; |
} |
if (logger.has_error()) { |
ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
logger.message(), logger.argument_opt(), |
logger.error_type()); |
*ok = false; |
- return; |
+ return kLazyParsingComplete; |
} |
scope->set_end_position(logger.end()); |
- Expect(Token::RBRACE, CHECK_OK_VOID); |
+ Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); |
total_preparse_skipped_ += scope->end_position() - function_block_pos; |
*materialized_literal_count = logger.literals(); |
*expected_property_count = logger.properties(); |
@@ -4148,6 +4145,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
*expected_property_count, language_mode(), |
scope->uses_super_property(), scope->calls_eval()); |
} |
+ return kLazyParsingComplete; |
} |
@@ -4599,9 +4597,8 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
return result; |
} |
- |
PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
- SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { |
+ SingletonLogger* logger, bool may_abort) { |
// This function may be called on a background thread too; record only the |
// main thread preparse times. |
if (pre_parse_timer_ != NULL) { |
@@ -4628,7 +4625,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
language_mode(), function_state_->kind(), |
scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, |
- logger, bookmark, use_counts_); |
+ logger, may_abort, use_counts_); |
if (pre_parse_timer_ != NULL) { |
pre_parse_timer_->Stop(); |
} |