Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index 4ac9d0e6a463047319ef43317ebd6551b798e110..10548f99381e933d3dc9ccd3063e25fdea38c378 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -197,6 +197,8 @@ void Scope::SetDefaults(ScopeType type, |
outer_scope_calls_non_strict_eval_ = false; |
inner_scope_calls_eval_ = false; |
force_eager_compilation_ = false; |
+ force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) |
+ ? outer_scope->has_forced_context_allocation() : false; |
num_var_or_const_ = 0; |
num_stack_slots_ = 0; |
num_heap_slots_ = 0; |
@@ -603,12 +605,18 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
} |
} |
- // Collect temporaries which are always allocated on the stack. |
+ // Collect temporaries which are always allocated on the stack, unless the |
+ // context as a whole has forced context allocation. |
for (int i = 0; i < temps_.length(); i++) { |
Variable* var = temps_[i]; |
if (var->is_used()) { |
- ASSERT(var->IsStackLocal()); |
- stack_locals->Add(var, zone()); |
+ if (var->IsContextSlot()) { |
+ ASSERT(has_forced_context_allocation()); |
+ context_locals->Add(var, zone()); |
+ } else { |
+ ASSERT(var->IsStackLocal()); |
+ stack_locals->Add(var, zone()); |
+ } |
} |
} |
@@ -1182,8 +1190,11 @@ bool Scope::MustAllocateInContext(Variable* var) { |
// an eval() call or a runtime with lookup), it must be allocated in the |
// context. |
// |
- // Exceptions: temporary variables are never allocated in a context; |
- // catch-bound variables are always allocated in a context. |
+ // Exceptions: If the scope as a whole has forced context allocation, all |
+ // variables will have context allocation, even temporaries. Otherwise |
+ // temporary variables are always stack-allocated. Catch-bound variables are |
+ // always context-allocated. |
+ if (has_forced_context_allocation()) return true; |
if (var->mode() == TEMPORARY) return false; |
if (var->mode() == INTERNAL) return true; |
if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |