OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 // ---------------------------------------------------------------------------- | 104 // ---------------------------------------------------------------------------- |
105 // Implementation of Scope | 105 // Implementation of Scope |
106 | 106 |
107 Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone) | 107 Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone) |
108 : isolate_(Isolate::Current()), | 108 : isolate_(Isolate::Current()), |
109 inner_scopes_(4, zone), | 109 inner_scopes_(4, zone), |
110 variables_(zone), | 110 variables_(zone), |
| 111 internals_(4, zone), |
111 temps_(4, zone), | 112 temps_(4, zone), |
112 params_(4, zone), | 113 params_(4, zone), |
113 unresolved_(16, zone), | 114 unresolved_(16, zone), |
114 decls_(4, zone), | 115 decls_(4, zone), |
115 interface_(FLAG_harmony_modules && | 116 interface_(FLAG_harmony_modules && |
116 (type == MODULE_SCOPE || type == GLOBAL_SCOPE) | 117 (type == MODULE_SCOPE || type == GLOBAL_SCOPE) |
117 ? Interface::NewModule(zone) : NULL), | 118 ? Interface::NewModule(zone) : NULL), |
118 already_resolved_(false), | 119 already_resolved_(false), |
119 zone_(zone) { | 120 zone_(zone) { |
120 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); | 121 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); |
121 // The outermost scope must be a global scope. | 122 // The outermost scope must be a global scope. |
122 ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL); | 123 ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL); |
123 ASSERT(!HasIllegalRedeclaration()); | 124 ASSERT(!HasIllegalRedeclaration()); |
124 } | 125 } |
125 | 126 |
126 | 127 |
127 Scope::Scope(Scope* inner_scope, | 128 Scope::Scope(Scope* inner_scope, |
128 ScopeType type, | 129 ScopeType type, |
129 Handle<ScopeInfo> scope_info, | 130 Handle<ScopeInfo> scope_info, |
130 Zone* zone) | 131 Zone* zone) |
131 : isolate_(Isolate::Current()), | 132 : isolate_(Isolate::Current()), |
132 inner_scopes_(4, zone), | 133 inner_scopes_(4, zone), |
133 variables_(zone), | 134 variables_(zone), |
| 135 internals_(4, zone), |
134 temps_(4, zone), | 136 temps_(4, zone), |
135 params_(4, zone), | 137 params_(4, zone), |
136 unresolved_(16, zone), | 138 unresolved_(16, zone), |
137 decls_(4, zone), | 139 decls_(4, zone), |
138 interface_(NULL), | 140 interface_(NULL), |
139 already_resolved_(true), | 141 already_resolved_(true), |
140 zone_(zone) { | 142 zone_(zone) { |
141 SetDefaults(type, NULL, scope_info); | 143 SetDefaults(type, NULL, scope_info); |
142 if (!scope_info.is_null()) { | 144 if (!scope_info.is_null()) { |
143 num_heap_slots_ = scope_info_->ContextLength(); | 145 num_heap_slots_ = scope_info_->ContextLength(); |
144 } | 146 } |
145 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 147 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
146 num_heap_slots_ = Max(num_heap_slots_, | 148 num_heap_slots_ = Max(num_heap_slots_, |
147 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 149 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
148 AddInnerScope(inner_scope); | 150 AddInnerScope(inner_scope); |
149 } | 151 } |
150 | 152 |
151 | 153 |
152 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone) | 154 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone) |
153 : isolate_(Isolate::Current()), | 155 : isolate_(Isolate::Current()), |
154 inner_scopes_(1, zone), | 156 inner_scopes_(1, zone), |
155 variables_(zone), | 157 variables_(zone), |
| 158 internals_(0, zone), |
156 temps_(0, zone), | 159 temps_(0, zone), |
157 params_(0, zone), | 160 params_(0, zone), |
158 unresolved_(0, zone), | 161 unresolved_(0, zone), |
159 decls_(0, zone), | 162 decls_(0, zone), |
160 interface_(NULL), | 163 interface_(NULL), |
161 already_resolved_(true), | 164 already_resolved_(true), |
162 zone_(zone) { | 165 zone_(zone) { |
163 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 166 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
164 AddInnerScope(inner_scope); | 167 AddInnerScope(inner_scope); |
165 ++num_var_or_const_; | 168 ++num_var_or_const_; |
(...skipping 24 matching lines...) Expand all Loading... |
190 scope_calls_eval_ = false; | 193 scope_calls_eval_ = false; |
191 // Inherit the strict mode from the parent scope. | 194 // Inherit the strict mode from the parent scope. |
192 language_mode_ = (outer_scope != NULL) | 195 language_mode_ = (outer_scope != NULL) |
193 ? outer_scope->language_mode_ : CLASSIC_MODE; | 196 ? outer_scope->language_mode_ : CLASSIC_MODE; |
194 outer_scope_calls_non_strict_eval_ = false; | 197 outer_scope_calls_non_strict_eval_ = false; |
195 inner_scope_calls_eval_ = false; | 198 inner_scope_calls_eval_ = false; |
196 force_eager_compilation_ = false; | 199 force_eager_compilation_ = false; |
197 num_var_or_const_ = 0; | 200 num_var_or_const_ = 0; |
198 num_stack_slots_ = 0; | 201 num_stack_slots_ = 0; |
199 num_heap_slots_ = 0; | 202 num_heap_slots_ = 0; |
| 203 num_modules_ = 0; |
| 204 module_var_ = NULL, |
200 scope_info_ = scope_info; | 205 scope_info_ = scope_info; |
201 start_position_ = RelocInfo::kNoPosition; | 206 start_position_ = RelocInfo::kNoPosition; |
202 end_position_ = RelocInfo::kNoPosition; | 207 end_position_ = RelocInfo::kNoPosition; |
203 if (!scope_info.is_null()) { | 208 if (!scope_info.is_null()) { |
204 scope_calls_eval_ = scope_info->CallsEval(); | 209 scope_calls_eval_ = scope_info->CallsEval(); |
205 language_mode_ = scope_info->language_mode(); | 210 language_mode_ = scope_info->language_mode(); |
206 } | 211 } |
207 } | 212 } |
208 | 213 |
209 | 214 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 VAR, | 373 VAR, |
369 true, | 374 true, |
370 Variable::ARGUMENTS, | 375 Variable::ARGUMENTS, |
371 kCreatedInitialized); | 376 kCreatedInitialized); |
372 } | 377 } |
373 } | 378 } |
374 | 379 |
375 | 380 |
376 Scope* Scope::FinalizeBlockScope() { | 381 Scope* Scope::FinalizeBlockScope() { |
377 ASSERT(is_block_scope()); | 382 ASSERT(is_block_scope()); |
| 383 ASSERT(internals_.is_empty()); |
378 ASSERT(temps_.is_empty()); | 384 ASSERT(temps_.is_empty()); |
379 ASSERT(params_.is_empty()); | 385 ASSERT(params_.is_empty()); |
380 | 386 |
381 if (num_var_or_const() > 0) return this; | 387 if (num_var_or_const() > 0) return this; |
382 | 388 |
383 // Remove this scope from outer scope. | 389 // Remove this scope from outer scope. |
384 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { | 390 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { |
385 if (outer_scope_->inner_scopes_[i] == this) { | 391 if (outer_scope_->inner_scopes_[i] == this) { |
386 outer_scope_->inner_scopes_.Remove(i); | 392 outer_scope_->inner_scopes_.Remove(i); |
387 break; | 393 break; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 // was just added before, so we search backwards. | 514 // was just added before, so we search backwards. |
509 for (int i = unresolved_.length(); i-- > 0;) { | 515 for (int i = unresolved_.length(); i-- > 0;) { |
510 if (unresolved_[i] == var) { | 516 if (unresolved_[i] == var) { |
511 unresolved_.Remove(i); | 517 unresolved_.Remove(i); |
512 return; | 518 return; |
513 } | 519 } |
514 } | 520 } |
515 } | 521 } |
516 | 522 |
517 | 523 |
| 524 Variable* Scope::NewInternal(Handle<String> name) { |
| 525 ASSERT(!already_resolved()); |
| 526 Variable* var = new(zone()) Variable(this, |
| 527 name, |
| 528 INTERNAL, |
| 529 false, |
| 530 Variable::NORMAL, |
| 531 kCreatedInitialized); |
| 532 internals_.Add(var, zone()); |
| 533 return var; |
| 534 } |
| 535 |
| 536 |
518 Variable* Scope::NewTemporary(Handle<String> name) { | 537 Variable* Scope::NewTemporary(Handle<String> name) { |
519 ASSERT(!already_resolved()); | 538 ASSERT(!already_resolved()); |
520 Variable* var = new(zone()) Variable(this, | 539 Variable* var = new(zone()) Variable(this, |
521 name, | 540 name, |
522 TEMPORARY, | 541 TEMPORARY, |
523 true, | 542 true, |
524 Variable::NORMAL, | 543 Variable::NORMAL, |
525 kCreatedInitialized); | 544 kCreatedInitialized); |
526 temps_.Add(var, zone()); | 545 temps_.Add(var, zone()); |
527 return var; | 546 return var; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 Variable* var_; | 627 Variable* var_; |
609 int order_; | 628 int order_; |
610 }; | 629 }; |
611 | 630 |
612 | 631 |
613 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 632 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
614 ZoneList<Variable*>* context_locals) { | 633 ZoneList<Variable*>* context_locals) { |
615 ASSERT(stack_locals != NULL); | 634 ASSERT(stack_locals != NULL); |
616 ASSERT(context_locals != NULL); | 635 ASSERT(context_locals != NULL); |
617 | 636 |
| 637 // Collect internals which are always allocated on the heap. |
| 638 for (int i = 0; i < internals_.length(); i++) { |
| 639 Variable* var = internals_[i]; |
| 640 if (var->is_used()) { |
| 641 ASSERT(var->IsContextSlot()); |
| 642 context_locals->Add(var, zone()); |
| 643 } |
| 644 } |
| 645 |
618 // Collect temporaries which are always allocated on the stack. | 646 // Collect temporaries which are always allocated on the stack. |
619 for (int i = 0; i < temps_.length(); i++) { | 647 for (int i = 0; i < temps_.length(); i++) { |
620 Variable* var = temps_[i]; | 648 Variable* var = temps_[i]; |
621 if (var->is_used()) { | 649 if (var->is_used()) { |
622 ASSERT(var->IsStackLocal()); | 650 ASSERT(var->IsStackLocal()); |
623 stack_locals->Add(var, zone()); | 651 stack_locals->Add(var, zone()); |
624 } | 652 } |
625 } | 653 } |
626 | 654 |
| 655 // Collect declared local variables. |
627 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 656 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
628 | |
629 // Collect declared local variables. | |
630 for (VariableMap::Entry* p = variables_.Start(); | 657 for (VariableMap::Entry* p = variables_.Start(); |
631 p != NULL; | 658 p != NULL; |
632 p = variables_.Next(p)) { | 659 p = variables_.Next(p)) { |
633 Variable* var = reinterpret_cast<Variable*>(p->value); | 660 Variable* var = reinterpret_cast<Variable*>(p->value); |
634 if (var->is_used()) { | 661 if (var->is_used()) { |
635 vars.Add(VarAndOrder(var, p->order), zone()); | 662 vars.Add(VarAndOrder(var, p->order), zone()); |
636 } | 663 } |
637 } | 664 } |
638 vars.Sort(VarAndOrder::Compare); | 665 vars.Sort(VarAndOrder::Compare); |
639 int var_count = vars.length(); | 666 int var_count = vars.length(); |
(...skipping 12 matching lines...) Expand all Loading... |
652 AstNodeFactory<AstNullVisitor>* factory) { | 679 AstNodeFactory<AstNullVisitor>* factory) { |
653 // 1) Propagate scope information. | 680 // 1) Propagate scope information. |
654 bool outer_scope_calls_non_strict_eval = false; | 681 bool outer_scope_calls_non_strict_eval = false; |
655 if (outer_scope_ != NULL) { | 682 if (outer_scope_ != NULL) { |
656 outer_scope_calls_non_strict_eval = | 683 outer_scope_calls_non_strict_eval = |
657 outer_scope_->outer_scope_calls_non_strict_eval() | | 684 outer_scope_->outer_scope_calls_non_strict_eval() | |
658 outer_scope_->calls_non_strict_eval(); | 685 outer_scope_->calls_non_strict_eval(); |
659 } | 686 } |
660 PropagateScopeInfo(outer_scope_calls_non_strict_eval); | 687 PropagateScopeInfo(outer_scope_calls_non_strict_eval); |
661 | 688 |
662 // 2) Resolve variables. | 689 // 2) Allocate module instances. |
| 690 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { |
| 691 ASSERT(num_modules_ == 0); |
| 692 AllocateModulesRecursively(this); |
| 693 } |
| 694 |
| 695 // 3) Resolve variables. |
663 if (!ResolveVariablesRecursively(info, factory)) return false; | 696 if (!ResolveVariablesRecursively(info, factory)) return false; |
664 | 697 |
665 // 3) Allocate variables. | 698 // 4) Allocate variables. |
666 AllocateVariablesRecursively(); | 699 AllocateVariablesRecursively(); |
667 | 700 |
668 // 4) Allocate and link module instance objects. | |
669 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { | |
670 AllocateModules(info); | |
671 LinkModules(info); | |
672 } | |
673 | |
674 return true; | 701 return true; |
675 } | 702 } |
676 | 703 |
677 | 704 |
678 bool Scope::HasTrivialContext() const { | 705 bool Scope::HasTrivialContext() const { |
679 // A function scope has a trivial context if it always is the global | 706 // A function scope has a trivial context if it always is the global |
680 // context. We iteratively scan out the context chain to see if | 707 // context. We iteratively scan out the context chain to see if |
681 // there is anything that makes this scope non-trivial; otherwise we | 708 // there is anything that makes this scope non-trivial; otherwise we |
682 // return true. | 709 // return true. |
683 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 710 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 int Scope::ContextChainLength(Scope* scope) { | 762 int Scope::ContextChainLength(Scope* scope) { |
736 int n = 0; | 763 int n = 0; |
737 for (Scope* s = this; s != scope; s = s->outer_scope_) { | 764 for (Scope* s = this; s != scope; s = s->outer_scope_) { |
738 ASSERT(s != NULL); // scope must be in the scope chain | 765 ASSERT(s != NULL); // scope must be in the scope chain |
739 if (s->num_heap_slots() > 0) n++; | 766 if (s->num_heap_slots() > 0) n++; |
740 } | 767 } |
741 return n; | 768 return n; |
742 } | 769 } |
743 | 770 |
744 | 771 |
| 772 Scope* Scope::GlobalScope() { |
| 773 Scope* scope = this; |
| 774 while (!scope->is_global_scope()) { |
| 775 scope = scope->outer_scope(); |
| 776 } |
| 777 return scope; |
| 778 } |
| 779 |
| 780 |
745 Scope* Scope::DeclarationScope() { | 781 Scope* Scope::DeclarationScope() { |
746 Scope* scope = this; | 782 Scope* scope = this; |
747 while (!scope->is_declaration_scope()) { | 783 while (!scope->is_declaration_scope()) { |
748 scope = scope->outer_scope(); | 784 scope = scope->outer_scope(); |
749 } | 785 } |
750 return scope; | 786 return scope; |
751 } | 787 } |
752 | 788 |
753 | 789 |
754 Handle<ScopeInfo> Scope::GetScopeInfo() { | 790 Handle<ScopeInfo> Scope::GetScopeInfo() { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 Indent(n1, "// function var\n"); | 944 Indent(n1, "// function var\n"); |
909 if (function_ != NULL) { | 945 if (function_ != NULL) { |
910 PrintVar(n1, function_->proxy()->var()); | 946 PrintVar(n1, function_->proxy()->var()); |
911 } | 947 } |
912 | 948 |
913 Indent(n1, "// temporary vars\n"); | 949 Indent(n1, "// temporary vars\n"); |
914 for (int i = 0; i < temps_.length(); i++) { | 950 for (int i = 0; i < temps_.length(); i++) { |
915 PrintVar(n1, temps_[i]); | 951 PrintVar(n1, temps_[i]); |
916 } | 952 } |
917 | 953 |
| 954 Indent(n1, "// internal vars\n"); |
| 955 for (int i = 0; i < internals_.length(); i++) { |
| 956 PrintVar(n1, internals_[i]); |
| 957 } |
| 958 |
918 Indent(n1, "// local vars\n"); | 959 Indent(n1, "// local vars\n"); |
919 PrintMap(n1, &variables_); | 960 PrintMap(n1, &variables_); |
920 | 961 |
921 Indent(n1, "// dynamic vars\n"); | 962 Indent(n1, "// dynamic vars\n"); |
922 if (dynamics_ != NULL) { | 963 if (dynamics_ != NULL) { |
923 PrintMap(n1, dynamics_->GetMap(DYNAMIC)); | 964 PrintMap(n1, dynamics_->GetMap(DYNAMIC)); |
924 PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL)); | 965 PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL)); |
925 PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL)); | 966 PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL)); |
926 } | 967 } |
927 | 968 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 1099 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); |
1059 break; | 1100 break; |
1060 | 1101 |
1061 case DYNAMIC_LOOKUP: | 1102 case DYNAMIC_LOOKUP: |
1062 // The variable could not be resolved statically. | 1103 // The variable could not be resolved statically. |
1063 var = NonLocal(proxy->name(), DYNAMIC); | 1104 var = NonLocal(proxy->name(), DYNAMIC); |
1064 break; | 1105 break; |
1065 } | 1106 } |
1066 | 1107 |
1067 ASSERT(var != NULL); | 1108 ASSERT(var != NULL); |
1068 proxy->BindTo(var); | |
1069 | 1109 |
1070 if (FLAG_harmony_modules) { | 1110 if (FLAG_harmony_modules) { |
1071 bool ok; | 1111 bool ok; |
1072 #ifdef DEBUG | 1112 #ifdef DEBUG |
1073 if (FLAG_print_interface_details) | 1113 if (FLAG_print_interface_details) |
1074 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); | 1114 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); |
1075 #endif | 1115 #endif |
1076 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1116 proxy->interface()->Unify(var->interface(), zone(), &ok); |
1077 if (!ok) { | 1117 if (!ok) { |
1078 #ifdef DEBUG | 1118 #ifdef DEBUG |
(...skipping 15 matching lines...) Expand all Loading... |
1094 Factory* factory = isolate->factory(); | 1134 Factory* factory = isolate->factory(); |
1095 Handle<JSArray> array = factory->NewJSArray(1); | 1135 Handle<JSArray> array = factory->NewJSArray(1); |
1096 USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode)); | 1136 USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode)); |
1097 Handle<Object> result = | 1137 Handle<Object> result = |
1098 factory->NewSyntaxError("module_type_error", array); | 1138 factory->NewSyntaxError("module_type_error", array); |
1099 isolate->Throw(*result, &location); | 1139 isolate->Throw(*result, &location); |
1100 return false; | 1140 return false; |
1101 } | 1141 } |
1102 } | 1142 } |
1103 | 1143 |
| 1144 proxy->BindTo(var); |
| 1145 |
1104 return true; | 1146 return true; |
1105 } | 1147 } |
1106 | 1148 |
1107 | 1149 |
1108 bool Scope::ResolveVariablesRecursively( | 1150 bool Scope::ResolveVariablesRecursively( |
1109 CompilationInfo* info, | 1151 CompilationInfo* info, |
1110 AstNodeFactory<AstNullVisitor>* factory) { | 1152 AstNodeFactory<AstNullVisitor>* factory) { |
1111 ASSERT(info->global_scope()->is_global_scope()); | 1153 ASSERT(info->global_scope()->is_global_scope()); |
1112 | 1154 |
1113 // Resolve unresolved variables for this scope. | 1155 // Resolve unresolved variables for this scope. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 | 1210 |
1169 bool Scope::MustAllocateInContext(Variable* var) { | 1211 bool Scope::MustAllocateInContext(Variable* var) { |
1170 // If var is accessed from an inner scope, or if there is a possibility | 1212 // If var is accessed from an inner scope, or if there is a possibility |
1171 // that it might be accessed from the current or an inner scope (through | 1213 // that it might be accessed from the current or an inner scope (through |
1172 // an eval() call or a runtime with lookup), it must be allocated in the | 1214 // an eval() call or a runtime with lookup), it must be allocated in the |
1173 // context. | 1215 // context. |
1174 // | 1216 // |
1175 // Exceptions: temporary variables are never allocated in a context; | 1217 // Exceptions: temporary variables are never allocated in a context; |
1176 // catch-bound variables are always allocated in a context. | 1218 // catch-bound variables are always allocated in a context. |
1177 if (var->mode() == TEMPORARY) return false; | 1219 if (var->mode() == TEMPORARY) return false; |
| 1220 if (var->mode() == INTERNAL) return true; |
1178 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; | 1221 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |
1179 if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true; | 1222 if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true; |
1180 return var->has_forced_context_allocation() || | 1223 return var->has_forced_context_allocation() || |
1181 scope_calls_eval_ || | 1224 scope_calls_eval_ || |
1182 inner_scope_calls_eval_ || | 1225 inner_scope_calls_eval_ || |
1183 scope_contains_with_; | 1226 scope_contains_with_; |
1184 } | 1227 } |
1185 | 1228 |
1186 | 1229 |
1187 bool Scope::HasArgumentsParameter() { | 1230 bool Scope::HasArgumentsParameter() { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 } | 1317 } |
1275 } | 1318 } |
1276 | 1319 |
1277 | 1320 |
1278 void Scope::AllocateNonParameterLocals() { | 1321 void Scope::AllocateNonParameterLocals() { |
1279 // All variables that have no rewrite yet are non-parameter locals. | 1322 // All variables that have no rewrite yet are non-parameter locals. |
1280 for (int i = 0; i < temps_.length(); i++) { | 1323 for (int i = 0; i < temps_.length(); i++) { |
1281 AllocateNonParameterLocal(temps_[i]); | 1324 AllocateNonParameterLocal(temps_[i]); |
1282 } | 1325 } |
1283 | 1326 |
| 1327 for (int i = 0; i < internals_.length(); i++) { |
| 1328 AllocateNonParameterLocal(internals_[i]); |
| 1329 } |
| 1330 |
1284 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1331 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
1285 | |
1286 for (VariableMap::Entry* p = variables_.Start(); | 1332 for (VariableMap::Entry* p = variables_.Start(); |
1287 p != NULL; | 1333 p != NULL; |
1288 p = variables_.Next(p)) { | 1334 p = variables_.Next(p)) { |
1289 Variable* var = reinterpret_cast<Variable*>(p->value); | 1335 Variable* var = reinterpret_cast<Variable*>(p->value); |
1290 vars.Add(VarAndOrder(var, p->order), zone()); | 1336 vars.Add(VarAndOrder(var, p->order), zone()); |
1291 } | 1337 } |
1292 | |
1293 vars.Sort(VarAndOrder::Compare); | 1338 vars.Sort(VarAndOrder::Compare); |
1294 int var_count = vars.length(); | 1339 int var_count = vars.length(); |
1295 for (int i = 0; i < var_count; i++) { | 1340 for (int i = 0; i < var_count; i++) { |
1296 AllocateNonParameterLocal(vars[i].var()); | 1341 AllocateNonParameterLocal(vars[i].var()); |
1297 } | 1342 } |
1298 | 1343 |
1299 // For now, function_ must be allocated at the very end. If it gets | 1344 // For now, function_ must be allocated at the very end. If it gets |
1300 // allocated in the context, it must be the last slot in the context, | 1345 // allocated in the context, it must be the last slot in the context, |
1301 // because of the current ScopeInfo implementation (see | 1346 // because of the current ScopeInfo implementation (see |
1302 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1347 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 // need the minimal number of slots if we must have a context. | 1380 // need the minimal number of slots if we must have a context. |
1336 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1381 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1337 num_heap_slots_ = 0; | 1382 num_heap_slots_ = 0; |
1338 } | 1383 } |
1339 | 1384 |
1340 // Allocation done. | 1385 // Allocation done. |
1341 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1386 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1342 } | 1387 } |
1343 | 1388 |
1344 | 1389 |
| 1390 void Scope::AllocateModulesRecursively(Scope* host_scope) { |
| 1391 if (already_resolved()) return; |
| 1392 if (is_module_scope()) { |
| 1393 ASSERT(interface_->IsFrozen()); |
| 1394 const char raw_name[] = ".module"; |
| 1395 Handle<String> name = isolate_->factory()->LookupSymbol( |
| 1396 Vector<const char>(raw_name, StrLength(raw_name))); |
| 1397 ASSERT(module_var_ == NULL); |
| 1398 module_var_ = host_scope->NewInternal(name); |
| 1399 ++host_scope->num_modules_; |
| 1400 } |
| 1401 |
| 1402 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1403 Scope* inner_scope = inner_scopes_.at(i); |
| 1404 inner_scope->AllocateModulesRecursively(host_scope); |
| 1405 } |
| 1406 } |
| 1407 |
| 1408 |
1345 int Scope::StackLocalCount() const { | 1409 int Scope::StackLocalCount() const { |
1346 return num_stack_slots() - | 1410 return num_stack_slots() - |
1347 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1411 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1348 } | 1412 } |
1349 | 1413 |
1350 | 1414 |
1351 int Scope::ContextLocalCount() const { | 1415 int Scope::ContextLocalCount() const { |
1352 if (num_heap_slots() == 0) return 0; | 1416 if (num_heap_slots() == 0) return 0; |
1353 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1417 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1354 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1418 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1355 } | 1419 } |
1356 | 1420 |
1357 | |
1358 void Scope::AllocateModules(CompilationInfo* info) { | |
1359 ASSERT(is_global_scope() || is_module_scope()); | |
1360 | |
1361 if (is_module_scope()) { | |
1362 ASSERT(interface_->IsFrozen()); | |
1363 ASSERT(scope_info_.is_null()); | |
1364 | |
1365 // TODO(rossberg): This has to be the initial compilation of this code. | |
1366 // We currently do not allow recompiling any module definitions. | |
1367 Handle<ScopeInfo> scope_info = GetScopeInfo(); | |
1368 Factory* factory = info->isolate()->factory(); | |
1369 Handle<Context> context = factory->NewModuleContext(scope_info); | |
1370 Handle<JSModule> instance = factory->NewJSModule(context, scope_info); | |
1371 context->set_module(*instance); | |
1372 | |
1373 bool ok; | |
1374 interface_->MakeSingleton(instance, &ok); | |
1375 ASSERT(ok); | |
1376 } | |
1377 | |
1378 // Allocate nested modules. | |
1379 for (int i = 0; i < inner_scopes_.length(); i++) { | |
1380 Scope* inner_scope = inner_scopes_.at(i); | |
1381 if (inner_scope->is_module_scope()) { | |
1382 inner_scope->AllocateModules(info); | |
1383 } | |
1384 } | |
1385 } | |
1386 | |
1387 | |
1388 void Scope::LinkModules(CompilationInfo* info) { | |
1389 ASSERT(is_global_scope() || is_module_scope()); | |
1390 | |
1391 if (is_module_scope()) { | |
1392 Handle<JSModule> instance = interface_->Instance(); | |
1393 | |
1394 // Populate the module instance object. | |
1395 const PropertyAttributes ro_attr = | |
1396 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); | |
1397 const PropertyAttributes rw_attr = | |
1398 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM); | |
1399 for (Interface::Iterator it = interface_->iterator(); | |
1400 !it.done(); it.Advance()) { | |
1401 if (it.interface()->IsModule()) { | |
1402 Handle<Object> value = it.interface()->Instance(); | |
1403 ASSERT(!value.is_null()); | |
1404 JSReceiver::SetProperty( | |
1405 instance, it.name(), value, ro_attr, kStrictMode); | |
1406 } else { | |
1407 Variable* var = LocalLookup(it.name()); | |
1408 ASSERT(var != NULL && var->IsContextSlot()); | |
1409 PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr; | |
1410 Handle<AccessorInfo> info = | |
1411 Accessors::MakeModuleExport(it.name(), var->index(), attr); | |
1412 Handle<Object> result = SetAccessor(instance, info); | |
1413 ASSERT(!(result.is_null() || result->IsUndefined())); | |
1414 USE(result); | |
1415 } | |
1416 } | |
1417 USE(JSObject::PreventExtensions(instance)); | |
1418 } | |
1419 | |
1420 // Link nested modules. | |
1421 for (int i = 0; i < inner_scopes_.length(); i++) { | |
1422 Scope* inner_scope = inner_scopes_.at(i); | |
1423 if (inner_scope->is_module_scope()) { | |
1424 inner_scope->LinkModules(info); | |
1425 } | |
1426 } | |
1427 } | |
1428 | |
1429 | |
1430 } } // namespace v8::internal | 1421 } } // namespace v8::internal |
OLD | NEW |