Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index cd87da8d14bfb46babba23408e08a987b795a9ca..0ada440354515d4fd7f6e73437d2359912da9b5d 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -127,13 +127,15 @@ class DiscardableZoneScope { |
} |
} |
} |
- ~DiscardableZoneScope() { |
+ void Reset() { |
parser_->fni_ = prev_fni_; |
parser_->zone_ = prev_zone_; |
if (parser_->reusable_preparser_ != nullptr) { |
parser_->reusable_preparser_->zone_ = prev_zone_; |
} |
+ ast_node_factory_scope_.Reset(); |
} |
+ ~DiscardableZoneScope() { Reset(); } |
private: |
AstNodeFactory::BodyScope ast_node_factory_scope_; |
@@ -2680,11 +2682,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
// will migrate unresolved variable into a Scope in the main Zone. |
// TODO(marja): Refactor parsing modes: simplify this. |
bool use_temp_zone = |
- !is_lazy_top_level_function && allow_lazy() && |
- function_type == FunctionLiteral::kDeclaration && |
+ allow_lazy() && function_type == FunctionLiteral::kDeclaration && |
eager_compile_hint != FunctionLiteral::kShouldEagerCompile && |
!(FLAG_validate_asm && scope()->IsAsmModule()); |
- bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions; |
+ bool is_lazy_inner_function = |
+ use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; |
// This Scope lives in the main zone. We'll migrate data into that zone later. |
DeclarationScope* scope = NewFunctionScope(kind); |
@@ -2698,6 +2700,45 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
bool should_be_used_once_hint = false; |
bool has_duplicate_parameters; |
+ FunctionState function_state(&function_state_, &scope_state_, scope); |
+#ifdef DEBUG |
+ scope->SetScopeName(function_name); |
+#endif |
+ |
+ ExpressionClassifier formals_classifier(this, &duplicate_finder); |
+ |
+ if (is_generator) { |
+ // For generators, allocating variables in contexts is currently a win |
+ // because it minimizes the work needed to suspend and resume an |
+ // activation. The machine code produced for generators (by full-codegen) |
+ // relies on this forced context allocation, but not in an essential way. |
+ this->scope()->ForceContextAllocation(); |
+ |
+ // Calling a generator returns a generator object. That object is stored |
+ // in a temporary variable, a definition that is used by "yield" |
+ // expressions. This also marks the FunctionState as a generator. |
+ Variable* temp = |
+ NewTemporary(ast_value_factory()->dot_generator_object_string()); |
+ function_state.set_generator_object_variable(temp); |
+ } |
+ |
+ Expect(Token::LPAREN, CHECK_OK); |
+ int start_position = scanner()->location().beg_pos; |
+ this->scope()->set_start_position(start_position); |
+ ParserFormalParameters formals(scope); |
+ ParseFormalParameterList(&formals, CHECK_OK); |
+ arity = formals.Arity(); |
+ Expect(Token::RPAREN, CHECK_OK); |
+ int formals_end_position = scanner()->location().end_pos; |
+ |
+ CheckArityRestrictions(arity, kind, formals.has_rest, start_position, |
+ formals_end_position, CHECK_OK); |
+ Expect(Token::LBRACE, CHECK_OK); |
+ // Don't include the rest parameter into the function's formal parameter |
+ // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, |
+ // which says whether we need to create an arguments adaptor frame). |
+ if (formals.has_rest) arity--; |
+ |
{ |
// Temporary zones can nest. When we migrate free variables (see below), we |
// need to recreate them in the previous Zone. |
@@ -2711,45 +2752,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
// information when the function is parsed. |
Zone temp_zone(zone()->allocator()); |
DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); |
- |
- FunctionState function_state(&function_state_, &scope_state_, scope); |
#ifdef DEBUG |
- scope->SetScopeName(function_name); |
if (use_temp_zone) scope->set_needs_migration(); |
#endif |
- ExpressionClassifier formals_classifier(this, &duplicate_finder); |
- |
- if (is_generator) { |
- // For generators, allocating variables in contexts is currently a win |
- // because it minimizes the work needed to suspend and resume an |
- // activation. The machine code produced for generators (by full-codegen) |
- // relies on this forced context allocation, but not in an essential way. |
- this->scope()->ForceContextAllocation(); |
- |
- // Calling a generator returns a generator object. That object is stored |
- // in a temporary variable, a definition that is used by "yield" |
- // expressions. This also marks the FunctionState as a generator. |
- Variable* temp = |
- NewTemporary(ast_value_factory()->dot_generator_object_string()); |
- function_state.set_generator_object_variable(temp); |
- } |
- |
- Expect(Token::LPAREN, CHECK_OK); |
- int start_position = scanner()->location().beg_pos; |
- this->scope()->set_start_position(start_position); |
- ParserFormalParameters formals(scope); |
- ParseFormalParameterList(&formals, CHECK_OK); |
- arity = formals.Arity(); |
- Expect(Token::RPAREN, CHECK_OK); |
- int formals_end_position = scanner()->location().end_pos; |
- |
- CheckArityRestrictions(arity, kind, formals.has_rest, start_position, |
- formals_end_position, CHECK_OK); |
- Expect(Token::LBRACE, CHECK_OK); |
- // Don't include the rest parameter into the function's formal parameter |
- // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, |
- // which says whether we need to create an arguments adaptor frame). |
- if (formals.has_rest) arity--; |
// Eager or lazy parse? If is_lazy_top_level_function, we'll parse |
// lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy |
@@ -2778,6 +2783,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
eager_compile_hint = FunctionLiteral::kShouldEagerCompile; |
should_be_used_once_hint = true; |
scope->ResetAfterPreparsing(true); |
+ zone_scope.Reset(); |
+ use_temp_zone = false; |
} |
} |