Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(813)

Unified Diff: src/scopes.cc

Issue 883823002: Implement proper scoping for "this" in arrow functions Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make sure an unresolved VariableProxy for "this" is not considered a valid LHS Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/scopes.h ('K') | « src/scopes.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« src/scopes.h ('K') | « src/scopes.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698