| Index: src/scopes.cc
|
| diff --git a/src/scopes.cc b/src/scopes.cc
|
| index 32bd4bfc41261485b9cbdeb3eb004e157b056c56..8b623f90ce908ac548bfd8ea46bdcf088121bbcf 100644
|
| --- a/src/scopes.cc
|
| +++ b/src/scopes.cc
|
| @@ -309,16 +309,22 @@
|
| scope_inside_with_ = is_with_scope();
|
| }
|
|
|
| - // Declare convenience variables and the receiver.
|
| + // Declare convenience variables.
|
| + // Declare and allocate receiver (even for the script scope, and even
|
| + // if naccesses_ == 0).
|
| + // NOTE: When loading parameters in the script scope, we must take
|
| + // care not to access them as properties of the global object, but
|
| + // instead load them directly from the stack. Currently, the only
|
| + // such parameter is 'this' which is passed on the stack when
|
| + // invoking scripts
|
| if (is_declaration_scope()) {
|
| DCHECK(!subclass_constructor || is_function_scope());
|
| - if (has_this_declaration()) {
|
| - Variable* var = variables_.Declare(
|
| - this, ast_value_factory_->this_string(),
|
| - subclass_constructor ? CONST : VAR, Variable::THIS,
|
| - subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
| - receiver_ = var;
|
| - }
|
| + Variable* var = variables_.Declare(
|
| + this, ast_value_factory_->this_string(),
|
| + subclass_constructor ? CONST : VAR, Variable::THIS,
|
| + subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
| + var->AllocateTo(Variable::PARAMETER, -1);
|
| + receiver_ = var;
|
|
|
| if (subclass_constructor) {
|
| new_target_ =
|
| @@ -327,6 +333,9 @@
|
| new_target_->AllocateTo(Variable::PARAMETER, -2);
|
| new_target_->set_is_used();
|
| }
|
| + } else {
|
| + DCHECK(outer_scope() != NULL);
|
| + receiver_ = outer_scope()->receiver();
|
| }
|
|
|
| if (is_function_scope() && !is_arrow_scope()) {
|
| @@ -1040,7 +1049,7 @@
|
| DCHECK(is_script_scope());
|
| }
|
|
|
| - if (is_with_scope() && (var == nullptr || !var->is_this())) {
|
| + if (is_with_scope()) {
|
| DCHECK(!already_resolved());
|
| // The current scope is a with scope, so the variable binding can not be
|
| // statically resolved. However, note that it was necessary to do a lookup
|
| @@ -1406,37 +1415,21 @@
|
| // Force context allocation of the parameter.
|
| var->ForceContextAllocation();
|
| }
|
| - AllocateParameter(var, i);
|
| - }
|
| -}
|
| -
|
| -
|
| -void Scope::AllocateParameter(Variable* var, int index) {
|
| - if (MustAllocate(var)) {
|
| - if (MustAllocateInContext(var)) {
|
| - DCHECK(var->IsUnallocated() || var->IsContextSlot());
|
| - if (var->IsUnallocated()) {
|
| - AllocateHeapSlot(var);
|
| +
|
| + if (MustAllocate(var)) {
|
| + if (MustAllocateInContext(var)) {
|
| + DCHECK(var->IsUnallocated() || var->IsContextSlot());
|
| + if (var->IsUnallocated()) {
|
| + AllocateHeapSlot(var);
|
| + }
|
| + } else {
|
| + DCHECK(var->IsUnallocated() || var->IsParameter());
|
| + if (var->IsUnallocated()) {
|
| + var->AllocateTo(Variable::PARAMETER, i);
|
| + }
|
| }
|
| - } else {
|
| - DCHECK(var->IsUnallocated() || var->IsParameter());
|
| - if (var->IsUnallocated()) {
|
| - var->AllocateTo(Variable::PARAMETER, index);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -void Scope::AllocateReceiver() {
|
| - DCHECK_NOT_NULL(receiver());
|
| - DCHECK_EQ(receiver()->scope(), this);
|
| -
|
| - if (has_forced_context_allocation()) {
|
| - // Force context allocation of the receiver.
|
| - receiver()->ForceContextAllocation();
|
| - }
|
| - AllocateParameter(receiver(), -1);
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -1509,7 +1502,6 @@
|
| // Allocate variables for this scope.
|
| // Parameters must be allocated first, if any.
|
| if (is_function_scope()) AllocateParameterLocals(isolate);
|
| - if (has_this_declaration()) AllocateReceiver();
|
| AllocateNonParameterLocals(isolate);
|
|
|
| // Force allocation of a context for this scope if necessary. For a 'with'
|
|
|