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

Side by Side Diff: src/scopes.cc

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

Powered by Google App Engine
This is Rietveld 408576698