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

Side by Side Diff: src/scopes.cc

Issue 5753005: Make closures optimizable by Crankshaft compiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Next round Created 9 years, 11 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/variables.h » ('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
159
160
174 bool Scope::Analyze(CompilationInfo* info) { 161 bool Scope::Analyze(CompilationInfo* info) {
175 ASSERT(info->function() != NULL); 162 ASSERT(info->function() != NULL);
176 Scope* top = info->function()->scope(); 163 Scope* top = info->function()->scope();
164
165 // If we have a serialized scope info, reuse it.
166 if (!info->closure().is_null()) {
167 SerializedScopeInfo* scope_info = info->closure()->shared()->scope_info();
168 if (scope_info != SerializedScopeInfo::Empty()) {
169 Scope* scope = top;
170 JSFunction* current = *info->closure();
171 do {
172 current = current->context()->closure();
173 SerializedScopeInfo* scope_info = current->shared()->scope_info();
174 if (scope_info != SerializedScopeInfo::Empty()) {
175 scope = new Scope(scope, scope_info);
176 } else {
177 ASSERT(current->context()->IsGlobalContext());
178 }
179 } while (!current->context()->IsGlobalContext());
180 }
181 }
182
177 while (top->outer_scope() != NULL) top = top->outer_scope(); 183 while (top->outer_scope() != NULL) top = top->outer_scope();
178 top->AllocateVariables(info->calling_context()); 184 top->AllocateVariables(info->calling_context());
179 185
180 #ifdef DEBUG 186 #ifdef DEBUG
181 if (Bootstrapper::IsActive() 187 if (Bootstrapper::IsActive()
182 ? FLAG_print_builtin_scopes 188 ? FLAG_print_builtin_scopes
183 : FLAG_print_scopes) { 189 : FLAG_print_scopes) {
184 info->function()->scope()->Print(); 190 info->function()->scope()->Print();
185 } 191 }
186 #endif 192 #endif
187 193
188 info->SetScope(info->function()->scope()); 194 info->SetScope(info->function()->scope());
189 return true; // Can not fail. 195 return true; // Can not fail.
190 } 196 }
191 197
192 198
193 void Scope::Initialize(bool inside_with) { 199 void Scope::Initialize(bool inside_with) {
200 ASSERT(!resolved());
201
194 // Add this scope as a new inner scope of the outer scope. 202 // Add this scope as a new inner scope of the outer scope.
195 if (outer_scope_ != NULL) { 203 if (outer_scope_ != NULL) {
196 outer_scope_->inner_scopes_.Add(this); 204 outer_scope_->inner_scopes_.Add(this);
197 scope_inside_with_ = outer_scope_->scope_inside_with_ || inside_with; 205 scope_inside_with_ = outer_scope_->scope_inside_with_ || inside_with;
198 } else { 206 } else {
199 scope_inside_with_ = inside_with; 207 scope_inside_with_ = inside_with;
200 } 208 }
201 209
202 // Declare convenience variables. 210 // Declare convenience variables.
203 // Declare and allocate receiver (even for the global scope, and even 211 // Declare and allocate receiver (even for the global scope, and even
204 // if naccesses_ == 0). 212 // if naccesses_ == 0).
205 // NOTE: When loading parameters in the global scope, we must take 213 // NOTE: When loading parameters in the global scope, we must take
206 // care not to access them as properties of the global object, but 214 // care not to access them as properties of the global object, but
207 // instead load them directly from the stack. Currently, the only 215 // instead load them directly from the stack. Currently, the only
208 // such parameter is 'this' which is passed on the stack when 216 // such parameter is 'this' which is passed on the stack when
209 // invoking scripts 217 // invoking scripts
210 Variable* var = 218 Variable* var =
211 variables_.Declare(this, Factory::this_symbol(), Variable::VAR, 219 variables_.Declare(this, Factory::this_symbol(), Variable::VAR,
212 false, Variable::THIS); 220 false, Variable::THIS);
213 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); 221 var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
214 receiver_ = var; 222 receiver_ = var;
215 223
216 if (is_function_scope()) { 224 if (is_function_scope()) {
217 // Declare 'arguments' variable which exists in all functions. 225 // Declare 'arguments' variable which exists in all functions.
218 // Note that it might never be accessed, in which case it won't be 226 // Note that it might never be accessed, in which case it won't be
219 // allocated during variable allocation. 227 // allocated during variable allocation.
220 variables_.Declare(this, Factory::arguments_symbol(), Variable::VAR, 228 variables_.Declare(this, Factory::arguments_symbol(), Variable::VAR,
221 true, Variable::ARGUMENTS); 229 true, Variable::ARGUMENTS);
222 } 230 }
223 } 231 }
224 232
225 233
226 Variable* Scope::LocalLookup(Handle<String> name) { 234 Variable* Scope::LocalLookup(Handle<String> name) {
227 return variables_.Lookup(name); 235 Variable* result = variables_.Lookup(name);
236 if (result != NULL || !resolved()) {
237 return result;
238 }
239 // If the scope is resolved, we can find a variable in serialized scope info.
240
241 // We should never lookup 'arguments' in this scope
242 // as it is impllicitly present in any scope.
243 ASSERT(*name != *Factory::arguments_symbol());
244
245 // Check context slot lookup.
246 Variable::Mode mode;
247 int index = scope_info_->ContextSlotIndex(*name, &mode);
248 if (index < 0) {
249 return NULL;
250 }
251
252 // Check that there is no local slot with the given name.
253 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
254 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL);
255 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
256 return var;
228 } 257 }
229 258
230 259
231 Variable* Scope::Lookup(Handle<String> name) { 260 Variable* Scope::Lookup(Handle<String> name) {
232 for (Scope* scope = this; 261 for (Scope* scope = this;
233 scope != NULL; 262 scope != NULL;
234 scope = scope->outer_scope()) { 263 scope = scope->outer_scope()) {
235 Variable* var = scope->LocalLookup(name); 264 Variable* var = scope->LocalLookup(name);
236 if (var != NULL) return var; 265 if (var != NULL) return var;
237 } 266 }
238 return NULL; 267 return NULL;
239 } 268 }
240 269
241 270
242 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 271 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
243 ASSERT(is_function_scope() && function_ == NULL); 272 ASSERT(is_function_scope() && function_ == NULL);
244 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 273 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
245 return function_; 274 return function_;
246 } 275 }
247 276
248 277
249 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) { 278 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
250 // DYNAMIC variables are introduces during variable allocation, 279 // DYNAMIC variables are introduces during variable allocation,
251 // INTERNAL variables are allocated explicitly, and TEMPORARY 280 // INTERNAL variables are allocated explicitly, and TEMPORARY
252 // variables are allocated via NewTemporary(). 281 // variables are allocated via NewTemporary().
282 ASSERT(!resolved());
253 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 283 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
254 return variables_.Declare(this, name, mode, true, Variable::NORMAL); 284 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
255 } 285 }
256 286
257 287
258 Variable* Scope::DeclareGlobal(Handle<String> name) { 288 Variable* Scope::DeclareGlobal(Handle<String> name) {
259 ASSERT(is_global_scope()); 289 ASSERT(is_global_scope());
260 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true, 290 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true,
261 Variable::NORMAL); 291 Variable::NORMAL);
262 } 292 }
263 293
264 294
265 void Scope::AddParameter(Variable* var) { 295 void Scope::AddParameter(Variable* var) {
266 ASSERT(is_function_scope()); 296 ASSERT(is_function_scope());
267 ASSERT(LocalLookup(var->name()) == var); 297 ASSERT(LocalLookup(var->name()) == var);
268 params_.Add(var); 298 params_.Add(var);
269 } 299 }
270 300
271 301
272 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) { 302 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) {
273 // Note that we must not share the unresolved variables with 303 // Note that we must not share the unresolved variables with
274 // the same name because they may be removed selectively via 304 // the same name because they may be removed selectively via
275 // RemoveUnresolved(). 305 // RemoveUnresolved().
306 ASSERT(!resolved());
276 VariableProxy* proxy = new VariableProxy(name, false, inside_with); 307 VariableProxy* proxy = new VariableProxy(name, false, inside_with);
277 unresolved_.Add(proxy); 308 unresolved_.Add(proxy);
278 return proxy; 309 return proxy;
279 } 310 }
280 311
281 312
282 void Scope::RemoveUnresolved(VariableProxy* var) { 313 void Scope::RemoveUnresolved(VariableProxy* var) {
283 // Most likely (always?) any variable we want to remove 314 // Most likely (always?) any variable we want to remove
284 // was just added before, so we search backwards. 315 // was just added before, so we search backwards.
285 for (int i = unresolved_.length(); i-- > 0;) { 316 for (int i = unresolved_.length(); i-- > 0;) {
286 if (unresolved_[i] == var) { 317 if (unresolved_[i] == var) {
287 unresolved_.Remove(i); 318 unresolved_.Remove(i);
288 return; 319 return;
289 } 320 }
290 } 321 }
291 } 322 }
292 323
293 324
294 Variable* Scope::NewTemporary(Handle<String> name) { 325 Variable* Scope::NewTemporary(Handle<String> name) {
326 ASSERT(!resolved());
295 Variable* var = 327 Variable* var =
296 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL); 328 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL);
297 temps_.Add(var); 329 temps_.Add(var);
298 return var; 330 return var;
299 } 331 }
300 332
301 333
302 void Scope::AddDeclaration(Declaration* declaration) { 334 void Scope::AddDeclaration(Declaration* declaration) {
303 decls_.Add(declaration); 335 decls_.Add(declaration);
304 } 336 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 575
544 576
545 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 577 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
546 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 578 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
547 VariableMap* map = dynamics_->GetMap(mode); 579 VariableMap* map = dynamics_->GetMap(mode);
548 Variable* var = map->Lookup(name); 580 Variable* var = map->Lookup(name);
549 if (var == NULL) { 581 if (var == NULL) {
550 // Declare a new non-local. 582 // Declare a new non-local.
551 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 583 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
552 // Allocate it by giving it a dynamic lookup. 584 // Allocate it by giving it a dynamic lookup.
553 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 585 var->set_rewrite(new Slot(var, Slot::LOOKUP, -1));
554 } 586 }
555 return var; 587 return var;
556 } 588 }
557 589
558 590
559 // Lookup a variable starting with this scope. The result is either 591 // Lookup a variable starting with this scope. The result is either
560 // the statically resolved variable belonging to an outer scope, or 592 // 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) 593 // 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 594 // because the variable is just a guess (and may be shadowed by
563 // another variable that is introduced dynamically via an 'eval' call 595 // another variable that is introduced dynamically via an 'eval' call
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 637 }
606 638
607 // If we did not find a variable, we are done. 639 // If we did not find a variable, we are done.
608 if (var == NULL) 640 if (var == NULL)
609 return NULL; 641 return NULL;
610 } 642 }
611 643
612 ASSERT(var != NULL); 644 ASSERT(var != NULL);
613 645
614 // If this is a lookup from an inner scope, mark the variable. 646 // If this is a lookup from an inner scope, mark the variable.
615 if (inner_lookup) 647 if (inner_lookup) {
616 var->is_accessed_from_inner_scope_ = true; 648 var->MarkAsAccessedFromInnerScope();
649 }
617 650
618 // If the variable we have found is just a guess, invalidate the 651 // 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 652 // 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. 653 // can generate fast code to get it if it is not shadowed by eval.
621 if (guess) { 654 if (guess) {
622 if (!var->is_global()) *invalidated_local = var; 655 if (!var->is_global()) *invalidated_local = var;
623 var = NULL; 656 var = NULL;
624 } 657 }
625 658
626 return var; 659 return var;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 779
747 return scope_calls_eval_ || inner_scope_calls_eval_; 780 return scope_calls_eval_ || inner_scope_calls_eval_;
748 } 781 }
749 782
750 783
751 bool Scope::MustAllocate(Variable* var) { 784 bool Scope::MustAllocate(Variable* var) {
752 // Give var a read/write use if there is a chance it might be accessed 785 // 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 786 // via an eval() call. This is only possible if the variable has a
754 // visible name. 787 // visible name.
755 if ((var->is_this() || var->name()->length() > 0) && 788 if ((var->is_this() || var->name()->length() > 0) &&
756 (var->is_accessed_from_inner_scope_ || 789 (var->is_accessed_from_inner_scope() ||
757 scope_calls_eval_ || inner_scope_calls_eval_ || 790 scope_calls_eval_ || inner_scope_calls_eval_ ||
758 scope_contains_with_)) { 791 scope_contains_with_)) {
759 var->set_is_used(true); 792 var->set_is_used(true);
760 } 793 }
761 // Global variables do not need to be allocated. 794 // Global variables do not need to be allocated.
762 return !var->is_global() && var->is_used(); 795 return !var->is_global() && var->is_used();
763 } 796 }
764 797
765 798
766 bool Scope::MustAllocateInContext(Variable* var) { 799 bool Scope::MustAllocateInContext(Variable* var) {
767 // If var is accessed from an inner scope, or if there is a 800 // 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 801 // possibility that it might be accessed from the current or an inner
769 // scope (through an eval() call), it must be allocated in the 802 // scope (through an eval() call), it must be allocated in the
770 // context. Exception: temporary variables are not allocated in the 803 // context. Exception: temporary variables are not allocated in the
771 // context. 804 // context.
772 return 805 return
773 var->mode() != Variable::TEMPORARY && 806 var->mode() != Variable::TEMPORARY &&
774 (var->is_accessed_from_inner_scope_ || 807 (var->is_accessed_from_inner_scope() ||
775 scope_calls_eval_ || inner_scope_calls_eval_ || 808 scope_calls_eval_ || inner_scope_calls_eval_ ||
776 scope_contains_with_ || var->is_global()); 809 scope_contains_with_ || var->is_global());
777 } 810 }
778 811
779 812
780 bool Scope::HasArgumentsParameter() { 813 bool Scope::HasArgumentsParameter() {
781 for (int i = 0; i < params_.length(); i++) { 814 for (int i = 0; i < params_.length(); i++) {
782 if (params_[i]->name().is_identical_to(Factory::arguments_symbol())) 815 if (params_[i]->name().is_identical_to(Factory::arguments_symbol()))
783 return true; 816 return true;
784 } 817 }
785 return false; 818 return false;
786 } 819 }
787 820
788 821
789 void Scope::AllocateStackSlot(Variable* var) { 822 void Scope::AllocateStackSlot(Variable* var) {
790 var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++); 823 var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++));
791 } 824 }
792 825
793 826
794 void Scope::AllocateHeapSlot(Variable* var) { 827 void Scope::AllocateHeapSlot(Variable* var) {
795 var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++); 828 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
796 } 829 }
797 830
798 831
799 void Scope::AllocateParameterLocals() { 832 void Scope::AllocateParameterLocals() {
800 ASSERT(is_function_scope()); 833 ASSERT(is_function_scope());
801 Variable* arguments = LocalLookup(Factory::arguments_symbol()); 834 Variable* arguments = LocalLookup(Factory::arguments_symbol());
802 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 835 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
803 if (MustAllocate(arguments) && !HasArgumentsParameter()) { 836 if (MustAllocate(arguments) && !HasArgumentsParameter()) {
804 // 'arguments' is used. Unless there is also a parameter called 837 // 'arguments' is used. Unless there is also a parameter called
805 // 'arguments', we must be conservative and access all parameters via 838 // 'arguments', we must be conservative and access all parameters via
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 883
851 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. 884 // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
852 for (int i = 0; i < params_.length(); i++) { 885 for (int i = 0; i < params_.length(); i++) {
853 Variable* var = params_[i]; 886 Variable* var = params_[i];
854 ASSERT(var->scope() == this); 887 ASSERT(var->scope() == this);
855 if (MustAllocate(var)) { 888 if (MustAllocate(var)) {
856 if (MustAllocateInContext(var)) { 889 if (MustAllocateInContext(var)) {
857 // It is ok to set this only now, because arguments is a local 890 // It is ok to set this only now, because arguments is a local
858 // variable that is allocated after the parameters have been 891 // variable that is allocated after the parameters have been
859 // allocated. 892 // allocated.
860 arguments_shadow_->is_accessed_from_inner_scope_ = true; 893 arguments_shadow_->MarkAsAccessedFromInnerScope();
861 } 894 }
862 Property* rewrite = 895 Property* rewrite =
863 new Property(new VariableProxy(arguments_shadow_), 896 new Property(new VariableProxy(arguments_shadow_),
864 new Literal(Handle<Object>(Smi::FromInt(i))), 897 new Literal(Handle<Object>(Smi::FromInt(i))),
865 RelocInfo::kNoPosition, 898 RelocInfo::kNoPosition,
866 Property::SYNTHETIC); 899 Property::SYNTHETIC);
867 rewrite->set_is_arguments_access(true); 900 rewrite->set_is_arguments_access(true);
868 var->rewrite_ = rewrite; 901 var->set_rewrite(rewrite);
869 } 902 }
870 } 903 }
871 904
872 } else { 905 } else {
873 // The arguments object is not used, so we can access parameters directly. 906 // The arguments object is not used, so we can access parameters directly.
874 // The same parameter may occur multiple times in the parameters_ list. 907 // 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 908 // 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 909 // receive the highest parameter index for that parameter; thus iteration
877 // order is relevant! 910 // order is relevant!
878 for (int i = 0; i < params_.length(); i++) { 911 for (int i = 0; i < params_.length(); i++) {
879 Variable* var = params_[i]; 912 Variable* var = params_[i];
880 ASSERT(var->scope() == this); 913 ASSERT(var->scope() == this);
881 if (MustAllocate(var)) { 914 if (MustAllocate(var)) {
882 if (MustAllocateInContext(var)) { 915 if (MustAllocateInContext(var)) {
883 ASSERT(var->rewrite_ == NULL || 916 ASSERT(var->rewrite() == NULL ||
884 (var->AsSlot() != NULL && 917 (var->AsSlot() != NULL &&
885 var->AsSlot()->type() == Slot::CONTEXT)); 918 var->AsSlot()->type() == Slot::CONTEXT));
886 if (var->rewrite_ == NULL) { 919 if (var->rewrite() == NULL) {
887 // Only set the heap allocation if the parameter has not 920 // Only set the heap allocation if the parameter has not
888 // been allocated yet. 921 // been allocated yet.
889 AllocateHeapSlot(var); 922 AllocateHeapSlot(var);
890 } 923 }
891 } else { 924 } else {
892 ASSERT(var->rewrite_ == NULL || 925 ASSERT(var->rewrite() == NULL ||
893 (var->AsSlot() != NULL && 926 (var->AsSlot() != NULL &&
894 var->AsSlot()->type() == Slot::PARAMETER)); 927 var->AsSlot()->type() == Slot::PARAMETER));
895 // Set the parameter index always, even if the parameter 928 // Set the parameter index always, even if the parameter
896 // was seen before! (We need to access the actual parameter 929 // was seen before! (We need to access the actual parameter
897 // supplied for the last occurrence of a multiply declared 930 // supplied for the last occurrence of a multiply declared
898 // parameter.) 931 // parameter.)
899 var->rewrite_ = new Slot(var, Slot::PARAMETER, i); 932 var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
900 } 933 }
901 } 934 }
902 } 935 }
903 } 936 }
904 } 937 }
905 938
906 939
907 void Scope::AllocateNonParameterLocal(Variable* var) { 940 void Scope::AllocateNonParameterLocal(Variable* var) {
908 ASSERT(var->scope() == this); 941 ASSERT(var->scope() == this);
909 ASSERT(var->rewrite_ == NULL || 942 ASSERT(var->rewrite() == NULL ||
910 (!var->IsVariable(Factory::result_symbol())) || 943 (!var->IsVariable(Factory::result_symbol())) ||
911 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); 944 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
912 if (var->rewrite_ == NULL && MustAllocate(var)) { 945 if (var->rewrite() == NULL && MustAllocate(var)) {
913 if (MustAllocateInContext(var)) { 946 if (MustAllocateInContext(var)) {
914 AllocateHeapSlot(var); 947 AllocateHeapSlot(var);
915 } else { 948 } else {
916 AllocateStackSlot(var); 949 AllocateStackSlot(var);
917 } 950 }
918 } 951 }
919 } 952 }
920 953
921 954
922 void Scope::AllocateNonParameterLocals() { 955 void Scope::AllocateNonParameterLocals() {
(...skipping 13 matching lines...) Expand all
936 // allocated in the context, it must be the last slot in the context, 969 // allocated in the context, it must be the last slot in the context,
937 // because of the current ScopeInfo implementation (see 970 // because of the current ScopeInfo implementation (see
938 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 971 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
939 if (function_ != NULL) { 972 if (function_ != NULL) {
940 AllocateNonParameterLocal(function_); 973 AllocateNonParameterLocal(function_);
941 } 974 }
942 } 975 }
943 976
944 977
945 void Scope::AllocateVariablesRecursively() { 978 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. 979 // Allocate variables for inner scopes.
951 for (int i = 0; i < inner_scopes_.length(); i++) { 980 for (int i = 0; i < inner_scopes_.length(); i++) {
952 inner_scopes_[i]->AllocateVariablesRecursively(); 981 inner_scopes_[i]->AllocateVariablesRecursively();
953 } 982 }
954 983
984 // If scope is already resolved, we still need to allocate
985 // variables in inner scopes which might not had been resolved yet.
986 if (resolved()) return;
987 // The number of slots required for variables.
988 num_stack_slots_ = 0;
989 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
990
955 // Allocate variables for this scope. 991 // Allocate variables for this scope.
956 // Parameters must be allocated first, if any. 992 // Parameters must be allocated first, if any.
957 if (is_function_scope()) AllocateParameterLocals(); 993 if (is_function_scope()) AllocateParameterLocals();
958 AllocateNonParameterLocals(); 994 AllocateNonParameterLocals();
959 995
960 // Allocate context if necessary. 996 // Allocate context if necessary.
961 bool must_have_local_context = false; 997 bool must_have_local_context = false;
962 if (scope_calls_eval_ || scope_contains_with_) { 998 if (scope_calls_eval_ || scope_contains_with_) {
963 // The context for the eval() call or 'with' statement in this scope. 999 // 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 1000 // 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, 1001 // context even if we didn't statically allocate any locals in it,
966 // and the compiler will access the context variable. If we are 1002 // and the compiler will access the context variable. If we are
967 // not in an inner scope, the scope is provided from the outside. 1003 // not in an inner scope, the scope is provided from the outside.
968 must_have_local_context = is_function_scope(); 1004 must_have_local_context = is_function_scope();
969 } 1005 }
970 1006
971 // If we didn't allocate any locals in the local context, then we only 1007 // 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. 1008 // need the minimal number of slots if we must have a local context.
973 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1009 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
974 !must_have_local_context) { 1010 !must_have_local_context) {
975 num_heap_slots_ = 0; 1011 num_heap_slots_ = 0;
976 } 1012 }
977 1013
978 // Allocation done. 1014 // Allocation done.
979 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1015 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
980 } 1016 }
981 1017
982 } } // namespace v8::internal 1018 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698