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" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/counters.h" | 12 #include "src/counters.h" |
13 #include "src/messages.h" | 13 #include "src/messages.h" |
14 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
15 #include "src/objects/module-info.h" | 15 #include "src/objects/module-info.h" |
16 #include "src/parsing/parse-info.h" | 16 #include "src/parsing/parse-info.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 | 20 |
21 namespace { | 21 namespace { |
22 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); | 22 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); |
| 23 void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2); |
| 24 |
| 25 bool IsLexical(Variable* variable) { |
| 26 if (variable == kDummyPreParserLexicalVariable) return true; |
| 27 if (variable == kDummyPreParserVariable) return false; |
| 28 return IsLexicalVariableMode(variable->mode()); |
| 29 } |
| 30 |
23 } // namespace | 31 } // namespace |
24 | 32 |
25 // ---------------------------------------------------------------------------- | 33 // ---------------------------------------------------------------------------- |
26 // Implementation of LocalsMap | 34 // Implementation of LocalsMap |
27 // | 35 // |
28 // Note: We are storing the handle locations as key values in the hash map. | 36 // Note: We are storing the handle locations as key values in the hash map. |
29 // When inserting a new variable via Declare(), we rely on the fact that | 37 // When inserting a new variable via Declare(), we rely on the fact that |
30 // the handle location remains alive for the duration of that variable | 38 // the handle location remains alive for the duration of that variable |
31 // use. Because a Variable holding a handle with the same location exists | 39 // use. Because a Variable holding a handle with the same location exists |
32 // this is ensured. | 40 // this is ensured. |
(...skipping 16 matching lines...) Expand all Loading... |
49 if (added) *added = p->value == nullptr; | 57 if (added) *added = p->value == nullptr; |
50 if (p->value == nullptr) { | 58 if (p->value == nullptr) { |
51 // The variable has not been declared yet -> insert it. | 59 // The variable has not been declared yet -> insert it. |
52 DCHECK_EQ(name, p->key); | 60 DCHECK_EQ(name, p->key); |
53 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, | 61 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, |
54 maybe_assigned_flag); | 62 maybe_assigned_flag); |
55 } | 63 } |
56 return reinterpret_cast<Variable*>(p->value); | 64 return reinterpret_cast<Variable*>(p->value); |
57 } | 65 } |
58 | 66 |
59 void VariableMap::DeclareName(Zone* zone, const AstRawString* name) { | 67 void VariableMap::DeclareName(Zone* zone, const AstRawString* name, |
| 68 VariableMode mode) { |
60 Entry* p = | 69 Entry* p = |
61 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
62 ZoneAllocationPolicy(zone)); | 71 ZoneAllocationPolicy(zone)); |
63 if (p->value == nullptr) { | 72 if (p->value == nullptr) { |
64 // The variable has not been declared yet -> insert it. | 73 // The variable has not been declared yet -> insert it. |
65 DCHECK_EQ(name, p->key); | 74 DCHECK_EQ(name, p->key); |
66 p->value = kDummyPreParserVariable; | 75 p->value = |
| 76 mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable; |
67 } | 77 } |
68 } | 78 } |
69 | 79 |
70 void VariableMap::Remove(Variable* var) { | 80 void VariableMap::Remove(Variable* var) { |
71 const AstRawString* name = var->raw_name(); | 81 const AstRawString* name = var->raw_name(); |
72 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); | 82 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); |
73 } | 83 } |
74 | 84 |
75 void VariableMap::Add(Zone* zone, Variable* var) { | 85 void VariableMap::Add(Zone* zone, Variable* var) { |
76 const AstRawString* name = var->raw_name(); | 86 const AstRawString* name = var->raw_name(); |
77 Entry* p = | 87 Entry* p = |
78 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 88 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
79 ZoneAllocationPolicy(zone)); | 89 ZoneAllocationPolicy(zone)); |
80 DCHECK_NULL(p->value); | 90 DCHECK_NULL(p->value); |
81 DCHECK_EQ(name, p->key); | 91 DCHECK_EQ(name, p->key); |
82 p->value = var; | 92 p->value = var; |
83 } | 93 } |
84 | 94 |
85 Variable* VariableMap::Lookup(const AstRawString* name) { | 95 Variable* VariableMap::Lookup(const AstRawString* name) { |
86 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); | 96 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); |
87 if (p != NULL) { | 97 if (p != NULL) { |
88 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); | 98 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); |
89 DCHECK(p->value != NULL); | 99 DCHECK(p->value != NULL); |
90 return reinterpret_cast<Variable*>(p->value); | 100 return reinterpret_cast<Variable*>(p->value); |
91 } | 101 } |
92 return NULL; | 102 return NULL; |
93 } | 103 } |
94 | 104 |
| 105 void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) { |
| 106 if (statement_ != nullptr) { |
| 107 statement_->set_statement(statement); |
| 108 } |
| 109 } |
| 110 |
95 SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone) | 111 SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone) |
96 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} | 112 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} |
97 | 113 |
98 void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name, | 114 void SloppyBlockFunctionMap::Declare( |
99 SloppyBlockFunctionStatement* stmt) { | 115 Zone* zone, const AstRawString* name, |
| 116 SloppyBlockFunctionMap::Delegate* delegate) { |
100 // AstRawStrings are unambiguous, i.e., the same string is always represented | 117 // AstRawStrings are unambiguous, i.e., the same string is always represented |
101 // by the same AstRawString*. | 118 // by the same AstRawString*. |
102 Entry* p = | 119 Entry* p = |
103 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 120 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
104 ZoneAllocationPolicy(zone)); | 121 ZoneAllocationPolicy(zone)); |
105 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); | 122 delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value)); |
106 p->value = stmt; | 123 p->value = delegate; |
107 } | 124 } |
108 | 125 |
109 | |
110 // ---------------------------------------------------------------------------- | 126 // ---------------------------------------------------------------------------- |
111 // Implementation of Scope | 127 // Implementation of Scope |
112 | 128 |
113 Scope::Scope(Zone* zone) | 129 Scope::Scope(Zone* zone) |
114 : zone_(zone), | 130 : zone_(zone), |
115 outer_scope_(nullptr), | 131 outer_scope_(nullptr), |
116 variables_(zone), | 132 variables_(zone), |
117 scope_type_(SCRIPT_SCOPE) { | 133 scope_type_(SCRIPT_SCOPE) { |
118 SetDefaults(); | 134 SetDefaults(); |
119 } | 135 } |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 | 457 |
442 const ModuleScope* Scope::AsModuleScope() const { | 458 const ModuleScope* Scope::AsModuleScope() const { |
443 DCHECK(is_module_scope()); | 459 DCHECK(is_module_scope()); |
444 return static_cast<const ModuleScope*>(this); | 460 return static_cast<const ModuleScope*>(this); |
445 } | 461 } |
446 | 462 |
447 int Scope::num_parameters() const { | 463 int Scope::num_parameters() const { |
448 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | 464 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; |
449 } | 465 } |
450 | 466 |
| 467 void DeclarationScope::DeclareSloppyBlockFunction( |
| 468 const AstRawString* name, Scope* scope, |
| 469 SloppyBlockFunctionStatement* statement) { |
| 470 auto* delegate = |
| 471 new (zone()) SloppyBlockFunctionMap::Delegate(scope, statement); |
| 472 sloppy_block_function_map_.Declare(zone(), name, delegate); |
| 473 } |
| 474 |
451 void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { | 475 void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { |
452 DCHECK(is_sloppy(language_mode())); | 476 DCHECK(is_sloppy(language_mode())); |
453 DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() || | 477 DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() || |
454 (is_block_scope() && outer_scope()->is_function_scope())); | 478 (is_block_scope() && outer_scope()->is_function_scope())); |
455 DCHECK(HasSimpleParameters() || is_block_scope()); | 479 DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_); |
| 480 DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_); |
| 481 |
456 bool has_simple_parameters = HasSimpleParameters(); | 482 bool has_simple_parameters = HasSimpleParameters(); |
457 // For each variable which is used as a function declaration in a sloppy | 483 // For each variable which is used as a function declaration in a sloppy |
458 // block, | 484 // block, |
459 SloppyBlockFunctionMap* map = sloppy_block_function_map(); | 485 SloppyBlockFunctionMap* map = sloppy_block_function_map(); |
460 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | 486 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { |
461 AstRawString* name = static_cast<AstRawString*>(p->key); | 487 AstRawString* name = static_cast<AstRawString*>(p->key); |
462 | 488 |
463 // If the variable wouldn't conflict with a lexical declaration | 489 // If the variable wouldn't conflict with a lexical declaration |
464 // or parameter, | 490 // or parameter, |
465 | 491 |
(...skipping 11 matching lines...) Expand all Loading... |
477 } | 503 } |
478 } else { | 504 } else { |
479 if (IsDeclaredParameter(name)) { | 505 if (IsDeclaredParameter(name)) { |
480 continue; | 506 continue; |
481 } | 507 } |
482 } | 508 } |
483 | 509 |
484 bool var_created = false; | 510 bool var_created = false; |
485 | 511 |
486 // Write in assignments to var for each block-scoped function declaration | 512 // Write in assignments to var for each block-scoped function declaration |
487 auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value); | 513 auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value); |
488 | 514 |
489 DeclarationScope* decl_scope = this; | 515 DeclarationScope* decl_scope = this; |
490 while (decl_scope->is_eval_scope()) { | 516 while (decl_scope->is_eval_scope()) { |
491 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); | 517 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); |
492 } | 518 } |
493 Scope* outer_scope = decl_scope->outer_scope(); | 519 Scope* outer_scope = decl_scope->outer_scope(); |
494 | 520 |
495 for (SloppyBlockFunctionStatement* delegate = delegates; | 521 for (SloppyBlockFunctionMap::Delegate* delegate = delegates; |
496 delegate != nullptr; delegate = delegate->next()) { | 522 delegate != nullptr; delegate = delegate->next()) { |
497 // Check if there's a conflict with a lexical declaration | 523 // Check if there's a conflict with a lexical declaration |
498 Scope* query_scope = delegate->scope()->outer_scope(); | 524 Scope* query_scope = delegate->scope()->outer_scope(); |
499 Variable* var = nullptr; | 525 Variable* var = nullptr; |
500 bool should_hoist = true; | 526 bool should_hoist = true; |
501 | 527 |
502 // Note that we perform this loop for each delegate named 'name', | 528 // Note that we perform this loop for each delegate named 'name', |
503 // which may duplicate work if those delegates share scopes. | 529 // which may duplicate work if those delegates share scopes. |
504 // It is not sufficient to just do a Lookup on query_scope: for | 530 // It is not sufficient to just do a Lookup on query_scope: for |
505 // example, that does not prevent hoisting of the function in | 531 // example, that does not prevent hoisting of the function in |
506 // `{ let e; try {} catch (e) { function e(){} } }` | 532 // `{ let e; try {} catch (e) { function e(){} } }` |
507 do { | 533 do { |
508 var = query_scope->LookupLocal(name); | 534 var = query_scope->LookupLocal(name); |
509 if (var != nullptr && IsLexicalVariableMode(var->mode())) { | 535 if (var != nullptr && IsLexical(var)) { |
510 should_hoist = false; | 536 should_hoist = false; |
511 break; | 537 break; |
512 } | 538 } |
513 query_scope = query_scope->outer_scope(); | 539 query_scope = query_scope->outer_scope(); |
514 } while (query_scope != outer_scope); | 540 } while (query_scope != outer_scope); |
515 | 541 |
516 if (!should_hoist) continue; | 542 if (!should_hoist) continue; |
517 | 543 |
518 // Declare a var-style binding for the function in the outer scope | 544 // Declare a var-style binding for the function in the outer scope |
519 if (!var_created) { | 545 if (!var_created) { |
520 var_created = true; | 546 var_created = true; |
521 VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE); | 547 if (factory) { |
522 Declaration* declaration = | 548 VariableProxy* proxy = |
523 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); | 549 factory->NewVariableProxy(name, NORMAL_VARIABLE); |
524 // Based on the preceding check, it doesn't matter what we pass as | 550 auto declaration = |
525 // allow_harmony_restrictive_generators and | 551 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); |
526 // sloppy_mode_block_scope_function_redefinition. | 552 // Based on the preceding check, it doesn't matter what we pass as |
527 bool ok = true; | 553 // allow_harmony_restrictive_generators and |
528 DeclareVariable(declaration, VAR, | 554 // sloppy_mode_block_scope_function_redefinition. |
529 Variable::DefaultInitializationFlag(VAR), false, | 555 bool ok = true; |
530 nullptr, &ok); | 556 DeclareVariable(declaration, VAR, |
531 CHECK(ok); // Based on the preceding check, this should not fail | 557 Variable::DefaultInitializationFlag(VAR), false, |
| 558 nullptr, &ok); |
| 559 CHECK(ok); // Based on the preceding check, this should not fail |
| 560 } else { |
| 561 DeclareVariableName(name, VAR); |
| 562 } |
532 } | 563 } |
533 | 564 |
534 Expression* assignment = factory->NewAssignment( | 565 if (factory) { |
535 Token::ASSIGN, NewUnresolved(factory, name), | 566 Expression* assignment = factory->NewAssignment( |
536 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); | 567 Token::ASSIGN, NewUnresolved(factory, name), |
537 Statement* statement = | 568 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); |
538 factory->NewExpressionStatement(assignment, kNoSourcePosition); | 569 Statement* statement = |
539 delegate->set_statement(statement); | 570 factory->NewExpressionStatement(assignment, kNoSourcePosition); |
| 571 delegate->set_statement(statement); |
| 572 } |
540 } | 573 } |
541 } | 574 } |
542 } | 575 } |
543 | 576 |
544 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { | 577 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { |
545 RuntimeCallTimerScope runtimeTimer(info->isolate(), | 578 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
546 &RuntimeCallStats::CompileScopeAnalysis); | 579 &RuntimeCallStats::CompileScopeAnalysis); |
547 DCHECK(info->literal() != NULL); | 580 DCHECK(info->literal() != NULL); |
548 DeclarationScope* scope = info->literal()->scope(); | 581 DeclarationScope* scope = info->literal()->scope(); |
549 | 582 |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 DCHECK(!is_eval_scope()); | 1074 DCHECK(!is_eval_scope()); |
1042 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in | 1075 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in |
1043 // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by | 1076 // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by |
1044 // calling DeclareLocal directly, and it doesn't make sense to add a similar | 1077 // calling DeclareLocal directly, and it doesn't make sense to add a similar |
1045 // bypass mechanism for PreParser. | 1078 // bypass mechanism for PreParser. |
1046 DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) && | 1079 DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) && |
1047 (is_block_scope() || is_catch_scope()))); | 1080 (is_block_scope() || is_catch_scope()))); |
1048 DCHECK(scope_info_.is_null()); | 1081 DCHECK(scope_info_.is_null()); |
1049 | 1082 |
1050 // Declare the variable in the declaration scope. | 1083 // Declare the variable in the declaration scope. |
1051 variables_.DeclareName(zone(), name); | 1084 variables_.DeclareName(zone(), name, mode); |
1052 } | 1085 } |
1053 | 1086 |
1054 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1087 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
1055 const AstRawString* name, | 1088 const AstRawString* name, |
1056 int start_position, VariableKind kind) { | 1089 int start_position, VariableKind kind) { |
1057 // Note that we must not share the unresolved variables with | 1090 // Note that we must not share the unresolved variables with |
1058 // the same name because they may be removed selectively via | 1091 // the same name because they may be removed selectively via |
1059 // RemoveUnresolved(). | 1092 // RemoveUnresolved(). |
1060 DCHECK(!already_resolved_); | 1093 DCHECK(!already_resolved_); |
1061 DCHECK_EQ(factory->zone(), zone()); | 1094 DCHECK_EQ(factory->zone(), zone()); |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 } | 1673 } |
1641 | 1674 |
1642 DCHECK(!is_script_scope()); | 1675 DCHECK(!is_script_scope()); |
1643 | 1676 |
1644 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); | 1677 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); |
1645 | 1678 |
1646 // The variable could not be resolved statically. | 1679 // The variable could not be resolved statically. |
1647 if (var == nullptr) return var; | 1680 if (var == nullptr) return var; |
1648 | 1681 |
1649 // TODO(marja): Separate LookupRecursive for preparsed scopes better. | 1682 // TODO(marja): Separate LookupRecursive for preparsed scopes better. |
1650 if (var == kDummyPreParserVariable) { | 1683 if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) { |
1651 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); | 1684 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
1652 DCHECK(FLAG_lazy_inner_functions); | 1685 DCHECK(FLAG_lazy_inner_functions); |
1653 return var; | 1686 return var; |
1654 } | 1687 } |
1655 | 1688 |
1656 if (is_function_scope() && !var->is_dynamic()) { | 1689 if (is_function_scope() && !var->is_dynamic()) { |
1657 var->ForceContextAllocation(); | 1690 var->ForceContextAllocation(); |
1658 } | 1691 } |
1659 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 1692 // "this" can't be shadowed by "eval"-introduced bindings or by "with" |
1660 // scopes. | 1693 // scopes. |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1838 : this; | 1871 : this; |
1839 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1872 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
1840 proxy = next) { | 1873 proxy = next) { |
1841 next = proxy->next_unresolved(); | 1874 next = proxy->next_unresolved(); |
1842 DCHECK(!proxy->is_resolved()); | 1875 DCHECK(!proxy->is_resolved()); |
1843 Variable* var = | 1876 Variable* var = |
1844 lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); | 1877 lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); |
1845 if (var == nullptr) { | 1878 if (var == nullptr) { |
1846 proxy->set_next_unresolved(stack); | 1879 proxy->set_next_unresolved(stack); |
1847 stack = proxy; | 1880 stack = proxy; |
1848 } else if (var != kDummyPreParserVariable) { | 1881 } else if (var != kDummyPreParserVariable && |
| 1882 var != kDummyPreParserLexicalVariable) { |
1849 if (info != nullptr) { | 1883 if (info != nullptr) { |
1850 // In this case we need to leave scopes in a way that they can be | 1884 // In this case we need to leave scopes in a way that they can be |
1851 // allocated. If we resolved variables from lazy parsed scopes, we need | 1885 // allocated. If we resolved variables from lazy parsed scopes, we need |
1852 // to context allocate the var. | 1886 // to context allocate the var. |
1853 ResolveTo(info, proxy, var); | 1887 ResolveTo(info, proxy, var); |
1854 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); | 1888 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); |
1855 } else { | 1889 } else { |
1856 var->set_is_used(); | 1890 var->set_is_used(); |
1857 } | 1891 } |
1858 } | 1892 } |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 Variable* function = | 2168 Variable* function = |
2135 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2169 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2136 bool is_function_var_in_context = | 2170 bool is_function_var_in_context = |
2137 function != nullptr && function->IsContextSlot(); | 2171 function != nullptr && function->IsContextSlot(); |
2138 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2172 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
2139 (is_function_var_in_context ? 1 : 0); | 2173 (is_function_var_in_context ? 1 : 0); |
2140 } | 2174 } |
2141 | 2175 |
2142 } // namespace internal | 2176 } // namespace internal |
2143 } // namespace v8 | 2177 } // namespace v8 |
OLD | NEW |