Chromium Code Reviews| 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 |