| 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 11 matching lines...) Expand all Loading... |
| 22 // When inserting a new variable via Declare(), we rely on the fact that | 22 // When inserting a new variable via Declare(), we rely on the fact that |
| 23 // the handle location remains alive for the duration of that variable | 23 // the handle location remains alive for the duration of that variable |
| 24 // use. Because a Variable holding a handle with the same location exists | 24 // use. Because a Variable holding a handle with the same location exists |
| 25 // this is ensured. | 25 // this is ensured. |
| 26 | 26 |
| 27 VariableMap::VariableMap(Zone* zone) | 27 VariableMap::VariableMap(Zone* zone) |
| 28 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)) {} | 28 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)) {} |
| 29 | 29 |
| 30 Variable* VariableMap::Declare(Zone* zone, Scope* scope, | 30 Variable* VariableMap::Declare(Zone* zone, Scope* scope, |
| 31 const AstRawString* name, VariableMode mode, | 31 const AstRawString* name, VariableMode mode, |
| 32 Variable::Kind kind, | 32 VariableKind kind, |
| 33 InitializationFlag initialization_flag, | 33 InitializationFlag initialization_flag, |
| 34 MaybeAssignedFlag maybe_assigned_flag, | 34 MaybeAssignedFlag maybe_assigned_flag, |
| 35 bool* added) { | 35 bool* added) { |
| 36 // AstRawStrings are unambiguous, i.e., the same string is always represented | 36 // AstRawStrings are unambiguous, i.e., the same string is always represented |
| 37 // by the same AstRawString*. | 37 // by the same AstRawString*. |
| 38 // FIXME(marja): fix the type of Lookup. | 38 // FIXME(marja): fix the type of Lookup. |
| 39 Entry* p = | 39 Entry* p = |
| 40 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 40 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 41 ZoneAllocationPolicy(zone)); | 41 ZoneAllocationPolicy(zone)); |
| 42 if (added) *added = p->value == nullptr; | 42 if (added) *added = p->value == nullptr; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 AstValueFactory* ast_value_factory) | 128 AstValueFactory* ast_value_factory) |
| 129 : Scope(zone), | 129 : Scope(zone), |
| 130 function_kind_(kNormalFunction), | 130 function_kind_(kNormalFunction), |
| 131 params_(4, zone), | 131 params_(4, zone), |
| 132 sloppy_block_function_map_(zone) { | 132 sloppy_block_function_map_(zone) { |
| 133 DCHECK_EQ(scope_type_, SCRIPT_SCOPE); | 133 DCHECK_EQ(scope_type_, SCRIPT_SCOPE); |
| 134 SetDefaults(); | 134 SetDefaults(); |
| 135 | 135 |
| 136 // Make sure that if we don't find the global 'this', it won't be declared as | 136 // Make sure that if we don't find the global 'this', it won't be declared as |
| 137 // a regular dynamic global by predeclaring it with the right variable kind. | 137 // a regular dynamic global by predeclaring it with the right variable kind. |
| 138 DeclareDynamicGlobal(ast_value_factory->this_string(), Variable::THIS); | 138 DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE); |
| 139 } | 139 } |
| 140 | 140 |
| 141 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, | 141 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, |
| 142 ScopeType scope_type, | 142 ScopeType scope_type, |
| 143 FunctionKind function_kind) | 143 FunctionKind function_kind) |
| 144 : Scope(zone, outer_scope, scope_type), | 144 : Scope(zone, outer_scope, scope_type), |
| 145 function_kind_(function_kind), | 145 function_kind_(function_kind), |
| 146 params_(4, zone), | 146 params_(4, zone), |
| 147 sloppy_block_function_map_(zone) { | 147 sloppy_block_function_map_(zone) { |
| 148 DCHECK_NE(scope_type, SCRIPT_SCOPE); | 148 DCHECK_NE(scope_type, SCRIPT_SCOPE); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 scope_info_(scope_info), | 228 scope_info_(scope_info), |
| 229 scope_type_(CATCH_SCOPE) { | 229 scope_type_(CATCH_SCOPE) { |
| 230 SetDefaults(); | 230 SetDefaults(); |
| 231 #ifdef DEBUG | 231 #ifdef DEBUG |
| 232 already_resolved_ = true; | 232 already_resolved_ = true; |
| 233 #endif | 233 #endif |
| 234 // Cache the catch variable, even though it's also available via the | 234 // Cache the catch variable, even though it's also available via the |
| 235 // scope_info, as the parser expects that a catch scope always has the catch | 235 // scope_info, as the parser expects that a catch scope always has the catch |
| 236 // variable as first and only variable. | 236 // variable as first and only variable. |
| 237 Variable* variable = Declare(zone, this, catch_variable_name, VAR, | 237 Variable* variable = Declare(zone, this, catch_variable_name, VAR, |
| 238 Variable::NORMAL, kCreatedInitialized); | 238 NORMAL_VARIABLE, kCreatedInitialized); |
| 239 AllocateHeapSlot(variable); | 239 AllocateHeapSlot(variable); |
| 240 } | 240 } |
| 241 | 241 |
| 242 void DeclarationScope::SetDefaults() { | 242 void DeclarationScope::SetDefaults() { |
| 243 is_declaration_scope_ = true; | 243 is_declaration_scope_ = true; |
| 244 has_simple_parameters_ = true; | 244 has_simple_parameters_ = true; |
| 245 asm_module_ = false; | 245 asm_module_ = false; |
| 246 asm_function_ = false; | 246 asm_function_ = false; |
| 247 force_eager_compilation_ = false; | 247 force_eager_compilation_ = false; |
| 248 has_arguments_parameter_ = false; | 248 has_arguments_parameter_ = false; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 // Internalize context local variables. | 413 // Internalize context local variables. |
| 414 for (int var = 0; var < scope_info_->ContextLocalCount(); ++var) { | 414 for (int var = 0; var < scope_info_->ContextLocalCount(); ++var) { |
| 415 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); | 415 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); |
| 416 const AstRawString* name = ast_value_factory->GetString(name_handle); | 416 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 417 int index = Context::MIN_CONTEXT_SLOTS + var; | 417 int index = Context::MIN_CONTEXT_SLOTS + var; |
| 418 VariableMode mode = scope_info_->ContextLocalMode(var); | 418 VariableMode mode = scope_info_->ContextLocalMode(var); |
| 419 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); | 419 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); |
| 420 MaybeAssignedFlag maybe_assigned_flag = | 420 MaybeAssignedFlag maybe_assigned_flag = |
| 421 scope_info_->ContextLocalMaybeAssignedFlag(var); | 421 scope_info_->ContextLocalMaybeAssignedFlag(var); |
| 422 VariableLocation location = VariableLocation::CONTEXT; | 422 VariableLocation location = VariableLocation::CONTEXT; |
| 423 Variable::Kind kind = Variable::NORMAL; | 423 VariableKind kind = NORMAL_VARIABLE; |
| 424 if (index == scope_info_->ReceiverContextSlotIndex()) { | 424 if (index == scope_info_->ReceiverContextSlotIndex()) { |
| 425 kind = Variable::THIS; | 425 kind = THIS_VARIABLE; |
| 426 } | 426 } |
| 427 | 427 |
| 428 Variable* result = variables_.Declare(zone(), this, name, mode, kind, | 428 Variable* result = variables_.Declare(zone(), this, name, mode, kind, |
| 429 init_flag, maybe_assigned_flag); | 429 init_flag, maybe_assigned_flag); |
| 430 result->AllocateTo(location, index); | 430 result->AllocateTo(location, index); |
| 431 } | 431 } |
| 432 | 432 |
| 433 // Internalize function proxy for this scope. | 433 // Internalize function proxy for this scope. |
| 434 if (scope_info_->HasFunctionName()) { | 434 if (scope_info_->HasFunctionName()) { |
| 435 Handle<String> name_handle(scope_info_->FunctionName(), isolate); | 435 Handle<String> name_handle(scope_info_->FunctionName(), isolate); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 } | 586 } |
| 587 | 587 |
| 588 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { | 588 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 589 DCHECK(!already_resolved_); | 589 DCHECK(!already_resolved_); |
| 590 DCHECK(is_declaration_scope()); | 590 DCHECK(is_declaration_scope()); |
| 591 DCHECK(has_this_declaration()); | 591 DCHECK(has_this_declaration()); |
| 592 | 592 |
| 593 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 593 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 594 Variable* var = Declare( | 594 Variable* var = Declare( |
| 595 zone(), this, ast_value_factory->this_string(), | 595 zone(), this, ast_value_factory->this_string(), |
| 596 subclass_constructor ? CONST : VAR, Variable::THIS, | 596 subclass_constructor ? CONST : VAR, THIS_VARIABLE, |
| 597 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 597 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| 598 receiver_ = var; | 598 receiver_ = var; |
| 599 } | 599 } |
| 600 | 600 |
| 601 void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) { | 601 void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) { |
| 602 DCHECK(is_function_scope()); | 602 DCHECK(is_function_scope()); |
| 603 DCHECK(!is_arrow_scope()); | 603 DCHECK(!is_arrow_scope()); |
| 604 | 604 |
| 605 // Check if there's lexically declared variable named arguments to avoid | 605 // Check if there's lexically declared variable named arguments to avoid |
| 606 // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20. | 606 // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20. |
| 607 Variable* arg_variable = LookupLocal(ast_value_factory->arguments_string()); | 607 Variable* arg_variable = LookupLocal(ast_value_factory->arguments_string()); |
| 608 if (arg_variable != nullptr && IsLexicalVariableMode(arg_variable->mode())) { | 608 if (arg_variable != nullptr && IsLexicalVariableMode(arg_variable->mode())) { |
| 609 return; | 609 return; |
| 610 } | 610 } |
| 611 | 611 |
| 612 // Declare 'arguments' variable which exists in all non arrow functions. | 612 // Declare 'arguments' variable which exists in all non arrow functions. |
| 613 // Note that it might never be accessed, in which case it won't be | 613 // Note that it might never be accessed, in which case it won't be |
| 614 // allocated during variable allocation. | 614 // allocated during variable allocation. |
| 615 if (arg_variable == nullptr) { | 615 if (arg_variable == nullptr) { |
| 616 arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(), | 616 arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(), |
| 617 VAR, Variable::ARGUMENTS, kCreatedInitialized); | 617 VAR, ARGUMENTS_VARIABLE, kCreatedInitialized); |
| 618 } else { | 618 } else { |
| 619 arguments_ = arg_variable; | 619 arguments_ = arg_variable; |
| 620 } | 620 } |
| 621 } | 621 } |
| 622 | 622 |
| 623 void DeclarationScope::DeclareDefaultFunctionVariables( | 623 void DeclarationScope::DeclareDefaultFunctionVariables( |
| 624 AstValueFactory* ast_value_factory) { | 624 AstValueFactory* ast_value_factory) { |
| 625 DCHECK(is_function_scope()); | 625 DCHECK(is_function_scope()); |
| 626 DCHECK(!is_arrow_scope()); | 626 DCHECK(!is_arrow_scope()); |
| 627 | 627 |
| 628 new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(), | 628 new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(), |
| 629 CONST, Variable::NORMAL, kCreatedInitialized); | 629 CONST, NORMAL_VARIABLE, kCreatedInitialized); |
| 630 | 630 |
| 631 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 631 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
| 632 IsAccessorFunction(function_kind_)) { | 632 IsAccessorFunction(function_kind_)) { |
| 633 this_function_ = | 633 this_function_ = |
| 634 Declare(zone(), this, ast_value_factory->this_function_string(), CONST, | 634 Declare(zone(), this, ast_value_factory->this_function_string(), CONST, |
| 635 Variable::NORMAL, kCreatedInitialized); | 635 NORMAL_VARIABLE, kCreatedInitialized); |
| 636 } | 636 } |
| 637 } | 637 } |
| 638 | 638 |
| 639 Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) { | 639 Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) { |
| 640 DCHECK(is_function_scope()); | 640 DCHECK(is_function_scope()); |
| 641 DCHECK_NULL(function_); | 641 DCHECK_NULL(function_); |
| 642 Variable::Kind kind = is_sloppy(language_mode()) | 642 VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE |
| 643 ? Variable::SLOPPY_FUNCTION_NAME | 643 : NORMAL_VARIABLE; |
| 644 : Variable::NORMAL; | |
| 645 function_ = | 644 function_ = |
| 646 new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized); | 645 new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized); |
| 647 return function_; | 646 return function_; |
| 648 } | 647 } |
| 649 | 648 |
| 650 Scope* Scope::FinalizeBlockScope() { | 649 Scope* Scope::FinalizeBlockScope() { |
| 651 DCHECK(is_block_scope()); | 650 DCHECK(is_block_scope()); |
| 652 | 651 |
| 653 if (variables_.occupancy() > 0 || | 652 if (variables_.occupancy() > 0 || |
| 654 (is_declaration_scope() && calls_sloppy_eval())) { | 653 (is_declaration_scope() && calls_sloppy_eval())) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 VariableLocation location = VariableLocation::CONTEXT; | 778 VariableLocation location = VariableLocation::CONTEXT; |
| 780 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, | 779 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, |
| 781 &init_flag, &maybe_assigned_flag); | 780 &init_flag, &maybe_assigned_flag); |
| 782 if (index < 0 && scope_type() == MODULE_SCOPE) { | 781 if (index < 0 && scope_type() == MODULE_SCOPE) { |
| 783 location = VariableLocation::MODULE; | 782 location = VariableLocation::MODULE; |
| 784 index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag, | 783 index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag, |
| 785 &maybe_assigned_flag); | 784 &maybe_assigned_flag); |
| 786 } | 785 } |
| 787 if (index < 0) return nullptr; // Nowhere found. | 786 if (index < 0) return nullptr; // Nowhere found. |
| 788 | 787 |
| 789 Variable::Kind kind = Variable::NORMAL; | 788 VariableKind kind = NORMAL_VARIABLE; |
| 790 if (location == VariableLocation::CONTEXT && | 789 if (location == VariableLocation::CONTEXT && |
| 791 index == scope_info_->ReceiverContextSlotIndex()) { | 790 index == scope_info_->ReceiverContextSlotIndex()) { |
| 792 kind = Variable::THIS; | 791 kind = THIS_VARIABLE; |
| 793 } | 792 } |
| 794 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and | 793 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and |
| 795 // ARGUMENTS bindings as their corresponding Variable::Kind. | 794 // ARGUMENTS bindings as their corresponding VariableKind. |
| 796 | 795 |
| 797 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag, | 796 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag, |
| 798 maybe_assigned_flag); | 797 maybe_assigned_flag); |
| 799 var->AllocateTo(location, index); | 798 var->AllocateTo(location, index); |
| 800 return var; | 799 return var; |
| 801 } | 800 } |
| 802 | 801 |
| 803 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name) { | 802 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name) { |
| 804 if (function_ != nullptr && function_->raw_name() == name) { | 803 if (function_ != nullptr && function_->raw_name() == name) { |
| 805 return function_; | 804 return function_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 830 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, | 829 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
| 831 bool* is_duplicate, AstValueFactory* ast_value_factory) { | 830 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
| 832 DCHECK(!already_resolved_); | 831 DCHECK(!already_resolved_); |
| 833 DCHECK(is_function_scope()); | 832 DCHECK(is_function_scope()); |
| 834 DCHECK(!has_rest_); | 833 DCHECK(!has_rest_); |
| 835 DCHECK(!is_optional || !is_rest); | 834 DCHECK(!is_optional || !is_rest); |
| 836 Variable* var; | 835 Variable* var; |
| 837 if (mode == TEMPORARY) { | 836 if (mode == TEMPORARY) { |
| 838 var = NewTemporary(name); | 837 var = NewTemporary(name); |
| 839 } else { | 838 } else { |
| 840 var = Declare(zone(), this, name, mode, Variable::NORMAL, | 839 var = |
| 841 kCreatedInitialized); | 840 Declare(zone(), this, name, mode, NORMAL_VARIABLE, kCreatedInitialized); |
| 842 // TODO(wingo): Avoid O(n^2) check. | 841 // TODO(wingo): Avoid O(n^2) check. |
| 843 *is_duplicate = IsDeclaredParameter(name); | 842 *is_duplicate = IsDeclaredParameter(name); |
| 844 } | 843 } |
| 845 if (!is_optional && !is_rest && arity_ == params_.length()) { | 844 if (!is_optional && !is_rest && arity_ == params_.length()) { |
| 846 ++arity_; | 845 ++arity_; |
| 847 } | 846 } |
| 848 has_rest_ = is_rest; | 847 has_rest_ = is_rest; |
| 849 params_.Add(var, zone()); | 848 params_.Add(var, zone()); |
| 850 if (name == ast_value_factory->arguments_string()) { | 849 if (name == ast_value_factory->arguments_string()) { |
| 851 has_arguments_parameter_ = true; | 850 has_arguments_parameter_ = true; |
| 852 } | 851 } |
| 853 return var; | 852 return var; |
| 854 } | 853 } |
| 855 | 854 |
| 856 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 855 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
| 857 InitializationFlag init_flag, Variable::Kind kind, | 856 InitializationFlag init_flag, VariableKind kind, |
| 858 MaybeAssignedFlag maybe_assigned_flag) { | 857 MaybeAssignedFlag maybe_assigned_flag) { |
| 859 DCHECK(!already_resolved_); | 858 DCHECK(!already_resolved_); |
| 860 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 859 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 861 // introduced during variable allocation, and TEMPORARY variables are | 860 // introduced during variable allocation, and TEMPORARY variables are |
| 862 // allocated via NewTemporary(). | 861 // allocated via NewTemporary(). |
| 863 DCHECK(IsDeclaredVariableMode(mode)); | 862 DCHECK(IsDeclaredVariableMode(mode)); |
| 864 return Declare(zone(), this, name, mode, kind, init_flag, | 863 return Declare(zone(), this, name, mode, kind, init_flag, |
| 865 maybe_assigned_flag); | 864 maybe_assigned_flag); |
| 866 } | 865 } |
| 867 | 866 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 886 DCHECK(proxy->raw_name() != NULL); | 885 DCHECK(proxy->raw_name() != NULL); |
| 887 const AstRawString* name = proxy->raw_name(); | 886 const AstRawString* name = proxy->raw_name(); |
| 888 bool is_function_declaration = declaration->IsFunctionDeclaration(); | 887 bool is_function_declaration = declaration->IsFunctionDeclaration(); |
| 889 | 888 |
| 890 Variable* var = nullptr; | 889 Variable* var = nullptr; |
| 891 if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) { | 890 if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) { |
| 892 // In a var binding in a sloppy direct eval, pollute the enclosing scope | 891 // In a var binding in a sloppy direct eval, pollute the enclosing scope |
| 893 // with this new binding by doing the following: | 892 // with this new binding by doing the following: |
| 894 // The proxy is bound to a lookup variable to force a dynamic declaration | 893 // The proxy is bound to a lookup variable to force a dynamic declaration |
| 895 // using the DeclareEvalVar or DeclareEvalFunction runtime functions. | 894 // using the DeclareEvalVar or DeclareEvalFunction runtime functions. |
| 896 Variable::Kind kind = Variable::NORMAL; | 895 VariableKind kind = NORMAL_VARIABLE; |
| 897 // TODO(sigurds) figure out if kNotAssigned is OK here | 896 // TODO(sigurds) figure out if kNotAssigned is OK here |
| 898 var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned); | 897 var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned); |
| 899 var->AllocateTo(VariableLocation::LOOKUP, -1); | 898 var->AllocateTo(VariableLocation::LOOKUP, -1); |
| 900 } else { | 899 } else { |
| 901 // Declare the variable in the declaration scope. | 900 // Declare the variable in the declaration scope. |
| 902 var = LookupLocal(name); | 901 var = LookupLocal(name); |
| 903 if (var == NULL) { | 902 if (var == NULL) { |
| 904 // Declare the name. | 903 // Declare the name. |
| 905 Variable::Kind kind = Variable::NORMAL; | 904 VariableKind kind = NORMAL_VARIABLE; |
| 906 if (is_function_declaration) { | 905 if (is_function_declaration) { |
| 907 kind = Variable::FUNCTION; | 906 kind = FUNCTION_VARIABLE; |
| 908 } | 907 } |
| 909 var = DeclareLocal(name, mode, init, kind, kNotAssigned); | 908 var = DeclareLocal(name, mode, init, kind, kNotAssigned); |
| 910 } else if (IsLexicalVariableMode(mode) || | 909 } else if (IsLexicalVariableMode(mode) || |
| 911 IsLexicalVariableMode(var->mode())) { | 910 IsLexicalVariableMode(var->mode())) { |
| 912 // Allow duplicate function decls for web compat, see bug 4693. | 911 // Allow duplicate function decls for web compat, see bug 4693. |
| 913 bool duplicate_allowed = false; | 912 bool duplicate_allowed = false; |
| 914 if (is_sloppy(language_mode()) && is_function_declaration && | 913 if (is_sloppy(language_mode()) && is_function_declaration && |
| 915 var->is_function()) { | 914 var->is_function()) { |
| 916 DCHECK(IsLexicalVariableMode(mode) && | 915 DCHECK(IsLexicalVariableMode(mode) && |
| 917 IsLexicalVariableMode(var->mode())); | 916 IsLexicalVariableMode(var->mode())); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 // semantic issue, but it may be a performance issue since it may | 964 // semantic issue, but it may be a performance issue since it may |
| 966 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. | 965 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. |
| 967 decls_.Add(declaration, zone()); | 966 decls_.Add(declaration, zone()); |
| 968 proxy->BindTo(var); | 967 proxy->BindTo(var); |
| 969 return var; | 968 return var; |
| 970 } | 969 } |
| 971 | 970 |
| 972 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 971 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
| 973 const AstRawString* name, | 972 const AstRawString* name, |
| 974 int start_position, int end_position, | 973 int start_position, int end_position, |
| 975 Variable::Kind kind) { | 974 VariableKind kind) { |
| 976 // Note that we must not share the unresolved variables with | 975 // Note that we must not share the unresolved variables with |
| 977 // the same name because they may be removed selectively via | 976 // the same name because they may be removed selectively via |
| 978 // RemoveUnresolved(). | 977 // RemoveUnresolved(). |
| 979 DCHECK(!already_resolved_); | 978 DCHECK(!already_resolved_); |
| 980 DCHECK_EQ(factory->zone(), zone()); | 979 DCHECK_EQ(factory->zone(), zone()); |
| 981 VariableProxy* proxy = | 980 VariableProxy* proxy = |
| 982 factory->NewVariableProxy(name, kind, start_position, end_position); | 981 factory->NewVariableProxy(name, kind, start_position, end_position); |
| 983 proxy->set_next_unresolved(unresolved_); | 982 proxy->set_next_unresolved(unresolved_); |
| 984 unresolved_ = proxy; | 983 unresolved_ = proxy; |
| 985 return proxy; | 984 return proxy; |
| 986 } | 985 } |
| 987 | 986 |
| 988 void Scope::AddUnresolved(VariableProxy* proxy) { | 987 void Scope::AddUnresolved(VariableProxy* proxy) { |
| 989 DCHECK(!already_resolved_); | 988 DCHECK(!already_resolved_); |
| 990 DCHECK(!proxy->is_resolved()); | 989 DCHECK(!proxy->is_resolved()); |
| 991 proxy->set_next_unresolved(unresolved_); | 990 proxy->set_next_unresolved(unresolved_); |
| 992 unresolved_ = proxy; | 991 unresolved_ = proxy; |
| 993 } | 992 } |
| 994 | 993 |
| 995 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, | 994 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, |
| 996 Variable::Kind kind) { | 995 VariableKind kind) { |
| 997 DCHECK(is_script_scope()); | 996 DCHECK(is_script_scope()); |
| 998 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, | 997 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, |
| 999 kCreatedInitialized); | 998 kCreatedInitialized); |
| 1000 } | 999 } |
| 1001 | 1000 |
| 1002 | 1001 |
| 1003 bool Scope::RemoveUnresolved(VariableProxy* var) { | 1002 bool Scope::RemoveUnresolved(VariableProxy* var) { |
| 1004 if (unresolved_ == var) { | 1003 if (unresolved_ == var) { |
| 1005 unresolved_ = var->next_unresolved(); | 1004 unresolved_ = var->next_unresolved(); |
| 1006 var->set_next_unresolved(nullptr); | 1005 var->set_next_unresolved(nullptr); |
| 1007 return true; | 1006 return true; |
| 1008 } | 1007 } |
| 1009 VariableProxy* current = unresolved_; | 1008 VariableProxy* current = unresolved_; |
| 1010 while (current != nullptr) { | 1009 while (current != nullptr) { |
| 1011 VariableProxy* next = current->next_unresolved(); | 1010 VariableProxy* next = current->next_unresolved(); |
| 1012 if (var == next) { | 1011 if (var == next) { |
| 1013 current->set_next_unresolved(next->next_unresolved()); | 1012 current->set_next_unresolved(next->next_unresolved()); |
| 1014 var->set_next_unresolved(nullptr); | 1013 var->set_next_unresolved(nullptr); |
| 1015 return true; | 1014 return true; |
| 1016 } | 1015 } |
| 1017 current = next; | 1016 current = next; |
| 1018 } | 1017 } |
| 1019 return false; | 1018 return false; |
| 1020 } | 1019 } |
| 1021 | 1020 |
| 1022 | 1021 |
| 1023 Variable* Scope::NewTemporary(const AstRawString* name) { | 1022 Variable* Scope::NewTemporary(const AstRawString* name) { |
| 1024 DeclarationScope* scope = GetClosureScope(); | 1023 DeclarationScope* scope = GetClosureScope(); |
| 1025 Variable* var = new(zone()) Variable(scope, | 1024 Variable* var = new (zone()) |
| 1026 name, | 1025 Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized); |
| 1027 TEMPORARY, | |
| 1028 Variable::NORMAL, | |
| 1029 kCreatedInitialized); | |
| 1030 scope->AddLocal(var); | 1026 scope->AddLocal(var); |
| 1031 return var; | 1027 return var; |
| 1032 } | 1028 } |
| 1033 | 1029 |
| 1034 Declaration* Scope::CheckConflictingVarDeclarations() { | 1030 Declaration* Scope::CheckConflictingVarDeclarations() { |
| 1035 int length = decls_.length(); | 1031 int length = decls_.length(); |
| 1036 for (int i = 0; i < length; i++) { | 1032 for (int i = 0; i < length; i++) { |
| 1037 Declaration* decl = decls_[i]; | 1033 Declaration* decl = decls_[i]; |
| 1038 VariableMode mode = decl->proxy()->var()->mode(); | 1034 VariableMode mode = decl->proxy()->var()->mode(); |
| 1039 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; | 1035 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 break; | 1265 break; |
| 1270 case VariableLocation::MODULE: | 1266 case VariableLocation::MODULE: |
| 1271 PrintF("module"); | 1267 PrintF("module"); |
| 1272 break; | 1268 break; |
| 1273 } | 1269 } |
| 1274 } | 1270 } |
| 1275 | 1271 |
| 1276 | 1272 |
| 1277 static void PrintVar(int indent, Variable* var) { | 1273 static void PrintVar(int indent, Variable* var) { |
| 1278 if (var->is_used() || !var->IsUnallocated()) { | 1274 if (var->is_used() || !var->IsUnallocated()) { |
| 1279 Indent(indent, Variable::Mode2String(var->mode())); | 1275 Indent(indent, VariableMode2String(var->mode())); |
| 1280 PrintF(" "); | 1276 PrintF(" "); |
| 1281 if (var->raw_name()->IsEmpty()) | 1277 if (var->raw_name()->IsEmpty()) |
| 1282 PrintF(".%p", reinterpret_cast<void*>(var)); | 1278 PrintF(".%p", reinterpret_cast<void*>(var)); |
| 1283 else | 1279 else |
| 1284 PrintName(var->raw_name()); | 1280 PrintName(var->raw_name()); |
| 1285 PrintF("; // "); | 1281 PrintF("; // "); |
| 1286 PrintLocation(var); | 1282 PrintLocation(var); |
| 1287 bool comma = !var->IsUnallocated(); | 1283 bool comma = !var->IsUnallocated(); |
| 1288 if (var->has_forced_context_allocation()) { | 1284 if (var->has_forced_context_allocation()) { |
| 1289 if (comma) PrintF(", "); | 1285 if (comma) PrintF(", "); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 void Scope::CheckZones() { | 1412 void Scope::CheckZones() { |
| 1417 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1413 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1418 CHECK_EQ(scope->zone(), zone()); | 1414 CHECK_EQ(scope->zone(), zone()); |
| 1419 } | 1415 } |
| 1420 } | 1416 } |
| 1421 #endif // DEBUG | 1417 #endif // DEBUG |
| 1422 | 1418 |
| 1423 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { | 1419 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
| 1424 // Declare a new non-local. | 1420 // Declare a new non-local. |
| 1425 DCHECK(IsDynamicVariableMode(mode)); | 1421 DCHECK(IsDynamicVariableMode(mode)); |
| 1426 Variable* var = variables_.Declare(zone(), NULL, name, mode, Variable::NORMAL, | 1422 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, |
| 1427 kCreatedInitialized); | 1423 kCreatedInitialized); |
| 1428 // Allocate it by giving it a dynamic lookup. | 1424 // Allocate it by giving it a dynamic lookup. |
| 1429 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1425 var->AllocateTo(VariableLocation::LOOKUP, -1); |
| 1430 return var; | 1426 return var; |
| 1431 } | 1427 } |
| 1432 | 1428 |
| 1433 Variable* Scope::LookupRecursive(VariableProxy* proxy, bool declare_free, | 1429 Variable* Scope::LookupRecursive(VariableProxy* proxy, bool declare_free, |
| 1434 Scope* outer_scope_end) { | 1430 Scope* outer_scope_end) { |
| 1435 DCHECK_NE(outer_scope_end, this); | 1431 DCHECK_NE(outer_scope_end, this); |
| 1436 // Short-cut: whenever we find a debug-evaluate scope, just look everything up | 1432 // Short-cut: whenever we find a debug-evaluate scope, just look everything up |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1461 if (calls_sloppy_eval()) return NonLocal(proxy->raw_name(), DYNAMIC); | 1457 if (calls_sloppy_eval()) return NonLocal(proxy->raw_name(), DYNAMIC); |
| 1462 return var; | 1458 return var; |
| 1463 } | 1459 } |
| 1464 } | 1460 } |
| 1465 | 1461 |
| 1466 if (outer_scope_ == outer_scope_end) { | 1462 if (outer_scope_ == outer_scope_end) { |
| 1467 if (!declare_free) return nullptr; | 1463 if (!declare_free) return nullptr; |
| 1468 DCHECK(is_script_scope()); | 1464 DCHECK(is_script_scope()); |
| 1469 // No binding has been found. Declare a variable on the global object. | 1465 // No binding has been found. Declare a variable on the global object. |
| 1470 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), | 1466 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), |
| 1471 Variable::NORMAL); | 1467 NORMAL_VARIABLE); |
| 1472 } | 1468 } |
| 1473 | 1469 |
| 1474 DCHECK(!is_script_scope()); | 1470 DCHECK(!is_script_scope()); |
| 1475 | 1471 |
| 1476 var = outer_scope_->LookupRecursive(proxy, declare_free, outer_scope_end); | 1472 var = outer_scope_->LookupRecursive(proxy, declare_free, outer_scope_end); |
| 1477 | 1473 |
| 1478 // The variable could not be resolved statically. | 1474 // The variable could not be resolved statically. |
| 1479 if (var == nullptr) return var; | 1475 if (var == nullptr) return var; |
| 1480 | 1476 |
| 1481 if (is_function_scope() && !var->is_dynamic()) { | 1477 if (is_function_scope() && !var->is_dynamic()) { |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 Variable* function = | 1845 Variable* function = |
| 1850 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1846 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1851 bool is_function_var_in_context = | 1847 bool is_function_var_in_context = |
| 1852 function != nullptr && function->IsContextSlot(); | 1848 function != nullptr && function->IsContextSlot(); |
| 1853 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1849 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1854 (is_function_var_in_context ? 1 : 0); | 1850 (is_function_var_in_context ? 1 : 0); |
| 1855 } | 1851 } |
| 1856 | 1852 |
| 1857 } // namespace internal | 1853 } // namespace internal |
| 1858 } // namespace v8 | 1854 } // namespace v8 |
| OLD | NEW |