OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { | 1085 void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { |
1086 ResolveVariablesRecursively(info); | 1086 ResolveVariablesRecursively(info); |
1087 AllocateVariablesRecursively(); | 1087 AllocateVariablesRecursively(); |
1088 | 1088 |
1089 MaybeHandle<ScopeInfo> outer_scope; | 1089 MaybeHandle<ScopeInfo> outer_scope; |
1090 for (const Scope* s = outer_scope_; s != nullptr; s = s->outer_scope_) { | 1090 for (const Scope* s = outer_scope_; s != nullptr; s = s->outer_scope_) { |
1091 if (s->scope_info_.is_null()) continue; | 1091 if (s->scope_info_.is_null()) continue; |
1092 outer_scope = s->scope_info_; | 1092 outer_scope = s->scope_info_; |
1093 break; | 1093 break; |
1094 } | 1094 } |
1095 AllocateScopeInfosRecursively(info->isolate(), mode, outer_scope); | 1095 AllocateScopeInfosRecursively(info->isolate(), outer_scope); |
| 1096 if (mode == AnalyzeMode::kDebugger) { |
| 1097 AllocateDebuggerScopeInfos(info->isolate(), outer_scope); |
| 1098 } |
1096 // The debugger expects all shared function infos to contain a scope info. | 1099 // The debugger expects all shared function infos to contain a scope info. |
1097 // Since the top-most scope will end up in a shared function info, make sure | 1100 // Since the top-most scope will end up in a shared function info, make sure |
1098 // it has one, even if it doesn't need a scope info. | 1101 // it has one, even if it doesn't need a scope info. |
1099 // TODO(jochen|yangguo): Remove this requirement. | 1102 // TODO(jochen|yangguo): Remove this requirement. |
1100 if (scope_info_.is_null()) { | 1103 if (scope_info_.is_null()) { |
1101 scope_info_ = ScopeInfo::Create(info->isolate(), zone(), this, outer_scope); | 1104 scope_info_ = ScopeInfo::Create(info->isolate(), zone(), this, outer_scope); |
1102 } | 1105 } |
1103 } | 1106 } |
1104 | 1107 |
1105 bool Scope::AllowsLazyParsingWithoutUnresolvedVariables( | 1108 bool Scope::AllowsLazyParsingWithoutUnresolvedVariables( |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 DeclarationScope* Scope::GetClosureScope() { | 1190 DeclarationScope* Scope::GetClosureScope() { |
1188 Scope* scope = this; | 1191 Scope* scope = this; |
1189 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 1192 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
1190 scope = scope->outer_scope(); | 1193 scope = scope->outer_scope(); |
1191 } | 1194 } |
1192 return scope->AsDeclarationScope(); | 1195 return scope->AsDeclarationScope(); |
1193 } | 1196 } |
1194 | 1197 |
1195 bool Scope::NeedsScopeInfo() const { | 1198 bool Scope::NeedsScopeInfo() const { |
1196 DCHECK(!already_resolved_); | 1199 DCHECK(!already_resolved_); |
1197 // A lazily parsed scope doesn't contain enough information to create a | 1200 DCHECK(GetClosureScope()->ShouldEagerCompile()); |
1198 // ScopeInfo from it. | |
1199 if (!GetClosureScope()->ShouldEagerCompile()) return false; | |
1200 // The debugger expects all functions to have scope infos. | 1201 // The debugger expects all functions to have scope infos. |
1201 // TODO(jochen|yangguo): Remove this requirement. | 1202 // TODO(jochen|yangguo): Remove this requirement. |
1202 if (is_function_scope()) return true; | 1203 if (is_function_scope()) return true; |
1203 return NeedsContext(); | 1204 return NeedsContext(); |
1204 } | 1205 } |
1205 | 1206 |
1206 ModuleScope* Scope::GetModuleScope() { | 1207 ModuleScope* Scope::GetModuleScope() { |
1207 Scope* scope = this; | 1208 Scope* scope = this; |
1208 DCHECK(!scope->is_script_scope()); | 1209 DCHECK(!scope->is_script_scope()); |
1209 while (!scope->is_module_scope()) { | 1210 while (!scope->is_module_scope()) { |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1922 // If we didn't allocate any locals in the local context, then we only | 1923 // If we didn't allocate any locals in the local context, then we only |
1923 // need the minimal number of slots if we must have a context. | 1924 // need the minimal number of slots if we must have a context. |
1924 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1925 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1925 num_heap_slots_ = 0; | 1926 num_heap_slots_ = 0; |
1926 } | 1927 } |
1927 | 1928 |
1928 // Allocation done. | 1929 // Allocation done. |
1929 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1930 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1930 } | 1931 } |
1931 | 1932 |
1932 void Scope::AllocateScopeInfosRecursively(Isolate* isolate, AnalyzeMode mode, | 1933 void Scope::AllocateScopeInfosRecursively(Isolate* isolate, |
1933 MaybeHandle<ScopeInfo> outer_scope) { | 1934 MaybeHandle<ScopeInfo> outer_scope) { |
1934 DCHECK(scope_info_.is_null()); | 1935 DCHECK(scope_info_.is_null()); |
1935 if (mode == AnalyzeMode::kDebugger || NeedsScopeInfo()) { | 1936 MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; |
| 1937 |
| 1938 if (NeedsScopeInfo()) { |
1936 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); | 1939 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); |
| 1940 // The ScopeInfo chain should mirror the context chain, so we only link to |
| 1941 // the next outer scope that needs a context. |
| 1942 if (NeedsContext()) next_outer_scope = scope_info_; |
1937 } | 1943 } |
1938 | 1944 |
1939 // The ScopeInfo chain should mirror the context chain, so we only link to | |
1940 // the next outer scope that needs a context. | |
1941 MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; | |
1942 if (NeedsContext()) next_outer_scope = scope_info_; | |
1943 | |
1944 // Allocate ScopeInfos for inner scopes. | 1945 // Allocate ScopeInfos for inner scopes. |
1945 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1946 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1946 // The ScopeIterator which uses the AnalyzeMode::kDebugger only expects | 1947 if (!scope->is_function_scope() || |
1947 // to find ScopeInfos for the current function and all its inner | 1948 scope->AsDeclarationScope()->ShouldEagerCompile()) { |
1948 // non-function scopes (see ScopeIterator::GetNestedScopeChain). | 1949 scope->AllocateScopeInfosRecursively(isolate, next_outer_scope); |
1949 AnalyzeMode next_mode = | 1950 } |
1950 scope->is_function_scope() ? AnalyzeMode::kRegular : mode; | |
1951 scope->AllocateScopeInfosRecursively(isolate, next_mode, next_outer_scope); | |
1952 } | 1951 } |
1953 } | 1952 } |
1954 | 1953 |
| 1954 void Scope::AllocateDebuggerScopeInfos(Isolate* isolate, |
| 1955 MaybeHandle<ScopeInfo> outer_scope) { |
| 1956 if (scope_info_.is_null()) { |
| 1957 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); |
| 1958 } |
| 1959 MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope; |
| 1960 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1961 if (scope->is_function_scope()) continue; |
| 1962 scope->AllocateDebuggerScopeInfos(isolate, outer); |
| 1963 } |
| 1964 } |
| 1965 |
1955 int Scope::StackLocalCount() const { | 1966 int Scope::StackLocalCount() const { |
1956 Variable* function = | 1967 Variable* function = |
1957 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1968 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1958 return num_stack_slots() - | 1969 return num_stack_slots() - |
1959 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 1970 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
1960 } | 1971 } |
1961 | 1972 |
1962 | 1973 |
1963 int Scope::ContextLocalCount() const { | 1974 int Scope::ContextLocalCount() const { |
1964 if (num_heap_slots() == 0) return 0; | 1975 if (num_heap_slots() == 0) return 0; |
1965 Variable* function = | 1976 Variable* function = |
1966 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1977 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1967 bool is_function_var_in_context = | 1978 bool is_function_var_in_context = |
1968 function != nullptr && function->IsContextSlot(); | 1979 function != nullptr && function->IsContextSlot(); |
1969 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1980 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1970 (is_function_var_in_context ? 1 : 0); | 1981 (is_function_var_in_context ? 1 : 0); |
1971 } | 1982 } |
1972 | 1983 |
1973 } // namespace internal | 1984 } // namespace internal |
1974 } // namespace v8 | 1985 } // namespace v8 |
OLD | NEW |