Chromium Code Reviews| Index: src/scopes.cc |
| diff --git a/src/scopes.cc b/src/scopes.cc |
| index 58a10ee346401d9ba6bac3c49e24a490f4d81140..28664d649414102987f47024b0dee36bc2d657fa 100644 |
| --- a/src/scopes.cc |
| +++ b/src/scopes.cc |
| @@ -154,6 +154,25 @@ Scope::Scope(Scope* inner_scope, SerializedScopeInfo* scope_info) |
| if (scope_info->HasHeapAllocatedLocals()) { |
| num_heap_slots_ = scope_info_->NumberOfContextSlots(); |
| } |
| + |
| + // arguments shadow would be saved to the list of context slots |
| + // only if inner scopes access some parameters. Prepare to |
| + // this situation by allocating arguments_shadow_ object |
| + // and thread access to this scope's parameters via arguments shadow. |
|
Kevin Millikin (Chromium)
2011/01/19 07:39:57
Suggested rewording, something like:
This scope's
antonm
2011/01/19 08:18:19
Done.
|
| + Variable::Mode mode; |
| + int arguments_shadow_index = |
| + scope_info_->ContextSlotIndex(Heap::arguments_shadow_symbol(), &mode); |
| + if (arguments_shadow_index >= 0) { |
| + ASSERT(mode == Variable::INTERNAL); |
| + arguments_shadow_ = new Variable(this, |
| + Factory::arguments_shadow_symbol(), |
| + Variable::INTERNAL, |
| + true, |
| + Variable::ARGUMENTS); |
| + arguments_shadow_->set_rewrite( |
| + new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index)); |
| + arguments_shadow_->set_is_used(true); |
| + } |
| } |
| @@ -245,15 +264,44 @@ Variable* Scope::LocalLookup(Handle<String> name) { |
| // Check context slot lookup. |
| Variable::Mode mode; |
| int index = scope_info_->ContextSlotIndex(*name, &mode); |
| - if (index < 0) { |
| - return NULL; |
| + if (index >= 0) { |
| + // Check that there is no local slot with the given name. |
| + ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
|
Kevin Millikin (Chromium)
2011/01/19 07:39:57
This assert could be lifted higher (up to the prev
antonm
2011/01/19 08:18:19
Done.
|
| + Variable* var = |
| + variables_.Declare(this, name, mode, true, Variable::NORMAL); |
| + var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); |
| + return var; |
| } |
| - // Check that there is no local slot with the given name. |
| - ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
| - Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL); |
| - var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); |
| - return var; |
| + index = scope_info_->ParameterIndex(*name); |
| + if (index >= 0) { |
| + // ".arguments" must be present in context slots. |
| + ASSERT(arguments_shadow_ != NULL); |
| + // Check that there is no local slot with the given name. |
| + ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
| + Variable* var = |
| + variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL); |
| + Property* rewrite = |
| + new Property(new VariableProxy(arguments_shadow_), |
| + new Literal(Handle<Object>(Smi::FromInt(index))), |
|
Kevin Millikin (Chromium)
2011/01/19 07:39:57
Indentation is a bit off here.
antonm
2011/01/19 08:18:19
Done.
|
| + RelocInfo::kNoPosition, |
| + Property::SYNTHETIC); |
| + rewrite->set_is_arguments_access(true); |
| + var->set_rewrite(rewrite); |
| + return var; |
| + } |
| + |
| + index = scope_info_->FunctionContextSlotIndex(*name); |
| + if (index >= 0) { |
| + // Check that there is no local slot with the given name. |
| + ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
| + Variable* var = |
| + variables_.Declare(this, name, mode, true, Variable::NORMAL); |
|
Kevin Millikin (Chromium)
2011/01/19 07:39:57
Will this be the right mode?
antonm
2011/01/19 08:18:19
Oops, thanks a lot for spotting this. Now passing
|
| + var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); |
| + return var; |
| + } |
| + |
| + return NULL; |
| } |