| 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 "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/ast/scopeinfo.h" | 8 #include "src/ast/scopeinfo.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 sloppy_block_function_map_(zone), | 125 sloppy_block_function_map_(zone), |
| 126 already_resolved_(true), | 126 already_resolved_(true), |
| 127 ast_value_factory_(value_factory), | 127 ast_value_factory_(value_factory), |
| 128 zone_(zone), | 128 zone_(zone), |
| 129 class_declaration_group_start_(-1) { | 129 class_declaration_group_start_(-1) { |
| 130 SetDefaults(scope_type, NULL, scope_info); | 130 SetDefaults(scope_type, NULL, scope_info); |
| 131 if (!scope_info.is_null()) { | 131 if (!scope_info.is_null()) { |
| 132 num_heap_slots_ = scope_info_->ContextLength(); | 132 num_heap_slots_ = scope_info_->ContextLength(); |
| 133 } | 133 } |
| 134 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 134 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 135 num_heap_slots_ = Max(num_heap_slots_, | 135 num_heap_slots_ = |
| 136 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 136 Max(num_heap_slots_, static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 137 AddInnerScope(inner_scope); | 137 AddInnerScope(inner_scope); |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 Scope::Scope(Zone* zone, Scope* inner_scope, | 141 Scope::Scope(Zone* zone, Scope* inner_scope, |
| 142 const AstRawString* catch_variable_name, | 142 const AstRawString* catch_variable_name, |
| 143 AstValueFactory* value_factory) | 143 AstValueFactory* value_factory) |
| 144 : inner_scopes_(1, zone), | 144 : inner_scopes_(1, zone), |
| 145 variables_(zone), | 145 variables_(zone), |
| 146 temps_(0, zone), | 146 temps_(0, zone), |
| 147 params_(0, zone), | 147 params_(0, zone), |
| 148 unresolved_(0, zone), | 148 unresolved_(0, zone), |
| 149 decls_(0, zone), | 149 decls_(0, zone), |
| 150 module_descriptor_(NULL), | 150 module_descriptor_(NULL), |
| 151 sloppy_block_function_map_(zone), | 151 sloppy_block_function_map_(zone), |
| 152 already_resolved_(true), | 152 already_resolved_(true), |
| 153 ast_value_factory_(value_factory), | 153 ast_value_factory_(value_factory), |
| 154 zone_(zone), | 154 zone_(zone), |
| 155 class_declaration_group_start_(-1) { | 155 class_declaration_group_start_(-1) { |
| 156 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 156 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
| 157 AddInnerScope(inner_scope); | 157 AddInnerScope(inner_scope); |
| 158 ++num_var_or_const_; | 158 ++num_var_or_const_; |
| 159 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 159 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 160 Variable* variable = variables_.Declare(this, | 160 Variable* variable = variables_.Declare( |
| 161 catch_variable_name, | 161 this, catch_variable_name, VAR, Variable::NORMAL, kCreatedInitialized); |
| 162 VAR, | |
| 163 Variable::NORMAL, | |
| 164 kCreatedInitialized); | |
| 165 AllocateHeapSlot(variable); | 162 AllocateHeapSlot(variable); |
| 166 } | 163 } |
| 167 | 164 |
| 168 | 165 |
| 169 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, | 166 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
| 170 Handle<ScopeInfo> scope_info, | 167 Handle<ScopeInfo> scope_info, |
| 171 FunctionKind function_kind) { | 168 FunctionKind function_kind) { |
| 172 outer_scope_ = outer_scope; | 169 outer_scope_ = outer_scope; |
| 173 scope_type_ = scope_type; | 170 scope_type_ = scope_type; |
| 174 is_declaration_scope_ = | 171 is_declaration_scope_ = is_eval_scope() || is_function_scope() || |
| 175 is_eval_scope() || is_function_scope() || | 172 is_module_scope() || is_script_scope(); |
| 176 is_module_scope() || is_script_scope(); | |
| 177 function_kind_ = function_kind; | 173 function_kind_ = function_kind; |
| 178 scope_name_ = ast_value_factory_->empty_string(); | 174 scope_name_ = ast_value_factory_->empty_string(); |
| 179 dynamics_ = nullptr; | 175 dynamics_ = nullptr; |
| 180 receiver_ = nullptr; | 176 receiver_ = nullptr; |
| 181 new_target_ = nullptr; | 177 new_target_ = nullptr; |
| 182 function_ = nullptr; | 178 function_ = nullptr; |
| 183 arguments_ = nullptr; | 179 arguments_ = nullptr; |
| 184 this_function_ = nullptr; | 180 this_function_ = nullptr; |
| 185 illegal_redecl_ = nullptr; | 181 illegal_redecl_ = nullptr; |
| 186 scope_inside_with_ = false; | 182 scope_inside_with_ = false; |
| 187 scope_contains_with_ = false; | 183 scope_contains_with_ = false; |
| 188 scope_calls_eval_ = false; | 184 scope_calls_eval_ = false; |
| 189 scope_uses_arguments_ = false; | 185 scope_uses_arguments_ = false; |
| 190 scope_uses_super_property_ = false; | 186 scope_uses_super_property_ = false; |
| 191 asm_module_ = false; | 187 asm_module_ = false; |
| 192 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 188 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
| 193 // Inherit the language mode from the parent scope. | 189 // Inherit the language mode from the parent scope. |
| 194 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; | 190 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; |
| 195 outer_scope_calls_sloppy_eval_ = false; | 191 outer_scope_calls_sloppy_eval_ = false; |
| 196 inner_scope_calls_eval_ = false; | 192 inner_scope_calls_eval_ = false; |
| 197 scope_nonlinear_ = false; | 193 scope_nonlinear_ = false; |
| 198 force_eager_compilation_ = false; | 194 force_eager_compilation_ = false; |
| 199 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) | 195 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) |
| 200 ? outer_scope->has_forced_context_allocation() : false; | 196 ? outer_scope->has_forced_context_allocation() |
| 197 : false; |
| 201 num_var_or_const_ = 0; | 198 num_var_or_const_ = 0; |
| 202 num_stack_slots_ = 0; | 199 num_stack_slots_ = 0; |
| 203 num_heap_slots_ = 0; | 200 num_heap_slots_ = 0; |
| 204 num_global_slots_ = 0; | 201 num_global_slots_ = 0; |
| 205 num_modules_ = 0; | 202 num_modules_ = 0; |
| 206 module_var_ = NULL; | 203 module_var_ = NULL; |
| 207 arity_ = 0; | 204 arity_ = 0; |
| 208 has_simple_parameters_ = true; | 205 has_simple_parameters_ = true; |
| 209 rest_parameter_ = NULL; | 206 rest_parameter_ = NULL; |
| 210 rest_index_ = -1; | 207 rest_index_ = -1; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 281 |
| 285 | 282 |
| 286 bool Scope::Analyze(ParseInfo* info) { | 283 bool Scope::Analyze(ParseInfo* info) { |
| 287 DCHECK(info->literal() != NULL); | 284 DCHECK(info->literal() != NULL); |
| 288 DCHECK(info->scope() == NULL); | 285 DCHECK(info->scope() == NULL); |
| 289 Scope* scope = info->literal()->scope(); | 286 Scope* scope = info->literal()->scope(); |
| 290 Scope* top = scope; | 287 Scope* top = scope; |
| 291 | 288 |
| 292 // Traverse the scope tree up to the first unresolved scope or the global | 289 // Traverse the scope tree up to the first unresolved scope or the global |
| 293 // scope and start scope resolution and variable allocation from that scope. | 290 // scope and start scope resolution and variable allocation from that scope. |
| 294 while (!top->is_script_scope() && | 291 while (!top->is_script_scope() && !top->outer_scope()->already_resolved()) { |
| 295 !top->outer_scope()->already_resolved()) { | |
| 296 top = top->outer_scope(); | 292 top = top->outer_scope(); |
| 297 } | 293 } |
| 298 | 294 |
| 299 // Allocate the variables. | 295 // Allocate the variables. |
| 300 { | 296 { |
| 301 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 297 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
| 302 if (!top->AllocateVariables(info, &ast_node_factory)) { | 298 if (!top->AllocateVariables(info, &ast_node_factory)) { |
| 303 DCHECK(top->pending_error_handler_.has_pending_error()); | 299 DCHECK(top->pending_error_handler_.has_pending_error()); |
| 304 top->pending_error_handler_.ThrowPendingError(info->isolate(), | 300 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
| 305 info->script()); | 301 info->script()); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 DeclareFunctionVar(declaration); | 486 DeclareFunctionVar(declaration); |
| 491 var->AllocateTo(VariableLocation::CONTEXT, index); | 487 var->AllocateTo(VariableLocation::CONTEXT, index); |
| 492 return var; | 488 return var; |
| 493 } else { | 489 } else { |
| 494 return NULL; | 490 return NULL; |
| 495 } | 491 } |
| 496 } | 492 } |
| 497 | 493 |
| 498 | 494 |
| 499 Variable* Scope::Lookup(const AstRawString* name) { | 495 Variable* Scope::Lookup(const AstRawString* name) { |
| 500 for (Scope* scope = this; | 496 for (Scope* scope = this; scope != NULL; scope = scope->outer_scope()) { |
| 501 scope != NULL; | |
| 502 scope = scope->outer_scope()) { | |
| 503 Variable* var = scope->LookupLocal(name); | 497 Variable* var = scope->LookupLocal(name); |
| 504 if (var != NULL) return var; | 498 if (var != NULL) return var; |
| 505 } | 499 } |
| 506 return NULL; | 500 return NULL; |
| 507 } | 501 } |
| 508 | 502 |
| 509 | 503 |
| 510 Variable* Scope::DeclareParameter( | 504 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, |
| 511 const AstRawString* name, VariableMode mode, | 505 bool is_optional, bool is_rest, |
| 512 bool is_optional, bool is_rest, bool* is_duplicate) { | 506 bool* is_duplicate) { |
| 513 DCHECK(!already_resolved()); | 507 DCHECK(!already_resolved()); |
| 514 DCHECK(is_function_scope()); | 508 DCHECK(is_function_scope()); |
| 515 DCHECK(!is_optional || !is_rest); | 509 DCHECK(!is_optional || !is_rest); |
| 516 Variable* var; | 510 Variable* var; |
| 517 if (mode == TEMPORARY) { | 511 if (mode == TEMPORARY) { |
| 518 var = NewTemporary(name); | 512 var = NewTemporary(name); |
| 519 } else { | 513 } else { |
| 520 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 514 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
| 521 kCreatedInitialized); | 515 kCreatedInitialized); |
| 522 // TODO(wingo): Avoid O(n^2) check. | 516 // TODO(wingo): Avoid O(n^2) check. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 545 // allocated via NewTemporary(). | 539 // allocated via NewTemporary(). |
| 546 DCHECK(IsDeclaredVariableMode(mode)); | 540 DCHECK(IsDeclaredVariableMode(mode)); |
| 547 ++num_var_or_const_; | 541 ++num_var_or_const_; |
| 548 return variables_.Declare(this, name, mode, kind, init_flag, | 542 return variables_.Declare(this, name, mode, kind, init_flag, |
| 549 maybe_assigned_flag, declaration_group_start); | 543 maybe_assigned_flag, declaration_group_start); |
| 550 } | 544 } |
| 551 | 545 |
| 552 | 546 |
| 553 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | 547 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
| 554 DCHECK(is_script_scope()); | 548 DCHECK(is_script_scope()); |
| 555 return variables_.Declare(this, | 549 return variables_.Declare(this, name, DYNAMIC_GLOBAL, Variable::NORMAL, |
| 556 name, | |
| 557 DYNAMIC_GLOBAL, | |
| 558 Variable::NORMAL, | |
| 559 kCreatedInitialized); | 550 kCreatedInitialized); |
| 560 } | 551 } |
| 561 | 552 |
| 562 | 553 |
| 563 bool Scope::RemoveUnresolved(VariableProxy* var) { | 554 bool Scope::RemoveUnresolved(VariableProxy* var) { |
| 564 // Most likely (always?) any variable we want to remove | 555 // Most likely (always?) any variable we want to remove |
| 565 // was just added before, so we search backwards. | 556 // was just added before, so we search backwards. |
| 566 for (int i = unresolved_.length(); i-- > 0;) { | 557 for (int i = unresolved_.length(); i-- > 0;) { |
| 567 if (unresolved_[i] == var) { | 558 if (unresolved_[i] == var) { |
| 568 unresolved_.Remove(i); | 559 unresolved_.Remove(i); |
| 569 return true; | 560 return true; |
| 570 } | 561 } |
| 571 } | 562 } |
| 572 return false; | 563 return false; |
| 573 } | 564 } |
| 574 | 565 |
| 575 | 566 |
| 576 Variable* Scope::NewTemporary(const AstRawString* name) { | 567 Variable* Scope::NewTemporary(const AstRawString* name) { |
| 577 DCHECK(!already_resolved()); | 568 DCHECK(!already_resolved()); |
| 578 Scope* scope = this->ClosureScope(); | 569 Scope* scope = this->ClosureScope(); |
| 579 Variable* var = new(zone()) Variable(scope, | 570 Variable* var = new (zone()) |
| 580 name, | 571 Variable(scope, name, TEMPORARY, Variable::NORMAL, kCreatedInitialized); |
| 581 TEMPORARY, | |
| 582 Variable::NORMAL, | |
| 583 kCreatedInitialized); | |
| 584 scope->temps_.Add(var, zone()); | 572 scope->temps_.Add(var, zone()); |
| 585 return var; | 573 return var; |
| 586 } | 574 } |
| 587 | 575 |
| 588 | 576 |
| 589 void Scope::AddDeclaration(Declaration* declaration) { | 577 void Scope::AddDeclaration(Declaration* declaration) { |
| 590 decls_.Add(declaration, zone()); | 578 decls_.Add(declaration, zone()); |
| 591 } | 579 } |
| 592 | 580 |
| 593 | 581 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 previous = current; | 622 previous = current; |
| 635 current = current->outer_scope_; | 623 current = current->outer_scope_; |
| 636 } while (!previous->is_declaration_scope()); | 624 } while (!previous->is_declaration_scope()); |
| 637 } | 625 } |
| 638 return NULL; | 626 return NULL; |
| 639 } | 627 } |
| 640 | 628 |
| 641 | 629 |
| 642 class VarAndOrder { | 630 class VarAndOrder { |
| 643 public: | 631 public: |
| 644 VarAndOrder(Variable* var, int order) : var_(var), order_(order) { } | 632 VarAndOrder(Variable* var, int order) : var_(var), order_(order) {} |
| 645 Variable* var() const { return var_; } | 633 Variable* var() const { return var_; } |
| 646 int order() const { return order_; } | 634 int order() const { return order_; } |
| 647 static int Compare(const VarAndOrder* a, const VarAndOrder* b) { | 635 static int Compare(const VarAndOrder* a, const VarAndOrder* b) { |
| 648 return a->order_ - b->order_; | 636 return a->order_ - b->order_; |
| 649 } | 637 } |
| 650 | 638 |
| 651 private: | 639 private: |
| 652 Variable* var_; | 640 Variable* var_; |
| 653 int order_; | 641 int order_; |
| 654 }; | 642 }; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 673 } else if (var->IsStackLocal()) { | 661 } else if (var->IsStackLocal()) { |
| 674 stack_locals->Add(var, zone()); | 662 stack_locals->Add(var, zone()); |
| 675 } else { | 663 } else { |
| 676 DCHECK(var->IsParameter()); | 664 DCHECK(var->IsParameter()); |
| 677 } | 665 } |
| 678 } | 666 } |
| 679 } | 667 } |
| 680 | 668 |
| 681 // Collect declared local variables. | 669 // Collect declared local variables. |
| 682 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 670 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 683 for (VariableMap::Entry* p = variables_.Start(); | 671 for (VariableMap::Entry* p = variables_.Start(); p != NULL; |
| 684 p != NULL; | |
| 685 p = variables_.Next(p)) { | 672 p = variables_.Next(p)) { |
| 686 Variable* var = reinterpret_cast<Variable*>(p->value); | 673 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 687 if (strong_mode_free_variables && var->has_strong_mode_reference() && | 674 if (strong_mode_free_variables && var->has_strong_mode_reference() && |
| 688 var->mode() == DYNAMIC_GLOBAL) { | 675 var->mode() == DYNAMIC_GLOBAL) { |
| 689 strong_mode_free_variables->Add(var, zone()); | 676 strong_mode_free_variables->Add(var, zone()); |
| 690 } | 677 } |
| 691 | 678 |
| 692 if (var->is_used()) { | 679 if (var->is_used()) { |
| 693 vars.Add(VarAndOrder(var, p->order), zone()); | 680 vars.Add(VarAndOrder(var, p->order), zone()); |
| 694 } | 681 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 Scope* Scope::ReceiverScope() { | 810 Scope* Scope::ReceiverScope() { |
| 824 Scope* scope = this; | 811 Scope* scope = this; |
| 825 while (!scope->is_script_scope() && | 812 while (!scope->is_script_scope() && |
| 826 (!scope->is_function_scope() || scope->is_arrow_scope())) { | 813 (!scope->is_function_scope() || scope->is_arrow_scope())) { |
| 827 scope = scope->outer_scope(); | 814 scope = scope->outer_scope(); |
| 828 } | 815 } |
| 829 return scope; | 816 return scope; |
| 830 } | 817 } |
| 831 | 818 |
| 832 | 819 |
| 833 | |
| 834 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | 820 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
| 835 if (scope_info_.is_null()) { | 821 if (scope_info_.is_null()) { |
| 836 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | 822 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
| 837 } | 823 } |
| 838 return scope_info_; | 824 return scope_info_; |
| 839 } | 825 } |
| 840 | 826 |
| 841 | 827 |
| 842 void Scope::GetNestedScopeChain(Isolate* isolate, | 828 void Scope::GetNestedScopeChain(Isolate* isolate, |
| 843 List<Handle<ScopeInfo> >* chain, int position) { | 829 List<Handle<ScopeInfo> >* chain, int position) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 868 | 854 |
| 869 top->pending_error_handler_.ReportMessageAt(start_position, end_position, | 855 top->pending_error_handler_.ReportMessageAt(start_position, end_position, |
| 870 message, arg, kReferenceError); | 856 message, arg, kReferenceError); |
| 871 } | 857 } |
| 872 | 858 |
| 873 | 859 |
| 874 #ifdef DEBUG | 860 #ifdef DEBUG |
| 875 static const char* Header(ScopeType scope_type, FunctionKind function_kind, | 861 static const char* Header(ScopeType scope_type, FunctionKind function_kind, |
| 876 bool is_declaration_scope) { | 862 bool is_declaration_scope) { |
| 877 switch (scope_type) { | 863 switch (scope_type) { |
| 878 case EVAL_SCOPE: return "eval"; | 864 case EVAL_SCOPE: |
| 865 return "eval"; |
| 879 // TODO(adamk): Should we print concise method scopes specially? | 866 // TODO(adamk): Should we print concise method scopes specially? |
| 880 case FUNCTION_SCOPE: | 867 case FUNCTION_SCOPE: |
| 881 return IsArrowFunction(function_kind) ? "arrow" : "function"; | 868 return IsArrowFunction(function_kind) ? "arrow" : "function"; |
| 882 case MODULE_SCOPE: return "module"; | 869 case MODULE_SCOPE: |
| 883 case SCRIPT_SCOPE: return "global"; | 870 return "module"; |
| 884 case CATCH_SCOPE: return "catch"; | 871 case SCRIPT_SCOPE: |
| 885 case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block"; | 872 return "global"; |
| 886 case WITH_SCOPE: return "with"; | 873 case CATCH_SCOPE: |
| 874 return "catch"; |
| 875 case BLOCK_SCOPE: |
| 876 return is_declaration_scope ? "varblock" : "block"; |
| 877 case WITH_SCOPE: |
| 878 return "with"; |
| 887 } | 879 } |
| 888 UNREACHABLE(); | 880 UNREACHABLE(); |
| 889 return NULL; | 881 return NULL; |
| 890 } | 882 } |
| 891 | 883 |
| 892 | 884 |
| 893 static void Indent(int n, const char* str) { | 885 static void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); } |
| 894 PrintF("%*s%s", n, "", str); | |
| 895 } | |
| 896 | 886 |
| 897 | 887 |
| 898 static void PrintName(const AstRawString* name) { | 888 static void PrintName(const AstRawString* name) { |
| 899 PrintF("%.*s", name->length(), name->raw_data()); | 889 PrintF("%.*s", name->length(), name->raw_data()); |
| 900 } | 890 } |
| 901 | 891 |
| 902 | 892 |
| 903 static void PrintLocation(Variable* var) { | 893 static void PrintLocation(Variable* var) { |
| 904 switch (var->location()) { | 894 switch (var->location()) { |
| 905 case VariableLocation::UNALLOCATED: | 895 case VariableLocation::UNALLOCATED: |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 } | 1050 } |
| 1061 #endif // DEBUG | 1051 #endif // DEBUG |
| 1062 | 1052 |
| 1063 | 1053 |
| 1064 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { | 1054 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
| 1065 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); | 1055 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); |
| 1066 VariableMap* map = dynamics_->GetMap(mode); | 1056 VariableMap* map = dynamics_->GetMap(mode); |
| 1067 Variable* var = map->Lookup(name); | 1057 Variable* var = map->Lookup(name); |
| 1068 if (var == NULL) { | 1058 if (var == NULL) { |
| 1069 // Declare a new non-local. | 1059 // Declare a new non-local. |
| 1070 InitializationFlag init_flag = (mode == VAR) | 1060 InitializationFlag init_flag = |
| 1071 ? kCreatedInitialized : kNeedsInitialization; | 1061 (mode == VAR) ? kCreatedInitialized : kNeedsInitialization; |
| 1072 var = map->Declare(NULL, | 1062 var = map->Declare(NULL, name, mode, Variable::NORMAL, init_flag); |
| 1073 name, | |
| 1074 mode, | |
| 1075 Variable::NORMAL, | |
| 1076 init_flag); | |
| 1077 // Allocate it by giving it a dynamic lookup. | 1063 // Allocate it by giving it a dynamic lookup. |
| 1078 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1064 var->AllocateTo(VariableLocation::LOOKUP, -1); |
| 1079 } | 1065 } |
| 1080 return var; | 1066 return var; |
| 1081 } | 1067 } |
| 1082 | 1068 |
| 1083 | 1069 |
| 1084 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 1070 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
| 1085 BindingKind* binding_kind, | 1071 BindingKind* binding_kind, |
| 1086 AstNodeFactory* factory) { | 1072 AstNodeFactory* factory) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 // Resolve unresolved variables for inner scopes. | 1322 // Resolve unresolved variables for inner scopes. |
| 1337 for (int i = 0; i < inner_scopes_.length(); i++) { | 1323 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1338 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) | 1324 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
| 1339 return false; | 1325 return false; |
| 1340 } | 1326 } |
| 1341 | 1327 |
| 1342 return true; | 1328 return true; |
| 1343 } | 1329 } |
| 1344 | 1330 |
| 1345 | 1331 |
| 1346 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { | 1332 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) { |
| 1347 if (outer_scope_calls_sloppy_eval) { | 1333 if (outer_scope_calls_sloppy_eval) { |
| 1348 outer_scope_calls_sloppy_eval_ = true; | 1334 outer_scope_calls_sloppy_eval_ = true; |
| 1349 } | 1335 } |
| 1350 | 1336 |
| 1351 bool calls_sloppy_eval = | 1337 bool calls_sloppy_eval = |
| 1352 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; | 1338 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; |
| 1353 for (int i = 0; i < inner_scopes_.length(); i++) { | 1339 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1354 Scope* inner = inner_scopes_[i]; | 1340 Scope* inner = inner_scopes_[i]; |
| 1355 inner->PropagateScopeInfo(calls_sloppy_eval); | 1341 inner->PropagateScopeInfo(calls_sloppy_eval); |
| 1356 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | 1342 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 // context. | 1375 // context. |
| 1390 // | 1376 // |
| 1391 // Exceptions: If the scope as a whole has forced context allocation, all | 1377 // Exceptions: If the scope as a whole has forced context allocation, all |
| 1392 // variables will have context allocation, even temporaries. Otherwise | 1378 // variables will have context allocation, even temporaries. Otherwise |
| 1393 // temporary variables are always stack-allocated. Catch-bound variables are | 1379 // temporary variables are always stack-allocated. Catch-bound variables are |
| 1394 // always context-allocated. | 1380 // always context-allocated. |
| 1395 if (has_forced_context_allocation()) return true; | 1381 if (has_forced_context_allocation()) return true; |
| 1396 if (var->mode() == TEMPORARY) return false; | 1382 if (var->mode() == TEMPORARY) return false; |
| 1397 if (is_catch_scope() || is_module_scope()) return true; | 1383 if (is_catch_scope() || is_module_scope()) return true; |
| 1398 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1384 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1399 return var->has_forced_context_allocation() || | 1385 return var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1400 scope_calls_eval_ || | 1386 inner_scope_calls_eval_ || scope_contains_with_; |
| 1401 inner_scope_calls_eval_ || | |
| 1402 scope_contains_with_; | |
| 1403 } | 1387 } |
| 1404 | 1388 |
| 1405 | 1389 |
| 1406 bool Scope::HasArgumentsParameter(Isolate* isolate) { | 1390 bool Scope::HasArgumentsParameter(Isolate* isolate) { |
| 1407 for (int i = 0; i < params_.length(); i++) { | 1391 for (int i = 0; i < params_.length(); i++) { |
| 1408 if (params_[i]->name().is_identical_to( | 1392 if (params_[i]->name().is_identical_to( |
| 1409 isolate->factory()->arguments_string())) { | 1393 isolate->factory()->arguments_string())) { |
| 1410 return true; | 1394 return true; |
| 1411 } | 1395 } |
| 1412 } | 1396 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 } | 1528 } |
| 1545 | 1529 |
| 1546 | 1530 |
| 1547 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) { | 1531 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) { |
| 1548 // All variables that have no rewrite yet are non-parameter locals. | 1532 // All variables that have no rewrite yet are non-parameter locals. |
| 1549 for (int i = 0; i < temps_.length(); i++) { | 1533 for (int i = 0; i < temps_.length(); i++) { |
| 1550 AllocateNonParameterLocal(isolate, temps_[i]); | 1534 AllocateNonParameterLocal(isolate, temps_[i]); |
| 1551 } | 1535 } |
| 1552 | 1536 |
| 1553 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1537 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 1554 for (VariableMap::Entry* p = variables_.Start(); | 1538 for (VariableMap::Entry* p = variables_.Start(); p != NULL; |
| 1555 p != NULL; | |
| 1556 p = variables_.Next(p)) { | 1539 p = variables_.Next(p)) { |
| 1557 Variable* var = reinterpret_cast<Variable*>(p->value); | 1540 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1558 vars.Add(VarAndOrder(var, p->order), zone()); | 1541 vars.Add(VarAndOrder(var, p->order), zone()); |
| 1559 } | 1542 } |
| 1560 vars.Sort(VarAndOrder::Compare); | 1543 vars.Sort(VarAndOrder::Compare); |
| 1561 int var_count = vars.length(); | 1544 int var_count = vars.length(); |
| 1562 for (int i = 0; i < var_count; i++) { | 1545 for (int i = 0; i < var_count; i++) { |
| 1563 AllocateNonParameterLocal(isolate, vars[i].var()); | 1546 AllocateNonParameterLocal(isolate, vars[i].var()); |
| 1564 } | 1547 } |
| 1565 | 1548 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 scope->module_var_ = | 1631 scope->module_var_ = |
| 1649 NewTemporary(ast_value_factory_->dot_module_string()); | 1632 NewTemporary(ast_value_factory_->dot_module_string()); |
| 1650 ++num_modules_; | 1633 ++num_modules_; |
| 1651 } | 1634 } |
| 1652 } | 1635 } |
| 1653 } | 1636 } |
| 1654 | 1637 |
| 1655 | 1638 |
| 1656 int Scope::StackLocalCount() const { | 1639 int Scope::StackLocalCount() const { |
| 1657 return num_stack_slots() - | 1640 return num_stack_slots() - |
| 1658 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1641 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 |
| 1642 : 0); |
| 1659 } | 1643 } |
| 1660 | 1644 |
| 1661 | 1645 |
| 1662 int Scope::ContextLocalCount() const { | 1646 int Scope::ContextLocalCount() const { |
| 1663 if (num_heap_slots() == 0) return 0; | 1647 if (num_heap_slots() == 0) return 0; |
| 1664 bool is_function_var_in_context = | 1648 bool is_function_var_in_context = |
| 1665 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1649 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
| 1666 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1650 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1667 (is_function_var_in_context ? 1 : 0); | 1651 (is_function_var_in_context ? 1 : 0); |
| 1668 } | 1652 } |
| 1669 | 1653 |
| 1670 | 1654 |
| 1671 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1655 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1672 | 1656 |
| 1673 } // namespace internal | 1657 } // namespace internal |
| 1674 } // namespace v8 | 1658 } // namespace v8 |
| OLD | NEW |