Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index fb52eef56382155d70889fa53efcc74ba8f5a700..f52e6c3b4aef8394a7d7048dfb8bce85e5d5fa69 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -4037,15 +4037,48 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| !parenthesized_function_); |
| parenthesized_function_ = false; // The bit was set for this function only. |
| - if (is_lazily_parsed) { |
| + // Trial parse. |
| + Scanner::BookmarkScope bookmark(scanner()); |
| + if (is_lazily_parsed && bookmark.Set()) { |
| + // We call SkipLazyFunctionBody with a bookmark, meaning that |
| + // SkipLazyFunctionBody may decide to abort the skipping if it |
| + // finds out the function should really have been eagerly parsed |
| + // afterall. |
| SkipLazyFunctionBody(function_name, &materialized_literal_count, |
| - &expected_property_count, CHECK_OK); |
| - } else { |
| + &expected_property_count, ok /*CHECK_OK*/, |
| + &bookmark); |
| + } |
| + |
| + // Following the trial parse we can be in one of these states now: |
| + // - we wanted to eagerly parse all along |
| + // condition: !is_lazily_parsed |
| + // action: eager parse. |
| + // - we wanted to lazy parse and have not tried trial parsing |
| + // condition: is_lazily_parsed (but none of the conditions below) |
|
marja
2015/04/22 16:40:55
... is this the same as "couldn't trial parse beca
vogelheim
2015/04/22 17:08:34
Yes. Cannot bookmark, or !is_lazily_parsed
|
| + // action: lazy parse |
| + // - we trial parsed, and trial parsing finished |
| + // condition: is_lazily_parsed && bookmark.HasBeenSet() |
| + // action: we're done. |
| + // - we trial parsed, and trial parsing aborted |
| + // condition: is_lazily_parsed && bookmark.HasBeenReset() |
| + // action: eager parse. |
|
marja
2015/04/22 16:40:55
The logic sounds correct, but... isn't there a sim
vogelheim
2015/04/22 17:08:34
That'd work as well. I'll change it.
|
| + if (!is_lazily_parsed || (is_lazily_parsed && bookmark.HasBeenReset())) { |
| + if (bookmark.HasBeenReset()) { |
| + // TODO(vogelheim): We're lying, the function is not parenthesized. |
| + // But this will cause the compiler to actually compile it. |
|
marja
2015/04/22 16:40:55
... we might want to use the non-hacky way of sayi
|
| + parenthesized = FunctionLiteral::kIsParenthesized; |
| + } |
| + |
| body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, |
| kind, CHECK_OK); |
| materialized_literal_count = function_state.materialized_literal_count(); |
| expected_property_count = function_state.expected_property_count(); |
| handler_count = function_state.handler_count(); |
| + } else if (is_lazily_parsed && bookmark.HasBeenSet()) { |
| + ; // Work was already done in trial parse, above. |
| + } else { |
| + SkipLazyFunctionBody(function_name, &materialized_literal_count, |
| + &expected_property_count, /*CHECK_OK*/ ok); |
| } |
| // Validate name and parameter names. We can do this only after parsing the |
| @@ -4094,8 +4127,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
| int* materialized_literal_count, |
| - int* expected_property_count, |
| - bool* ok) { |
| + int* expected_property_count, bool* ok, |
| + Scanner::BookmarkScope* bookmark) { |
| + DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
| if (produce_cached_parse_data()) CHECK(log_); |
| int function_block_pos = position(); |
| @@ -4128,7 +4162,10 @@ void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
| // AST. This gathers the data needed to build a lazy function. |
| SingletonLogger logger; |
| PreParser::PreParseResult result = |
| - ParseLazyFunctionBodyWithPreParser(&logger); |
| + ParseLazyFunctionBodyWithPreParser(&logger, bookmark); |
| + if (bookmark && bookmark->HasBeenReset()) { |
| + return; // Return immediately if pre-parser devided to abort parsing. |
| + } |
| if (result == PreParser::kPreParseStackOverflow) { |
| // Propagate stack overflow. |
| set_stack_overflow(); |
| @@ -4257,7 +4294,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| - SingletonLogger* logger) { |
| + SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { |
| // This function may be called on a background thread too; record only the |
| // main thread preparse times. |
| if (pre_parse_timer_ != NULL) { |
| @@ -4287,7 +4324,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); |
| } |
| PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| - language_mode(), function_state_->kind(), logger); |
| + language_mode(), function_state_->kind(), logger, bookmark); |
| if (pre_parse_timer_ != NULL) { |
| pre_parse_timer_->Stop(); |
| } |