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 |