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