OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 return NULL; | 109 return NULL; |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 // ---------------------------------------------------------------------------- | 113 // ---------------------------------------------------------------------------- |
114 // Implementation of Scope | 114 // Implementation of Scope |
115 | 115 |
116 | 116 |
117 // Dummy constructor | 117 // Dummy constructor |
118 Scope::Scope(Type type) | 118 Scope::Scope(Type type) |
119 : inner_scopes_(0), | 119 : isolate_(Isolate::Current()), |
120 variables_(false), | 120 inner_scopes_(0), |
121 temps_(0), | 121 variables_(false), |
122 params_(0), | 122 temps_(0), |
123 unresolved_(0), | 123 params_(0), |
124 decls_(0), | 124 unresolved_(0), |
125 already_resolved_(false) { | 125 decls_(0), |
| 126 already_resolved_(false) { |
126 SetDefaults(type, NULL, Handle<SerializedScopeInfo>::null()); | 127 SetDefaults(type, NULL, Handle<SerializedScopeInfo>::null()); |
127 } | 128 } |
128 | 129 |
129 | 130 |
130 Scope::Scope(Scope* outer_scope, Type type) | 131 Scope::Scope(Scope* outer_scope, Type type) |
131 : inner_scopes_(4), | 132 : isolate_(Isolate::Current()), |
132 variables_(), | 133 inner_scopes_(4), |
133 temps_(4), | 134 variables_(), |
134 params_(4), | 135 temps_(4), |
135 unresolved_(16), | 136 params_(4), |
136 decls_(4), | 137 unresolved_(16), |
137 already_resolved_(false) { | 138 decls_(4), |
| 139 already_resolved_(false) { |
138 SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null()); | 140 SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null()); |
139 // At some point we might want to provide outer scopes to | 141 // At some point we might want to provide outer scopes to |
140 // eval scopes (by walking the stack and reading the scope info). | 142 // eval scopes (by walking the stack and reading the scope info). |
141 // In that case, the ASSERT below needs to be adjusted. | 143 // In that case, the ASSERT below needs to be adjusted. |
142 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL)); | 144 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL)); |
143 ASSERT(!HasIllegalRedeclaration()); | 145 ASSERT(!HasIllegalRedeclaration()); |
144 } | 146 } |
145 | 147 |
146 | 148 |
147 Scope::Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info) | 149 Scope::Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info) |
148 : inner_scopes_(4), | 150 : isolate_(Isolate::Current()), |
149 variables_(), | 151 inner_scopes_(4), |
150 temps_(4), | 152 variables_(), |
151 params_(4), | 153 temps_(4), |
152 unresolved_(16), | 154 params_(4), |
153 decls_(4), | 155 unresolved_(16), |
154 already_resolved_(true) { | 156 decls_(4), |
| 157 already_resolved_(true) { |
155 ASSERT(!scope_info.is_null()); | 158 ASSERT(!scope_info.is_null()); |
156 SetDefaults(FUNCTION_SCOPE, NULL, scope_info); | 159 SetDefaults(FUNCTION_SCOPE, NULL, scope_info); |
157 if (scope_info->HasHeapAllocatedLocals()) { | 160 if (scope_info->HasHeapAllocatedLocals()) { |
158 num_heap_slots_ = scope_info_->NumberOfContextSlots(); | 161 num_heap_slots_ = scope_info_->NumberOfContextSlots(); |
159 } | 162 } |
160 AddInnerScope(inner_scope); | 163 AddInnerScope(inner_scope); |
161 } | 164 } |
162 | 165 |
163 | 166 |
164 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) | 167 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) |
165 : inner_scopes_(1), | 168 : isolate_(Isolate::Current()), |
| 169 inner_scopes_(1), |
166 variables_(), | 170 variables_(), |
167 temps_(0), | 171 temps_(0), |
168 params_(0), | 172 params_(0), |
169 unresolved_(0), | 173 unresolved_(0), |
170 decls_(0), | 174 decls_(0), |
171 already_resolved_(true) { | 175 already_resolved_(true) { |
172 SetDefaults(CATCH_SCOPE, NULL, Handle<SerializedScopeInfo>::null()); | 176 SetDefaults(CATCH_SCOPE, NULL, Handle<SerializedScopeInfo>::null()); |
173 AddInnerScope(inner_scope); | 177 AddInnerScope(inner_scope); |
174 ++num_var_or_const_; | 178 ++num_var_or_const_; |
175 Variable* variable = variables_.Declare(this, | 179 Variable* variable = variables_.Declare(this, |
176 catch_variable_name, | 180 catch_variable_name, |
177 Variable::VAR, | 181 Variable::VAR, |
178 true, // Valid left-hand side. | 182 true, // Valid left-hand side. |
179 Variable::NORMAL); | 183 Variable::NORMAL); |
180 AllocateHeapSlot(variable); | 184 AllocateHeapSlot(variable); |
181 } | 185 } |
182 | 186 |
183 | 187 |
184 void Scope::SetDefaults(Type type, | 188 void Scope::SetDefaults(Type type, |
185 Scope* outer_scope, | 189 Scope* outer_scope, |
186 Handle<SerializedScopeInfo> scope_info) { | 190 Handle<SerializedScopeInfo> scope_info) { |
187 outer_scope_ = outer_scope; | 191 outer_scope_ = outer_scope; |
188 type_ = type; | 192 type_ = type; |
189 scope_name_ = FACTORY->empty_symbol(); | 193 scope_name_ = isolate_->factory()->empty_symbol(); |
190 dynamics_ = NULL; | 194 dynamics_ = NULL; |
191 receiver_ = NULL; | 195 receiver_ = NULL; |
192 function_ = NULL; | 196 function_ = NULL; |
193 arguments_ = NULL; | 197 arguments_ = NULL; |
194 illegal_redecl_ = NULL; | 198 illegal_redecl_ = NULL; |
195 scope_inside_with_ = false; | 199 scope_inside_with_ = false; |
196 scope_contains_with_ = false; | 200 scope_contains_with_ = false; |
197 scope_calls_eval_ = false; | 201 scope_calls_eval_ = false; |
198 // Inherit the strict mode from the parent scope. | 202 // Inherit the strict mode from the parent scope. |
199 strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_; | 203 strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 // NOTE: When loading parameters in the global scope, we must take | 292 // NOTE: When loading parameters in the global scope, we must take |
289 // care not to access them as properties of the global object, but | 293 // care not to access them as properties of the global object, but |
290 // instead load them directly from the stack. Currently, the only | 294 // instead load them directly from the stack. Currently, the only |
291 // such parameter is 'this' which is passed on the stack when | 295 // such parameter is 'this' which is passed on the stack when |
292 // invoking scripts | 296 // invoking scripts |
293 if (is_catch_scope()) { | 297 if (is_catch_scope()) { |
294 ASSERT(outer_scope() != NULL); | 298 ASSERT(outer_scope() != NULL); |
295 receiver_ = outer_scope()->receiver(); | 299 receiver_ = outer_scope()->receiver(); |
296 } else { | 300 } else { |
297 Variable* var = | 301 Variable* var = |
298 variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR, | 302 variables_.Declare(this, |
299 false, Variable::THIS); | 303 isolate_->factory()->this_symbol(), |
300 var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); | 304 Variable::VAR, |
| 305 false, |
| 306 Variable::THIS); |
| 307 var->set_rewrite(new(isolate_->zone()) Slot(var, Slot::PARAMETER, -1)); |
301 receiver_ = var; | 308 receiver_ = var; |
302 } | 309 } |
303 | 310 |
304 if (is_function_scope()) { | 311 if (is_function_scope()) { |
305 // Declare 'arguments' variable which exists in all functions. | 312 // Declare 'arguments' variable which exists in all functions. |
306 // Note that it might never be accessed, in which case it won't be | 313 // Note that it might never be accessed, in which case it won't be |
307 // allocated during variable allocation. | 314 // allocated during variable allocation. |
308 variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR, | 315 variables_.Declare(this, |
309 true, Variable::ARGUMENTS); | 316 isolate_->factory()->arguments_symbol(), |
| 317 Variable::VAR, |
| 318 true, |
| 319 Variable::ARGUMENTS); |
310 } | 320 } |
311 } | 321 } |
312 | 322 |
313 | 323 |
314 Variable* Scope::LocalLookup(Handle<String> name) { | 324 Variable* Scope::LocalLookup(Handle<String> name) { |
315 Variable* result = variables_.Lookup(name); | 325 Variable* result = variables_.Lookup(name); |
316 if (result != NULL || scope_info_.is_null()) { | 326 if (result != NULL || scope_info_.is_null()) { |
317 return result; | 327 return result; |
318 } | 328 } |
319 // If we have a serialized scope info, we might find the variable there. | 329 // If we have a serialized scope info, we might find the variable there. |
320 // | 330 // |
321 // We should never lookup 'arguments' in this scope as it is implicitly | 331 // We should never lookup 'arguments' in this scope as it is implicitly |
322 // present in every scope. | 332 // present in every scope. |
323 ASSERT(*name != *FACTORY->arguments_symbol()); | 333 ASSERT(*name != *isolate_->factory()->arguments_symbol()); |
324 // There should be no local slot with the given name. | 334 // There should be no local slot with the given name. |
325 ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 335 ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
326 | 336 |
327 // Check context slot lookup. | 337 // Check context slot lookup. |
328 Variable::Mode mode; | 338 Variable::Mode mode; |
329 int index = scope_info_->ContextSlotIndex(*name, &mode); | 339 int index = scope_info_->ContextSlotIndex(*name, &mode); |
330 if (index < 0) { | 340 if (index < 0) { |
331 // Check parameters. | 341 // Check parameters. |
332 mode = Variable::VAR; | 342 mode = Variable::VAR; |
333 index = scope_info_->ParameterIndex(*name); | 343 index = scope_info_->ParameterIndex(*name); |
334 if (index < 0) { | 344 if (index < 0) { |
335 // Check the function name. | 345 // Check the function name. |
336 index = scope_info_->FunctionContextSlotIndex(*name); | 346 index = scope_info_->FunctionContextSlotIndex(*name); |
337 if (index < 0) return NULL; | 347 if (index < 0) return NULL; |
338 } | 348 } |
339 } | 349 } |
340 | 350 |
341 Variable* var = | 351 Variable* var = |
342 variables_.Declare(this, name, mode, true, Variable::NORMAL); | 352 variables_.Declare(this, name, mode, true, Variable::NORMAL); |
343 var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); | 353 var->set_rewrite(new(isolate_->zone()) Slot(var, Slot::CONTEXT, index)); |
344 return var; | 354 return var; |
345 } | 355 } |
346 | 356 |
347 | 357 |
348 Variable* Scope::Lookup(Handle<String> name) { | 358 Variable* Scope::Lookup(Handle<String> name) { |
349 for (Scope* scope = this; | 359 for (Scope* scope = this; |
350 scope != NULL; | 360 scope != NULL; |
351 scope = scope->outer_scope()) { | 361 scope = scope->outer_scope()) { |
352 Variable* var = scope->LocalLookup(name); | 362 Variable* var = scope->LocalLookup(name); |
353 if (var != NULL) return var; | 363 if (var != NULL) return var; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 } | 400 } |
391 | 401 |
392 | 402 |
393 VariableProxy* Scope::NewUnresolved(Handle<String> name, | 403 VariableProxy* Scope::NewUnresolved(Handle<String> name, |
394 bool inside_with, | 404 bool inside_with, |
395 int position) { | 405 int position) { |
396 // Note that we must not share the unresolved variables with | 406 // Note that we must not share the unresolved variables with |
397 // the same name because they may be removed selectively via | 407 // the same name because they may be removed selectively via |
398 // RemoveUnresolved(). | 408 // RemoveUnresolved(). |
399 ASSERT(!already_resolved()); | 409 ASSERT(!already_resolved()); |
400 VariableProxy* proxy = new VariableProxy(name, false, inside_with, position); | 410 VariableProxy* proxy = |
| 411 new(isolate_->zone()) VariableProxy(name, false, inside_with, position); |
401 unresolved_.Add(proxy); | 412 unresolved_.Add(proxy); |
402 return proxy; | 413 return proxy; |
403 } | 414 } |
404 | 415 |
405 | 416 |
406 void Scope::RemoveUnresolved(VariableProxy* var) { | 417 void Scope::RemoveUnresolved(VariableProxy* var) { |
407 // Most likely (always?) any variable we want to remove | 418 // Most likely (always?) any variable we want to remove |
408 // was just added before, so we search backwards. | 419 // was just added before, so we search backwards. |
409 for (int i = unresolved_.length(); i-- > 0;) { | 420 for (int i = unresolved_.length(); i-- > 0;) { |
410 if (unresolved_[i] == var) { | 421 if (unresolved_[i] == var) { |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 | 701 |
691 | 702 |
692 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { | 703 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { |
693 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); | 704 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); |
694 VariableMap* map = dynamics_->GetMap(mode); | 705 VariableMap* map = dynamics_->GetMap(mode); |
695 Variable* var = map->Lookup(name); | 706 Variable* var = map->Lookup(name); |
696 if (var == NULL) { | 707 if (var == NULL) { |
697 // Declare a new non-local. | 708 // Declare a new non-local. |
698 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); | 709 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); |
699 // Allocate it by giving it a dynamic lookup. | 710 // Allocate it by giving it a dynamic lookup. |
700 var->set_rewrite(new Slot(var, Slot::LOOKUP, -1)); | 711 var->set_rewrite(new(isolate_->zone()) Slot(var, Slot::LOOKUP, -1)); |
701 } | 712 } |
702 return var; | 713 return var; |
703 } | 714 } |
704 | 715 |
705 | 716 |
706 // Lookup a variable starting with this scope. The result is either | 717 // Lookup a variable starting with this scope. The result is either |
707 // the statically resolved variable belonging to an outer scope, or | 718 // the statically resolved variable belonging to an outer scope, or |
708 // NULL. It may be NULL because a) we couldn't find a variable, or b) | 719 // NULL. It may be NULL because a) we couldn't find a variable, or b) |
709 // because the variable is just a guess (and may be shadowed by | 720 // because the variable is just a guess (and may be shadowed by |
710 // another variable that is introduced dynamically via an 'eval' call | 721 // another variable that is introduced dynamically via an 'eval' call |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 return var->is_accessed_from_inner_scope() || | 947 return var->is_accessed_from_inner_scope() || |
937 scope_calls_eval_ || | 948 scope_calls_eval_ || |
938 inner_scope_calls_eval_ || | 949 inner_scope_calls_eval_ || |
939 scope_contains_with_ || | 950 scope_contains_with_ || |
940 var->is_global(); | 951 var->is_global(); |
941 } | 952 } |
942 | 953 |
943 | 954 |
944 bool Scope::HasArgumentsParameter() { | 955 bool Scope::HasArgumentsParameter() { |
945 for (int i = 0; i < params_.length(); i++) { | 956 for (int i = 0; i < params_.length(); i++) { |
946 if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol())) | 957 if (params_[i]->name().is_identical_to( |
| 958 isolate_->factory()->arguments_symbol())) { |
947 return true; | 959 return true; |
| 960 } |
948 } | 961 } |
949 return false; | 962 return false; |
950 } | 963 } |
951 | 964 |
952 | 965 |
953 void Scope::AllocateStackSlot(Variable* var) { | 966 void Scope::AllocateStackSlot(Variable* var) { |
954 var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++)); | 967 var->set_rewrite( |
| 968 new(isolate_->zone()) Slot(var, Slot::LOCAL, num_stack_slots_++)); |
955 } | 969 } |
956 | 970 |
957 | 971 |
958 void Scope::AllocateHeapSlot(Variable* var) { | 972 void Scope::AllocateHeapSlot(Variable* var) { |
959 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++)); | 973 var->set_rewrite( |
| 974 new(isolate_->zone()) Slot(var, Slot::CONTEXT, num_heap_slots_++)); |
960 } | 975 } |
961 | 976 |
962 | 977 |
963 void Scope::AllocateParameterLocals() { | 978 void Scope::AllocateParameterLocals() { |
964 ASSERT(is_function_scope()); | 979 ASSERT(is_function_scope()); |
965 Variable* arguments = LocalLookup(FACTORY->arguments_symbol()); | 980 Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol()); |
966 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly | 981 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly |
967 | 982 |
968 bool uses_nonstrict_arguments = false; | 983 bool uses_nonstrict_arguments = false; |
969 | 984 |
970 if (MustAllocate(arguments) && !HasArgumentsParameter()) { | 985 if (MustAllocate(arguments) && !HasArgumentsParameter()) { |
971 // 'arguments' is used. Unless there is also a parameter called | 986 // 'arguments' is used. Unless there is also a parameter called |
972 // 'arguments', we must be conservative and allocate all parameters to | 987 // 'arguments', we must be conservative and allocate all parameters to |
973 // the context assuming they will be captured by the arguments object. | 988 // the context assuming they will be captured by the arguments object. |
974 // If we have a parameter named 'arguments', a (new) value is always | 989 // If we have a parameter named 'arguments', a (new) value is always |
975 // assigned to it via the function invocation. Then 'arguments' denotes | 990 // assigned to it via the function invocation. Then 'arguments' denotes |
(...skipping 26 matching lines...) Expand all Loading... |
1002 | 1017 |
1003 if (MustAllocate(var)) { | 1018 if (MustAllocate(var)) { |
1004 if (MustAllocateInContext(var)) { | 1019 if (MustAllocateInContext(var)) { |
1005 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); | 1020 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); |
1006 if (var->rewrite() == NULL) { | 1021 if (var->rewrite() == NULL) { |
1007 AllocateHeapSlot(var); | 1022 AllocateHeapSlot(var); |
1008 } | 1023 } |
1009 } else { | 1024 } else { |
1010 ASSERT(var->rewrite() == NULL || var->IsParameter()); | 1025 ASSERT(var->rewrite() == NULL || var->IsParameter()); |
1011 if (var->rewrite() == NULL) { | 1026 if (var->rewrite() == NULL) { |
1012 var->set_rewrite(new Slot(var, Slot::PARAMETER, i)); | 1027 var->set_rewrite(new(isolate_->zone()) Slot(var, Slot::PARAMETER, i)); |
1013 } | 1028 } |
1014 } | 1029 } |
1015 } | 1030 } |
1016 } | 1031 } |
1017 } | 1032 } |
1018 | 1033 |
1019 | 1034 |
1020 void Scope::AllocateNonParameterLocal(Variable* var) { | 1035 void Scope::AllocateNonParameterLocal(Variable* var) { |
1021 ASSERT(var->scope() == this); | 1036 ASSERT(var->scope() == this); |
1022 ASSERT(var->rewrite() == NULL || | 1037 ASSERT(var->rewrite() == NULL || |
1023 !var->IsVariable(FACTORY->result_symbol()) || | 1038 !var->IsVariable(isolate_->factory()->result_symbol()) || |
1024 var->AsSlot() == NULL || | 1039 var->AsSlot() == NULL || |
1025 var->AsSlot()->type() != Slot::LOCAL); | 1040 var->AsSlot()->type() != Slot::LOCAL); |
1026 if (var->rewrite() == NULL && MustAllocate(var)) { | 1041 if (var->rewrite() == NULL && MustAllocate(var)) { |
1027 if (MustAllocateInContext(var)) { | 1042 if (MustAllocateInContext(var)) { |
1028 AllocateHeapSlot(var); | 1043 AllocateHeapSlot(var); |
1029 } else { | 1044 } else { |
1030 AllocateStackSlot(var); | 1045 AllocateStackSlot(var); |
1031 } | 1046 } |
1032 } | 1047 } |
1033 } | 1048 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 1105 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
1091 !must_have_local_context) { | 1106 !must_have_local_context) { |
1092 num_heap_slots_ = 0; | 1107 num_heap_slots_ = 0; |
1093 } | 1108 } |
1094 | 1109 |
1095 // Allocation done. | 1110 // Allocation done. |
1096 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1111 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1097 } | 1112 } |
1098 | 1113 |
1099 } } // namespace v8::internal | 1114 } } // namespace v8::internal |
OLD | NEW |