Chromium Code Reviews| Index: src/scopes.cc |
| diff --git a/src/scopes.cc b/src/scopes.cc |
| index 39b67a886444fe1db46a54e4006d37abd68d447a..01cc24eeeae5ac9cd6e647586d62d824a865c376 100644 |
| --- a/src/scopes.cc |
| +++ b/src/scopes.cc |
| @@ -609,6 +609,12 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
| } |
| } |
| + // Arrow functions can cause the receiver to be collected in the context. |
|
wingo
2015/01/15 10:09:06
"allocated". And really it's "copied to" the cont
aperez
2015/01/15 16:58:03
Done.
|
| + if (receiver_ && receiver_->has_forced_context_allocation()) { |
| + DCHECK(receiver_->IsContextSlot()); |
| + context_locals->Add(receiver_, zone()); |
| + } |
| + |
| // 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++) { |
| @@ -1181,7 +1187,7 @@ void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { |
| // If the inner scope is an arrow function, propagate the flags tracking |
| // usage of arguments/super/this, but do not propagate them out from normal |
| // functions. |
| - if (!inner->is_function_scope() || inner->is_arrow_scope()) { |
| + if (inner->is_arrow_scope()) { |
| if (inner->scope_uses_arguments_ || inner->inner_scope_uses_arguments_) { |
| inner_scope_uses_arguments_ = true; |
| } |
| @@ -1196,12 +1202,38 @@ void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { |
| if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) { |
| inner_scope_uses_this_ = true; |
| } |
| - } |
| - if (inner->force_eager_compilation_) { |
| - force_eager_compilation_ = true; |
| - } |
| - if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) { |
| - inner->asm_function_ = true; |
| + } else if (inner->is_block_scope()) { |
| + if (inner->scope_uses_this_) { |
|
wingo
2015/01/15 10:09:06
Why do we need the whole list of these? At some p
aperez
2015/01/15 16:58:03
I have been trying to factor out the flag propagat
|
| + scope_uses_this_ = true; |
| + } |
| + if (inner->scope_uses_arguments_) { |
| + scope_uses_arguments_ = true; |
| + } |
| + if (inner->scope_uses_super_property_) { |
| + scope_uses_super_property_ = true; |
| + } |
| + if (inner->scope_uses_super_constructor_call_) { |
| + scope_uses_super_constructor_call_ = true; |
| + } |
| + if (inner->inner_scope_uses_arguments_) { |
| + inner_scope_uses_arguments_ = true; |
| + } |
| + if (inner->inner_scope_uses_super_property_) { |
| + inner_scope_uses_super_property_ = true; |
| + } |
| + if (inner->inner_scope_uses_super_constructor_call_) { |
| + inner_scope_uses_super_constructor_call_ = true; |
| + } |
| + if (inner->inner_scope_uses_this_) { |
| + inner_scope_uses_this_ = true; |
| + } |
| + } else if (!inner->is_function_scope() || inner->is_arrow_scope()) { |
| + if (inner->force_eager_compilation_) { |
| + force_eager_compilation_ = true; |
| + } |
|
wingo
2015/01/15 10:09:05
These propagations should run for all scopes
aperez
2015/01/15 16:58:03
Done.
|
| + if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) { |
| + inner->asm_function_ = true; |
| + } |
| } |
| } |
| } |
| @@ -1324,6 +1356,18 @@ void Scope::AllocateParameterLocals() { |
| } |
| } |
| } |
| + |
| + // If the scope contains at least one inner arrow function which uses |
| + // "this", it must be copied in the context, from where it will be looked |
|
wingo
2015/01/15 10:09:06
s/it must be copied in/the receiver must be copied
aperez
2015/01/15 16:58:03
Done.
|
| + // up by code emitted in the prologues of arrow functions. |
| + if (inner_scope_uses_this_) { |
| + DCHECK(receiver_); |
| + if (receiver_->IsUnallocated() || !receiver_->IsContextSlot()) { |
| + receiver_->ForceContextAllocation(); |
| + AllocateHeapSlot(receiver_); |
| + } |
| + DCHECK(MustAllocateInContext(receiver_)); |
| + } |
| } |