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

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: Minor fix in hash function Created 10 years 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
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),
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 133 // At some point we might want to provide outer scopes to
167 // eval scopes (by walking the stack and reading the scope info). 134 // eval scopes (by walking the stack and reading the scope info).
168 // In that case, the ASSERT below needs to be adjusted. 135 // In that case, the ASSERT below needs to be adjusted.
136 SetDefaults(type, outer_scope, NULL);
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 if (!resolved()) {
236 return variables_.Lookup(name);
237 }
238
239 // Check arguments object lookup.
240 if (*name == *Factory::arguments_symbol()) {
241 return new Variable(this, name, Variable::VAR, true, Variable::ARGUMENTS);
242 }
243
244 // Check context slot lookup.
245 Variable::Mode mode;
246 int index = scope_info_->ContextSlotIndex(*name, &mode);
247 if (index < 0) {
248 return NULL;
249 }
250
251 Variable* var = new Variable(this, name, mode, true, Variable::NORMAL);
252 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
253 return var;
228 } 254 }
229 255
230 256
231 Variable* Scope::Lookup(Handle<String> name) { 257 Variable* Scope::Lookup(Handle<String> name) {
232 for (Scope* scope = this; 258 for (Scope* scope = this;
233 scope != NULL; 259 scope != NULL;
234 scope = scope->outer_scope()) { 260 scope = scope->outer_scope()) {
235 Variable* var = scope->LocalLookup(name); 261 Variable* var = scope->LocalLookup(name);
236 if (var != NULL) return var; 262 if (var != NULL) return var;
237 } 263 }
238 return NULL; 264 return NULL;
239 } 265 }
240 266
241 267
242 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 268 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
243 ASSERT(is_function_scope() && function_ == NULL); 269 ASSERT(is_function_scope() && function_ == NULL);
244 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 270 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
245 return function_; 271 return function_;
246 } 272 }
247 273
248 274
249 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) { 275 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
250 // DYNAMIC variables are introduces during variable allocation, 276 // DYNAMIC variables are introduces during variable allocation,
251 // INTERNAL variables are allocated explicitly, and TEMPORARY 277 // INTERNAL variables are allocated explicitly, and TEMPORARY
252 // variables are allocated via NewTemporary(). 278 // variables are allocated via NewTemporary().
279 ASSERT(!resolved());
253 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 280 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
254 return variables_.Declare(this, name, mode, true, Variable::NORMAL); 281 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
255 } 282 }
256 283
257 284
258 Variable* Scope::DeclareGlobal(Handle<String> name) { 285 Variable* Scope::DeclareGlobal(Handle<String> name) {
259 ASSERT(is_global_scope()); 286 ASSERT(is_global_scope());
260 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true, 287 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true,
261 Variable::NORMAL); 288 Variable::NORMAL);
262 } 289 }
263 290
264 291
265 void Scope::AddParameter(Variable* var) { 292 void Scope::AddParameter(Variable* var) {
266 ASSERT(is_function_scope()); 293 ASSERT(is_function_scope());
267 ASSERT(LocalLookup(var->name()) == var); 294 ASSERT(LocalLookup(var->name()) == var);
268 params_.Add(var); 295 params_.Add(var);
269 } 296 }
270 297
271 298
272 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) { 299 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) {
273 // Note that we must not share the unresolved variables with 300 // Note that we must not share the unresolved variables with
274 // the same name because they may be removed selectively via 301 // the same name because they may be removed selectively via
275 // RemoveUnresolved(). 302 // RemoveUnresolved().
303 ASSERT(!resolved());
276 VariableProxy* proxy = new VariableProxy(name, false, inside_with); 304 VariableProxy* proxy = new VariableProxy(name, false, inside_with);
277 unresolved_.Add(proxy); 305 unresolved_.Add(proxy);
278 return proxy; 306 return proxy;
279 } 307 }
280 308
281 309
282 void Scope::RemoveUnresolved(VariableProxy* var) { 310 void Scope::RemoveUnresolved(VariableProxy* var) {
283 // Most likely (always?) any variable we want to remove 311 // Most likely (always?) any variable we want to remove
284 // was just added before, so we search backwards. 312 // was just added before, so we search backwards.
285 for (int i = unresolved_.length(); i-- > 0;) { 313 for (int i = unresolved_.length(); i-- > 0;) {
286 if (unresolved_[i] == var) { 314 if (unresolved_[i] == var) {
287 unresolved_.Remove(i); 315 unresolved_.Remove(i);
288 return; 316 return;
289 } 317 }
290 } 318 }
291 } 319 }
292 320
293 321
294 Variable* Scope::NewTemporary(Handle<String> name) { 322 Variable* Scope::NewTemporary(Handle<String> name) {
323 ASSERT(!resolved());
295 Variable* var = 324 Variable* var =
296 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL); 325 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL);
297 temps_.Add(var); 326 temps_.Add(var);
298 return var; 327 return var;
299 } 328 }
300 329
301 330
302 void Scope::AddDeclaration(Declaration* declaration) { 331 void Scope::AddDeclaration(Declaration* declaration) {
303 decls_.Add(declaration); 332 decls_.Add(declaration);
304 } 333 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 572
544 573
545 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 574 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
546 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 575 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
547 VariableMap* map = dynamics_->GetMap(mode); 576 VariableMap* map = dynamics_->GetMap(mode);
548 Variable* var = map->Lookup(name); 577 Variable* var = map->Lookup(name);
549 if (var == NULL) { 578 if (var == NULL) {
550 // Declare a new non-local. 579 // Declare a new non-local.
551 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 580 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
552 // Allocate it by giving it a dynamic lookup. 581 // Allocate it by giving it a dynamic lookup.
553 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 582 var->set_rewrite(new Slot(var, Slot::LOOKUP, -1));
554 } 583 }
555 return var; 584 return var;
556 } 585 }
557 586
558 587
559 // Lookup a variable starting with this scope. The result is either 588 // Lookup a variable starting with this scope. The result is either
560 // the statically resolved variable belonging to an outer scope, or 589 // 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) 590 // 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 591 // because the variable is just a guess (and may be shadowed by
563 // another variable that is introduced dynamically via an 'eval' call 592 // another variable that is introduced dynamically via an 'eval' call
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 634 }
606 635
607 // If we did not find a variable, we are done. 636 // If we did not find a variable, we are done.
608 if (var == NULL) 637 if (var == NULL)
609 return NULL; 638 return NULL;
610 } 639 }
611 640
612 ASSERT(var != NULL); 641 ASSERT(var != NULL);
613 642
614 // If this is a lookup from an inner scope, mark the variable. 643 // If this is a lookup from an inner scope, mark the variable.
615 if (inner_lookup) 644 if (inner_lookup) {
616 var->is_accessed_from_inner_scope_ = true; 645 var->MarkAsAccessedFromInnerScope();
646 }
617 647
618 // If the variable we have found is just a guess, invalidate the 648 // 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 649 // 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. 650 // can generate fast code to get it if it is not shadowed by eval.
621 if (guess) { 651 if (guess) {
622 if (!var->is_global()) *invalidated_local = var; 652 if (!var->is_global()) *invalidated_local = var;
623 var = NULL; 653 var = NULL;
624 } 654 }
625 655
626 return var; 656 return var;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 776
747 return scope_calls_eval_ || inner_scope_calls_eval_; 777 return scope_calls_eval_ || inner_scope_calls_eval_;
748 } 778 }
749 779
750 780
751 bool Scope::MustAllocate(Variable* var) { 781 bool Scope::MustAllocate(Variable* var) {
752 // Give var a read/write use if there is a chance it might be accessed 782 // 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 783 // via an eval() call. This is only possible if the variable has a
754 // visible name. 784 // visible name.
755 if ((var->is_this() || var->name()->length() > 0) && 785 if ((var->is_this() || var->name()->length() > 0) &&
756 (var->is_accessed_from_inner_scope_ || 786 (var->is_accessed_from_inner_scope() ||
757 scope_calls_eval_ || inner_scope_calls_eval_ || 787 scope_calls_eval_ || inner_scope_calls_eval_ ||
758 scope_contains_with_)) { 788 scope_contains_with_)) {
759 var->set_is_used(true); 789 var->set_is_used(true);
760 } 790 }
761 // Global variables do not need to be allocated. 791 // Global variables do not need to be allocated.
762 return !var->is_global() && var->is_used(); 792 return !var->is_global() && var->is_used();
763 } 793 }
764 794
765 795
766 bool Scope::MustAllocateInContext(Variable* var) { 796 bool Scope::MustAllocateInContext(Variable* var) {
767 // If var is accessed from an inner scope, or if there is a 797 // 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 798 // possibility that it might be accessed from the current or an inner
769 // scope (through an eval() call), it must be allocated in the 799 // scope (through an eval() call), it must be allocated in the
770 // context. Exception: temporary variables are not allocated in the 800 // context. Exception: temporary variables are not allocated in the
771 // context. 801 // context.
772 return 802 return
773 var->mode() != Variable::TEMPORARY && 803 var->mode() != Variable::TEMPORARY &&
774 (var->is_accessed_from_inner_scope_ || 804 (var->is_accessed_from_inner_scope() ||
775 scope_calls_eval_ || inner_scope_calls_eval_ || 805 scope_calls_eval_ || inner_scope_calls_eval_ ||
776 scope_contains_with_ || var->is_global()); 806 scope_contains_with_ || var->is_global());
777 } 807 }
778 808
779 809
780 bool Scope::HasArgumentsParameter() { 810 bool Scope::HasArgumentsParameter() {
781 for (int i = 0; i < params_.length(); i++) { 811 for (int i = 0; i < params_.length(); i++) {
782 if (params_[i]->name().is_identical_to(Factory::arguments_symbol())) 812 if (params_[i]->name().is_identical_to(Factory::arguments_symbol()))
783 return true; 813 return true;
784 } 814 }
785 return false; 815 return false;
786 } 816 }
787 817
788 818
789 void Scope::AllocateStackSlot(Variable* var) { 819 void Scope::AllocateStackSlot(Variable* var) {
790 var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++); 820 var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++));
791 } 821 }
792 822
793 823
794 void Scope::AllocateHeapSlot(Variable* var) { 824 void Scope::AllocateHeapSlot(Variable* var) {
795 var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++); 825 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
796 } 826 }
797 827
798 828
799 void Scope::AllocateParameterLocals() { 829 void Scope::AllocateParameterLocals() {
800 ASSERT(is_function_scope()); 830 ASSERT(is_function_scope());
801 Variable* arguments = LocalLookup(Factory::arguments_symbol()); 831 Variable* arguments = LocalLookup(Factory::arguments_symbol());
802 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 832 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
803 if (MustAllocate(arguments) && !HasArgumentsParameter()) { 833 if (MustAllocate(arguments) && !HasArgumentsParameter()) {
804 // 'arguments' is used. Unless there is also a parameter called 834 // 'arguments' is used. Unless there is also a parameter called
805 // 'arguments', we must be conservative and access all parameters via 835 // 'arguments', we must be conservative and access all parameters via
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 880
851 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. 881 // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
852 for (int i = 0; i < params_.length(); i++) { 882 for (int i = 0; i < params_.length(); i++) {
853 Variable* var = params_[i]; 883 Variable* var = params_[i];
854 ASSERT(var->scope() == this); 884 ASSERT(var->scope() == this);
855 if (MustAllocate(var)) { 885 if (MustAllocate(var)) {
856 if (MustAllocateInContext(var)) { 886 if (MustAllocateInContext(var)) {
857 // It is ok to set this only now, because arguments is a local 887 // It is ok to set this only now, because arguments is a local
858 // variable that is allocated after the parameters have been 888 // variable that is allocated after the parameters have been
859 // allocated. 889 // allocated.
860 arguments_shadow_->is_accessed_from_inner_scope_ = true; 890 arguments_shadow_->MarkAsAccessedFromInnerScope();
861 } 891 }
862 Property* rewrite = 892 Property* rewrite =
863 new Property(new VariableProxy(arguments_shadow_), 893 new Property(new VariableProxy(arguments_shadow_),
864 new Literal(Handle<Object>(Smi::FromInt(i))), 894 new Literal(Handle<Object>(Smi::FromInt(i))),
865 RelocInfo::kNoPosition, 895 RelocInfo::kNoPosition,
866 Property::SYNTHETIC); 896 Property::SYNTHETIC);
867 rewrite->set_is_arguments_access(true); 897 rewrite->set_is_arguments_access(true);
868 var->rewrite_ = rewrite; 898 var->set_rewrite(rewrite);
869 } 899 }
870 } 900 }
871 901
872 } else { 902 } else {
873 // The arguments object is not used, so we can access parameters directly. 903 // The arguments object is not used, so we can access parameters directly.
874 // The same parameter may occur multiple times in the parameters_ list. 904 // 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 905 // 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 906 // receive the highest parameter index for that parameter; thus iteration
877 // order is relevant! 907 // order is relevant!
878 for (int i = 0; i < params_.length(); i++) { 908 for (int i = 0; i < params_.length(); i++) {
879 Variable* var = params_[i]; 909 Variable* var = params_[i];
880 ASSERT(var->scope() == this); 910 ASSERT(var->scope() == this);
881 if (MustAllocate(var)) { 911 if (MustAllocate(var)) {
882 if (MustAllocateInContext(var)) { 912 if (MustAllocateInContext(var)) {
883 ASSERT(var->rewrite_ == NULL || 913 ASSERT(var->rewrite() == NULL ||
884 (var->AsSlot() != NULL && 914 (var->AsSlot() != NULL &&
885 var->AsSlot()->type() == Slot::CONTEXT)); 915 var->AsSlot()->type() == Slot::CONTEXT));
886 if (var->rewrite_ == NULL) { 916 if (var->rewrite() == NULL) {
887 // Only set the heap allocation if the parameter has not 917 // Only set the heap allocation if the parameter has not
888 // been allocated yet. 918 // been allocated yet.
889 AllocateHeapSlot(var); 919 AllocateHeapSlot(var);
890 } 920 }
891 } else { 921 } else {
892 ASSERT(var->rewrite_ == NULL || 922 ASSERT(var->rewrite() == NULL ||
893 (var->AsSlot() != NULL && 923 (var->AsSlot() != NULL &&
894 var->AsSlot()->type() == Slot::PARAMETER)); 924 var->AsSlot()->type() == Slot::PARAMETER));
895 // Set the parameter index always, even if the parameter 925 // Set the parameter index always, even if the parameter
896 // was seen before! (We need to access the actual parameter 926 // was seen before! (We need to access the actual parameter
897 // supplied for the last occurrence of a multiply declared 927 // supplied for the last occurrence of a multiply declared
898 // parameter.) 928 // parameter.)
899 var->rewrite_ = new Slot(var, Slot::PARAMETER, i); 929 var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
900 } 930 }
901 } 931 }
902 } 932 }
903 } 933 }
904 } 934 }
905 935
906 936
907 void Scope::AllocateNonParameterLocal(Variable* var) { 937 void Scope::AllocateNonParameterLocal(Variable* var) {
908 ASSERT(var->scope() == this); 938 ASSERT(var->scope() == this);
909 ASSERT(var->rewrite_ == NULL || 939 ASSERT(var->rewrite() == NULL ||
910 (!var->IsVariable(Factory::result_symbol())) || 940 (!var->IsVariable(Factory::result_symbol())) ||
911 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); 941 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
912 if (var->rewrite_ == NULL && MustAllocate(var)) { 942 if (var->rewrite() == NULL && MustAllocate(var)) {
913 if (MustAllocateInContext(var)) { 943 if (MustAllocateInContext(var)) {
914 AllocateHeapSlot(var); 944 AllocateHeapSlot(var);
915 } else { 945 } else {
916 AllocateStackSlot(var); 946 AllocateStackSlot(var);
917 } 947 }
918 } 948 }
919 } 949 }
920 950
921 951
922 void Scope::AllocateNonParameterLocals() { 952 void Scope::AllocateNonParameterLocals() {
(...skipping 13 matching lines...) Expand all
936 // allocated in the context, it must be the last slot in the context, 966 // allocated in the context, it must be the last slot in the context,
937 // because of the current ScopeInfo implementation (see 967 // because of the current ScopeInfo implementation (see
938 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 968 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
939 if (function_ != NULL) { 969 if (function_ != NULL) {
940 AllocateNonParameterLocal(function_); 970 AllocateNonParameterLocal(function_);
941 } 971 }
942 } 972 }
943 973
944 974
945 void Scope::AllocateVariablesRecursively() { 975 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. 976 // Allocate variables for inner scopes.
951 for (int i = 0; i < inner_scopes_.length(); i++) { 977 for (int i = 0; i < inner_scopes_.length(); i++) {
952 inner_scopes_[i]->AllocateVariablesRecursively(); 978 inner_scopes_[i]->AllocateVariablesRecursively();
953 } 979 }
954 980
981 // If scope is already resolved, we still need to allocate
982 // variables in inner scopes which might not had been resolved yet.
983 if (resolved()) return;
984 // The number of slots required for variables.
985 num_stack_slots_ = 0;
986 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
987
955 // Allocate variables for this scope. 988 // Allocate variables for this scope.
956 // Parameters must be allocated first, if any. 989 // Parameters must be allocated first, if any.
957 if (is_function_scope()) AllocateParameterLocals(); 990 if (is_function_scope()) AllocateParameterLocals();
958 AllocateNonParameterLocals(); 991 AllocateNonParameterLocals();
959 992
960 // Allocate context if necessary. 993 // Allocate context if necessary.
961 bool must_have_local_context = false; 994 bool must_have_local_context = false;
962 if (scope_calls_eval_ || scope_contains_with_) { 995 if (scope_calls_eval_ || scope_contains_with_) {
963 // The context for the eval() call or 'with' statement in this scope. 996 // 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 997 // 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, 998 // context even if we didn't statically allocate any locals in it,
966 // and the compiler will access the context variable. If we are 999 // and the compiler will access the context variable. If we are
967 // not in an inner scope, the scope is provided from the outside. 1000 // not in an inner scope, the scope is provided from the outside.
968 must_have_local_context = is_function_scope(); 1001 must_have_local_context = is_function_scope();
969 } 1002 }
970 1003
971 // If we didn't allocate any locals in the local context, then we only 1004 // 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. 1005 // need the minimal number of slots if we must have a local context.
973 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1006 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
974 !must_have_local_context) { 1007 !must_have_local_context) {
975 num_heap_slots_ = 0; 1008 num_heap_slots_ = 0;
976 } 1009 }
977 1010
978 // Allocation done. 1011 // Allocation done.
979 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1012 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
980 } 1013 }
981 1014
982 } } // namespace v8::internal 1015 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698