Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index 7687a4cbb6dc69fe12dcf5e6285a4321100d5052..3c36dc3c0c54181ae58b6cde3bb49068ab2a66a2 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -163,7 +163,6 @@ void Scope::SetDefaults(ScopeType scope_type, |
scope_uses_arguments_ = false; |
scope_uses_super_property_ = false; |
scope_uses_super_constructor_call_ = false; |
- scope_uses_this_ = false; |
asm_module_ = false; |
asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
// Inherit the strict mode from the parent scope. |
@@ -171,7 +170,6 @@ void Scope::SetDefaults(ScopeType scope_type, |
outer_scope_calls_sloppy_eval_ = false; |
inner_scope_calls_eval_ = false; |
inner_scope_uses_arguments_ = false; |
- inner_scope_uses_this_ = false; |
inner_scope_uses_super_property_ = false; |
inner_scope_uses_super_constructor_call_ = false; |
force_eager_compilation_ = false; |
@@ -310,7 +308,7 @@ void Scope::Initialize() { |
// 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()) { |
+ if (has_this_declaration()) { |
Variable* var = |
variables_.Declare(this, |
ast_value_factory_->this_string(), |
@@ -318,11 +316,7 @@ void Scope::Initialize() { |
false, |
Variable::THIS, |
kCreatedInitialized); |
- var->AllocateTo(Variable::PARAMETER, -1); |
receiver_ = var; |
- } else { |
- DCHECK(outer_scope() != NULL); |
- receiver_ = outer_scope()->receiver(); |
} |
if (is_function_scope()) { |
@@ -370,7 +364,6 @@ Scope* Scope::FinalizeBlockScope() { |
if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage(); |
if (uses_super_constructor_call()) |
outer_scope_->RecordSuperConstructorCallUsage(); |
- if (uses_this()) outer_scope_->RecordThisUsage(); |
return NULL; |
} |
@@ -894,7 +887,6 @@ void Scope::Print(int n) { |
Indent(n1, "// scope uses 'super' property\n"); |
if (scope_uses_super_constructor_call_) |
Indent(n1, "// scope uses 'super' constructor\n"); |
- if (scope_uses_this_) Indent(n1, "// scope uses 'this'\n"); |
if (inner_scope_uses_arguments_) { |
Indent(n1, "// inner scope uses 'arguments'\n"); |
} |
@@ -903,7 +895,6 @@ void Scope::Print(int n) { |
if (inner_scope_uses_super_constructor_call_) { |
Indent(n1, "// inner scope uses 'super' constructor\n"); |
} |
- if (inner_scope_uses_this_) Indent(n1, "// inner scope uses 'this'\n"); |
if (outer_scope_calls_sloppy_eval_) { |
Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
} |
@@ -1183,10 +1174,8 @@ void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { |
inner->inner_scope_uses_super_constructor_call_) { |
inner_scope_uses_super_constructor_call_ = true; |
} |
- if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) { |
- inner_scope_uses_this_ = true; |
- } |
} |
+ |
wingo
2015/02/04 10:02:13
extra whitespace
aperez
2015/02/04 21:00:42
Acknowledged.
|
if (inner->force_eager_compilation_) { |
force_eager_compilation_ = true; |
} |
@@ -1213,8 +1202,9 @@ bool Scope::MustAllocate(Variable* var) { |
var->set_is_used(); |
if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
} |
- // Global variables do not need to be allocated. |
- return !var->IsGlobalObjectProperty() && var->is_used(); |
+ // Global variables do not need to be allocated, except the receiver |
+ // which is not preallocated. |
wingo
2015/02/04 10:02:13
Confusing comment. Also I think the conditional
aperez
2015/02/04 21:00:42
Acknowledged.
|
+ return (var->is_this() || !var->IsGlobalObjectProperty()) && var->is_used(); |
} |
@@ -1299,18 +1289,34 @@ void Scope::AllocateParameterLocals() { |
// 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::AllocateReceiver() { |
+ DCHECK(receiver()); |
+ DCHECK(receiver()->scope() == this); |
wingo
2015/02/04 10:02:13
the second DCHECK is sufficient, I think, if we ad
aperez
2015/02/04 21:00:42
Acknowledged.
|
+ |
+ if (has_forced_context_allocation()) { |
+ // Force context allocation of the receiver. |
+ receiver()->ForceContextAllocation(); |
+ } |
+ AllocateParameter(receiver(), -1); |
+} |
+ |
+ |
+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); |
} |
} |
} |
@@ -1379,6 +1385,7 @@ void Scope::AllocateVariablesRecursively() { |
// Allocate variables for this scope. |
// Parameters must be allocated first, if any. |
+ if (has_this_declaration()) AllocateReceiver(); |
if (is_function_scope()) AllocateParameterLocals(); |
AllocateNonParameterLocals(); |