| 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 |