Clean up some messiness in Scopes.

For some reason, the scope's arguments and arguments shadow were
variable proxies, which resulted in all references to the arguments
shadow being shared in the AST.  This makes it hard to put per-node
state on the AST nodes.

I took the opportunity to remove Variable::AsVariable which has
confused people in the past, and to rename Variable::slot to the more
accurate Variable::AsSlot.

Review URL: http://codereview.chromium.org/3432022

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5517 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5e572e46
This diff is collapsed.
......@@ -100,7 +100,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Copy any necessary parameters into the context.
int num_parameters = scope()->num_parameters();
for (int i = 0; i < num_parameters; i++) {
Slot* slot = scope()->parameter(i)->slot();
Slot* slot = scope()->parameter(i)->AsSlot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
int parameter_offset = StandardFrameConstants::kCallerSPOffset +
(num_parameters - 1 - i) * kPointerSize;
......@@ -118,7 +118,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
}
}
Variable* arguments = scope()->arguments()->AsVariable();
Variable* arguments = scope()->arguments();
if (arguments != NULL) {
// Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object");
......@@ -143,9 +143,8 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
__ CallStub(&stub);
// Duplicate the value; move-to-slot operation might clobber registers.
__ mov(r3, r0);
Move(arguments->slot(), r0, r1, r2);
Slot* dot_arguments_slot =
scope()->arguments_shadow()->AsVariable()->slot();
Move(arguments->AsSlot(), r0, r1, r2);
Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
Move(dot_arguments_slot, r3, r1, r2);
}
......@@ -530,7 +529,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
FunctionLiteral* function) {
Comment cmnt(masm_, "[ Declaration");
ASSERT(variable != NULL); // Must have been resolved.
Slot* slot = variable->slot();
Slot* slot = variable->AsSlot();
Property* prop = variable->AsProperty();
if (slot != NULL) {
......@@ -924,7 +923,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
__ jmp(done);
} else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
if (potential_slot != NULL) {
// Generate fast case for locals that rewrite to slots.
......@@ -949,7 +948,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
// variables. Then load the argument from the arguments
// object using keyed load.
__ ldr(r1,
ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ mov(r0, Operand(key_literal->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
......@@ -1027,7 +1026,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Four cases: non-this global variables, lookup slots, all other
// types of slots, and parameters that rewrite to explicit property
// accesses on the arguments object.
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
Property* property = var->AsProperty();
if (var->is_global() && !var->is_this()) {
......@@ -1080,7 +1079,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Assert that the object is in a slot.
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(object_var);
Slot* object_slot = object_var->slot();
Slot* object_slot = object_var->AsSlot();
ASSERT_NOT_NULL(object_slot);
// Load the object.
......@@ -1489,7 +1488,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Left-hand sides that rewrite to explicit property accesses do not reach
// here.
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
ASSERT(var->is_global() || var->AsSlot() != NULL);
if (var->is_global()) {
ASSERT(!var->is_this());
......@@ -1505,7 +1504,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Perform the assignment for non-const variables and for initialization
// of const variables. Const assignments are simply skipped.
Label done;
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
......@@ -1785,14 +1784,14 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ ldr(r0, CodeGenerator::GlobalObject());
__ push(r0);
EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
} else if (var != NULL && var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::LOOKUP) {
// Call to a lookup slot (dynamically introduced variable).
Label slow, done;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLoadFromSlotFastCase(var->slot(),
EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
NOT_INSIDE_TYPEOF,
&slow,
&done);
......@@ -2782,8 +2781,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(true);
} else if (var != NULL &&
!var->is_global() &&
var->slot() != NULL &&
var->slot()->type() != Slot::LOOKUP) {
var->AsSlot() != NULL &&
var->AsSlot()->type() != Slot::LOOKUP) {
// Result of deleting non-global, non-dynamic variables is false.
// The subexpression does not have side effects.
context()->Plug(false);
......@@ -3068,13 +3067,13 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
EmitCallIC(ic, RelocInfo::CODE_TARGET);
context()->Plug(r0);
} else if (proxy != NULL &&
proxy->var()->slot() != NULL &&
proxy->var()->slot()->type() == Slot::LOOKUP) {
proxy->var()->AsSlot() != NULL &&
proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
Slot* slot = proxy->var()->slot();
Slot* slot = proxy->var()->AsSlot();
EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
......
......@@ -70,6 +70,16 @@ CountOperation* ExpressionStatement::StatementAsCountOperation() {
}
VariableProxy::VariableProxy(Variable* var)
: name_(var->name()),
var_(NULL), // Will be set by the call to BindTo.
is_this_(var->is_this()),
inside_with_(false),
is_trivial_(false) {
BindTo(var);
}
VariableProxy::VariableProxy(Handle<String> name,
bool is_this,
bool inside_with)
......
......@@ -948,6 +948,8 @@ class CatchExtensionObject: public Expression {
class VariableProxy: public Expression {
public:
explicit VariableProxy(Variable* var);
virtual void Accept(AstVisitor* v);
// Type testing & conversion
......@@ -960,7 +962,10 @@ class VariableProxy: public Expression {
}
Variable* AsVariable() {
return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
if (this == NULL || var_ == NULL) return NULL;
Expression* rewrite = var_->rewrite();
if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
return NULL;
}
virtual bool IsValidLeftHandSide() {
......
......@@ -289,7 +289,7 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
for (int i = 0; i < length; i++) {
Declaration* node = declarations->at(i);
Variable* var = node->proxy()->var();
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
// If it was not possible to allocate the variable at compile
// time, we need to "declare" it at runtime to make sure it
......@@ -310,7 +310,7 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
for (int j = 0, i = 0; i < length; i++) {
Declaration* node = declarations->at(i);
Variable* var = node->proxy()->var();
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
// Skip - already processed.
......
......@@ -125,7 +125,7 @@ Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) {
int AssignedVariablesAnalyzer::BitIndex(Variable* var) {
ASSERT(var != NULL);
ASSERT(var->IsStackAllocated());
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
if (slot->type() == Slot::PARAMETER) {
return slot->index();
} else {
......
......@@ -429,7 +429,7 @@ void FullCodeGenerator::VisitDeclarations(
for (int i = 0; i < length; i++) {
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
// If it was not possible to allocate the variable at compile
// time, we need to "declare" it at runtime to make sure it
......@@ -449,7 +449,7 @@ void FullCodeGenerator::VisitDeclarations(
for (int j = 0, i = 0; i < length; i++) {
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) {
array->set(j++, *(var->name()));
......@@ -1018,7 +1018,7 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
// The catch variable is *always* a variable proxy for a local variable.
Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(catch_var);
Slot* variable_slot = catch_var->slot();
Slot* variable_slot = catch_var->AsSlot();
ASSERT_NOT_NULL(variable_slot);
ASSERT_EQ(Slot::LOCAL, variable_slot->type());
StoreToFrameField(SlotOffset(variable_slot), result_register());
......
This diff is collapsed.
......@@ -100,7 +100,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Copy parameters into context if necessary.
int num_parameters = scope()->num_parameters();
for (int i = 0; i < num_parameters; i++) {
Slot* slot = scope()->parameter(i)->slot();
Slot* slot = scope()->parameter(i)->AsSlot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
int parameter_offset = StandardFrameConstants::kCallerSPOffset +
(num_parameters - 1 - i) * kPointerSize;
......@@ -118,7 +118,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
}
}
Variable* arguments = scope()->arguments()->AsVariable();
Variable* arguments = scope()->arguments();
if (arguments != NULL) {
// Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object");
......@@ -140,9 +140,8 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
__ CallStub(&stub);
__ mov(ecx, eax); // Duplicate result.
Move(arguments->slot(), eax, ebx, edx);
Slot* dot_arguments_slot =
scope()->arguments_shadow()->AsVariable()->slot();
Move(arguments->AsSlot(), eax, ebx, edx);
Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
Move(dot_arguments_slot, ecx, ebx, edx);
}
......@@ -516,7 +515,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
FunctionLiteral* function) {
Comment cmnt(masm_, "[ Declaration");
ASSERT(variable != NULL); // Must have been resolved.
Slot* slot = variable->slot();
Slot* slot = variable->AsSlot();
Property* prop = variable->AsProperty();
if (slot != NULL) {
switch (slot->type()) {
......@@ -1001,7 +1000,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
__ jmp(done);
} else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
if (potential_slot != NULL) {
// Generate fast case for locals that rewrite to slots.
......@@ -1027,7 +1026,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
// variables. Then load the argument from the arguments
// object using keyed load.
__ mov(edx,
ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ mov(eax, Immediate(key_literal->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
......@@ -1044,7 +1043,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Four cases: non-this global variables, lookup slots, all other
// types of slots, and parameters that rewrite to explicit property
// accesses on the arguments object.
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
Property* property = var->AsProperty();
if (var->is_global() && !var->is_this()) {
......@@ -1100,7 +1099,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Assert that the object is in a slot.
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(object_var);
Slot* object_slot = object_var->slot();
Slot* object_slot = object_var->AsSlot();
ASSERT_NOT_NULL(object_slot);
// Load the object.
......@@ -1809,7 +1808,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Left-hand sides that rewrite to explicit property accesses do not reach
// here.
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
ASSERT(var->is_global() || var->AsSlot() != NULL);
if (var->is_global()) {
ASSERT(!var->is_this());
......@@ -1825,7 +1824,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Perform the assignment for non-const variables and for initialization
// of const variables. Const assignments are simply skipped.
Label done;
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
......@@ -2086,14 +2085,14 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Push global object as receiver for the call IC.
__ push(CodeGenerator::GlobalObject());
EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
} else if (var != NULL && var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::LOOKUP) {
// Call to a lookup slot (dynamically introduced variable).
Label slow, done;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLoadFromSlotFastCase(var->slot(),
EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
NOT_INSIDE_TYPEOF,
&slow,
&done);
......@@ -3095,8 +3094,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(true);
} else if (var != NULL &&
!var->is_global() &&
var->slot() != NULL &&
var->slot()->type() != Slot::LOOKUP) {
var->AsSlot() != NULL &&
var->AsSlot()->type() != Slot::LOOKUP) {
// Result of deleting non-global, non-dynamic variables is false.
// The subexpression does not have side effects.
context()->Plug(false);
......@@ -3393,13 +3392,13 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
EmitCallIC(ic, RelocInfo::CODE_TARGET);
context()->Plug(eax);
} else if (proxy != NULL &&
proxy->var()->slot() != NULL &&
proxy->var()->slot()->type() == Slot::LOOKUP) {
proxy->var()->AsSlot() != NULL &&
proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
Slot* slot = proxy->var()->slot();
Slot* slot = proxy->var()->AsSlot();
EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
......
......@@ -1313,7 +1313,7 @@ void VirtualFrame::Push(Expression* expr) {
VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL) {
Slot* slot = proxy->var()->slot();
Slot* slot = proxy->var()->AsSlot();
if (slot->type() == Slot::LOCAL) {
PushLocalAt(slot->index());
return;
......
......@@ -664,7 +664,7 @@ class FunctionInfoListener {
int j = 0;
for (int i = 0; i < list.length(); i++) {
Variable* var1 = list[i];
Slot* slot = var1->slot();
Slot* slot = var1->AsSlot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
if (j != i) {
list[j] = var1;
......@@ -677,7 +677,7 @@ class FunctionInfoListener {
for (int k = 1; k < j; k++) {
int l = k;
for (int m = k + 1; m < j; m++) {
if (list[l]->slot()->index() > list[m]->slot()->index()) {
if (list[l]->AsSlot()->index() > list[m]->AsSlot()->index()) {
l = m;
}
}
......@@ -687,7 +687,7 @@ class FunctionInfoListener {
SetElement(scope_info_list, scope_info_length, list[i]->name());
scope_info_length++;
SetElement(scope_info_list, scope_info_length,
Handle<Smi>(Smi::FromInt(list[i]->slot()->index())));
Handle<Smi>(Smi::FromInt(list[i]->AsSlot()->index())));
scope_info_length++;
}
SetElement(scope_info_list, scope_info_length,
......
......@@ -525,8 +525,8 @@ void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
Variable* rvar = rvar_proxy->AsVariable();
if (lvar != NULL && rvar != NULL) {
if (lvar->mode() == Variable::VAR && rvar->mode() == Variable::VAR) {
Slot* lslot = lvar->slot();
Slot* rslot = rvar->slot();
Slot* lslot = lvar->AsSlot();
Slot* rslot = rvar->AsSlot();
if (lslot->type() == rslot->type() &&
(lslot->type() == Slot::PARAMETER ||
lslot->type() == Slot::LOCAL) &&
......
......@@ -37,8 +37,8 @@ namespace internal {
static int CompareLocal(Variable* const* v, Variable* const* w) {
Slot* s = (*v)->slot();
Slot* t = (*w)->slot();
Slot* s = (*v)->AsSlot();
Slot* t = (*w)->AsSlot();
// We may have rewritten parameters (that are in the arguments object)
// and which may have a NULL slot... - find a better solution...
int x = (s != NULL ? s->index() : 0);
......@@ -83,7 +83,7 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
for (int i = 0; i < locals.length(); i++) {
Variable* var = locals[i];
if (var->is_used()) {
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
if (slot != NULL) {
switch (slot->type()) {
case Slot::PARAMETER:
......@@ -112,9 +112,9 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
if (scope->num_heap_slots() > 0) {
// Add user-defined slots.
for (int i = 0; i < heap_locals.length(); i++) {
ASSERT(heap_locals[i]->slot()->index() - Context::MIN_CONTEXT_SLOTS ==
ASSERT(heap_locals[i]->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
context_slots_.length());
ASSERT(heap_locals[i]->slot()->index() - Context::MIN_CONTEXT_SLOTS ==
ASSERT(heap_locals[i]->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
context_modes_.length());
context_slots_.Add(heap_locals[i]->name());
context_modes_.Add(heap_locals[i]->mode());
......@@ -131,15 +131,15 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
Variable* var = scope->function();
if (var != NULL &&
var->is_used() &&
var->slot()->type() == Slot::CONTEXT) {
var->AsSlot()->type() == Slot::CONTEXT) {
function_name_ = var->name();
// Note that we must not find the function name in the context slot
// list - instead it must be handled separately in the
// Contexts::Lookup() function. Thus record an empty symbol here so we
// get the correct number of context slots.
ASSERT(var->slot()->index() - Context::MIN_CONTEXT_SLOTS ==
ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
context_slots_.length());
ASSERT(var->slot()->index() - Context::MIN_CONTEXT_SLOTS ==
ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
context_modes_.length());
context_slots_.Add(Factory::empty_symbol());
context_modes_.Add(Variable::INTERNAL);
......
......@@ -810,8 +810,7 @@ void Scope::AllocateParameterLocals() {
// We are using 'arguments'. Tell the code generator that is needs to
// allocate the arguments object by setting 'arguments_'.
arguments_ = new VariableProxy(Factory::arguments_symbol(), false, false);
arguments_->BindTo(arguments);
arguments_ = arguments;
// We also need the '.arguments' shadow variable. Declare it and create
// and bind the corresponding proxy. It's ok to declare it only now
......@@ -822,13 +821,13 @@ void Scope::AllocateParameterLocals() {
// NewTemporary() because the mode needs to be INTERNAL since this
// variable may be allocated in the heap-allocated context (temporaries
// are never allocated in the context).
Variable* arguments_shadow =
new Variable(this, Factory::arguments_shadow_symbol(),
Variable::INTERNAL, true, Variable::ARGUMENTS);
arguments_shadow_ =
new VariableProxy(Factory::arguments_shadow_symbol(), false, false);
arguments_shadow_->BindTo(arguments_shadow);
temps_.Add(arguments_shadow);
arguments_shadow_ = new Variable(this,
Factory::arguments_shadow_symbol(),
Variable::INTERNAL,
true,
Variable::ARGUMENTS);
arguments_shadow_->set_is_used(true);
temps_.Add(arguments_shadow_);
// Allocate the parameters by rewriting them into '.arguments[i]' accesses.
for (int i = 0; i < params_.length(); i++) {
......@@ -839,14 +838,13 @@ void Scope::AllocateParameterLocals() {
// It is ok to set this only now, because arguments is a local
// variable that is allocated after the parameters have been
// allocated.
arguments_shadow->is_accessed_from_inner_scope_ = true;
arguments_shadow_->is_accessed_from_inner_scope_ = true;
}
var->rewrite_ =
new Property(arguments_shadow_,
new Literal(Handle<Object>(Smi::FromInt(i))),
RelocInfo::kNoPosition,
Property::SYNTHETIC);
if (var->is_used()) arguments_shadow->set_is_used(true);
new Property(new VariableProxy(arguments_shadow_),
new Literal(Handle<Object>(Smi::FromInt(i))),
RelocInfo::kNoPosition,
Property::SYNTHETIC);
}
}
......@@ -862,7 +860,8 @@ void Scope::AllocateParameterLocals() {
if (MustAllocate(var)) {
if (MustAllocateInContext(var)) {
ASSERT(var->rewrite_ == NULL ||
(var->slot() != NULL && var->slot()->type() == Slot::CONTEXT));
(var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::CONTEXT));
if (var->rewrite_ == NULL) {
// Only set the heap allocation if the parameter has not
// been allocated yet.
......@@ -870,8 +869,8 @@ void Scope::AllocateParameterLocals() {
}
} else {
ASSERT(var->rewrite_ == NULL ||
(var->slot() != NULL &&
var->slot()->type() == Slot::PARAMETER));
(var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::PARAMETER));
// Set the parameter index always, even if the parameter
// was seen before! (We need to access the actual parameter
// supplied for the last occurrence of a multiply declared
......@@ -888,7 +887,7 @@ void Scope::AllocateNonParameterLocal(Variable* var) {
ASSERT(var->scope() == this);
ASSERT(var->rewrite_ == NULL ||
(!var->IsVariable(Factory::result_symbol())) ||
(var->slot() == NULL || var->slot()->type() != Slot::LOCAL));
(var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
if (var->rewrite_ == NULL && MustAllocate(var)) {
if (MustAllocateInContext(var)) {
AllocateHeapSlot(var);
......
......@@ -233,11 +233,11 @@ class Scope: public ZoneObject {
// The local variable 'arguments' if we need to allocate it; NULL otherwise.
// If arguments() exist, arguments_shadow() exists, too.
VariableProxy* arguments() const { return arguments_; }
Variable* arguments() const { return arguments_; }
// The '.arguments' shadow variable if we need to allocate it; NULL otherwise.
// If arguments_shadow() exist, arguments() exists, too.
VariableProxy* arguments_shadow() const { return arguments_shadow_; }
Variable* arguments_shadow() const { return arguments_shadow_; }
// Declarations list.
ZoneList<Declaration*>* declarations() { return &decls_; }
......@@ -322,9 +322,9 @@ class Scope: public ZoneObject {
// Function variable, if any; function scopes only.
Variable* function_;
// Convenience variable; function scopes only.
VariableProxy* arguments_;
Variable* arguments_;
// Convenience variable; function scopes only.
VariableProxy* arguments_shadow_;
Variable* arguments_shadow_;
// Illegal redeclaration.
Expression* illegal_redecl_;
......
......@@ -70,24 +70,19 @@ const char* Variable::Mode2String(Mode mode) {
}
Property* Variable::AsProperty() {
Property* Variable::AsProperty() const {
return rewrite_ == NULL ? NULL : rewrite_->AsProperty();
}
Variable* Variable::AsVariable() {
return rewrite_ == NULL || rewrite_->AsSlot() != NULL ? this : NULL;
}
Slot* Variable::slot() const {
return rewrite_ != NULL ? rewrite_->AsSlot() : NULL;
Slot* Variable::AsSlot() const {
return rewrite_ == NULL ? NULL : rewrite_->AsSlot();
}
bool Variable::IsStackAllocated() const {
Slot* s = slot();
return s != NULL && s->IsStackAllocated();
Slot* slot = AsSlot();
return slot != NULL && slot->IsStackAllocated();
}
......
......@@ -122,8 +122,9 @@ class Variable: public ZoneObject {
static const char* Mode2String(Mode mode);
// Type testing & conversion
Property* AsProperty();
Variable* AsVariable();
Property* AsProperty() const;
Slot* AsSlot() const;
bool IsValidLeftHandSide() { return is_valid_LHS_; }
// The source code for an eval() call may refer to a variable that is
......@@ -172,7 +173,6 @@ class Variable: public ZoneObject {
}
Expression* rewrite() const { return rewrite_; }
Slot* slot() const;
StaticType* type() { return &type_; }
......
This diff is collapsed.
......@@ -100,7 +100,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Copy any necessary parameters into the context.
int num_parameters = scope()->num_parameters();
for (int i = 0; i < num_parameters; i++) {
Slot* slot = scope()->parameter(i)->slot();
Slot* slot = scope()->parameter(i)->AsSlot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
int parameter_offset = StandardFrameConstants::kCallerSPOffset +
(num_parameters - 1 - i) * kPointerSize;
......@@ -119,7 +119,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
}
// Possibly allocate an arguments object.
Variable* arguments = scope()->arguments()->AsVariable();
Variable* arguments = scope()->arguments();
if (arguments != NULL) {
// Arguments object must be allocated after the context object, in
// case the "arguments" or ".arguments" variables are in the context.
......@@ -143,9 +143,8 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
__ CallStub(&stub);
// Store new arguments object in both "arguments" and ".arguments" slots.
__ movq(rcx, rax);
Move(arguments->slot(), rax, rbx, rdx);
Slot* dot_arguments_slot =
scope()->arguments_shadow()->AsVariable()->slot();
Move(arguments->AsSlot(), rax, rbx, rdx);
Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
Move(dot_arguments_slot, rcx, rbx, rdx);
}
......@@ -519,7 +518,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
FunctionLiteral* function) {
Comment cmnt(masm_, "[ Declaration");
ASSERT(variable != NULL); // Must have been resolved.
Slot* slot = variable->slot();
Slot* slot = variable->AsSlot();
Property* prop = variable->AsProperty();
if (slot != NULL) {
......@@ -960,7 +959,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
__ jmp(done);
} else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
if (potential_slot != NULL) {
// Generate fast case for locals that rewrite to slots.
......@@ -986,7 +985,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
// variables. Then load the argument from the arguments
// object using keyed load.
__ movq(rdx,
ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ Move(rax, key_literal->handle());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
......@@ -1003,7 +1002,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Four cases: non-this global variables, lookup slots, all other
// types of slots, and parameters that rewrite to explicit property
// accesses on the arguments object.
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
Property* property = var->AsProperty();
if (var->is_global() && !var->is_this()) {
......@@ -1059,7 +1058,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
// Assert that the object is in a slot.
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(object_var);
Slot* object_slot = object_var->slot();
Slot* object_slot = object_var->AsSlot();
ASSERT_NOT_NULL(object_slot);
// Load the object.
......@@ -1531,7 +1530,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Left-hand sides that rewrite to explicit property accesses do not reach
// here.
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
ASSERT(var->is_global() || var->AsSlot() != NULL);
if (var->is_global()) {
ASSERT(!var->is_this());
......@@ -1547,7 +1546,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// Perform the assignment for non-const variables and for initialization
// of const variables. Const assignments are simply skipped.
Label done;
Slot* slot = var->slot();
Slot* slot = var->AsSlot();
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
......@@ -1813,14 +1812,14 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Push global object as receiver for the call IC lookup.
__ push(CodeGenerator::GlobalObject());
EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
} else if (var != NULL && var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::LOOKUP) {
// Call to a lookup slot (dynamically introduced variable).
Label slow, done;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLoadFromSlotFastCase(var->slot(),
EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
NOT_INSIDE_TYPEOF,
&slow,
&done);
......@@ -2806,8 +2805,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(true);
} else if (var != NULL &&
!var->is_global() &&
var->slot() != NULL &&
var->slot()->type() != Slot::LOOKUP) {
var->AsSlot() != NULL &&
var->AsSlot()->type() != Slot::LOOKUP) {
// Result of deleting non-global, non-dynamic variables is false.
// The subexpression does not have side effects.
context()->Plug(false);
......@@ -3096,13 +3095,13 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
EmitCallIC(ic, RelocInfo::CODE_TARGET);
context()->Plug(rax);
} else if (proxy != NULL &&
proxy->var()->slot() != NULL &&
proxy->var()->slot()->type() == Slot::LOOKUP) {
proxy->var()->AsSlot() != NULL &&
proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
Slot* slot = proxy->var()->slot();
Slot* slot = proxy->var()->AsSlot();
EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
......
......@@ -259,7 +259,7 @@ void VirtualFrame::Push(Expression* expr) {
VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL) {
Slot* slot = proxy->var()->slot();
Slot* slot = proxy->var()->AsSlot();
if (slot->type() == Slot::LOCAL) {
PushLocalAt(slot->index());
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment