Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index 3565e11b58f710e280f1080c0fb479e5e01376f9..6aa682571d6c53082829ea4626e24f25af011faf 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -135,7 +135,8 @@ Scope::Scope(Type type) |
outer_scope_is_eval_scope_(false), |
force_eager_compilation_(false), |
num_stack_slots_(0), |
- num_heap_slots_(0) { |
+ num_heap_slots_(0), |
+ resolved_(false) { |
} |
@@ -162,7 +163,8 @@ Scope::Scope(Scope* outer_scope, Type type) |
outer_scope_is_eval_scope_(false), |
force_eager_compilation_(false), |
num_stack_slots_(0), |
- num_heap_slots_(0) { |
+ num_heap_slots_(0), |
+ resolved_(false) { |
// At some point we might want to provide outer scopes to |
// eval scopes (by walking the stack and reading the scope info). |
// In that case, the ASSERT below needs to be adjusted. |
@@ -210,7 +212,7 @@ void Scope::Initialize(bool inside_with) { |
Variable* var = |
variables_.Declare(this, Factory::this_symbol(), Variable::VAR, |
false, Variable::THIS); |
- var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); |
+ var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); |
receiver_ = var; |
if (is_function_scope()) { |
@@ -550,7 +552,7 @@ Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { |
// Declare a new non-local. |
var = map->Declare(NULL, name, mode, true, Variable::NORMAL); |
// Allocate it by giving it a dynamic lookup. |
- var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); |
+ var->set_rewrite(new Slot(var, Slot::LOOKUP, -1)); |
} |
return var; |
} |
@@ -612,8 +614,9 @@ Variable* Scope::LookupRecursive(Handle<String> name, |
ASSERT(var != NULL); |
// If this is a lookup from an inner scope, mark the variable. |
- if (inner_lookup) |
- var->is_accessed_from_inner_scope_ = true; |
+ if (inner_lookup) { |
+ var->MarkAsAccessedFromInnerScope(); |
+ } |
// If the variable we have found is just a guess, invalidate the |
// result. If the found variable is local, record that fact so we |
@@ -753,7 +756,7 @@ bool Scope::MustAllocate(Variable* var) { |
// via an eval() call. This is only possible if the variable has a |
// visible name. |
if ((var->is_this() || var->name()->length() > 0) && |
- (var->is_accessed_from_inner_scope_ || |
+ (var->is_accessed_from_inner_scope() || |
scope_calls_eval_ || inner_scope_calls_eval_ || |
scope_contains_with_)) { |
var->set_is_used(true); |
@@ -771,7 +774,7 @@ bool Scope::MustAllocateInContext(Variable* var) { |
// context. |
return |
var->mode() != Variable::TEMPORARY && |
- (var->is_accessed_from_inner_scope_ || |
+ (var->is_accessed_from_inner_scope() || |
scope_calls_eval_ || inner_scope_calls_eval_ || |
scope_contains_with_ || var->is_global()); |
} |
@@ -787,12 +790,12 @@ bool Scope::HasArgumentsParameter() { |
void Scope::AllocateStackSlot(Variable* var) { |
- var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++); |
+ var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++)); |
} |
void Scope::AllocateHeapSlot(Variable* var) { |
- var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++); |
+ var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++)); |
} |
@@ -857,7 +860,7 @@ void Scope::AllocateParameterLocals() { |
// It is ok to set this only now, because arguments is a local |
// variable that is allocated after the parameters have been |
// allocated. |
- arguments_shadow_->is_accessed_from_inner_scope_ = true; |
+ arguments_shadow_->MarkAsAccessedFromInnerScope(); |
} |
Property* rewrite = |
new Property(new VariableProxy(arguments_shadow_), |
@@ -865,7 +868,7 @@ void Scope::AllocateParameterLocals() { |
RelocInfo::kNoPosition, |
Property::SYNTHETIC); |
rewrite->set_is_arguments_access(true); |
- var->rewrite_ = rewrite; |
+ var->set_rewrite(rewrite); |
} |
} |
@@ -880,23 +883,23 @@ void Scope::AllocateParameterLocals() { |
ASSERT(var->scope() == this); |
if (MustAllocate(var)) { |
if (MustAllocateInContext(var)) { |
- ASSERT(var->rewrite_ == NULL || |
+ ASSERT(var->rewrite() == NULL || |
(var->AsSlot() != NULL && |
var->AsSlot()->type() == Slot::CONTEXT)); |
- if (var->rewrite_ == NULL) { |
+ if (var->rewrite() == NULL) { |
// Only set the heap allocation if the parameter has not |
// been allocated yet. |
AllocateHeapSlot(var); |
} |
} else { |
- ASSERT(var->rewrite_ == NULL || |
+ ASSERT(var->rewrite() == NULL || |
(var->AsSlot() != NULL && |
var->AsSlot()->type() == Slot::PARAMETER)); |
// Set the parameter index always, even if the parameter |
// was seen before! (We need to access the actual parameter |
// supplied for the last occurrence of a multiply declared |
// parameter.) |
- var->rewrite_ = new Slot(var, Slot::PARAMETER, i); |
+ var->set_rewrite(new Slot(var, Slot::PARAMETER, i)); |
} |
} |
} |
@@ -906,10 +909,10 @@ void Scope::AllocateParameterLocals() { |
void Scope::AllocateNonParameterLocal(Variable* var) { |
ASSERT(var->scope() == this); |
- ASSERT(var->rewrite_ == NULL || |
+ ASSERT(var->rewrite() == NULL || |
(!var->IsVariable(Factory::result_symbol())) || |
(var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); |
- if (var->rewrite_ == NULL && MustAllocate(var)) { |
+ if (var->rewrite() == NULL && MustAllocate(var)) { |
if (MustAllocateInContext(var)) { |
AllocateHeapSlot(var); |
} else { |
@@ -943,15 +946,18 @@ void Scope::AllocateNonParameterLocals() { |
void Scope::AllocateVariablesRecursively() { |
- // The number of slots required for variables. |
- num_stack_slots_ = 0; |
- num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
- |
// Allocate variables for inner scopes. |
for (int i = 0; i < inner_scopes_.length(); i++) { |
inner_scopes_[i]->AllocateVariablesRecursively(); |
} |
+ // If scope is already resolved, we still need to allocate |
+ // variables in inner scopes which might not had been resolved yet. |
+ if (resolved_) return; |
+ // The number of slots required for variables. |
+ num_stack_slots_ = 0; |
+ num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
+ |
// Allocate variables for this scope. |
// Parameters must be allocated first, if any. |
if (is_function_scope()) AllocateParameterLocals(); |