OLD | NEW |
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 params_(4), | 147 params_(4), |
148 unresolved_(16), | 148 unresolved_(16), |
149 decls_(4) { | 149 decls_(4) { |
150 ASSERT(scope_info != NULL); | 150 ASSERT(scope_info != NULL); |
151 SetDefaults(FUNCTION_SCOPE, inner_scope->outer_scope(), scope_info); | 151 SetDefaults(FUNCTION_SCOPE, inner_scope->outer_scope(), scope_info); |
152 ASSERT(resolved()); | 152 ASSERT(resolved()); |
153 InsertAfterScope(inner_scope); | 153 InsertAfterScope(inner_scope); |
154 if (scope_info->HasHeapAllocatedLocals()) { | 154 if (scope_info->HasHeapAllocatedLocals()) { |
155 num_heap_slots_ = scope_info_->NumberOfContextSlots(); | 155 num_heap_slots_ = scope_info_->NumberOfContextSlots(); |
156 } | 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 } |
157 } | 175 } |
158 | 176 |
159 | 177 |
160 | 178 |
161 bool Scope::Analyze(CompilationInfo* info) { | 179 bool Scope::Analyze(CompilationInfo* info) { |
162 ASSERT(info->function() != NULL); | 180 ASSERT(info->function() != NULL); |
163 Scope* top = info->function()->scope(); | 181 Scope* top = info->function()->scope(); |
164 | 182 |
165 // If we have a serialized scope info, reuse it. | 183 // If we have a serialized scope info, reuse it. |
166 if (!info->closure().is_null()) { | 184 if (!info->closure().is_null()) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 250 |
233 | 251 |
234 Variable* Scope::LocalLookup(Handle<String> name) { | 252 Variable* Scope::LocalLookup(Handle<String> name) { |
235 Variable* result = variables_.Lookup(name); | 253 Variable* result = variables_.Lookup(name); |
236 if (result != NULL || !resolved()) { | 254 if (result != NULL || !resolved()) { |
237 return result; | 255 return result; |
238 } | 256 } |
239 // If the scope is resolved, we can find a variable in serialized scope info. | 257 // If the scope is resolved, we can find a variable in serialized scope info. |
240 | 258 |
241 // We should never lookup 'arguments' in this scope | 259 // We should never lookup 'arguments' in this scope |
242 // as it is impllicitly present in any scope. | 260 // as it is implicitly present in any scope. |
243 ASSERT(*name != *Factory::arguments_symbol()); | 261 ASSERT(*name != *Factory::arguments_symbol()); |
244 | 262 |
| 263 // Assert that there is no local slot with the given name. |
| 264 ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
| 265 |
245 // Check context slot lookup. | 266 // Check context slot lookup. |
246 Variable::Mode mode; | 267 Variable::Mode mode; |
247 int index = scope_info_->ContextSlotIndex(*name, &mode); | 268 int index = scope_info_->ContextSlotIndex(*name, &mode); |
248 if (index < 0) { | 269 if (index >= 0) { |
249 return NULL; | 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; |
250 } | 274 } |
251 | 275 |
252 // Check that there is no local slot with the given name. | 276 index = scope_info_->ParameterIndex(*name); |
253 ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 277 if (index >= 0) { |
254 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL); | 278 // ".arguments" must be present in context slots. |
255 var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); | 279 ASSERT(arguments_shadow_ != NULL); |
256 return var; | 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; |
257 } | 303 } |
258 | 304 |
259 | 305 |
260 Variable* Scope::Lookup(Handle<String> name) { | 306 Variable* Scope::Lookup(Handle<String> name) { |
261 for (Scope* scope = this; | 307 for (Scope* scope = this; |
262 scope != NULL; | 308 scope != NULL; |
263 scope = scope->outer_scope()) { | 309 scope = scope->outer_scope()) { |
264 Variable* var = scope->LocalLookup(name); | 310 Variable* var = scope->LocalLookup(name); |
265 if (var != NULL) return var; | 311 if (var != NULL) return var; |
266 } | 312 } |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 1055 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
1010 !must_have_local_context) { | 1056 !must_have_local_context) { |
1011 num_heap_slots_ = 0; | 1057 num_heap_slots_ = 0; |
1012 } | 1058 } |
1013 | 1059 |
1014 // Allocation done. | 1060 // Allocation done. |
1015 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1061 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1016 } | 1062 } |
1017 | 1063 |
1018 } } // namespace v8::internal | 1064 } } // namespace v8::internal |
OLD | NEW |