Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index 80bf82b6b60277627ece3d20b51e1f35da774d78..10bf867911551707ee36a78dcf5e7330c48758f5 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -31,7 +31,7 @@ VariableMap::~VariableMap() {} |
Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, |
- VariableMode mode, bool is_valid_lhs, |
+ VariableMode mode, |
Variable::Kind kind, |
InitializationFlag initialization_flag, |
MaybeAssignedFlag maybe_assigned_flag, |
@@ -45,7 +45,7 @@ Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, |
// The variable has not been declared yet -> insert it. |
DCHECK(p->key == name); |
p->value = new (zone()) |
- Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag, |
+ Variable(scope, name, mode, kind, initialization_flag, |
maybe_assigned_flag, interface); |
} |
return reinterpret_cast<Variable*>(p->value); |
@@ -137,7 +137,6 @@ Scope::Scope(Isolate* isolate, Zone* zone, Scope* inner_scope, |
Variable* variable = variables_.Declare(this, |
catch_variable_name, |
VAR, |
- true, // Valid left-hand side. |
Variable::NORMAL, |
kCreatedInitialized); |
AllocateHeapSlot(variable); |
@@ -161,7 +160,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. |
@@ -169,7 +167,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,19 +307,14 @@ 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(), |
VAR, |
- false, |
Variable::THIS, |
kCreatedInitialized); |
- var->AllocateTo(Variable::PARAMETER, -1); |
receiver_ = var; |
- } else { |
- DCHECK(outer_scope() != NULL); |
- receiver_ = outer_scope()->receiver(); |
} |
if (is_function_scope()) { |
@@ -332,7 +324,6 @@ void Scope::Initialize() { |
variables_.Declare(this, |
ast_value_factory_->arguments_string(), |
VAR, |
- true, |
Variable::ARGUMENTS, |
kCreatedInitialized); |
} |
@@ -370,7 +361,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; |
} |
@@ -410,7 +400,7 @@ Variable* Scope::LookupLocal(const AstRawString* name) { |
maybe_assigned_flag = kMaybeAssigned; |
} |
- Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
+ Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL, |
init_flag, maybe_assigned_flag); |
var->AllocateTo(location, index); |
return var; |
@@ -426,9 +416,8 @@ Variable* Scope::LookupFunctionVar(const AstRawString* name, |
VariableMode mode; |
int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
if (index < 0) return NULL; |
- Variable* var = new(zone()) Variable( |
- this, name, mode, true /* is valid LHS */, |
- Variable::NORMAL, kCreatedInitialized); |
+ Variable* var = new(zone()) Variable(this, name, |
+ mode, Variable::NORMAL, kCreatedInitialized); |
VariableProxy* proxy = factory->NewVariableProxy(var); |
VariableDeclaration* declaration = factory->NewVariableDeclaration( |
proxy, mode, this, RelocInfo::kNoPosition); |
@@ -456,7 +445,7 @@ Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, |
bool is_rest) { |
DCHECK(!already_resolved()); |
DCHECK(is_function_scope()); |
- Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
+ Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL, |
kCreatedInitialized); |
if (is_rest) { |
DCHECK_NULL(rest_parameter_); |
@@ -478,7 +467,7 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
// explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
DCHECK(IsDeclaredVariableMode(mode)); |
++num_var_or_const_; |
- return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, |
+ return variables_.Declare(this, name, mode, Variable::NORMAL, init_flag, |
maybe_assigned_flag, interface); |
} |
@@ -488,7 +477,6 @@ Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
return variables_.Declare(this, |
name, |
DYNAMIC_GLOBAL, |
- true, |
Variable::NORMAL, |
kCreatedInitialized); |
} |
@@ -511,7 +499,6 @@ Variable* Scope::NewInternal(const AstRawString* name) { |
Variable* var = new(zone()) Variable(this, |
name, |
INTERNAL, |
- false, |
Variable::NORMAL, |
kCreatedInitialized); |
internals_.Add(var, zone()); |
@@ -524,7 +511,6 @@ Variable* Scope::NewTemporary(const AstRawString* name) { |
Variable* var = new(zone()) Variable(this, |
name, |
TEMPORARY, |
- true, |
Variable::NORMAL, |
kCreatedInitialized); |
temps_.Add(var, zone()); |
@@ -900,7 +886,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"); |
} |
@@ -909,7 +894,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"); |
} |
@@ -975,7 +959,6 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
var = map->Declare(NULL, |
name, |
mode, |
- true, |
Variable::NORMAL, |
init_flag); |
// Allocate it by giving it a dynamic lookup. |
@@ -1189,9 +1172,6 @@ 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; |
- } |
} |
if (inner->force_eager_compilation_) { |
force_eager_compilation_ = true; |
@@ -1220,7 +1200,7 @@ bool Scope::MustAllocate(Variable* var) { |
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(); |
+ return var->is_this() || (var->is_used() && !var->IsGlobalObjectProperty()); |
} |
@@ -1311,18 +1291,33 @@ 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_EQ(receiver()->scope(), this); |
+ |
+ 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); |
} |
} |
} |
@@ -1395,6 +1390,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(); |