| Index: src/ast/scopes.cc
|
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
| index a41d34303291da4fddd418c4d6a67ca5e8569310..c91126c27b9410b8233cfe055a2f32e6d5e39d18 100644
|
| --- a/src/ast/scopes.cc
|
| +++ b/src/ast/scopes.cc
|
| @@ -1006,7 +1006,7 @@ VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory,
|
| // the same name because they may be removed selectively via
|
| // RemoveUnresolved().
|
| DCHECK(!already_resolved_);
|
| - DCHECK_EQ(!needs_migration_, factory->zone() == zone());
|
| + DCHECK_EQ(factory->zone(), zone());
|
| VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position);
|
| proxy->set_next_unresolved(unresolved_);
|
| unresolved_ = proxy;
|
| @@ -1289,14 +1289,22 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
|
| params_.Clear();
|
| decls_.Clear();
|
| locals_.Clear();
|
| - sloppy_block_function_map_.Clear();
|
| - variables_.Clear();
|
| - // Make sure we won't walk the scope tree from here on.
|
| inner_scope_ = nullptr;
|
| unresolved_ = nullptr;
|
|
|
| - if (aborted && !IsArrowFunction(function_kind_)) {
|
| - DeclareDefaultFunctionVariables(ast_value_factory);
|
| + if (aborted) {
|
| + // Prepare scope for use in the outer zone.
|
| + zone_ = ast_value_factory->zone();
|
| + variables_.Reset(ZoneAllocationPolicy(zone_));
|
| + sloppy_block_function_map_.Reset(ZoneAllocationPolicy(zone_));
|
| + if (!IsArrowFunction(function_kind_)) {
|
| + DeclareDefaultFunctionVariables(ast_value_factory);
|
| + }
|
| + } else {
|
| + // Make sure this scope isn't used for allocation anymore.
|
| + zone_ = nullptr;
|
| + variables_.Invalidate();
|
| + sloppy_block_function_map_.Invalidate();
|
| }
|
|
|
| #ifdef DEBUG
|
| @@ -1502,7 +1510,7 @@ void Scope::Print(int n) {
|
| PrintVar(n1, function);
|
| }
|
|
|
| - if (variables_.Start() != NULL) {
|
| + if (variables_.occupancy() != 0) {
|
| Indent(n1, "// local vars:\n");
|
| PrintMap(n1, &variables_, true);
|
|
|
| @@ -1536,6 +1544,12 @@ void Scope::CheckScopePositions() {
|
| void Scope::CheckZones() {
|
| DCHECK(!needs_migration_);
|
| for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
|
| + if (scope->is_declaration_scope() &&
|
| + scope->AsDeclarationScope()->is_lazily_parsed()) {
|
| + DCHECK_NULL(scope->zone());
|
| + DCHECK_NULL(scope->inner_scope_);
|
| + continue;
|
| + }
|
| CHECK_EQ(scope->zone(), zone());
|
| scope->CheckZones();
|
| }
|
| @@ -1723,35 +1737,62 @@ void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
|
|
|
| void Scope::ResolveVariablesRecursively(ParseInfo* info) {
|
| DCHECK(info->script_scope()->is_script_scope());
|
| + // Lazy parsed declaration scopes are already partially analyzed. If there are
|
| + // unresolved references remaining, they just need to be resolved in outer
|
| + // scopes.
|
| + if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) {
|
| + DCHECK(variables_.occupancy() == 0);
|
| + for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
| + proxy = proxy->next_unresolved()) {
|
| + Variable* var = outer_scope()->LookupRecursive(proxy, nullptr);
|
| + if (!var->is_dynamic()) {
|
| + var->set_is_used();
|
| + var->ForceContextAllocation();
|
| + if (proxy->is_assigned()) var->set_maybe_assigned();
|
| + }
|
| + }
|
| + } else {
|
| + // Resolve unresolved variables for this scope.
|
| + for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
| + proxy = proxy->next_unresolved()) {
|
| + ResolveVariable(info, proxy);
|
| + }
|
|
|
| - // Resolve unresolved variables for this scope.
|
| - for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
| - proxy = proxy->next_unresolved()) {
|
| - ResolveVariable(info, proxy);
|
| - }
|
| -
|
| - // Resolve unresolved variables for inner scopes.
|
| - for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
|
| - scope->ResolveVariablesRecursively(info);
|
| + // Resolve unresolved variables for inner scopes.
|
| + for (Scope* scope = inner_scope_; scope != nullptr;
|
| + scope = scope->sibling_) {
|
| + scope->ResolveVariablesRecursively(info);
|
| + }
|
| }
|
| }
|
|
|
| VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
|
| bool try_to_resolve, ParseInfo* info,
|
| VariableProxy* stack) {
|
| + // Lazy parsed declaration scopes are already partially analyzed. If there are
|
| + // unresolved references remaining, they just need to be resolved in outer
|
| + // scopes.
|
| + Scope* lookup =
|
| + is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()
|
| + ? outer_scope()
|
| + : this;
|
| for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
|
| proxy = next) {
|
| next = proxy->next_unresolved();
|
| DCHECK(!proxy->is_resolved());
|
| Variable* var = nullptr;
|
| if (try_to_resolve) {
|
| - var = LookupRecursive(proxy, max_outer_scope->outer_scope());
|
| + var = lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
|
| }
|
| if (var == nullptr) {
|
| proxy->set_next_unresolved(stack);
|
| stack = proxy;
|
| } else if (info != nullptr) {
|
| + // In this case we need to leave scopes in a way that they can be
|
| + // allocated. If we resolved variables from lazy parsed scopes, we need to
|
| + // context allocate the var.
|
| ResolveTo(info, proxy, var);
|
| + if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
|
| } else {
|
| var->set_is_used();
|
| }
|
|
|