| Index: src/scopes.cc
|
| diff --git a/src/scopes.cc b/src/scopes.cc
|
| index 39b67a886444fe1db46a54e4006d37abd68d447a..cbb0d5dfe8f855e79eca7825c3f1f366ec1ffd80 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 copied in the context.
|
| + 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++) {
|
| @@ -1178,25 +1184,40 @@ void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) {
|
| if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) {
|
| inner_scope_calls_eval_ = true;
|
| }
|
| +
|
| // 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->scope_uses_arguments_ || inner->inner_scope_uses_arguments_) {
|
| + if (inner->is_arrow_scope()) {
|
| + if (inner->scope_uses_this_ || inner->inner_scope_uses_this_)
|
| + inner_scope_uses_this_ = true;
|
| + if (inner->scope_uses_arguments_ || inner->inner_scope_uses_arguments_)
|
| inner_scope_uses_arguments_ = true;
|
| - }
|
| if (inner->scope_uses_super_property_ ||
|
| - inner->inner_scope_uses_super_property_) {
|
| + inner->inner_scope_uses_super_property_)
|
| inner_scope_uses_super_property_ = true;
|
| - }
|
| if (inner->uses_super_constructor_call() ||
|
| - inner->inner_scope_uses_super_constructor_call_) {
|
| + inner->inner_scope_uses_super_constructor_call_)
|
| inner_scope_uses_super_constructor_call_ = true;
|
| - }
|
| - if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) {
|
| + } else if (!inner->is_function_scope()) {
|
| + if (inner->scope_uses_this_)
|
| + 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_this_)
|
| inner_scope_uses_this_ = 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->force_eager_compilation_) {
|
| force_eager_compilation_ = true;
|
| }
|
| @@ -1324,6 +1345,18 @@ void Scope::AllocateParameterLocals() {
|
| }
|
| }
|
| }
|
| +
|
| + // If the scope contains at least one inner arrow function which uses
|
| + // "this", the receiver must be copied to the context, from where it will
|
| + // be looked 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_));
|
| + }
|
| }
|
|
|
|
|
|
|