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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 asm_function_ = false; | 264 asm_function_ = false; |
265 force_eager_compilation_ = false; | 265 force_eager_compilation_ = false; |
266 has_arguments_parameter_ = false; | 266 has_arguments_parameter_ = false; |
267 scope_uses_super_property_ = false; | 267 scope_uses_super_property_ = false; |
268 has_rest_ = false; | 268 has_rest_ = false; |
269 receiver_ = nullptr; | 269 receiver_ = nullptr; |
270 new_target_ = nullptr; | 270 new_target_ = nullptr; |
271 function_ = nullptr; | 271 function_ = nullptr; |
272 arguments_ = nullptr; | 272 arguments_ = nullptr; |
273 this_function_ = nullptr; | 273 this_function_ = nullptr; |
| 274 should_eager_compile_ = false; |
| 275 is_lazily_parsed_ = false; |
274 } | 276 } |
275 | 277 |
276 void Scope::SetDefaults() { | 278 void Scope::SetDefaults() { |
277 #ifdef DEBUG | 279 #ifdef DEBUG |
278 scope_name_ = nullptr; | 280 scope_name_ = nullptr; |
279 already_resolved_ = false; | 281 already_resolved_ = false; |
280 needs_migration_ = false; | 282 needs_migration_ = false; |
281 #endif | 283 #endif |
282 inner_scope_ = nullptr; | 284 inner_scope_ = nullptr; |
283 sibling_ = nullptr; | 285 sibling_ = nullptr; |
284 unresolved_ = nullptr; | 286 unresolved_ = nullptr; |
285 | 287 |
286 start_position_ = kNoSourcePosition; | 288 start_position_ = kNoSourcePosition; |
287 end_position_ = kNoSourcePosition; | 289 end_position_ = kNoSourcePosition; |
288 | 290 |
289 num_stack_slots_ = 0; | 291 num_stack_slots_ = 0; |
290 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 292 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
291 | 293 |
292 set_language_mode(SLOPPY); | 294 set_language_mode(SLOPPY); |
293 | 295 |
294 scope_calls_eval_ = false; | 296 scope_calls_eval_ = false; |
295 scope_nonlinear_ = false; | 297 scope_nonlinear_ = false; |
296 is_hidden_ = false; | 298 is_hidden_ = false; |
297 is_debug_evaluate_scope_ = false; | 299 is_debug_evaluate_scope_ = false; |
298 | 300 |
299 inner_scope_calls_eval_ = false; | 301 inner_scope_calls_eval_ = false; |
300 force_context_allocation_ = false; | 302 force_context_allocation_ = false; |
301 | 303 |
302 is_declaration_scope_ = false; | 304 is_declaration_scope_ = false; |
303 | |
304 is_lazily_parsed_ = false; | |
305 should_eager_compile_ = false; | |
306 } | 305 } |
307 | 306 |
308 bool Scope::HasSimpleParameters() { | 307 bool Scope::HasSimpleParameters() { |
309 DeclarationScope* scope = GetClosureScope(); | 308 DeclarationScope* scope = GetClosureScope(); |
310 return !scope->is_function_scope() || scope->has_simple_parameters(); | 309 return !scope->is_function_scope() || scope->has_simple_parameters(); |
311 } | 310 } |
312 | 311 |
313 bool Scope::ShouldEagerCompile() const { | 312 bool DeclarationScope::ShouldEagerCompile() const { |
314 if (is_declaration_scope() && | 313 if (!AllowsLazyCompilation()) return true; |
315 !AsDeclarationScope()->AllowsLazyCompilation()) { | |
316 return true; | |
317 } | |
318 return !is_lazily_parsed_ && should_eager_compile_; | 314 return !is_lazily_parsed_ && should_eager_compile_; |
319 } | 315 } |
320 | 316 |
321 void Scope::SetShouldEagerCompile() { | 317 void DeclarationScope::set_should_eager_compile() { |
322 should_eager_compile_ = true; | 318 should_eager_compile_ = true; |
323 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | |
324 if (inner->is_function_scope()) continue; | |
325 inner->SetShouldEagerCompile(); | |
326 } | |
327 } | 319 } |
328 | 320 |
329 void DeclarationScope::set_asm_module() { | 321 void DeclarationScope::set_asm_module() { |
330 asm_module_ = true; | 322 asm_module_ = true; |
331 // Mark any existing inner function scopes as asm function scopes. | 323 // Mark any existing inner function scopes as asm function scopes. |
332 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | 324 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
333 if (inner->is_function_scope()) { | 325 if (inner->is_function_scope()) { |
334 inner->AsDeclarationScope()->set_asm_function(); | 326 inner->AsDeclarationScope()->set_asm_function(); |
335 } | 327 } |
336 } | 328 } |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 | 554 |
563 // We are compiling one of three cases: | 555 // We are compiling one of three cases: |
564 // 1) top-level code, | 556 // 1) top-level code, |
565 // 2) a function/eval/module on the top-level | 557 // 2) a function/eval/module on the top-level |
566 // 3) a function/eval in a scope that was already resolved. | 558 // 3) a function/eval in a scope that was already resolved. |
567 DCHECK(scope->scope_type() == SCRIPT_SCOPE || | 559 DCHECK(scope->scope_type() == SCRIPT_SCOPE || |
568 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || | 560 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || |
569 scope->outer_scope()->already_resolved_); | 561 scope->outer_scope()->already_resolved_); |
570 | 562 |
571 // The outer scope is never lazy. | 563 // The outer scope is never lazy. |
572 scope->SetShouldEagerCompile(); | 564 scope->set_should_eager_compile(); |
573 | 565 |
574 scope->AllocateVariables(info, mode); | 566 scope->AllocateVariables(info, mode); |
575 | 567 |
576 // Ensuring that the outer script scope has a scope info avoids having | 568 // Ensuring that the outer script scope has a scope info avoids having |
577 // special case for native contexts vs other contexts. | 569 // special case for native contexts vs other contexts. |
578 if (info->script_scope()->scope_info_.is_null()) { | 570 if (info->script_scope()->scope_info_.is_null()) { |
579 info->script_scope()->scope_info_ = | 571 info->script_scope()->scope_info_ = |
580 handle(ScopeInfo::Empty(info->isolate())); | 572 handle(ScopeInfo::Empty(info->isolate())); |
581 } | 573 } |
582 | 574 |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 } | 1169 } |
1178 | 1170 |
1179 DeclarationScope* Scope::GetDeclarationScope() { | 1171 DeclarationScope* Scope::GetDeclarationScope() { |
1180 Scope* scope = this; | 1172 Scope* scope = this; |
1181 while (!scope->is_declaration_scope()) { | 1173 while (!scope->is_declaration_scope()) { |
1182 scope = scope->outer_scope(); | 1174 scope = scope->outer_scope(); |
1183 } | 1175 } |
1184 return scope->AsDeclarationScope(); | 1176 return scope->AsDeclarationScope(); |
1185 } | 1177 } |
1186 | 1178 |
| 1179 const DeclarationScope* Scope::GetClosureScope() const { |
| 1180 const Scope* scope = this; |
| 1181 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
| 1182 scope = scope->outer_scope(); |
| 1183 } |
| 1184 return scope->AsDeclarationScope(); |
| 1185 } |
| 1186 |
1187 DeclarationScope* Scope::GetClosureScope() { | 1187 DeclarationScope* Scope::GetClosureScope() { |
1188 Scope* scope = this; | 1188 Scope* scope = this; |
1189 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 1189 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
1190 scope = scope->outer_scope(); | 1190 scope = scope->outer_scope(); |
1191 } | 1191 } |
1192 return scope->AsDeclarationScope(); | 1192 return scope->AsDeclarationScope(); |
1193 } | 1193 } |
1194 | 1194 |
| 1195 bool Scope::NeedsScopeInfo() const { |
| 1196 DCHECK(!already_resolved_); |
| 1197 // A lazily parsed scope doesn't contain enough information to create a |
| 1198 // ScopeInfo from it. |
| 1199 if (!GetClosureScope()->ShouldEagerCompile()) return false; |
| 1200 // The debugger expects all functions to have scope infos. |
| 1201 // TODO(jochen|yangguo): Remove this requirement. |
| 1202 if (is_function_scope()) return true; |
| 1203 return NeedsContext(); |
| 1204 } |
| 1205 |
1195 ModuleScope* Scope::GetModuleScope() { | 1206 ModuleScope* Scope::GetModuleScope() { |
1196 Scope* scope = this; | 1207 Scope* scope = this; |
1197 DCHECK(!scope->is_script_scope()); | 1208 DCHECK(!scope->is_script_scope()); |
1198 while (!scope->is_module_scope()) { | 1209 while (!scope->is_module_scope()) { |
1199 scope = scope->outer_scope(); | 1210 scope = scope->outer_scope(); |
1200 DCHECK_NOT_NULL(scope); | 1211 DCHECK_NOT_NULL(scope); |
1201 } | 1212 } |
1202 return scope->AsModuleScope(); | 1213 return scope->AsModuleScope(); |
1203 } | 1214 } |
1204 | 1215 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 if (is_strict(language_mode())) { | 1450 if (is_strict(language_mode())) { |
1440 Indent(n1, "// strict mode scope\n"); | 1451 Indent(n1, "// strict mode scope\n"); |
1441 } | 1452 } |
1442 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); | 1453 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); |
1443 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); | 1454 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); |
1444 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 1455 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
1445 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { | 1456 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { |
1446 Indent(n1, "// scope uses 'super' property\n"); | 1457 Indent(n1, "// scope uses 'super' property\n"); |
1447 } | 1458 } |
1448 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 1459 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
1449 if (is_lazily_parsed_) Indent(n1, "// lazily parsed\n"); | 1460 if (is_declaration_scope()) { |
1450 if (should_eager_compile_) Indent(n1, "// will be compiled\n"); | 1461 DeclarationScope* scope = AsDeclarationScope(); |
| 1462 if (scope->is_lazily_parsed()) Indent(n1, "// lazily parsed\n"); |
| 1463 if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n"); |
| 1464 } |
1451 if (num_stack_slots_ > 0) { | 1465 if (num_stack_slots_ > 0) { |
1452 Indent(n1, "// "); | 1466 Indent(n1, "// "); |
1453 PrintF("%d stack slots\n", num_stack_slots_); | 1467 PrintF("%d stack slots\n", num_stack_slots_); |
1454 } | 1468 } |
1455 if (num_heap_slots_ > 0) { | 1469 if (num_heap_slots_ > 0) { |
1456 Indent(n1, "// "); | 1470 Indent(n1, "// "); |
1457 PrintF("%d heap slots\n", num_heap_slots_); | 1471 PrintF("%d heap slots\n", num_heap_slots_); |
1458 } | 1472 } |
1459 | 1473 |
1460 // Print locals. | 1474 // Print locals. |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 for (const auto& it : module()->regular_exports()) { | 1879 for (const auto& it : module()->regular_exports()) { |
1866 Variable* var = LookupLocal(it.first); | 1880 Variable* var = LookupLocal(it.first); |
1867 var->AllocateTo(VariableLocation::MODULE, 0); | 1881 var->AllocateTo(VariableLocation::MODULE, 0); |
1868 } | 1882 } |
1869 } | 1883 } |
1870 | 1884 |
1871 void Scope::AllocateVariablesRecursively() { | 1885 void Scope::AllocateVariablesRecursively() { |
1872 DCHECK(!already_resolved_); | 1886 DCHECK(!already_resolved_); |
1873 DCHECK_EQ(0, num_stack_slots_); | 1887 DCHECK_EQ(0, num_stack_slots_); |
1874 // Don't allocate variables of preparsed scopes. | 1888 // Don't allocate variables of preparsed scopes. |
1875 if (is_lazily_parsed_) return; | 1889 if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) { |
| 1890 return; |
| 1891 } |
1876 | 1892 |
1877 // Allocate variables for inner scopes. | 1893 // Allocate variables for inner scopes. |
1878 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1894 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1879 scope->AllocateVariablesRecursively(); | 1895 scope->AllocateVariablesRecursively(); |
1880 } | 1896 } |
1881 | 1897 |
1882 DCHECK(!already_resolved_); | 1898 DCHECK(!already_resolved_); |
1883 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 1899 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
1884 | 1900 |
1885 // Allocate variables for this scope. | 1901 // Allocate variables for this scope. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); | 1936 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); |
1921 } | 1937 } |
1922 | 1938 |
1923 // The ScopeInfo chain should mirror the context chain, so we only link to | 1939 // The ScopeInfo chain should mirror the context chain, so we only link to |
1924 // the next outer scope that needs a context. | 1940 // the next outer scope that needs a context. |
1925 MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; | 1941 MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; |
1926 if (NeedsContext()) next_outer_scope = scope_info_; | 1942 if (NeedsContext()) next_outer_scope = scope_info_; |
1927 | 1943 |
1928 // Allocate ScopeInfos for inner scopes. | 1944 // Allocate ScopeInfos for inner scopes. |
1929 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1945 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1930 AnalyzeMode next_mode = mode; | 1946 // The ScopeIterator which uses the AnalyzeMode::kDebugger only expects |
1931 bool next_eager = should_eager_compile_; | 1947 // to find ScopeInfos for the current function and all its inner |
1932 if (scope->is_function_scope()) { | 1948 // non-function scopes (see ScopeIterator::GetNestedScopeChain). |
1933 // Make sure all inner scopes have are consistently marked: we can't | 1949 AnalyzeMode next_mode = |
1934 // eager compile inner functions of lazy functions, but if a function | 1950 scope->is_function_scope() ? AnalyzeMode::kRegular : mode; |
1935 // should be eagerly compiled, all its inner scopes are compiled as well. | |
1936 next_eager = should_eager_compile_ ? scope->ShouldEagerCompile() : false; | |
1937 | |
1938 // The ScopeIterator which uses the AnalyzeMode::kDebugger only expects | |
1939 // to find ScopeInfos for the current function and all its inner | |
1940 // non-function scopes (see ScopeIterator::GetNestedScopeChain). | |
1941 next_mode = AnalyzeMode::kRegular; | |
1942 } | |
1943 scope->should_eager_compile_ = next_eager; | |
1944 scope->AllocateScopeInfosRecursively(isolate, next_mode, next_outer_scope); | 1951 scope->AllocateScopeInfosRecursively(isolate, next_mode, next_outer_scope); |
1945 } | 1952 } |
1946 } | 1953 } |
1947 | 1954 |
1948 int Scope::StackLocalCount() const { | 1955 int Scope::StackLocalCount() const { |
1949 Variable* function = | 1956 Variable* function = |
1950 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1957 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1951 return num_stack_slots() - | 1958 return num_stack_slots() - |
1952 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 1959 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
1953 } | 1960 } |
1954 | 1961 |
1955 | 1962 |
1956 int Scope::ContextLocalCount() const { | 1963 int Scope::ContextLocalCount() const { |
1957 if (num_heap_slots() == 0) return 0; | 1964 if (num_heap_slots() == 0) return 0; |
1958 Variable* function = | 1965 Variable* function = |
1959 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1966 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1960 bool is_function_var_in_context = | 1967 bool is_function_var_in_context = |
1961 function != nullptr && function->IsContextSlot(); | 1968 function != nullptr && function->IsContextSlot(); |
1962 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1969 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1963 (is_function_var_in_context ? 1 : 0); | 1970 (is_function_var_in_context ? 1 : 0); |
1964 } | 1971 } |
1965 | 1972 |
1966 } // namespace internal | 1973 } // namespace internal |
1967 } // namespace v8 | 1974 } // namespace v8 |
OLD | NEW |