Chromium Code Reviews| Index: src/ast/scopes.cc |
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc |
| index 292916d6a6fb9bdfd69495731a78d8132a66654a..264cd46e576343124ffab6937a7401e828814d0e 100644 |
| --- a/src/ast/scopes.cc |
| +++ b/src/ast/scopes.cc |
| @@ -337,8 +337,7 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| DCHECK(context->previous()->IsNativeContext()); |
| break; |
| } else if (context->IsFunctionContext()) { |
| - Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), |
| - isolate); |
| + Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
| // TODO(neis): For an eval scope, we currently create an ordinary function |
| // context. This is wrong and needs to be fixed. |
| // https://bugs.chromium.org/p/v8/issues/detail?id=5295 |
| @@ -360,7 +359,7 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, scope_info); |
| } |
| } else if (context->IsModuleContext()) { |
| - ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| + ScopeInfo* scope_info = context->scope_info(); |
| DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); |
| outer_scope = new (zone) ModuleScope( |
| isolate, Handle<ScopeInfo>(scope_info), ast_value_factory); |
| @@ -373,6 +372,13 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| } |
| if (current_scope != nullptr) { |
| outer_scope->AddInnerScope(current_scope); |
| + DCHECK_IMPLIES( |
| + deserialization_mode == DeserializationMode::kKeepScopeInfo, |
|
jochen (gone - plz use gerrit)
2016/09/06 08:29:24
if we deserialize off heap, we nuke the scope_info
|
| + current_scope->scope_info_->HasOuterScopeInfo()); |
| + DCHECK_IMPLIES( |
| + deserialization_mode == DeserializationMode::kKeepScopeInfo, |
| + outer_scope->scope_info_->Equals( |
|
jochen (gone - plz use gerrit)
2016/09/06 08:29:24
the same context might have different scope infos:
|
| + current_scope->scope_info_->OuterScopeInfo())); |
| } |
| current_scope = outer_scope; |
| if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
| @@ -384,6 +390,17 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| if (innermost_scope == nullptr) return script_scope; |
| script_scope->AddInnerScope(current_scope); |
| +#if DEBUG |
| + if (deserialization_mode == DeserializationMode::kKeepScopeInfo) { |
| + if (script_scope->scope_info_.is_null()) { |
| + DCHECK(!current_scope->scope_info_->HasOuterScopeInfo()); |
| + } else { |
| + DCHECK(!script_scope->scope_info_->HasOuterScopeInfo()); |
| + DCHECK(script_scope->scope_info_->Equals( |
| + current_scope->scope_info_->OuterScopeInfo())); |
| + } |
| + } |
| +#endif |
| return innermost_scope; |
| } |
| @@ -956,7 +973,14 @@ Declaration* Scope::CheckLexDeclarationsConflictingWith( |
| void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { |
| ResolveVariablesRecursively(info); |
| AllocateVariablesRecursively(); |
| - AllocateScopeInfosRecursively(info->isolate(), mode); |
| + |
| + MaybeHandle<ScopeInfo> outer_scope; |
| + for (const Scope* s = outer_scope_; s != nullptr; s = s->outer_scope_) { |
| + if (s->scope_info_.is_null()) continue; |
| + outer_scope = s->scope_info_; |
| + break; |
| + } |
| + AllocateScopeInfosRecursively(info->isolate(), mode, outer_scope); |
| } |
| bool Scope::AllowsLazyParsing() const { |
| @@ -1687,15 +1711,21 @@ void Scope::AllocateVariablesRecursively() { |
| DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| } |
| -void Scope::AllocateScopeInfosRecursively(Isolate* isolate, AnalyzeMode mode) { |
| +void Scope::AllocateScopeInfosRecursively(Isolate* isolate, AnalyzeMode mode, |
| + MaybeHandle<ScopeInfo> outer_scope) { |
| DCHECK(scope_info_.is_null()); |
| if (mode == AnalyzeMode::kDebugger || NeedsScopeInfo()) { |
| - scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
| + scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); |
| } |
| + // The ScopeInfo chain should mirror the context chain, so we only link to |
| + // the next outer scope that needs a context. |
| + MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; |
| + if (NeedsContext()) next_outer_scope = scope_info_; |
| + |
| // Allocate ScopeInfos for inner scopes. |
| for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| - scope->AllocateScopeInfosRecursively(isolate, mode); |
| + scope->AllocateScopeInfosRecursively(isolate, mode, next_outer_scope); |
| } |
| } |