| 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 variables_(zone), | 236 variables_(zone), |
| 237 scope_info_(scope_info), | 237 scope_info_(scope_info), |
| 238 scope_type_(CATCH_SCOPE) { | 238 scope_type_(CATCH_SCOPE) { |
| 239 SetDefaults(); | 239 SetDefaults(); |
| 240 #ifdef DEBUG | 240 #ifdef DEBUG |
| 241 already_resolved_ = true; | 241 already_resolved_ = true; |
| 242 #endif | 242 #endif |
| 243 // Cache the catch variable, even though it's also available via the | 243 // Cache the catch variable, even though it's also available via the |
| 244 // scope_info, as the parser expects that a catch scope always has the catch | 244 // scope_info, as the parser expects that a catch scope always has the catch |
| 245 // variable as first and only variable. | 245 // variable as first and only variable. |
| 246 Variable* variable = Declare(zone, this, catch_variable_name, VAR, | 246 Variable* variable = Declare(zone, catch_variable_name, VAR, NORMAL_VARIABLE, |
| 247 NORMAL_VARIABLE, kCreatedInitialized); | 247 kCreatedInitialized); |
| 248 AllocateHeapSlot(variable); | 248 AllocateHeapSlot(variable); |
| 249 } | 249 } |
| 250 | 250 |
| 251 void DeclarationScope::SetDefaults() { | 251 void DeclarationScope::SetDefaults() { |
| 252 is_declaration_scope_ = true; | 252 is_declaration_scope_ = true; |
| 253 has_simple_parameters_ = true; | 253 has_simple_parameters_ = true; |
| 254 asm_module_ = false; | 254 asm_module_ = false; |
| 255 asm_function_ = false; | 255 asm_function_ = false; |
| 256 force_eager_compilation_ = false; | 256 force_eager_compilation_ = false; |
| 257 has_arguments_parameter_ = false; | 257 has_arguments_parameter_ = false; |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 #endif | 572 #endif |
| 573 } | 573 } |
| 574 | 574 |
| 575 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { | 575 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 576 DCHECK(!already_resolved_); | 576 DCHECK(!already_resolved_); |
| 577 DCHECK(is_declaration_scope()); | 577 DCHECK(is_declaration_scope()); |
| 578 DCHECK(has_this_declaration()); | 578 DCHECK(has_this_declaration()); |
| 579 | 579 |
| 580 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 580 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 581 Variable* var = Declare( | 581 Variable* var = Declare( |
| 582 zone(), this, ast_value_factory->this_string(), | 582 zone(), ast_value_factory->this_string(), |
| 583 subclass_constructor ? CONST : VAR, THIS_VARIABLE, | 583 subclass_constructor ? CONST : VAR, THIS_VARIABLE, |
| 584 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 584 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| 585 receiver_ = var; | 585 receiver_ = var; |
| 586 } | 586 } |
| 587 | 587 |
| 588 void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) { | 588 void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) { |
| 589 DCHECK(is_function_scope()); | 589 DCHECK(is_function_scope()); |
| 590 DCHECK(!is_arrow_scope()); | 590 DCHECK(!is_arrow_scope()); |
| 591 | 591 |
| 592 arguments_ = LookupLocal(ast_value_factory->arguments_string()); | 592 arguments_ = LookupLocal(ast_value_factory->arguments_string()); |
| 593 if (arguments_ == nullptr) { | 593 if (arguments_ == nullptr) { |
| 594 // Declare 'arguments' variable which exists in all non arrow functions. | 594 // Declare 'arguments' variable which exists in all non arrow functions. |
| 595 // Note that it might never be accessed, in which case it won't be | 595 // Note that it might never be accessed, in which case it won't be |
| 596 // allocated during variable allocation. | 596 // allocated during variable allocation. |
| 597 arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(), | 597 arguments_ = Declare(zone(), ast_value_factory->arguments_string(), VAR, |
| 598 VAR, NORMAL_VARIABLE, kCreatedInitialized); | 598 NORMAL_VARIABLE, kCreatedInitialized); |
| 599 } else if (IsLexicalVariableMode(arguments_->mode())) { | 599 } else if (IsLexicalVariableMode(arguments_->mode())) { |
| 600 // Check if there's lexically declared variable named arguments to avoid | 600 // Check if there's lexically declared variable named arguments to avoid |
| 601 // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20. | 601 // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20. |
| 602 arguments_ = nullptr; | 602 arguments_ = nullptr; |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 | 605 |
| 606 void DeclarationScope::DeclareDefaultFunctionVariables( | 606 void DeclarationScope::DeclareDefaultFunctionVariables( |
| 607 AstValueFactory* ast_value_factory) { | 607 AstValueFactory* ast_value_factory) { |
| 608 DCHECK(is_function_scope()); | 608 DCHECK(is_function_scope()); |
| 609 DCHECK(!is_arrow_scope()); | 609 DCHECK(!is_arrow_scope()); |
| 610 | 610 |
| 611 DeclareThis(ast_value_factory); | 611 DeclareThis(ast_value_factory); |
| 612 new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(), | 612 new_target_ = Declare(zone(), ast_value_factory->new_target_string(), CONST, |
| 613 CONST, NORMAL_VARIABLE, kCreatedInitialized); | 613 NORMAL_VARIABLE, kCreatedInitialized); |
| 614 | 614 |
| 615 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 615 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
| 616 IsAccessorFunction(function_kind_)) { | 616 IsAccessorFunction(function_kind_)) { |
| 617 this_function_ = | 617 this_function_ = Declare(zone(), ast_value_factory->this_function_string(), |
| 618 Declare(zone(), this, ast_value_factory->this_function_string(), CONST, | 618 CONST, NORMAL_VARIABLE, kCreatedInitialized); |
| 619 NORMAL_VARIABLE, kCreatedInitialized); | |
| 620 } | 619 } |
| 621 } | 620 } |
| 622 | 621 |
| 623 Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) { | 622 Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) { |
| 624 DCHECK(is_function_scope()); | 623 DCHECK(is_function_scope()); |
| 625 DCHECK_NULL(function_); | 624 DCHECK_NULL(function_); |
| 626 DCHECK_NULL(variables_.Lookup(name)); | 625 DCHECK_NULL(variables_.Lookup(name)); |
| 627 VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE | 626 VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE |
| 628 : NORMAL_VARIABLE; | 627 : NORMAL_VARIABLE; |
| 629 function_ = | 628 function_ = |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 return NULL; | 678 return NULL; |
| 680 } | 679 } |
| 681 | 680 |
| 682 void DeclarationScope::AddLocal(Variable* var) { | 681 void DeclarationScope::AddLocal(Variable* var) { |
| 683 DCHECK(!already_resolved_); | 682 DCHECK(!already_resolved_); |
| 684 // Temporaries are only placed in ClosureScopes. | 683 // Temporaries are only placed in ClosureScopes. |
| 685 DCHECK_EQ(GetClosureScope(), this); | 684 DCHECK_EQ(GetClosureScope(), this); |
| 686 locals_.Add(var); | 685 locals_.Add(var); |
| 687 } | 686 } |
| 688 | 687 |
| 689 Variable* Scope::Declare(Zone* zone, Scope* scope, const AstRawString* name, | 688 Variable* Scope::Declare(Zone* zone, const AstRawString* name, |
| 690 VariableMode mode, VariableKind kind, | 689 VariableMode mode, VariableKind kind, |
| 691 InitializationFlag initialization_flag, | 690 InitializationFlag initialization_flag, |
| 692 MaybeAssignedFlag maybe_assigned_flag) { | 691 MaybeAssignedFlag maybe_assigned_flag) { |
| 693 bool added; | 692 bool added; |
| 694 Variable* var = | 693 Variable* var = |
| 695 variables_.Declare(zone, scope, name, mode, kind, initialization_flag, | 694 variables_.Declare(zone, this, name, mode, kind, initialization_flag, |
| 696 maybe_assigned_flag, &added); | 695 maybe_assigned_flag, &added); |
| 697 if (added) locals_.Add(var); | 696 if (added) locals_.Add(var); |
| 698 return var; | 697 return var; |
| 699 } | 698 } |
| 700 | 699 |
| 701 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { | 700 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
| 702 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 701 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
| 703 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 702 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
| 704 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); | 703 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
| 705 DCHECK_NULL(new_parent->inner_scope_); | 704 DCHECK_NULL(new_parent->inner_scope_); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, | 836 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
| 838 bool* is_duplicate, AstValueFactory* ast_value_factory) { | 837 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
| 839 DCHECK(!already_resolved_); | 838 DCHECK(!already_resolved_); |
| 840 DCHECK(is_function_scope() || is_module_scope()); | 839 DCHECK(is_function_scope() || is_module_scope()); |
| 841 DCHECK(!has_rest_); | 840 DCHECK(!has_rest_); |
| 842 DCHECK(!is_optional || !is_rest); | 841 DCHECK(!is_optional || !is_rest); |
| 843 Variable* var; | 842 Variable* var; |
| 844 if (mode == TEMPORARY) { | 843 if (mode == TEMPORARY) { |
| 845 var = NewTemporary(name); | 844 var = NewTemporary(name); |
| 846 } else { | 845 } else { |
| 847 var = | 846 var = Declare(zone(), name, mode, NORMAL_VARIABLE, kCreatedInitialized); |
| 848 Declare(zone(), this, name, mode, NORMAL_VARIABLE, kCreatedInitialized); | |
| 849 // TODO(wingo): Avoid O(n^2) check. | 847 // TODO(wingo): Avoid O(n^2) check. |
| 850 *is_duplicate = IsDeclaredParameter(name); | 848 *is_duplicate = IsDeclaredParameter(name); |
| 851 } | 849 } |
| 852 has_rest_ = is_rest; | 850 has_rest_ = is_rest; |
| 853 params_.Add(var, zone()); | 851 params_.Add(var, zone()); |
| 854 if (name == ast_value_factory->arguments_string()) { | 852 if (name == ast_value_factory->arguments_string()) { |
| 855 has_arguments_parameter_ = true; | 853 has_arguments_parameter_ = true; |
| 856 } | 854 } |
| 857 return var; | 855 return var; |
| 858 } | 856 } |
| 859 | 857 |
| 860 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 858 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
| 861 InitializationFlag init_flag, VariableKind kind, | 859 InitializationFlag init_flag, VariableKind kind, |
| 862 MaybeAssignedFlag maybe_assigned_flag) { | 860 MaybeAssignedFlag maybe_assigned_flag) { |
| 863 DCHECK(!already_resolved_); | 861 DCHECK(!already_resolved_); |
| 864 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 862 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 865 // introduced during variable allocation, and TEMPORARY variables are | 863 // introduced during variable allocation, and TEMPORARY variables are |
| 866 // allocated via NewTemporary(). | 864 // allocated via NewTemporary(). |
| 867 DCHECK(IsDeclaredVariableMode(mode)); | 865 DCHECK(IsDeclaredVariableMode(mode)); |
| 868 return Declare(zone(), this, name, mode, kind, init_flag, | 866 return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag); |
| 869 maybe_assigned_flag); | |
| 870 } | 867 } |
| 871 | 868 |
| 872 Variable* Scope::DeclareVariable( | 869 Variable* Scope::DeclareVariable( |
| 873 Declaration* declaration, VariableMode mode, InitializationFlag init, | 870 Declaration* declaration, VariableMode mode, InitializationFlag init, |
| 874 bool allow_harmony_restrictive_generators, | 871 bool allow_harmony_restrictive_generators, |
| 875 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { | 872 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { |
| 876 DCHECK(IsDeclaredVariableMode(mode)); | 873 DCHECK(IsDeclaredVariableMode(mode)); |
| 877 DCHECK(!already_resolved_); | 874 DCHECK(!already_resolved_); |
| 878 | 875 |
| 879 if (mode == VAR && !is_declaration_scope()) { | 876 if (mode == VAR && !is_declaration_scope()) { |
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 Variable* function = | 2024 Variable* function = |
| 2028 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2025 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 2029 bool is_function_var_in_context = | 2026 bool is_function_var_in_context = |
| 2030 function != nullptr && function->IsContextSlot(); | 2027 function != nullptr && function->IsContextSlot(); |
| 2031 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2028 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 2032 (is_function_var_in_context ? 1 : 0); | 2029 (is_function_var_in_context ? 1 : 0); |
| 2033 } | 2030 } |
| 2034 | 2031 |
| 2035 } // namespace internal | 2032 } // namespace internal |
| 2036 } // namespace v8 | 2033 } // namespace v8 |
| OLD | NEW |