Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index b796452e00589b17b837a0eb6b5224885d9c389b..4e0b5c2f8b7551bf0a404801819dea806047875e 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -309,12 +309,13 @@ void Scope::Initialize() { |
// invoking scripts |
if (is_declaration_scope()) { |
DCHECK(!subclass_constructor || is_function_scope()); |
- 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 (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; |
+ } |
if (subclass_constructor) { |
new_target_ = |
@@ -323,9 +324,6 @@ void Scope::Initialize() { |
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()) { |
@@ -1338,24 +1336,40 @@ void Scope::AllocateParameterLocals(Isolate* isolate) { |
// Force context allocation of the parameter. |
var->ForceContextAllocation(); |
} |
+ AllocateParameter(var, i); |
+ } |
+} |
- 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); |
- } |
+ |
+void Scope::AllocateParameter(Variable* var, int index) { |
+ 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, 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); |
+} |
+ |
+ |
void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { |
DCHECK(var->scope() == this); |
DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || |
@@ -1423,6 +1437,7 @@ void Scope::AllocateVariablesRecursively(Isolate* isolate) { |
// 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' |