| 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();
|
|
|
|
|