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/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 | 73 |
74 | 74 |
75 // ---------------------------------------------------------------------------- | 75 // ---------------------------------------------------------------------------- |
76 // Implementation of Scope | 76 // Implementation of Scope |
77 | 77 |
78 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) | 78 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
79 : zone_(zone), | 79 : zone_(zone), |
80 outer_scope_(outer_scope), | 80 outer_scope_(outer_scope), |
81 variables_(zone), | 81 variables_(zone), |
82 decls_(4, zone), | 82 decls_(4, zone), |
83 scope_type_(scope_type), | 83 scope_type_(scope_type) { |
84 already_resolved_(false) { | |
85 SetDefaults(); | 84 SetDefaults(); |
86 if (outer_scope == nullptr) { | 85 if (outer_scope == nullptr) { |
87 // If the outer scope is null, this cannot be a with scope. The outermost | 86 // If the outer scope is null, this cannot be a with scope. The outermost |
88 // scope must be a script scope. | 87 // scope must be a script scope. |
89 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 88 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
90 } else { | 89 } else { |
91 asm_function_ = outer_scope_->asm_module_; | 90 asm_function_ = outer_scope_->asm_module_; |
92 // Inherit the language mode from the parent scope unless we're a module | 91 // Inherit the language mode from the parent scope unless we're a module |
93 // scope. | 92 // scope. |
94 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; | 93 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; |
(...skipping 25 matching lines...) Expand all Loading... | |
120 } | 119 } |
121 } | 120 } |
122 | 121 |
123 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 122 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
124 Handle<ScopeInfo> scope_info) | 123 Handle<ScopeInfo> scope_info) |
125 : zone_(zone), | 124 : zone_(zone), |
126 outer_scope_(nullptr), | 125 outer_scope_(nullptr), |
127 variables_(zone), | 126 variables_(zone), |
128 decls_(0, zone), | 127 decls_(0, zone), |
129 scope_info_(scope_info), | 128 scope_info_(scope_info), |
130 scope_type_(scope_type), | 129 scope_type_(scope_type) { |
131 already_resolved_(true) { | |
132 SetDefaults(); | 130 SetDefaults(); |
131 #ifdef DEBUG | |
132 already_resolved_ = true; | |
133 #endif | |
133 if (scope_type == WITH_SCOPE) { | 134 if (scope_type == WITH_SCOPE) { |
134 DCHECK(scope_info.is_null()); | 135 DCHECK(scope_info.is_null()); |
135 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | |
136 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | |
137 } else { | 136 } else { |
138 scope_calls_eval_ = scope_info->CallsEval(); | 137 scope_calls_eval_ = scope_info->CallsEval(); |
139 language_mode_ = scope_info->language_mode(); | 138 language_mode_ = scope_info->language_mode(); |
140 num_heap_slots_ = scope_info->ContextLength(); | 139 num_heap_slots_ = scope_info->ContextLength(); |
141 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | |
142 } | 140 } |
141 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | |
143 | 142 |
144 if (inner_scope != nullptr) AddInnerScope(inner_scope); | 143 if (inner_scope != nullptr) AddInnerScope(inner_scope); |
145 } | 144 } |
146 | 145 |
147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | 146 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, |
148 ScopeType scope_type, | 147 ScopeType scope_type, |
149 Handle<ScopeInfo> scope_info) | 148 Handle<ScopeInfo> scope_info) |
150 : Scope(zone, inner_scope, scope_type, scope_info), | 149 : Scope(zone, inner_scope, scope_type, scope_info), |
151 function_kind_(scope_info->function_kind()), | 150 function_kind_(scope_info->function_kind()), |
152 temps_(0, zone), | 151 temps_(0, zone), |
153 params_(0, zone), | 152 params_(0, zone), |
154 sloppy_block_function_map_(zone) { | 153 sloppy_block_function_map_(zone) { |
155 SetDefaults(); | 154 SetDefaults(); |
156 } | 155 } |
157 | 156 |
158 Scope::Scope(Zone* zone, Scope* inner_scope, | 157 Scope::Scope(Zone* zone, Scope* inner_scope, |
159 const AstRawString* catch_variable_name) | 158 const AstRawString* catch_variable_name) |
160 : zone_(zone), | 159 : zone_(zone), |
161 outer_scope_(nullptr), | 160 outer_scope_(nullptr), |
162 variables_(zone), | 161 variables_(zone), |
163 decls_(0, zone), | 162 decls_(0, zone), |
164 scope_type_(CATCH_SCOPE), | 163 scope_type_(CATCH_SCOPE) { |
165 already_resolved_(true) { | |
166 SetDefaults(); | 164 SetDefaults(); |
165 #ifdef DEBUG | |
166 already_resolved_ = true; | |
167 #endif | |
167 if (inner_scope != nullptr) AddInnerScope(inner_scope); | 168 if (inner_scope != nullptr) AddInnerScope(inner_scope); |
168 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | |
169 Variable* variable = | 169 Variable* variable = |
170 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, | 170 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, |
171 kCreatedInitialized); | 171 kCreatedInitialized); |
172 AllocateHeapSlot(variable); | 172 AllocateHeapSlot(variable); |
173 } | 173 } |
174 | 174 |
175 void DeclarationScope::SetDefaults() { | 175 void DeclarationScope::SetDefaults() { |
176 is_declaration_scope_ = true; | 176 is_declaration_scope_ = true; |
177 has_simple_parameters_ = true; | 177 has_simple_parameters_ = true; |
178 receiver_ = nullptr; | 178 receiver_ = nullptr; |
179 new_target_ = nullptr; | 179 new_target_ = nullptr; |
180 function_ = nullptr; | 180 function_ = nullptr; |
181 arguments_ = nullptr; | 181 arguments_ = nullptr; |
182 this_function_ = nullptr; | 182 this_function_ = nullptr; |
183 arity_ = 0; | 183 arity_ = 0; |
184 rest_parameter_ = nullptr; | 184 rest_parameter_ = nullptr; |
185 rest_index_ = -1; | 185 rest_index_ = -1; |
186 module_descriptor_ = nullptr; | 186 module_descriptor_ = nullptr; |
187 } | 187 } |
188 | 188 |
189 void Scope::SetDefaults() { | 189 void Scope::SetDefaults() { |
190 #ifdef DEBUG | 190 #ifdef DEBUG |
191 scope_name_ = nullptr; | 191 scope_name_ = nullptr; |
192 already_resolved_ = false; | |
192 #endif | 193 #endif |
193 inner_scope_ = nullptr; | 194 inner_scope_ = nullptr; |
194 sibling_ = nullptr; | 195 sibling_ = nullptr; |
195 unresolved_ = nullptr; | 196 unresolved_ = nullptr; |
196 dynamics_ = nullptr; | 197 dynamics_ = nullptr; |
197 | 198 |
198 start_position_ = kNoSourcePosition; | 199 start_position_ = kNoSourcePosition; |
199 end_position_ = kNoSourcePosition; | 200 end_position_ = kNoSourcePosition; |
200 | 201 |
201 num_stack_slots_ = 0; | 202 num_stack_slots_ = 0; |
202 num_heap_slots_ = 0; | 203 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
203 num_global_slots_ = 0; | 204 num_global_slots_ = 0; |
204 | 205 |
205 language_mode_ = SLOPPY; | 206 language_mode_ = SLOPPY; |
206 | 207 |
207 scope_inside_with_ = false; | 208 scope_inside_with_ = false; |
208 scope_calls_eval_ = false; | 209 scope_calls_eval_ = false; |
209 scope_uses_super_property_ = false; | 210 scope_uses_super_property_ = false; |
210 has_arguments_parameter_ = false; | 211 has_arguments_parameter_ = false; |
211 asm_module_ = false; | 212 asm_module_ = false; |
212 asm_function_ = false; | 213 asm_function_ = false; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 void Scope::Analyze(ParseInfo* info) { | 375 void Scope::Analyze(ParseInfo* info) { |
375 DCHECK(info->literal() != NULL); | 376 DCHECK(info->literal() != NULL); |
376 DeclarationScope* scope = info->literal()->scope(); | 377 DeclarationScope* scope = info->literal()->scope(); |
377 | 378 |
378 // We are compiling one of three cases: | 379 // We are compiling one of three cases: |
379 // 1) top-level code, | 380 // 1) top-level code, |
380 // 2) a function/eval/module on the top-level | 381 // 2) a function/eval/module on the top-level |
381 // 3) a function/eval in a scope that was already resolved. | 382 // 3) a function/eval in a scope that was already resolved. |
382 DCHECK(scope->scope_type() == SCRIPT_SCOPE || | 383 DCHECK(scope->scope_type() == SCRIPT_SCOPE || |
383 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || | 384 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || |
384 scope->outer_scope()->already_resolved()); | 385 scope->outer_scope()->already_resolved_); |
385 | 386 |
386 // Allocate the variables. | 387 // Allocate the variables. |
387 { | 388 { |
388 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 389 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
389 scope->AllocateVariables(info, &ast_node_factory); | 390 scope->AllocateVariables(info, &ast_node_factory); |
390 } | 391 } |
391 | 392 |
392 #ifdef DEBUG | 393 #ifdef DEBUG |
393 if (info->script_is_native() ? FLAG_print_builtin_scopes | 394 if (info->script_is_native() ? FLAG_print_builtin_scopes |
394 : FLAG_print_scopes) { | 395 : FLAG_print_scopes) { |
395 scope->Print(); | 396 scope->Print(); |
396 } | 397 } |
397 scope->CheckScopePositions(); | 398 scope->CheckScopePositions(); |
398 scope->CheckZones(); | 399 scope->CheckZones(); |
399 #endif | 400 #endif |
400 } | 401 } |
401 | 402 |
402 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { | 403 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
403 DCHECK(!already_resolved()); | 404 DCHECK(!already_resolved_); |
404 DCHECK(is_declaration_scope()); | 405 DCHECK(is_declaration_scope()); |
405 DCHECK(has_this_declaration()); | 406 DCHECK(has_this_declaration()); |
406 | 407 |
407 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 408 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
408 Variable* var = variables_.Declare( | 409 Variable* var = variables_.Declare( |
409 zone(), this, ast_value_factory->this_string(), | 410 zone(), this, ast_value_factory->this_string(), |
410 subclass_constructor ? CONST : VAR, Variable::THIS, | 411 subclass_constructor ? CONST : VAR, Variable::THIS, |
411 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 412 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
412 receiver_ = var; | 413 receiver_ = var; |
413 } | 414 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 while (unresolved->next_unresolved() != nullptr) { | 476 while (unresolved->next_unresolved() != nullptr) { |
476 unresolved = unresolved->next_unresolved(); | 477 unresolved = unresolved->next_unresolved(); |
477 } | 478 } |
478 unresolved->set_next_unresolved(outer_scope()->unresolved_); | 479 unresolved->set_next_unresolved(outer_scope()->unresolved_); |
479 } | 480 } |
480 outer_scope()->unresolved_ = unresolved_; | 481 outer_scope()->unresolved_ = unresolved_; |
481 unresolved_ = nullptr; | 482 unresolved_ = nullptr; |
482 } | 483 } |
483 | 484 |
484 PropagateUsageFlagsToScope(outer_scope_); | 485 PropagateUsageFlagsToScope(outer_scope_); |
485 | 486 // This block does not need a context. |
487 num_heap_slots_ = 0; | |
486 return NULL; | 488 return NULL; |
487 } | 489 } |
488 | 490 |
489 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { | 491 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
490 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 492 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
491 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 493 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
492 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); | 494 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
493 DCHECK_NULL(new_parent->inner_scope_); | 495 DCHECK_NULL(new_parent->inner_scope_); |
494 DCHECK_NULL(new_parent->unresolved_); | 496 DCHECK_NULL(new_parent->unresolved_); |
495 DCHECK_EQ(0, new_parent->temps()->length()); | 497 DCHECK_EQ(0, new_parent->temps()->length()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
528 temp->set_scope(new_parent); | 530 temp->set_scope(new_parent); |
529 new_parent->AddTemporary(temp); | 531 new_parent->AddTemporary(temp); |
530 } | 532 } |
531 temps->Rewind(top_temp_); | 533 temps->Rewind(top_temp_); |
532 } | 534 } |
533 } | 535 } |
534 | 536 |
535 void Scope::ReplaceOuterScope(Scope* outer) { | 537 void Scope::ReplaceOuterScope(Scope* outer) { |
536 DCHECK_NOT_NULL(outer); | 538 DCHECK_NOT_NULL(outer); |
537 DCHECK_NOT_NULL(outer_scope_); | 539 DCHECK_NOT_NULL(outer_scope_); |
538 DCHECK(!already_resolved()); | 540 DCHECK(!already_resolved_); |
ortuno
2016/08/19 02:20:54
This line is causing a crash in Debug builds. Is i
| |
539 DCHECK(!outer->already_resolved()); | 541 DCHECK(!outer->already_resolved_); |
540 DCHECK(!outer_scope_->already_resolved()); | 542 DCHECK(!outer_scope_->already_resolved_); |
541 outer_scope_->RemoveInnerScope(this); | 543 outer_scope_->RemoveInnerScope(this); |
542 outer->AddInnerScope(this); | 544 outer->AddInnerScope(this); |
543 outer_scope_ = outer; | 545 outer_scope_ = outer; |
544 } | 546 } |
545 | 547 |
546 | 548 |
547 void Scope::PropagateUsageFlagsToScope(Scope* other) { | 549 void Scope::PropagateUsageFlagsToScope(Scope* other) { |
548 DCHECK_NOT_NULL(other); | 550 DCHECK_NOT_NULL(other); |
549 DCHECK(!already_resolved()); | 551 DCHECK(!already_resolved_); |
550 DCHECK(!other->already_resolved()); | 552 DCHECK(!other->already_resolved_); |
551 if (uses_super_property()) other->RecordSuperPropertyUsage(); | 553 if (uses_super_property()) other->RecordSuperPropertyUsage(); |
552 if (calls_eval()) other->RecordEvalCall(); | 554 if (calls_eval()) other->RecordEvalCall(); |
553 } | 555 } |
554 | 556 |
555 | 557 |
556 Variable* Scope::LookupLocal(const AstRawString* name) { | 558 Variable* Scope::LookupLocal(const AstRawString* name) { |
557 Variable* result = variables_.Lookup(name); | 559 Variable* result = variables_.Lookup(name); |
558 if (result != NULL || scope_info_.is_null()) { | 560 if (result != NULL || scope_info_.is_null()) { |
559 return result; | 561 return result; |
560 } | 562 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
634 scope = scope->outer_scope()) { | 636 scope = scope->outer_scope()) { |
635 Variable* var = scope->LookupLocal(name); | 637 Variable* var = scope->LookupLocal(name); |
636 if (var != NULL) return var; | 638 if (var != NULL) return var; |
637 } | 639 } |
638 return NULL; | 640 return NULL; |
639 } | 641 } |
640 | 642 |
641 Variable* DeclarationScope::DeclareParameter( | 643 Variable* DeclarationScope::DeclareParameter( |
642 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, | 644 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
643 bool* is_duplicate, AstValueFactory* ast_value_factory) { | 645 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
644 DCHECK(!already_resolved()); | 646 DCHECK(!already_resolved_); |
645 DCHECK(is_function_scope()); | 647 DCHECK(is_function_scope()); |
646 DCHECK(!is_optional || !is_rest); | 648 DCHECK(!is_optional || !is_rest); |
647 Variable* var; | 649 Variable* var; |
648 if (mode == TEMPORARY) { | 650 if (mode == TEMPORARY) { |
649 var = NewTemporary(name); | 651 var = NewTemporary(name); |
650 } else { | 652 } else { |
651 var = variables_.Declare(zone(), this, name, mode, Variable::NORMAL, | 653 var = variables_.Declare(zone(), this, name, mode, Variable::NORMAL, |
652 kCreatedInitialized); | 654 kCreatedInitialized); |
653 // TODO(wingo): Avoid O(n^2) check. | 655 // TODO(wingo): Avoid O(n^2) check. |
654 *is_duplicate = IsDeclaredParameter(name); | 656 *is_duplicate = IsDeclaredParameter(name); |
655 } | 657 } |
656 if (!is_optional && !is_rest && arity_ == params_.length()) { | 658 if (!is_optional && !is_rest && arity_ == params_.length()) { |
657 ++arity_; | 659 ++arity_; |
658 } | 660 } |
659 if (is_rest) { | 661 if (is_rest) { |
660 DCHECK_NULL(rest_parameter_); | 662 DCHECK_NULL(rest_parameter_); |
661 rest_parameter_ = var; | 663 rest_parameter_ = var; |
662 rest_index_ = num_parameters(); | 664 rest_index_ = num_parameters(); |
663 } | 665 } |
664 params_.Add(var, zone()); | 666 params_.Add(var, zone()); |
665 if (name == ast_value_factory->arguments_string()) { | 667 if (name == ast_value_factory->arguments_string()) { |
666 has_arguments_parameter_ = true; | 668 has_arguments_parameter_ = true; |
667 } | 669 } |
668 return var; | 670 return var; |
669 } | 671 } |
670 | 672 |
671 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 673 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
672 InitializationFlag init_flag, Variable::Kind kind, | 674 InitializationFlag init_flag, Variable::Kind kind, |
673 MaybeAssignedFlag maybe_assigned_flag) { | 675 MaybeAssignedFlag maybe_assigned_flag) { |
674 DCHECK(!already_resolved()); | 676 DCHECK(!already_resolved_); |
675 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 677 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
676 // introduced during variable allocation, and TEMPORARY variables are | 678 // introduced during variable allocation, and TEMPORARY variables are |
677 // allocated via NewTemporary(). | 679 // allocated via NewTemporary(). |
678 DCHECK(IsDeclaredVariableMode(mode)); | 680 DCHECK(IsDeclaredVariableMode(mode)); |
679 return variables_.Declare(zone(), this, name, mode, kind, init_flag, | 681 return variables_.Declare(zone(), this, name, mode, kind, init_flag, |
680 maybe_assigned_flag); | 682 maybe_assigned_flag); |
681 } | 683 } |
682 | 684 |
683 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, | 685 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, |
684 Variable::Kind kind) { | 686 Variable::Kind kind) { |
(...skipping 28 matching lines...) Expand all Loading... | |
713 Variable* var = new(zone()) Variable(scope, | 715 Variable* var = new(zone()) Variable(scope, |
714 name, | 716 name, |
715 TEMPORARY, | 717 TEMPORARY, |
716 Variable::NORMAL, | 718 Variable::NORMAL, |
717 kCreatedInitialized); | 719 kCreatedInitialized); |
718 scope->AddTemporary(var); | 720 scope->AddTemporary(var); |
719 return var; | 721 return var; |
720 } | 722 } |
721 | 723 |
722 void Scope::AddDeclaration(Declaration* declaration) { | 724 void Scope::AddDeclaration(Declaration* declaration) { |
723 DCHECK(!already_resolved()); | 725 DCHECK(!already_resolved_); |
724 decls_.Add(declaration, zone()); | 726 decls_.Add(declaration, zone()); |
725 } | 727 } |
726 | 728 |
727 | 729 |
728 Declaration* Scope::CheckConflictingVarDeclarations() { | 730 Declaration* Scope::CheckConflictingVarDeclarations() { |
729 int length = decls_.length(); | 731 int length = decls_.length(); |
730 for (int i = 0; i < length; i++) { | 732 for (int i = 0; i < length; i++) { |
731 Declaration* decl = decls_[i]; | 733 Declaration* decl = decls_[i]; |
732 VariableMode mode = decl->proxy()->var()->mode(); | 734 VariableMode mode = decl->proxy()->var()->mode(); |
733 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; | 735 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1294 // TODO(wingo): There are other variables in this category; add them. | 1296 // TODO(wingo): There are other variables in this category; add them. |
1295 if (var != nullptr && var->is_this()) return var; | 1297 if (var != nullptr && var->is_this()) return var; |
1296 | 1298 |
1297 if (is_with_scope()) { | 1299 if (is_with_scope()) { |
1298 // The current scope is a with scope, so the variable binding can not be | 1300 // The current scope is a with scope, so the variable binding can not be |
1299 // statically resolved. However, note that it was necessary to do a lookup | 1301 // statically resolved. However, note that it was necessary to do a lookup |
1300 // in the outer scope anyway, because if a binding exists in an outer | 1302 // in the outer scope anyway, because if a binding exists in an outer |
1301 // scope, the associated variable has to be marked as potentially being | 1303 // scope, the associated variable has to be marked as potentially being |
1302 // accessed from inside of an inner with scope (the property may not be in | 1304 // accessed from inside of an inner with scope (the property may not be in |
1303 // the 'with' object). | 1305 // the 'with' object). |
1304 if (var != nullptr && !already_resolved()) { | 1306 if (var != nullptr && var->IsUnallocated()) { |
1307 DCHECK(!already_resolved_); | |
1305 var->set_is_used(); | 1308 var->set_is_used(); |
1306 var->ForceContextAllocation(); | 1309 var->ForceContextAllocation(); |
1307 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1310 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1308 } | 1311 } |
1309 *binding_kind = DYNAMIC_LOOKUP; | 1312 *binding_kind = DYNAMIC_LOOKUP; |
1310 return nullptr; | 1313 return nullptr; |
1311 } | 1314 } |
1312 } else { | 1315 } else { |
1313 DCHECK(!is_with_scope()); | 1316 DCHECK(!is_with_scope()); |
1314 DCHECK(is_function_scope() || is_script_scope() || is_eval_scope()); | 1317 DCHECK(is_function_scope() || is_script_scope() || is_eval_scope()); |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1698 } | 1701 } |
1699 | 1702 |
1700 for (auto entry : module()->exports()) { | 1703 for (auto entry : module()->exports()) { |
1701 if (entry->local_name == nullptr) continue; | 1704 if (entry->local_name == nullptr) continue; |
1702 Variable* var = LookupLocal(entry->local_name); | 1705 Variable* var = LookupLocal(entry->local_name); |
1703 var->AllocateTo(VariableLocation::MODULE, 42); | 1706 var->AllocateTo(VariableLocation::MODULE, 42); |
1704 } | 1707 } |
1705 } | 1708 } |
1706 | 1709 |
1707 void Scope::AllocateVariablesRecursively() { | 1710 void Scope::AllocateVariablesRecursively() { |
1708 if (!already_resolved()) { | 1711 DCHECK(!already_resolved_); |
1709 num_stack_slots_ = 0; | 1712 DCHECK_EQ(0, num_stack_slots_); |
1710 } | 1713 |
1711 // Allocate variables for inner scopes. | 1714 // Allocate variables for inner scopes. |
1712 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1715 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1713 scope->AllocateVariablesRecursively(); | 1716 scope->AllocateVariablesRecursively(); |
1714 } | 1717 } |
1715 | 1718 |
1716 // If scope is already resolved, we still need to allocate | 1719 DCHECK(!already_resolved_); |
1717 // variables in inner scopes which might not have been resolved yet. | 1720 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
1718 if (already_resolved()) return; | |
1719 // The number of slots required for variables. | |
1720 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | |
1721 | 1721 |
1722 // Allocate variables for this scope. | 1722 // Allocate variables for this scope. |
1723 // Parameters must be allocated first, if any. | 1723 // Parameters must be allocated first, if any. |
1724 if (is_declaration_scope()) { | 1724 if (is_declaration_scope()) { |
1725 if (is_module_scope()) { | 1725 if (is_module_scope()) { |
1726 AsDeclarationScope()->AllocateModuleVariables(); | 1726 AsDeclarationScope()->AllocateModuleVariables(); |
1727 } else if (is_function_scope()) { | 1727 } else if (is_function_scope()) { |
1728 AsDeclarationScope()->AllocateParameterLocals(); | 1728 AsDeclarationScope()->AllocateParameterLocals(); |
1729 } | 1729 } |
1730 AsDeclarationScope()->AllocateReceiver(); | 1730 AsDeclarationScope()->AllocateReceiver(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1767 function != nullptr && function->IsContextSlot(); | 1767 function != nullptr && function->IsContextSlot(); |
1768 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1768 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1769 (is_function_var_in_context ? 1 : 0); | 1769 (is_function_var_in_context ? 1 : 0); |
1770 } | 1770 } |
1771 | 1771 |
1772 | 1772 |
1773 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1773 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1774 | 1774 |
1775 } // namespace internal | 1775 } // namespace internal |
1776 } // namespace v8 | 1776 } // namespace v8 |
OLD | NEW |