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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 DCHECK(p->value != NULL); | 60 DCHECK(p->value != NULL); |
61 return reinterpret_cast<Variable*>(p->value); | 61 return reinterpret_cast<Variable*>(p->value); |
62 } | 62 } |
63 return NULL; | 63 return NULL; |
64 } | 64 } |
65 | 65 |
66 | 66 |
67 // ---------------------------------------------------------------------------- | 67 // ---------------------------------------------------------------------------- |
68 // Implementation of Scope | 68 // Implementation of Scope |
69 | 69 |
70 Scope::Scope(Isolate* isolate, Zone* zone, Scope* outer_scope, | 70 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
71 ScopeType scope_type, AstValueFactory* ast_value_factory) | 71 AstValueFactory* ast_value_factory) |
72 : isolate_(isolate), | 72 : inner_scopes_(4, zone), |
73 inner_scopes_(4, zone), | |
74 variables_(zone), | 73 variables_(zone), |
75 internals_(4, zone), | 74 internals_(4, zone), |
76 temps_(4, zone), | 75 temps_(4, zone), |
77 params_(4, zone), | 76 params_(4, zone), |
78 unresolved_(16, zone), | 77 unresolved_(16, zone), |
79 decls_(4, zone), | 78 decls_(4, zone), |
80 interface_(scope_type == MODULE_SCOPE ? Interface::NewModule(zone) | 79 interface_(scope_type == MODULE_SCOPE ? Interface::NewModule(zone) |
81 : NULL), | 80 : NULL), |
82 already_resolved_(false), | 81 already_resolved_(false), |
83 ast_value_factory_(ast_value_factory), | 82 ast_value_factory_(ast_value_factory), |
84 zone_(zone) { | 83 zone_(zone) { |
85 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); | 84 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); |
86 // The outermost scope must be a script scope. | 85 // The outermost scope must be a script scope. |
87 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); | 86 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); |
88 DCHECK(!HasIllegalRedeclaration()); | 87 DCHECK(!HasIllegalRedeclaration()); |
89 } | 88 } |
90 | 89 |
91 | 90 |
92 Scope::Scope(Isolate* isolate, Zone* zone, Scope* inner_scope, | 91 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
93 ScopeType scope_type, Handle<ScopeInfo> scope_info, | 92 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory) |
94 AstValueFactory* value_factory) | 93 : inner_scopes_(4, zone), |
95 : isolate_(isolate), | |
96 inner_scopes_(4, zone), | |
97 variables_(zone), | 94 variables_(zone), |
98 internals_(4, zone), | 95 internals_(4, zone), |
99 temps_(4, zone), | 96 temps_(4, zone), |
100 params_(4, zone), | 97 params_(4, zone), |
101 unresolved_(16, zone), | 98 unresolved_(16, zone), |
102 decls_(4, zone), | 99 decls_(4, zone), |
103 interface_(NULL), | 100 interface_(NULL), |
104 already_resolved_(true), | 101 already_resolved_(true), |
105 ast_value_factory_(value_factory), | 102 ast_value_factory_(value_factory), |
106 zone_(zone) { | 103 zone_(zone) { |
107 SetDefaults(scope_type, NULL, scope_info); | 104 SetDefaults(scope_type, NULL, scope_info); |
108 if (!scope_info.is_null()) { | 105 if (!scope_info.is_null()) { |
109 num_heap_slots_ = scope_info_->ContextLength(); | 106 num_heap_slots_ = scope_info_->ContextLength(); |
110 } | 107 } |
111 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 108 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
112 num_heap_slots_ = Max(num_heap_slots_, | 109 num_heap_slots_ = Max(num_heap_slots_, |
113 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 110 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
114 AddInnerScope(inner_scope); | 111 AddInnerScope(inner_scope); |
115 } | 112 } |
116 | 113 |
117 | 114 |
118 Scope::Scope(Isolate* isolate, Zone* zone, Scope* inner_scope, | 115 Scope::Scope(Zone* zone, Scope* inner_scope, |
119 const AstRawString* catch_variable_name, | 116 const AstRawString* catch_variable_name, |
120 AstValueFactory* value_factory) | 117 AstValueFactory* value_factory) |
121 : isolate_(isolate), | 118 : inner_scopes_(1, zone), |
122 inner_scopes_(1, zone), | |
123 variables_(zone), | 119 variables_(zone), |
124 internals_(0, zone), | 120 internals_(0, zone), |
125 temps_(0, zone), | 121 temps_(0, zone), |
126 params_(0, zone), | 122 params_(0, zone), |
127 unresolved_(0, zone), | 123 unresolved_(0, zone), |
128 decls_(0, zone), | 124 decls_(0, zone), |
129 interface_(NULL), | 125 interface_(NULL), |
130 already_resolved_(true), | 126 already_resolved_(true), |
131 ast_value_factory_(value_factory), | 127 ast_value_factory_(value_factory), |
132 zone_(zone) { | 128 zone_(zone) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 190 |
195 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 191 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
196 Context* context, Scope* script_scope) { | 192 Context* context, Scope* script_scope) { |
197 // Reconstruct the outer scope chain from a closure's context chain. | 193 // Reconstruct the outer scope chain from a closure's context chain. |
198 Scope* current_scope = NULL; | 194 Scope* current_scope = NULL; |
199 Scope* innermost_scope = NULL; | 195 Scope* innermost_scope = NULL; |
200 bool contains_with = false; | 196 bool contains_with = false; |
201 while (!context->IsNativeContext()) { | 197 while (!context->IsNativeContext()) { |
202 if (context->IsWithContext()) { | 198 if (context->IsWithContext()) { |
203 Scope* with_scope = new (zone) | 199 Scope* with_scope = new (zone) |
204 Scope(isolate, zone, current_scope, WITH_SCOPE, | 200 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null(), |
205 Handle<ScopeInfo>::null(), script_scope->ast_value_factory_); | 201 script_scope->ast_value_factory_); |
206 current_scope = with_scope; | 202 current_scope = with_scope; |
207 // All the inner scopes are inside a with. | 203 // All the inner scopes are inside a with. |
208 contains_with = true; | 204 contains_with = true; |
209 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 205 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
210 s->scope_inside_with_ = true; | 206 s->scope_inside_with_ = true; |
211 } | 207 } |
212 } else if (context->IsScriptContext()) { | 208 } else if (context->IsScriptContext()) { |
213 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 209 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
214 current_scope = new (zone) Scope( | 210 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, |
215 isolate, zone, current_scope, SCRIPT_SCOPE, | 211 Handle<ScopeInfo>(scope_info), |
216 Handle<ScopeInfo>(scope_info), script_scope->ast_value_factory_); | 212 script_scope->ast_value_factory_); |
217 } else if (context->IsModuleContext()) { | 213 } else if (context->IsModuleContext()) { |
218 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); | 214 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); |
219 current_scope = new (zone) Scope( | 215 current_scope = new (zone) Scope(zone, current_scope, MODULE_SCOPE, |
220 isolate, zone, current_scope, MODULE_SCOPE, | 216 Handle<ScopeInfo>(scope_info), |
221 Handle<ScopeInfo>(scope_info), script_scope->ast_value_factory_); | 217 script_scope->ast_value_factory_); |
222 } else if (context->IsFunctionContext()) { | 218 } else if (context->IsFunctionContext()) { |
223 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 219 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
224 current_scope = new (zone) Scope( | 220 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, |
225 isolate, zone, current_scope, FUNCTION_SCOPE, | 221 Handle<ScopeInfo>(scope_info), |
226 Handle<ScopeInfo>(scope_info), script_scope->ast_value_factory_); | 222 script_scope->ast_value_factory_); |
227 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 223 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
228 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 224 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
229 } else if (context->IsBlockContext()) { | 225 } else if (context->IsBlockContext()) { |
230 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 226 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
231 current_scope = new (zone) Scope( | 227 current_scope = new (zone) |
232 isolate, zone, current_scope, BLOCK_SCOPE, | 228 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), |
233 Handle<ScopeInfo>(scope_info), script_scope->ast_value_factory_); | 229 script_scope->ast_value_factory_); |
234 } else { | 230 } else { |
235 DCHECK(context->IsCatchContext()); | 231 DCHECK(context->IsCatchContext()); |
236 String* name = String::cast(context->extension()); | 232 String* name = String::cast(context->extension()); |
237 current_scope = new (zone) Scope( | 233 current_scope = new (zone) Scope( |
238 isolate, zone, current_scope, | 234 zone, current_scope, |
239 script_scope->ast_value_factory_->GetString(Handle<String>(name)), | 235 script_scope->ast_value_factory_->GetString(Handle<String>(name)), |
240 script_scope->ast_value_factory_); | 236 script_scope->ast_value_factory_); |
241 } | 237 } |
242 if (contains_with) current_scope->RecordWithStatement(); | 238 if (contains_with) current_scope->RecordWithStatement(); |
243 if (innermost_scope == NULL) innermost_scope = current_scope; | 239 if (innermost_scope == NULL) innermost_scope = current_scope; |
244 | 240 |
245 // Forget about a with when we move to a context for a different function. | 241 // Forget about a with when we move to a context for a different function. |
246 if (context->previous()->closure() != context->closure()) { | 242 if (context->previous()->closure() != context->closure()) { |
247 contains_with = false; | 243 contains_with = false; |
248 } | 244 } |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 // 2) Allocate module instances. | 651 // 2) Allocate module instances. |
656 if (FLAG_harmony_modules && (is_script_scope() || is_module_scope())) { | 652 if (FLAG_harmony_modules && (is_script_scope() || is_module_scope())) { |
657 DCHECK(num_modules_ == 0); | 653 DCHECK(num_modules_ == 0); |
658 AllocateModulesRecursively(this); | 654 AllocateModulesRecursively(this); |
659 } | 655 } |
660 | 656 |
661 // 3) Resolve variables. | 657 // 3) Resolve variables. |
662 if (!ResolveVariablesRecursively(info, factory)) return false; | 658 if (!ResolveVariablesRecursively(info, factory)) return false; |
663 | 659 |
664 // 4) Allocate variables. | 660 // 4) Allocate variables. |
665 AllocateVariablesRecursively(); | 661 AllocateVariablesRecursively(info->isolate()); |
666 | 662 |
667 return true; | 663 return true; |
668 } | 664 } |
669 | 665 |
670 | 666 |
671 bool Scope::HasTrivialContext() const { | 667 bool Scope::HasTrivialContext() const { |
672 // A function scope has a trivial context if it always is the global | 668 // A function scope has a trivial context if it always is the global |
673 // context. We iteratively scan out the context chain to see if | 669 // context. We iteratively scan out the context chain to see if |
674 // there is anything that makes this scope non-trivial; otherwise we | 670 // there is anything that makes this scope non-trivial; otherwise we |
675 // return true. | 671 // return true. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 | 740 |
745 Scope* Scope::DeclarationScope() { | 741 Scope* Scope::DeclarationScope() { |
746 Scope* scope = this; | 742 Scope* scope = this; |
747 while (!scope->is_declaration_scope()) { | 743 while (!scope->is_declaration_scope()) { |
748 scope = scope->outer_scope(); | 744 scope = scope->outer_scope(); |
749 } | 745 } |
750 return scope; | 746 return scope; |
751 } | 747 } |
752 | 748 |
753 | 749 |
754 Handle<ScopeInfo> Scope::GetScopeInfo() { | 750 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
755 if (scope_info_.is_null()) { | 751 if (scope_info_.is_null()) { |
756 scope_info_ = ScopeInfo::Create(isolate(), zone(), this); | 752 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
757 } | 753 } |
758 return scope_info_; | 754 return scope_info_; |
759 } | 755 } |
760 | 756 |
761 | 757 |
762 void Scope::GetNestedScopeChain( | 758 void Scope::GetNestedScopeChain(Isolate* isolate, |
763 List<Handle<ScopeInfo> >* chain, | 759 List<Handle<ScopeInfo> >* chain, int position) { |
764 int position) { | 760 if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo(isolate))); |
765 if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo())); | |
766 | 761 |
767 for (int i = 0; i < inner_scopes_.length(); i++) { | 762 for (int i = 0; i < inner_scopes_.length(); i++) { |
768 Scope* scope = inner_scopes_[i]; | 763 Scope* scope = inner_scopes_[i]; |
769 int beg_pos = scope->start_position(); | 764 int beg_pos = scope->start_position(); |
770 int end_pos = scope->end_position(); | 765 int end_pos = scope->end_position(); |
771 DCHECK(beg_pos >= 0 && end_pos >= 0); | 766 DCHECK(beg_pos >= 0 && end_pos >= 0); |
772 if (beg_pos <= position && position < end_pos) { | 767 if (beg_pos <= position && position < end_pos) { |
773 scope->GetNestedScopeChain(chain, position); | 768 scope->GetNestedScopeChain(isolate, chain, position); |
774 return; | 769 return; |
775 } | 770 } |
776 } | 771 } |
777 } | 772 } |
778 | 773 |
779 | 774 |
780 #ifdef DEBUG | 775 #ifdef DEBUG |
781 static const char* Header(ScopeType scope_type) { | 776 static const char* Header(ScopeType scope_type) { |
782 switch (scope_type) { | 777 switch (scope_type) { |
783 case EVAL_SCOPE: return "eval"; | 778 case EVAL_SCOPE: return "eval"; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 if (var->mode() == INTERNAL) return true; | 1233 if (var->mode() == INTERNAL) return true; |
1239 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; | 1234 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |
1240 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1235 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1241 return var->has_forced_context_allocation() || | 1236 return var->has_forced_context_allocation() || |
1242 scope_calls_eval_ || | 1237 scope_calls_eval_ || |
1243 inner_scope_calls_eval_ || | 1238 inner_scope_calls_eval_ || |
1244 scope_contains_with_; | 1239 scope_contains_with_; |
1245 } | 1240 } |
1246 | 1241 |
1247 | 1242 |
1248 bool Scope::HasArgumentsParameter() { | 1243 bool Scope::HasArgumentsParameter(Isolate* isolate) { |
1249 for (int i = 0; i < params_.length(); i++) { | 1244 for (int i = 0; i < params_.length(); i++) { |
1250 if (params_[i]->name().is_identical_to( | 1245 if (params_[i]->name().is_identical_to( |
1251 isolate_->factory()->arguments_string())) { | 1246 isolate->factory()->arguments_string())) { |
1252 return true; | 1247 return true; |
1253 } | 1248 } |
1254 } | 1249 } |
1255 return false; | 1250 return false; |
1256 } | 1251 } |
1257 | 1252 |
1258 | 1253 |
1259 void Scope::AllocateStackSlot(Variable* var) { | 1254 void Scope::AllocateStackSlot(Variable* var) { |
1260 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); | 1255 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); |
1261 } | 1256 } |
1262 | 1257 |
1263 | 1258 |
1264 void Scope::AllocateHeapSlot(Variable* var) { | 1259 void Scope::AllocateHeapSlot(Variable* var) { |
1265 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); | 1260 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); |
1266 } | 1261 } |
1267 | 1262 |
1268 | 1263 |
1269 void Scope::AllocateParameterLocals() { | 1264 void Scope::AllocateParameterLocals(Isolate* isolate) { |
1270 DCHECK(is_function_scope()); | 1265 DCHECK(is_function_scope()); |
1271 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); | 1266 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); |
1272 DCHECK(arguments != NULL); // functions have 'arguments' declared implicitly | 1267 DCHECK(arguments != NULL); // functions have 'arguments' declared implicitly |
1273 | 1268 |
1274 bool uses_sloppy_arguments = false; | 1269 bool uses_sloppy_arguments = false; |
1275 | 1270 |
1276 if (MustAllocate(arguments) && !HasArgumentsParameter()) { | 1271 if (MustAllocate(arguments) && !HasArgumentsParameter(isolate)) { |
1277 // 'arguments' is used. Unless there is also a parameter called | 1272 // 'arguments' is used. Unless there is also a parameter called |
1278 // 'arguments', we must be conservative and allocate all parameters to | 1273 // 'arguments', we must be conservative and allocate all parameters to |
1279 // the context assuming they will be captured by the arguments object. | 1274 // the context assuming they will be captured by the arguments object. |
1280 // If we have a parameter named 'arguments', a (new) value is always | 1275 // If we have a parameter named 'arguments', a (new) value is always |
1281 // assigned to it via the function invocation. Then 'arguments' denotes | 1276 // assigned to it via the function invocation. Then 'arguments' denotes |
1282 // that specific parameter value and cannot be used to access the | 1277 // that specific parameter value and cannot be used to access the |
1283 // parameters, which is why we don't need to allocate an arguments | 1278 // parameters, which is why we don't need to allocate an arguments |
1284 // object in that case. | 1279 // object in that case. |
1285 | 1280 |
1286 // We are using 'arguments'. Tell the code generator that is needs to | 1281 // We are using 'arguments'. Tell the code generator that is needs to |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1316 DCHECK(var->IsUnallocated() || var->IsParameter()); |
1322 if (var->IsUnallocated()) { | 1317 if (var->IsUnallocated()) { |
1323 var->AllocateTo(Variable::PARAMETER, i); | 1318 var->AllocateTo(Variable::PARAMETER, i); |
1324 } | 1319 } |
1325 } | 1320 } |
1326 } | 1321 } |
1327 } | 1322 } |
1328 } | 1323 } |
1329 | 1324 |
1330 | 1325 |
1331 void Scope::AllocateNonParameterLocal(Variable* var) { | 1326 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { |
1332 DCHECK(var->scope() == this); | 1327 DCHECK(var->scope() == this); |
1333 DCHECK(!var->IsVariable(isolate_->factory()->dot_result_string()) || | 1328 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || |
1334 !var->IsStackLocal()); | 1329 !var->IsStackLocal()); |
1335 if (var->IsUnallocated() && MustAllocate(var)) { | 1330 if (var->IsUnallocated() && MustAllocate(var)) { |
1336 if (MustAllocateInContext(var)) { | 1331 if (MustAllocateInContext(var)) { |
1337 AllocateHeapSlot(var); | 1332 AllocateHeapSlot(var); |
1338 } else { | 1333 } else { |
1339 AllocateStackSlot(var); | 1334 AllocateStackSlot(var); |
1340 } | 1335 } |
1341 } | 1336 } |
1342 } | 1337 } |
1343 | 1338 |
1344 | 1339 |
1345 void Scope::AllocateNonParameterLocals() { | 1340 void Scope::AllocateNonParameterLocals(Isolate* isolate) { |
1346 // All variables that have no rewrite yet are non-parameter locals. | 1341 // All variables that have no rewrite yet are non-parameter locals. |
1347 for (int i = 0; i < temps_.length(); i++) { | 1342 for (int i = 0; i < temps_.length(); i++) { |
1348 AllocateNonParameterLocal(temps_[i]); | 1343 AllocateNonParameterLocal(isolate, temps_[i]); |
1349 } | 1344 } |
1350 | 1345 |
1351 for (int i = 0; i < internals_.length(); i++) { | 1346 for (int i = 0; i < internals_.length(); i++) { |
1352 AllocateNonParameterLocal(internals_[i]); | 1347 AllocateNonParameterLocal(isolate, internals_[i]); |
1353 } | 1348 } |
1354 | 1349 |
1355 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1350 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
1356 for (VariableMap::Entry* p = variables_.Start(); | 1351 for (VariableMap::Entry* p = variables_.Start(); |
1357 p != NULL; | 1352 p != NULL; |
1358 p = variables_.Next(p)) { | 1353 p = variables_.Next(p)) { |
1359 Variable* var = reinterpret_cast<Variable*>(p->value); | 1354 Variable* var = reinterpret_cast<Variable*>(p->value); |
1360 vars.Add(VarAndOrder(var, p->order), zone()); | 1355 vars.Add(VarAndOrder(var, p->order), zone()); |
1361 } | 1356 } |
1362 vars.Sort(VarAndOrder::Compare); | 1357 vars.Sort(VarAndOrder::Compare); |
1363 int var_count = vars.length(); | 1358 int var_count = vars.length(); |
1364 for (int i = 0; i < var_count; i++) { | 1359 for (int i = 0; i < var_count; i++) { |
1365 AllocateNonParameterLocal(vars[i].var()); | 1360 AllocateNonParameterLocal(isolate, vars[i].var()); |
1366 } | 1361 } |
1367 | 1362 |
1368 // For now, function_ must be allocated at the very end. If it gets | 1363 // For now, function_ must be allocated at the very end. If it gets |
1369 // allocated in the context, it must be the last slot in the context, | 1364 // allocated in the context, it must be the last slot in the context, |
1370 // because of the current ScopeInfo implementation (see | 1365 // because of the current ScopeInfo implementation (see |
1371 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1366 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1372 if (function_ != NULL) { | 1367 if (function_ != NULL) { |
1373 AllocateNonParameterLocal(function_->proxy()->var()); | 1368 AllocateNonParameterLocal(isolate, function_->proxy()->var()); |
1374 } | 1369 } |
1375 | 1370 |
1376 if (rest_parameter_) { | 1371 if (rest_parameter_) { |
1377 AllocateNonParameterLocal(rest_parameter_); | 1372 AllocateNonParameterLocal(isolate, rest_parameter_); |
1378 } | 1373 } |
1379 } | 1374 } |
1380 | 1375 |
1381 | 1376 |
1382 void Scope::AllocateVariablesRecursively() { | 1377 void Scope::AllocateVariablesRecursively(Isolate* isolate) { |
1383 // Allocate variables for inner scopes. | 1378 // Allocate variables for inner scopes. |
1384 for (int i = 0; i < inner_scopes_.length(); i++) { | 1379 for (int i = 0; i < inner_scopes_.length(); i++) { |
1385 inner_scopes_[i]->AllocateVariablesRecursively(); | 1380 inner_scopes_[i]->AllocateVariablesRecursively(isolate); |
1386 } | 1381 } |
1387 | 1382 |
1388 // If scope is already resolved, we still need to allocate | 1383 // If scope is already resolved, we still need to allocate |
1389 // variables in inner scopes which might not had been resolved yet. | 1384 // variables in inner scopes which might not had been resolved yet. |
1390 if (already_resolved()) return; | 1385 if (already_resolved()) return; |
1391 // The number of slots required for variables. | 1386 // The number of slots required for variables. |
1392 num_stack_slots_ = 0; | 1387 num_stack_slots_ = 0; |
1393 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1388 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1394 | 1389 |
1395 // Allocate variables for this scope. | 1390 // Allocate variables for this scope. |
1396 // Parameters must be allocated first, if any. | 1391 // Parameters must be allocated first, if any. |
1397 if (is_function_scope()) AllocateParameterLocals(); | 1392 if (is_function_scope()) AllocateParameterLocals(isolate); |
1398 AllocateNonParameterLocals(); | 1393 AllocateNonParameterLocals(isolate); |
1399 | 1394 |
1400 // Force allocation of a context for this scope if necessary. For a 'with' | 1395 // Force allocation of a context for this scope if necessary. For a 'with' |
1401 // scope and for a function scope that makes an 'eval' call we need a context, | 1396 // scope and for a function scope that makes an 'eval' call we need a context, |
1402 // even if no local variables were statically allocated in the scope. | 1397 // even if no local variables were statically allocated in the scope. |
1403 // Likewise for modules. | 1398 // Likewise for modules. |
1404 bool must_have_context = is_with_scope() || is_module_scope() || | 1399 bool must_have_context = is_with_scope() || is_module_scope() || |
1405 (is_function_scope() && calls_eval()); | 1400 (is_function_scope() && calls_eval()); |
1406 | 1401 |
1407 // If we didn't allocate any locals in the local context, then we only | 1402 // If we didn't allocate any locals in the local context, then we only |
1408 // need the minimal number of slots if we must have a context. | 1403 // need the minimal number of slots if we must have a context. |
(...skipping 29 matching lines...) Expand all Loading... |
1438 } | 1433 } |
1439 | 1434 |
1440 | 1435 |
1441 int Scope::ContextLocalCount() const { | 1436 int Scope::ContextLocalCount() const { |
1442 if (num_heap_slots() == 0) return 0; | 1437 if (num_heap_slots() == 0) return 0; |
1443 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1438 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1444 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1439 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1445 } | 1440 } |
1446 | 1441 |
1447 } } // namespace v8::internal | 1442 } } // namespace v8::internal |
OLD | NEW |