Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Side by Side Diff: src/scopes.cc

Issue 6597029: [Isolates] Merge r 6300:6500 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/scopes.h ('k') | src/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 return NULL; 107 return NULL;
108 } 108 }
109 109
110 110
111 // ---------------------------------------------------------------------------- 111 // ----------------------------------------------------------------------------
112 // Implementation of Scope 112 // Implementation of Scope
113 113
114 114
115 // Dummy constructor 115 // Dummy constructor
116 Scope::Scope(Type type) 116 Scope::Scope(Type type)
117 : outer_scope_(NULL), 117 : inner_scopes_(0),
118 inner_scopes_(0),
119 type_(type),
120 scope_name_(FACTORY->empty_symbol()),
121 variables_(false), 118 variables_(false),
122 temps_(0), 119 temps_(0),
123 params_(0), 120 params_(0),
124 dynamics_(NULL),
125 unresolved_(0), 121 unresolved_(0),
126 decls_(0), 122 decls_(0) {
127 receiver_(NULL), 123 SetDefaults(type, NULL, NULL);
128 function_(NULL), 124 ASSERT(!resolved());
129 arguments_(NULL),
130 arguments_shadow_(NULL),
131 illegal_redecl_(NULL),
132 scope_inside_with_(false),
133 scope_contains_with_(false),
134 scope_calls_eval_(false),
135 outer_scope_calls_eval_(false),
136 inner_scope_calls_eval_(false),
137 outer_scope_is_eval_scope_(false),
138 force_eager_compilation_(false),
139 num_stack_slots_(0),
140 num_heap_slots_(0) {
141 } 125 }
142 126
143 127
144 Scope::Scope(Scope* outer_scope, Type type) 128 Scope::Scope(Scope* outer_scope, Type type)
145 : outer_scope_(outer_scope), 129 : inner_scopes_(4),
146 inner_scopes_(4), 130 variables_(),
147 type_(type),
148 scope_name_(FACTORY->empty_symbol()),
149 temps_(4), 131 temps_(4),
150 params_(4), 132 params_(4),
151 dynamics_(NULL),
152 unresolved_(16), 133 unresolved_(16),
153 decls_(4), 134 decls_(4) {
154 receiver_(NULL), 135 SetDefaults(type, outer_scope, NULL);
155 function_(NULL),
156 arguments_(NULL),
157 arguments_shadow_(NULL),
158 illegal_redecl_(NULL),
159 scope_inside_with_(false),
160 scope_contains_with_(false),
161 scope_calls_eval_(false),
162 outer_scope_calls_eval_(false),
163 inner_scope_calls_eval_(false),
164 outer_scope_is_eval_scope_(false),
165 force_eager_compilation_(false),
166 num_stack_slots_(0),
167 num_heap_slots_(0) {
168 // At some point we might want to provide outer scopes to 136 // At some point we might want to provide outer scopes to
169 // eval scopes (by walking the stack and reading the scope info). 137 // eval scopes (by walking the stack and reading the scope info).
170 // In that case, the ASSERT below needs to be adjusted. 138 // In that case, the ASSERT below needs to be adjusted.
171 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL)); 139 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL));
172 ASSERT(!HasIllegalRedeclaration()); 140 ASSERT(!HasIllegalRedeclaration());
141 ASSERT(!resolved());
173 } 142 }
174 143
175 144
145 Scope::Scope(Scope* inner_scope, SerializedScopeInfo* scope_info)
146 : inner_scopes_(4),
147 variables_(),
148 temps_(4),
149 params_(4),
150 unresolved_(16),
151 decls_(4) {
152 ASSERT(scope_info != NULL);
153 SetDefaults(FUNCTION_SCOPE, inner_scope->outer_scope(), scope_info);
154 ASSERT(resolved());
155 InsertAfterScope(inner_scope);
156 if (scope_info->HasHeapAllocatedLocals()) {
157 num_heap_slots_ = scope_info_->NumberOfContextSlots();
158 }
159
160 // This scope's arguments shadow (if present) is context-allocated if an inner
161 // scope accesses this one's parameters. Allocate the arguments_shadow_
162 // variable if necessary.
163 Isolate* isolate = Isolate::Current();
164 Variable::Mode mode;
165 int arguments_shadow_index =
166 scope_info_->ContextSlotIndex(
167 isolate->heap()->arguments_shadow_symbol(), &mode);
168 if (arguments_shadow_index >= 0) {
169 ASSERT(mode == Variable::INTERNAL);
170 arguments_shadow_ = new Variable(
171 this,
172 isolate->factory()->arguments_shadow_symbol(),
173 Variable::INTERNAL,
174 true,
175 Variable::ARGUMENTS);
176 arguments_shadow_->set_rewrite(
177 new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index));
178 arguments_shadow_->set_is_used(true);
179 }
180 }
181
182
183
176 bool Scope::Analyze(CompilationInfo* info) { 184 bool Scope::Analyze(CompilationInfo* info) {
177 ASSERT(info->function() != NULL); 185 ASSERT(info->function() != NULL);
178 Scope* top = info->function()->scope(); 186 Scope* top = info->function()->scope();
187
188 // If we have a serialized scope info, reuse it.
189 if (!info->closure().is_null()) {
190 SerializedScopeInfo* scope_info = info->closure()->shared()->scope_info();
191 if (scope_info != SerializedScopeInfo::Empty()) {
192 Scope* scope = top;
193 JSFunction* current = *info->closure();
194 do {
195 current = current->context()->closure();
196 SerializedScopeInfo* scope_info = current->shared()->scope_info();
197 if (scope_info != SerializedScopeInfo::Empty()) {
198 scope = new Scope(scope, scope_info);
199 } else {
200 ASSERT(current->context()->IsGlobalContext());
201 }
202 } while (!current->context()->IsGlobalContext());
203 }
204 }
205
179 while (top->outer_scope() != NULL) top = top->outer_scope(); 206 while (top->outer_scope() != NULL) top = top->outer_scope();
180 top->AllocateVariables(info->calling_context()); 207 top->AllocateVariables(info->calling_context());
181 208
182 #ifdef DEBUG 209 #ifdef DEBUG
183 if (info->isolate()->bootstrapper()->IsActive() 210 if (info->isolate()->bootstrapper()->IsActive()
184 ? FLAG_print_builtin_scopes 211 ? FLAG_print_builtin_scopes
185 : FLAG_print_scopes) { 212 : FLAG_print_scopes) {
186 info->function()->scope()->Print(); 213 info->function()->scope()->Print();
187 } 214 }
188 #endif 215 #endif
189 216
190 info->SetScope(info->function()->scope()); 217 info->SetScope(info->function()->scope());
191 return true; // Can not fail. 218 return true; // Can not fail.
192 } 219 }
193 220
194 221
195 void Scope::Initialize(bool inside_with) { 222 void Scope::Initialize(bool inside_with) {
223 ASSERT(!resolved());
224
196 // Add this scope as a new inner scope of the outer scope. 225 // Add this scope as a new inner scope of the outer scope.
197 if (outer_scope_ != NULL) { 226 if (outer_scope_ != NULL) {
198 outer_scope_->inner_scopes_.Add(this); 227 outer_scope_->inner_scopes_.Add(this);
199 scope_inside_with_ = outer_scope_->scope_inside_with_ || inside_with; 228 scope_inside_with_ = outer_scope_->scope_inside_with_ || inside_with;
200 } else { 229 } else {
201 scope_inside_with_ = inside_with; 230 scope_inside_with_ = inside_with;
202 } 231 }
203 232
204 // Declare convenience variables. 233 // Declare convenience variables.
205 // Declare and allocate receiver (even for the global scope, and even 234 // Declare and allocate receiver (even for the global scope, and even
206 // if naccesses_ == 0). 235 // if naccesses_ == 0).
207 // NOTE: When loading parameters in the global scope, we must take 236 // NOTE: When loading parameters in the global scope, we must take
208 // care not to access them as properties of the global object, but 237 // care not to access them as properties of the global object, but
209 // instead load them directly from the stack. Currently, the only 238 // instead load them directly from the stack. Currently, the only
210 // such parameter is 'this' which is passed on the stack when 239 // such parameter is 'this' which is passed on the stack when
211 // invoking scripts 240 // invoking scripts
212 Variable* var = 241 Variable* var =
213 variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR, 242 variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR,
214 false, Variable::THIS); 243 false, Variable::THIS);
215 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); 244 var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
216 receiver_ = var; 245 receiver_ = var;
217 246
218 if (is_function_scope()) { 247 if (is_function_scope()) {
219 // Declare 'arguments' variable which exists in all functions. 248 // Declare 'arguments' variable which exists in all functions.
220 // Note that it might never be accessed, in which case it won't be 249 // Note that it might never be accessed, in which case it won't be
221 // allocated during variable allocation. 250 // allocated during variable allocation.
222 variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR, 251 variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR,
223 true, Variable::ARGUMENTS); 252 true, Variable::ARGUMENTS);
224 } 253 }
225 } 254 }
226 255
227 256
228 Variable* Scope::LocalLookup(Handle<String> name) { 257 Variable* Scope::LocalLookup(Handle<String> name) {
229 return variables_.Lookup(name); 258 Variable* result = variables_.Lookup(name);
259 if (result != NULL || !resolved()) {
260 return result;
261 }
262 // If the scope is resolved, we can find a variable in serialized scope info.
263
264 // We should never lookup 'arguments' in this scope
265 // as it is implicitly present in any scope.
266 ASSERT(*name != *FACTORY->arguments_symbol());
267
268 // Assert that there is no local slot with the given name.
269 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
270
271 // Check context slot lookup.
272 Variable::Mode mode;
273 int index = scope_info_->ContextSlotIndex(*name, &mode);
274 if (index >= 0) {
275 Variable* var =
276 variables_.Declare(this, name, mode, true, Variable::NORMAL);
277 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
278 return var;
279 }
280
281 index = scope_info_->ParameterIndex(*name);
282 if (index >= 0) {
283 // ".arguments" must be present in context slots.
284 ASSERT(arguments_shadow_ != NULL);
285 Variable* var =
286 variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
287 Property* rewrite =
288 new Property(new VariableProxy(arguments_shadow_),
289 new Literal(Handle<Object>(Smi::FromInt(index))),
290 RelocInfo::kNoPosition,
291 Property::SYNTHETIC);
292 rewrite->set_is_arguments_access(true);
293 var->set_rewrite(rewrite);
294 return var;
295 }
296
297 index = scope_info_->FunctionContextSlotIndex(*name);
298 if (index >= 0) {
299 // Check that there is no local slot with the given name.
300 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
301 Variable* var =
302 variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
303 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
304 return var;
305 }
306
307 return NULL;
230 } 308 }
231 309
232 310
233 Variable* Scope::Lookup(Handle<String> name) { 311 Variable* Scope::Lookup(Handle<String> name) {
234 for (Scope* scope = this; 312 for (Scope* scope = this;
235 scope != NULL; 313 scope != NULL;
236 scope = scope->outer_scope()) { 314 scope = scope->outer_scope()) {
237 Variable* var = scope->LocalLookup(name); 315 Variable* var = scope->LocalLookup(name);
238 if (var != NULL) return var; 316 if (var != NULL) return var;
239 } 317 }
240 return NULL; 318 return NULL;
241 } 319 }
242 320
243 321
244 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 322 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
245 ASSERT(is_function_scope() && function_ == NULL); 323 ASSERT(is_function_scope() && function_ == NULL);
246 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 324 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
247 return function_; 325 return function_;
248 } 326 }
249 327
250 328
251 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) { 329 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
252 // DYNAMIC variables are introduces during variable allocation, 330 // DYNAMIC variables are introduces during variable allocation,
253 // INTERNAL variables are allocated explicitly, and TEMPORARY 331 // INTERNAL variables are allocated explicitly, and TEMPORARY
254 // variables are allocated via NewTemporary(). 332 // variables are allocated via NewTemporary().
333 ASSERT(!resolved());
255 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 334 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
256 return variables_.Declare(this, name, mode, true, Variable::NORMAL); 335 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
257 } 336 }
258 337
259 338
260 Variable* Scope::DeclareGlobal(Handle<String> name) { 339 Variable* Scope::DeclareGlobal(Handle<String> name) {
261 ASSERT(is_global_scope()); 340 ASSERT(is_global_scope());
262 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true, 341 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true,
263 Variable::NORMAL); 342 Variable::NORMAL);
264 } 343 }
265 344
266 345
267 void Scope::AddParameter(Variable* var) { 346 void Scope::AddParameter(Variable* var) {
268 ASSERT(is_function_scope()); 347 ASSERT(is_function_scope());
269 ASSERT(LocalLookup(var->name()) == var); 348 ASSERT(LocalLookup(var->name()) == var);
270 params_.Add(var); 349 params_.Add(var);
271 } 350 }
272 351
273 352
274 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) { 353 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) {
275 // Note that we must not share the unresolved variables with 354 // Note that we must not share the unresolved variables with
276 // the same name because they may be removed selectively via 355 // the same name because they may be removed selectively via
277 // RemoveUnresolved(). 356 // RemoveUnresolved().
357 ASSERT(!resolved());
278 VariableProxy* proxy = new VariableProxy(name, false, inside_with); 358 VariableProxy* proxy = new VariableProxy(name, false, inside_with);
279 unresolved_.Add(proxy); 359 unresolved_.Add(proxy);
280 return proxy; 360 return proxy;
281 } 361 }
282 362
283 363
284 void Scope::RemoveUnresolved(VariableProxy* var) { 364 void Scope::RemoveUnresolved(VariableProxy* var) {
285 // Most likely (always?) any variable we want to remove 365 // Most likely (always?) any variable we want to remove
286 // was just added before, so we search backwards. 366 // was just added before, so we search backwards.
287 for (int i = unresolved_.length(); i-- > 0;) { 367 for (int i = unresolved_.length(); i-- > 0;) {
288 if (unresolved_[i] == var) { 368 if (unresolved_[i] == var) {
289 unresolved_.Remove(i); 369 unresolved_.Remove(i);
290 return; 370 return;
291 } 371 }
292 } 372 }
293 } 373 }
294 374
295 375
296 Variable* Scope::NewTemporary(Handle<String> name) { 376 Variable* Scope::NewTemporary(Handle<String> name) {
377 ASSERT(!resolved());
297 Variable* var = 378 Variable* var =
298 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL); 379 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL);
299 temps_.Add(var); 380 temps_.Add(var);
300 return var; 381 return var;
301 } 382 }
302 383
303 384
304 void Scope::AddDeclaration(Declaration* declaration) { 385 void Scope::AddDeclaration(Declaration* declaration) {
305 decls_.Add(declaration); 386 decls_.Add(declaration);
306 } 387 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 626
546 627
547 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 628 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
548 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 629 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
549 VariableMap* map = dynamics_->GetMap(mode); 630 VariableMap* map = dynamics_->GetMap(mode);
550 Variable* var = map->Lookup(name); 631 Variable* var = map->Lookup(name);
551 if (var == NULL) { 632 if (var == NULL) {
552 // Declare a new non-local. 633 // Declare a new non-local.
553 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 634 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
554 // Allocate it by giving it a dynamic lookup. 635 // Allocate it by giving it a dynamic lookup.
555 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 636 var->set_rewrite(new Slot(var, Slot::LOOKUP, -1));
556 } 637 }
557 return var; 638 return var;
558 } 639 }
559 640
560 641
561 // Lookup a variable starting with this scope. The result is either 642 // Lookup a variable starting with this scope. The result is either
562 // the statically resolved variable belonging to an outer scope, or 643 // the statically resolved variable belonging to an outer scope, or
563 // NULL. It may be NULL because a) we couldn't find a variable, or b) 644 // NULL. It may be NULL because a) we couldn't find a variable, or b)
564 // because the variable is just a guess (and may be shadowed by 645 // because the variable is just a guess (and may be shadowed by
565 // another variable that is introduced dynamically via an 'eval' call 646 // another variable that is introduced dynamically via an 'eval' call
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 } 688 }
608 689
609 // If we did not find a variable, we are done. 690 // If we did not find a variable, we are done.
610 if (var == NULL) 691 if (var == NULL)
611 return NULL; 692 return NULL;
612 } 693 }
613 694
614 ASSERT(var != NULL); 695 ASSERT(var != NULL);
615 696
616 // If this is a lookup from an inner scope, mark the variable. 697 // If this is a lookup from an inner scope, mark the variable.
617 if (inner_lookup) 698 if (inner_lookup) {
618 var->is_accessed_from_inner_scope_ = true; 699 var->MarkAsAccessedFromInnerScope();
700 }
619 701
620 // If the variable we have found is just a guess, invalidate the 702 // If the variable we have found is just a guess, invalidate the
621 // result. If the found variable is local, record that fact so we 703 // result. If the found variable is local, record that fact so we
622 // can generate fast code to get it if it is not shadowed by eval. 704 // can generate fast code to get it if it is not shadowed by eval.
623 if (guess) { 705 if (guess) {
624 if (!var->is_global()) *invalidated_local = var; 706 if (!var->is_global()) *invalidated_local = var;
625 var = NULL; 707 var = NULL;
626 } 708 }
627 709
628 return var; 710 return var;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 830
749 return scope_calls_eval_ || inner_scope_calls_eval_; 831 return scope_calls_eval_ || inner_scope_calls_eval_;
750 } 832 }
751 833
752 834
753 bool Scope::MustAllocate(Variable* var) { 835 bool Scope::MustAllocate(Variable* var) {
754 // Give var a read/write use if there is a chance it might be accessed 836 // Give var a read/write use if there is a chance it might be accessed
755 // via an eval() call. This is only possible if the variable has a 837 // via an eval() call. This is only possible if the variable has a
756 // visible name. 838 // visible name.
757 if ((var->is_this() || var->name()->length() > 0) && 839 if ((var->is_this() || var->name()->length() > 0) &&
758 (var->is_accessed_from_inner_scope_ || 840 (var->is_accessed_from_inner_scope() ||
759 scope_calls_eval_ || inner_scope_calls_eval_ || 841 scope_calls_eval_ || inner_scope_calls_eval_ ||
760 scope_contains_with_)) { 842 scope_contains_with_)) {
761 var->set_is_used(true); 843 var->set_is_used(true);
762 } 844 }
763 // Global variables do not need to be allocated. 845 // Global variables do not need to be allocated.
764 return !var->is_global() && var->is_used(); 846 return !var->is_global() && var->is_used();
765 } 847 }
766 848
767 849
768 bool Scope::MustAllocateInContext(Variable* var) { 850 bool Scope::MustAllocateInContext(Variable* var) {
769 // If var is accessed from an inner scope, or if there is a 851 // If var is accessed from an inner scope, or if there is a
770 // possibility that it might be accessed from the current or an inner 852 // possibility that it might be accessed from the current or an inner
771 // scope (through an eval() call), it must be allocated in the 853 // scope (through an eval() call), it must be allocated in the
772 // context. Exception: temporary variables are not allocated in the 854 // context. Exception: temporary variables are not allocated in the
773 // context. 855 // context.
774 return 856 return
775 var->mode() != Variable::TEMPORARY && 857 var->mode() != Variable::TEMPORARY &&
776 (var->is_accessed_from_inner_scope_ || 858 (var->is_accessed_from_inner_scope() ||
777 scope_calls_eval_ || inner_scope_calls_eval_ || 859 scope_calls_eval_ || inner_scope_calls_eval_ ||
778 scope_contains_with_ || var->is_global()); 860 scope_contains_with_ || var->is_global());
779 } 861 }
780 862
781 863
782 bool Scope::HasArgumentsParameter() { 864 bool Scope::HasArgumentsParameter() {
783 for (int i = 0; i < params_.length(); i++) { 865 for (int i = 0; i < params_.length(); i++) {
784 if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol())) 866 if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol()))
785 return true; 867 return true;
786 } 868 }
787 return false; 869 return false;
788 } 870 }
789 871
790 872
791 void Scope::AllocateStackSlot(Variable* var) { 873 void Scope::AllocateStackSlot(Variable* var) {
792 var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++); 874 var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++));
793 } 875 }
794 876
795 877
796 void Scope::AllocateHeapSlot(Variable* var) { 878 void Scope::AllocateHeapSlot(Variable* var) {
797 var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++); 879 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
798 } 880 }
799 881
800 882
801 void Scope::AllocateParameterLocals() { 883 void Scope::AllocateParameterLocals() {
802 ASSERT(is_function_scope()); 884 ASSERT(is_function_scope());
803 Variable* arguments = LocalLookup(FACTORY->arguments_symbol()); 885 Variable* arguments = LocalLookup(FACTORY->arguments_symbol());
804 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 886 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
805 if (MustAllocate(arguments) && !HasArgumentsParameter()) { 887 if (MustAllocate(arguments) && !HasArgumentsParameter()) {
806 // 'arguments' is used. Unless there is also a parameter called 888 // 'arguments' is used. Unless there is also a parameter called
807 // 'arguments', we must be conservative and access all parameters via 889 // 'arguments', we must be conservative and access all parameters via
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 934
853 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. 935 // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
854 for (int i = 0; i < params_.length(); i++) { 936 for (int i = 0; i < params_.length(); i++) {
855 Variable* var = params_[i]; 937 Variable* var = params_[i];
856 ASSERT(var->scope() == this); 938 ASSERT(var->scope() == this);
857 if (MustAllocate(var)) { 939 if (MustAllocate(var)) {
858 if (MustAllocateInContext(var)) { 940 if (MustAllocateInContext(var)) {
859 // It is ok to set this only now, because arguments is a local 941 // It is ok to set this only now, because arguments is a local
860 // variable that is allocated after the parameters have been 942 // variable that is allocated after the parameters have been
861 // allocated. 943 // allocated.
862 arguments_shadow_->is_accessed_from_inner_scope_ = true; 944 arguments_shadow_->MarkAsAccessedFromInnerScope();
863 } 945 }
864 Property* rewrite = 946 Property* rewrite =
865 new Property(new VariableProxy(arguments_shadow_), 947 new Property(new VariableProxy(arguments_shadow_),
866 new Literal(Handle<Object>(Smi::FromInt(i))), 948 new Literal(Handle<Object>(Smi::FromInt(i))),
867 RelocInfo::kNoPosition, 949 RelocInfo::kNoPosition,
868 Property::SYNTHETIC); 950 Property::SYNTHETIC);
869 rewrite->set_is_arguments_access(true); 951 rewrite->set_is_arguments_access(true);
870 var->rewrite_ = rewrite; 952 var->set_rewrite(rewrite);
871 } 953 }
872 } 954 }
873 955
874 } else { 956 } else {
875 // The arguments object is not used, so we can access parameters directly. 957 // The arguments object is not used, so we can access parameters directly.
876 // The same parameter may occur multiple times in the parameters_ list. 958 // The same parameter may occur multiple times in the parameters_ list.
877 // If it does, and if it is not copied into the context object, it must 959 // If it does, and if it is not copied into the context object, it must
878 // receive the highest parameter index for that parameter; thus iteration 960 // receive the highest parameter index for that parameter; thus iteration
879 // order is relevant! 961 // order is relevant!
880 for (int i = 0; i < params_.length(); i++) { 962 for (int i = 0; i < params_.length(); i++) {
881 Variable* var = params_[i]; 963 Variable* var = params_[i];
882 ASSERT(var->scope() == this); 964 ASSERT(var->scope() == this);
883 if (MustAllocate(var)) { 965 if (MustAllocate(var)) {
884 if (MustAllocateInContext(var)) { 966 if (MustAllocateInContext(var)) {
885 ASSERT(var->rewrite_ == NULL || 967 ASSERT(var->rewrite() == NULL ||
886 (var->AsSlot() != NULL && 968 (var->AsSlot() != NULL &&
887 var->AsSlot()->type() == Slot::CONTEXT)); 969 var->AsSlot()->type() == Slot::CONTEXT));
888 if (var->rewrite_ == NULL) { 970 if (var->rewrite() == NULL) {
889 // Only set the heap allocation if the parameter has not 971 // Only set the heap allocation if the parameter has not
890 // been allocated yet. 972 // been allocated yet.
891 AllocateHeapSlot(var); 973 AllocateHeapSlot(var);
892 } 974 }
893 } else { 975 } else {
894 ASSERT(var->rewrite_ == NULL || 976 ASSERT(var->rewrite() == NULL ||
895 (var->AsSlot() != NULL && 977 (var->AsSlot() != NULL &&
896 var->AsSlot()->type() == Slot::PARAMETER)); 978 var->AsSlot()->type() == Slot::PARAMETER));
897 // Set the parameter index always, even if the parameter 979 // Set the parameter index always, even if the parameter
898 // was seen before! (We need to access the actual parameter 980 // was seen before! (We need to access the actual parameter
899 // supplied for the last occurrence of a multiply declared 981 // supplied for the last occurrence of a multiply declared
900 // parameter.) 982 // parameter.)
901 var->rewrite_ = new Slot(var, Slot::PARAMETER, i); 983 var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
902 } 984 }
903 } 985 }
904 } 986 }
905 } 987 }
906 } 988 }
907 989
908 990
909 void Scope::AllocateNonParameterLocal(Variable* var) { 991 void Scope::AllocateNonParameterLocal(Variable* var) {
910 ASSERT(var->scope() == this); 992 ASSERT(var->scope() == this);
911 ASSERT(var->rewrite_ == NULL || 993 ASSERT(var->rewrite() == NULL ||
912 (!var->IsVariable(FACTORY->result_symbol())) || 994 (!var->IsVariable(FACTORY->result_symbol())) ||
913 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); 995 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
914 if (var->rewrite_ == NULL && MustAllocate(var)) { 996 if (var->rewrite() == NULL && MustAllocate(var)) {
915 if (MustAllocateInContext(var)) { 997 if (MustAllocateInContext(var)) {
916 AllocateHeapSlot(var); 998 AllocateHeapSlot(var);
917 } else { 999 } else {
918 AllocateStackSlot(var); 1000 AllocateStackSlot(var);
919 } 1001 }
920 } 1002 }
921 } 1003 }
922 1004
923 1005
924 void Scope::AllocateNonParameterLocals() { 1006 void Scope::AllocateNonParameterLocals() {
(...skipping 13 matching lines...) Expand all
938 // allocated in the context, it must be the last slot in the context, 1020 // allocated in the context, it must be the last slot in the context,
939 // because of the current ScopeInfo implementation (see 1021 // because of the current ScopeInfo implementation (see
940 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1022 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
941 if (function_ != NULL) { 1023 if (function_ != NULL) {
942 AllocateNonParameterLocal(function_); 1024 AllocateNonParameterLocal(function_);
943 } 1025 }
944 } 1026 }
945 1027
946 1028
947 void Scope::AllocateVariablesRecursively() { 1029 void Scope::AllocateVariablesRecursively() {
948 // The number of slots required for variables.
949 num_stack_slots_ = 0;
950 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
951
952 // Allocate variables for inner scopes. 1030 // Allocate variables for inner scopes.
953 for (int i = 0; i < inner_scopes_.length(); i++) { 1031 for (int i = 0; i < inner_scopes_.length(); i++) {
954 inner_scopes_[i]->AllocateVariablesRecursively(); 1032 inner_scopes_[i]->AllocateVariablesRecursively();
955 } 1033 }
956 1034
1035 // If scope is already resolved, we still need to allocate
1036 // variables in inner scopes which might not had been resolved yet.
1037 if (resolved()) return;
1038 // The number of slots required for variables.
1039 num_stack_slots_ = 0;
1040 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1041
957 // Allocate variables for this scope. 1042 // Allocate variables for this scope.
958 // Parameters must be allocated first, if any. 1043 // Parameters must be allocated first, if any.
959 if (is_function_scope()) AllocateParameterLocals(); 1044 if (is_function_scope()) AllocateParameterLocals();
960 AllocateNonParameterLocals(); 1045 AllocateNonParameterLocals();
961 1046
962 // Allocate context if necessary. 1047 // Allocate context if necessary.
963 bool must_have_local_context = false; 1048 bool must_have_local_context = false;
964 if (scope_calls_eval_ || scope_contains_with_) { 1049 if (scope_calls_eval_ || scope_contains_with_) {
965 // The context for the eval() call or 'with' statement in this scope. 1050 // The context for the eval() call or 'with' statement in this scope.
966 // Unless we are in the global or an eval scope, we need a local 1051 // Unless we are in the global or an eval scope, we need a local
967 // context even if we didn't statically allocate any locals in it, 1052 // context even if we didn't statically allocate any locals in it,
968 // and the compiler will access the context variable. If we are 1053 // and the compiler will access the context variable. If we are
969 // not in an inner scope, the scope is provided from the outside. 1054 // not in an inner scope, the scope is provided from the outside.
970 must_have_local_context = is_function_scope(); 1055 must_have_local_context = is_function_scope();
971 } 1056 }
972 1057
973 // If we didn't allocate any locals in the local context, then we only 1058 // If we didn't allocate any locals in the local context, then we only
974 // need the minimal number of slots if we must have a local context. 1059 // need the minimal number of slots if we must have a local context.
975 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1060 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
976 !must_have_local_context) { 1061 !must_have_local_context) {
977 num_heap_slots_ = 0; 1062 num_heap_slots_ = 0;
978 } 1063 }
979 1064
980 // Allocation done. 1065 // Allocation done.
981 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1066 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
982 } 1067 }
983 1068
984 } } // namespace v8::internal 1069 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698