Chromium Code Reviews| Index: src/scopes.cc |
| diff --git a/src/scopes.cc b/src/scopes.cc |
| index 4ac9d0e6a463047319ef43317ebd6551b798e110..f9a882d2f5771ef1ccad54ff63085ff3115a3de4 100644 |
| --- a/src/scopes.cc |
| +++ b/src/scopes.cc |
| @@ -119,6 +119,10 @@ Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone) |
| already_resolved_(false), |
| zone_(zone) { |
| SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); |
| + if (!is_function_scope() && |
|
Michael Starzinger
2013/04/05 11:38:42
I would feel more comfortable if we could move thi
wingo
2013/04/05 12:25:06
Done. I assume you meant !is_function_scope() her
Michael Starzinger
2013/04/05 13:06:56
Yep, that was a typo on my end.
|
| + outer_scope && |
| + outer_scope->has_forced_context_allocation()) |
| + ForceContextAllocation(); |
| // The outermost scope must be a global scope. |
| ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL); |
| ASSERT(!HasIllegalRedeclaration()); |
| @@ -197,6 +201,7 @@ void Scope::SetDefaults(ScopeType type, |
| outer_scope_calls_non_strict_eval_ = false; |
| inner_scope_calls_eval_ = false; |
| force_eager_compilation_ = false; |
| + force_context_allocation_ = false; |
| num_var_or_const_ = 0; |
| num_stack_slots_ = 0; |
| num_heap_slots_ = 0; |
| @@ -603,12 +608,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 +1193,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; |