OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 LocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap() {} | 74 LocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap() {} |
75 | 75 |
76 LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8) {} | 76 LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8) {} |
77 LocalsMap::~LocalsMap() {} | 77 LocalsMap::~LocalsMap() {} |
78 | 78 |
79 | 79 |
80 Variable* LocalsMap::Declare(Scope* scope, | 80 Variable* LocalsMap::Declare(Scope* scope, |
81 Handle<String> name, | 81 Handle<String> name, |
82 Variable::Mode mode, | 82 Variable::Mode mode, |
83 bool is_valid_LHS, | 83 bool is_valid_LHS, |
84 bool is_this) { | 84 Variable::Kind kind) { |
85 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); | 85 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); |
86 if (p->value == NULL) { | 86 if (p->value == NULL) { |
87 // The variable has not been declared yet -> insert it. | 87 // The variable has not been declared yet -> insert it. |
88 ASSERT(p->key == name.location()); | 88 ASSERT(p->key == name.location()); |
89 p->value = new Variable(scope, name, mode, is_valid_LHS, is_this); | 89 p->value = new Variable(scope, name, mode, is_valid_LHS, kind); |
90 } | 90 } |
91 return reinterpret_cast<Variable*>(p->value); | 91 return reinterpret_cast<Variable*>(p->value); |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 Variable* LocalsMap::Lookup(Handle<String> name) { | 95 Variable* LocalsMap::Lookup(Handle<String> name) { |
96 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); | 96 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); |
97 if (p != NULL) { | 97 if (p != NULL) { |
98 ASSERT(*reinterpret_cast<String**>(p->key) == *name); | 98 ASSERT(*reinterpret_cast<String**>(p->key) == *name); |
99 ASSERT(p->value != NULL); | 99 ASSERT(p->value != NULL); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 | 162 |
163 // Declare convenience variables. | 163 // Declare convenience variables. |
164 // Declare and allocate receiver (even for the global scope, and even | 164 // Declare and allocate receiver (even for the global scope, and even |
165 // if naccesses_ == 0). | 165 // if naccesses_ == 0). |
166 // NOTE: When loading parameters in the global scope, we must take | 166 // NOTE: When loading parameters in the global scope, we must take |
167 // care not to access them as properties of the global object, but | 167 // care not to access them as properties of the global object, but |
168 // instead load them directly from the stack. Currently, the only | 168 // instead load them directly from the stack. Currently, the only |
169 // such parameter is 'this' which is passed on the stack when | 169 // such parameter is 'this' which is passed on the stack when |
170 // invoking scripts | 170 // invoking scripts |
171 { Variable* var = | 171 { Variable* var = |
172 locals_.Declare(this, Factory::this_symbol(), Variable::VAR, false, true); | 172 locals_.Declare(this, Factory::this_symbol(), Variable::VAR, |
| 173 false, Variable::THIS); |
173 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); | 174 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); |
174 receiver_ = new VariableProxy(Factory::this_symbol(), true, false); | 175 receiver_ = new VariableProxy(Factory::this_symbol(), true, false); |
175 receiver_->BindTo(var); | 176 receiver_->BindTo(var); |
176 } | 177 } |
177 | 178 |
178 if (is_function_scope()) { | 179 if (is_function_scope()) { |
179 // Declare 'arguments' variable which exists in all functions. | 180 // Declare 'arguments' variable which exists in all functions. |
180 // Note that it may never be accessed, in which case it won't | 181 // Note that it may never be accessed, in which case it won't |
181 // be allocated during variable allocation. | 182 // be allocated during variable allocation. |
182 Declare(Factory::arguments_symbol(), Variable::VAR); | 183 locals_.Declare(this, Factory::arguments_symbol(), Variable::VAR, |
| 184 true, Variable::ARGUMENTS); |
183 } | 185 } |
184 } | 186 } |
185 | 187 |
186 | 188 |
187 | 189 |
188 Variable* Scope::LookupLocal(Handle<String> name) { | 190 Variable* Scope::LookupLocal(Handle<String> name) { |
189 return locals_.Lookup(name); | 191 return locals_.Lookup(name); |
190 } | 192 } |
191 | 193 |
192 | 194 |
193 Variable* Scope::Lookup(Handle<String> name) { | 195 Variable* Scope::Lookup(Handle<String> name) { |
194 for (Scope* scope = this; | 196 for (Scope* scope = this; |
195 scope != NULL; | 197 scope != NULL; |
196 scope = scope->outer_scope()) { | 198 scope = scope->outer_scope()) { |
197 Variable* var = scope->LookupLocal(name); | 199 Variable* var = scope->LookupLocal(name); |
198 if (var != NULL) return var; | 200 if (var != NULL) return var; |
199 } | 201 } |
200 return NULL; | 202 return NULL; |
201 } | 203 } |
202 | 204 |
203 | 205 |
204 Variable* Scope::DeclareFunctionVar(Handle<String> name) { | 206 Variable* Scope::DeclareFunctionVar(Handle<String> name) { |
205 ASSERT(is_function_scope() && function_ == NULL); | 207 ASSERT(is_function_scope() && function_ == NULL); |
206 function_ = new Variable(this, name, Variable::CONST, true, false); | 208 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); |
207 return function_; | 209 return function_; |
208 } | 210 } |
209 | 211 |
210 | 212 |
211 Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) { | 213 Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) { |
212 // DYNAMIC variables are introduces during variable allocation, | 214 // DYNAMIC variables are introduces during variable allocation, |
213 // INTERNAL variables are allocated explicitly, and TEMPORARY | 215 // INTERNAL variables are allocated explicitly, and TEMPORARY |
214 // variables are allocated via NewTemporary(). | 216 // variables are allocated via NewTemporary(). |
215 ASSERT(mode == Variable::VAR || mode == Variable::CONST); | 217 ASSERT(mode == Variable::VAR || mode == Variable::CONST); |
216 return locals_.Declare(this, name, mode, true, false); | 218 return locals_.Declare(this, name, mode, true, Variable::NORMAL); |
217 } | 219 } |
218 | 220 |
219 | 221 |
220 void Scope::AddParameter(Variable* var) { | 222 void Scope::AddParameter(Variable* var) { |
221 ASSERT(is_function_scope()); | 223 ASSERT(is_function_scope()); |
222 ASSERT(LookupLocal(var->name()) == var); | 224 ASSERT(LookupLocal(var->name()) == var); |
223 params_.Add(var); | 225 params_.Add(var); |
224 } | 226 } |
225 | 227 |
226 | 228 |
(...skipping 13 matching lines...) Expand all Loading... |
240 for (int i = unresolved_.length(); i-- > 0;) { | 242 for (int i = unresolved_.length(); i-- > 0;) { |
241 if (unresolved_[i] == var) { | 243 if (unresolved_[i] == var) { |
242 unresolved_.Remove(i); | 244 unresolved_.Remove(i); |
243 return; | 245 return; |
244 } | 246 } |
245 } | 247 } |
246 } | 248 } |
247 | 249 |
248 | 250 |
249 VariableProxy* Scope::NewTemporary(Handle<String> name) { | 251 VariableProxy* Scope::NewTemporary(Handle<String> name) { |
250 Variable* var = new Variable(this, name, Variable::TEMPORARY, true, false); | 252 Variable* var = new Variable(this, name, Variable::TEMPORARY, true, |
| 253 Variable::NORMAL); |
251 VariableProxy* tmp = new VariableProxy(name, false, false); | 254 VariableProxy* tmp = new VariableProxy(name, false, false); |
252 tmp->BindTo(var); | 255 tmp->BindTo(var); |
253 temps_.Add(var); | 256 temps_.Add(var); |
254 return tmp; | 257 return tmp; |
255 } | 258 } |
256 | 259 |
257 | 260 |
258 void Scope::AddDeclaration(Declaration* declaration) { | 261 void Scope::AddDeclaration(Declaration* declaration) { |
259 decls_.Add(declaration); | 262 decls_.Add(declaration); |
260 } | 263 } |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 499 } |
497 #endif // DEBUG | 500 #endif // DEBUG |
498 | 501 |
499 | 502 |
500 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { | 503 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { |
501 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); | 504 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); |
502 LocalsMap* map = dynamics_->GetMap(mode); | 505 LocalsMap* map = dynamics_->GetMap(mode); |
503 Variable* var = map->Lookup(name); | 506 Variable* var = map->Lookup(name); |
504 if (var == NULL) { | 507 if (var == NULL) { |
505 // Declare a new non-local. | 508 // Declare a new non-local. |
506 var = map->Declare(NULL, name, mode, true, false); | 509 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); |
507 // Allocate it by giving it a dynamic lookup. | 510 // Allocate it by giving it a dynamic lookup. |
508 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); | 511 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); |
509 } | 512 } |
510 return var; | 513 return var; |
511 } | 514 } |
512 | 515 |
513 | 516 |
514 // Lookup a variable starting with this scope. The result is either | 517 // Lookup a variable starting with this scope. The result is either |
515 // the statically resolved (local!) variable belonging to an outer scope, | 518 // the statically resolved (local!) variable belonging to an outer scope, |
516 // or NULL. It may be NULL because a) we couldn't find a variable, or b) | 519 // or NULL. It may be NULL because a) we couldn't find a variable, or b) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 // that the variable might be introduced dynamically (through | 615 // that the variable might be introduced dynamically (through |
613 // a local or outer eval() call, or an outer 'with' statement), | 616 // a local or outer eval() call, or an outer 'with' statement), |
614 // or we don't know about the outer scope (because we are | 617 // or we don't know about the outer scope (because we are |
615 // in an eval scope). | 618 // in an eval scope). |
616 if (is_global_scope() || | 619 if (is_global_scope() || |
617 !(scope_inside_with_ || outer_scope_is_eval_scope_ || | 620 !(scope_inside_with_ || outer_scope_is_eval_scope_ || |
618 scope_calls_eval_ || outer_scope_calls_eval_)) { | 621 scope_calls_eval_ || outer_scope_calls_eval_)) { |
619 // We must have a global variable. | 622 // We must have a global variable. |
620 ASSERT(global_scope != NULL); | 623 ASSERT(global_scope != NULL); |
621 var = new Variable(global_scope, proxy->name(), | 624 var = new Variable(global_scope, proxy->name(), |
622 Variable::DYNAMIC, true, false); | 625 Variable::DYNAMIC, true, Variable::NORMAL); |
623 | 626 |
624 } else if (scope_inside_with_) { | 627 } else if (scope_inside_with_) { |
625 // If we are inside a with statement we give up and look up | 628 // If we are inside a with statement we give up and look up |
626 // the variable at runtime. | 629 // the variable at runtime. |
627 var = NonLocal(proxy->name(), Variable::DYNAMIC); | 630 var = NonLocal(proxy->name(), Variable::DYNAMIC); |
628 | 631 |
629 } else if (invalidated_local != NULL) { | 632 } else if (invalidated_local != NULL) { |
630 // No with statements are involved and we found a local | 633 // No with statements are involved and we found a local |
631 // variable that might be shadowed by eval introduced | 634 // variable that might be shadowed by eval introduced |
632 // variables. | 635 // variables. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 // and bind the corresponding proxy. It's ok to declare it only now | 793 // and bind the corresponding proxy. It's ok to declare it only now |
791 // because it's a local variable that is allocated after the parameters | 794 // because it's a local variable that is allocated after the parameters |
792 // have been allocated. | 795 // have been allocated. |
793 // | 796 // |
794 // Note: This is "almost" at temporary variable but we cannot use | 797 // Note: This is "almost" at temporary variable but we cannot use |
795 // NewTemporary() because the mode needs to be INTERNAL since this | 798 // NewTemporary() because the mode needs to be INTERNAL since this |
796 // variable may be allocated in the heap-allocated context (temporaries | 799 // variable may be allocated in the heap-allocated context (temporaries |
797 // are never allocated in the context). | 800 // are never allocated in the context). |
798 Variable* arguments_shadow = | 801 Variable* arguments_shadow = |
799 new Variable(this, Factory::arguments_shadow_symbol(), | 802 new Variable(this, Factory::arguments_shadow_symbol(), |
800 Variable::INTERNAL, true, false); | 803 Variable::INTERNAL, true, Variable::ARGUMENTS); |
801 arguments_shadow_ = | 804 arguments_shadow_ = |
802 new VariableProxy(Factory::arguments_shadow_symbol(), false, false); | 805 new VariableProxy(Factory::arguments_shadow_symbol(), false, false); |
803 arguments_shadow_->BindTo(arguments_shadow); | 806 arguments_shadow_->BindTo(arguments_shadow); |
804 temps_.Add(arguments_shadow); | 807 temps_.Add(arguments_shadow); |
805 | 808 |
806 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. | 809 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. |
807 for (int i = 0; i < params_.length(); i++) { | 810 for (int i = 0; i < params_.length(); i++) { |
808 Variable* var = params_[i]; | 811 Variable* var = params_[i]; |
809 ASSERT(var->scope() == this); | 812 ASSERT(var->scope() == this); |
810 if (MustAllocate(var)) { | 813 if (MustAllocate(var)) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 935 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
933 !must_have_local_context) { | 936 !must_have_local_context) { |
934 num_heap_slots_ = 0; | 937 num_heap_slots_ = 0; |
935 } | 938 } |
936 | 939 |
937 // Allocation done. | 940 // Allocation done. |
938 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 941 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
939 } | 942 } |
940 | 943 |
941 } } // namespace v8::internal | 944 } } // namespace v8::internal |
OLD | NEW |