Move the Location class into the AST Expression class as a member.

Since it is (currently) only an enum, change it to an enum (for now).

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3181 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 143b4b87
...@@ -117,13 +117,13 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { ...@@ -117,13 +117,13 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
} }
void FastCodeGenerator::Move(Location destination, Slot* source) { void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ ldr(ip, MemOperand(fp, SlotOffset(source))); __ ldr(ip, MemOperand(fp, SlotOffset(source)));
__ push(ip); __ push(ip);
break; break;
...@@ -131,13 +131,13 @@ void FastCodeGenerator::Move(Location destination, Slot* source) { ...@@ -131,13 +131,13 @@ void FastCodeGenerator::Move(Location destination, Slot* source) {
} }
void FastCodeGenerator::Move(Location destination, Literal* expr) { void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ mov(ip, Operand(expr->handle())); __ mov(ip, Operand(expr->handle()));
__ push(ip); __ push(ip);
break; break;
...@@ -145,27 +145,15 @@ void FastCodeGenerator::Move(Location destination, Literal* expr) { ...@@ -145,27 +145,15 @@ void FastCodeGenerator::Move(Location destination, Literal* expr) {
} }
void FastCodeGenerator::Move(Slot* destination, Location source) { void FastCodeGenerator::DropAndMove(Expression::Context context,
switch (source.type()) { Register source) {
case Location::kUninitialized: // Fall through. switch (context) {
case Location::kEffect: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kValue: case Expression::kEffect:
__ pop(ip);
__ str(ip, MemOperand(fp, SlotOffset(destination)));
break;
}
}
void FastCodeGenerator::DropAndMove(Location destination, Register source) {
switch (destination.type()) {
case Location::kUninitialized:
UNREACHABLE();
case Location::kEffect:
__ pop(); __ pop();
break; break;
case Location::kValue: case Expression::kValue:
__ str(source, MemOperand(sp)); __ str(source, MemOperand(sp));
break; break;
} }
...@@ -191,8 +179,9 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { ...@@ -191,8 +179,9 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
if (expr->AsLiteral() != NULL) { if (expr->AsLiteral() != NULL) {
__ mov(r0, Operand(expr->AsLiteral()->handle())); __ mov(r0, Operand(expr->AsLiteral()->handle()));
} else { } else {
ASSERT_EQ(Expression::kValue, expr->context());
Visit(expr); Visit(expr);
Move(r0, expr->location()); __ pop(r0);
} }
if (FLAG_trace) { if (FLAG_trace) {
...@@ -222,7 +211,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -222,7 +211,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
__ mov(r0, Operand(boilerplate)); __ mov(r0, Operand(boilerplate));
__ stm(db_w, sp, cp.bit() | r0.bit()); __ stm(db_w, sp, cp.bit() | r0.bit());
__ CallRuntime(Runtime::kNewClosure, 2); __ CallRuntime(Runtime::kNewClosure, 2);
Move(expr->location(), r0); Move(expr->context(), r0);
} }
...@@ -238,10 +227,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { ...@@ -238,10 +227,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
__ mov(r2, Operand(expr->name())); __ mov(r2, Operand(expr->name()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
DropAndMove(expr->location(), r0); DropAndMove(expr->context(), r0);
} else { } else {
Comment cmnt(masm_, "Stack slot"); Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot()); Move(expr->context(), rewrite->AsSlot());
} }
} }
...@@ -269,7 +258,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -269,7 +258,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
__ bind(&done); __ bind(&done);
Move(expr->location(), r0); Move(expr->context(), r0);
} }
...@@ -326,7 +315,8 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -326,7 +315,8 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) { if (key->handle()->IsSymbol()) {
Visit(value); Visit(value);
Move(r0, value->location()); ASSERT_EQ(Expression::kValue, value->context());
__ pop(r0);
__ mov(r2, Operand(key->handle())); __ mov(r2, Operand(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -338,9 +328,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -338,9 +328,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
__ push(r0); __ push(r0);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3); __ CallRuntime(Runtime::kSetProperty, 3);
__ ldr(r0, MemOperand(sp)); // Restore result into r0 __ ldr(r0, MemOperand(sp)); // Restore result into r0
break; break;
...@@ -349,25 +339,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -349,25 +339,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::SETTER: case ObjectLiteral::Property::SETTER:
__ push(r0); __ push(r0);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
__ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ? __ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) : Smi::FromInt(1) :
Smi::FromInt(0))); Smi::FromInt(0)));
__ push(r1); __ push(r1);
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4); __ CallRuntime(Runtime::kDefineAccessor, 4);
__ ldr(r0, MemOperand(sp)); // Restore result into r0 __ ldr(r0, MemOperand(sp)); // Restore result into r0
break; break;
} }
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ pop(); if (result_saved) __ pop();
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(r0); if (!result_saved) __ push(r0);
break; break;
} }
...@@ -423,7 +413,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -423,7 +413,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
result_saved = true; result_saved = true;
} }
Visit(subexpr); Visit(subexpr);
ASSERT(subexpr->location().is_value()); ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements. // Store the subexpression value in the array's elements.
__ pop(r0); // Subexpression value. __ pop(r0); // Subexpression value.
...@@ -438,13 +428,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -438,13 +428,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ RecordWrite(r1, r2, r0); __ RecordWrite(r1, r2, r0);
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ pop(); if (result_saved) __ pop();
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(r0); if (!result_saved) __ push(r0);
break; break;
} }
...@@ -474,7 +464,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -474,7 +464,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment // NAMED property assignment
Visit(rhs); Visit(rhs);
Move(r0, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(r0);
__ mov(r2, Operand(literal_key->handle())); __ mov(r2, Operand(literal_key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -482,14 +473,15 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -482,14 +473,15 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// KEYED property assignment // KEYED property assignment
Visit(prop->key()); Visit(prop->key());
Visit(rhs); Visit(rhs);
Move(r0, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(r0);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
// Drop key from the stack // Drop key from the stack
__ pop(); __ pop();
} }
// Overwrite the receiver on the stack with the result if needed. // Overwrite the receiver on the stack with the result if needed.
DropAndMove(expr->location(), r0); DropAndMove(expr->context(), r0);
} else if (var->is_global()) { } else if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side // Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in r0, variable name in r2, and the global object on // value is passed in r0, variable name in r2, and the global object on
...@@ -499,7 +491,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -499,7 +491,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
if (rhs->AsLiteral() != NULL) { if (rhs->AsLiteral() != NULL) {
__ mov(r0, Operand(rhs->AsLiteral()->handle())); __ mov(r0, Operand(rhs->AsLiteral()->handle()));
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
__ pop(r0); __ pop(r0);
} }
...@@ -509,7 +501,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -509,7 +501,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed. // Overwrite the global object on the stack with the result if needed.
DropAndMove(expr->location(), r0); DropAndMove(expr->context(), r0);
} else { } else {
// Local or parameter assignment. // Local or parameter assignment.
...@@ -519,19 +511,19 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -519,19 +511,19 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// discarded result. Always perform the assignment. // discarded result. Always perform the assignment.
__ mov(ip, Operand(rhs->AsLiteral()->handle())); __ mov(ip, Operand(rhs->AsLiteral()->handle()));
__ str(ip, MemOperand(fp, SlotOffset(var->slot()))); __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
Move(expr->location(), ip); Move(expr->context(), ip);
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
// Load right-hand side into ip. // Load right-hand side into ip.
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary. // Case 'var = temp'. Discard right-hand-side temporary.
__ pop(ip); __ pop(ip);
break; break;
case Location::kValue: case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack. // temporary on the stack.
__ ldr(ip, MemOperand(sp)); __ ldr(ip, MemOperand(sp));
...@@ -570,7 +562,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -570,7 +562,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
// Drop key and receiver left on the stack by IC. // Drop key and receiver left on the stack by IC.
__ pop(); __ pop();
} }
DropAndMove(expr->location(), r0); DropAndMove(expr->context(), r0);
} }
...@@ -589,7 +581,7 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -589,7 +581,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
// Record source position for debugger // Record source position for debugger
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
...@@ -599,35 +591,35 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -599,35 +591,35 @@ void FastCodeGenerator::VisitCall(Call* expr) {
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
DropAndMove(expr->location(), r0); DropAndMove(expr->context(), r0);
} }
void FastCodeGenerator::VisitCallNew(CallNew* node) { void FastCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew"); Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function // According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the // expression in new calls must be evaluated before the
// arguments. // arguments.
// Push function on the stack. // Push function on the stack.
Visit(node->expression()); Visit(expr->expression());
ASSERT(node->expression()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->expression()->context());
// Push global object (receiver). // Push global object (receiver).
__ ldr(r0, CodeGenerator::GlobalObject()); __ ldr(r0, CodeGenerator::GlobalObject());
__ push(r0); __ push(r0);
// Push the arguments ("left-to-right") on the stack. // Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = node->arguments(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
// If location is value, it is already on the stack, // If location is value, it is already on the stack,
// so nothing to do here. // so nothing to do here.
} }
// Call the construct call builtin that handles allocation and // Call the construct call builtin that handles allocation and
// constructor invocation. // constructor invocation.
SetSourcePosition(node->position()); SetSourcePosition(expr->position());
// Load function, arg_count into r1 and r0. // Load function, arg_count into r1 and r0.
__ mov(r0, Operand(arg_count)); __ mov(r0, Operand(arg_count));
...@@ -638,7 +630,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) { ...@@ -638,7 +630,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in r0, or pop it. // Replace function on TOS with result in r0, or pop it.
DropAndMove(node->location(), r0); DropAndMove(expr->context(), r0);
} }
...@@ -653,19 +645,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -653,19 +645,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
__ CallRuntime(function, arg_count); __ CallRuntime(function, arg_count);
Move(expr->location(), r0); Move(expr->context(), r0);
} }
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT(expr->left()->location().is_effect()); ASSERT_EQ(Expression::kEffect, expr->left()->context());
ASSERT_EQ(expr->right()->location().type(), expr->location().type()); ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -686,8 +678,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -686,8 +678,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SHL: case Token::SHL:
case Token::SHR: case Token::SHR:
case Token::SAR: { case Token::SAR: {
ASSERT(expr->left()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->left()->context());
ASSERT(expr->right()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
...@@ -696,7 +688,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -696,7 +688,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
GenericBinaryOpStub stub(expr->op(), GenericBinaryOpStub stub(expr->op(),
NO_OVERWRITE); NO_OVERWRITE);
__ CallStub(&stub); __ CallStub(&stub);
Move(expr->location(), r0); Move(expr->context(), r0);
break; break;
} }
...@@ -715,7 +707,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -715,7 +707,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
// (let (temp = e0) !temp ? temp : e1). // (let (temp = e0) !temp ? temp : e1).
Label done; Label done;
Location destination = expr->location(); Expression::Context context = expr->context();
Expression* left = expr->left(); Expression* left = expr->left();
Expression* right = expr->right(); Expression* right = expr->right();
...@@ -725,11 +717,11 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -725,11 +717,11 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
if (left->AsLiteral() != NULL) { if (left->AsLiteral() != NULL) {
__ mov(r0, Operand(left->AsLiteral()->handle())); __ mov(r0, Operand(left->AsLiteral()->handle()));
__ push(r0); __ push(r0);
if (destination.is_value()) __ push(r0); if (context == Expression::kValue) __ push(r0);
} else { } else {
Visit(left); Visit(left);
ASSERT(left->location().is_value()); ASSERT_EQ(Expression::kValue, left->context());
if (destination.is_value()) { if (context == Expression::kValue) {
__ ldr(r0, MemOperand(sp)); __ ldr(r0, MemOperand(sp));
__ push(r0); __ push(r0);
} }
...@@ -746,10 +738,10 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -746,10 +738,10 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
__ b(eq, &done); __ b(eq, &done);
// Discard the left-hand value if present on the stack. // Discard the left-hand value if present on the stack.
if (destination.is_value()) __ pop(); if (context == Expression::kValue) __ pop();
// Save or discard the right-hand value as needed. // Save or discard the right-hand value as needed.
Visit(right); Visit(right);
ASSERT_EQ(destination.type(), right->location().type()); ASSERT_EQ(context, right->context());
__ bind(&done); __ bind(&done);
} }
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#ifndef V8_AST_H_ #ifndef V8_AST_H_
#define V8_AST_H_ #define V8_AST_H_
#include "location.h"
#include "execution.h" #include "execution.h"
#include "factory.h" #include "factory.h"
#include "jsregexp.h" #include "jsregexp.h"
...@@ -162,7 +161,13 @@ class Statement: public AstNode { ...@@ -162,7 +161,13 @@ class Statement: public AstNode {
class Expression: public AstNode { class Expression: public AstNode {
public: public:
Expression() : location_(Location::Uninitialized()) {} enum Context {
kUninitialized,
kEffect,
kValue
};
Expression() : context_(kUninitialized) {}
virtual Expression* AsExpression() { return this; } virtual Expression* AsExpression() { return this; }
...@@ -177,12 +182,12 @@ class Expression: public AstNode { ...@@ -177,12 +182,12 @@ class Expression: public AstNode {
// Static type information for this expression. // Static type information for this expression.
SmiAnalysis* type() { return &type_; } SmiAnalysis* type() { return &type_; }
Location location() { return location_; } Context context() { return context_; }
void set_location(Location loc) { location_ = loc; } void set_context(Context context) { context_ = context; }
private: private:
SmiAnalysis type_; SmiAnalysis type_;
Location location_; Context context_;
}; };
......
...@@ -48,23 +48,24 @@ class CodeGenSelector: public AstVisitor { ...@@ -48,23 +48,24 @@ class CodeGenSelector: public AstVisitor {
CodeGenSelector() CodeGenSelector()
: has_supported_syntax_(true), : has_supported_syntax_(true),
location_(Location::Uninitialized()) { context_(Expression::kUninitialized) {
} }
CodeGenTag Select(FunctionLiteral* fun); CodeGenTag Select(FunctionLiteral* fun);
private: private:
// Visit an expression in a given expression context.
void ProcessExpression(Expression* expr, Expression::Context context) {
Expression::Context saved = context_;
context_ = context;
Visit(expr);
expr->set_context(context);
context_ = saved;
}
void VisitDeclarations(ZoneList<Declaration*>* decls); void VisitDeclarations(ZoneList<Declaration*>* decls);
void VisitStatements(ZoneList<Statement*>* stmts); void VisitStatements(ZoneList<Statement*>* stmts);
// Visit an expression in effect context with a desired location of
// nowhere.
void VisitAsEffect(Expression* expr);
// Visit an expression in value context with a desired location of
// temporary.
void VisitAsValue(Expression* expr);
// AST node visit functions. // AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node); #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT) AST_NODE_LIST(DECLARE_VISIT)
...@@ -72,8 +73,8 @@ class CodeGenSelector: public AstVisitor { ...@@ -72,8 +73,8 @@ class CodeGenSelector: public AstVisitor {
bool has_supported_syntax_; bool has_supported_syntax_;
// The desired location of the currently visited expression. // The desired expression context of the currently visited expression.
Location location_; Expression::Context context_;
DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
}; };
...@@ -513,30 +514,6 @@ void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) { ...@@ -513,30 +514,6 @@ void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) {
} }
void CodeGenSelector::VisitAsEffect(Expression* expr) {
if (location_.is_effect()) {
Visit(expr);
} else {
Location saved = location_;
location_ = Location::Effect();
Visit(expr);
location_ = saved;
}
}
void CodeGenSelector::VisitAsValue(Expression* expr) {
if (location_.is_value()) {
Visit(expr);
} else {
Location saved = location_;
location_ = Location::Value();
Visit(expr);
location_ = saved;
}
}
void CodeGenSelector::VisitDeclaration(Declaration* decl) { void CodeGenSelector::VisitDeclaration(Declaration* decl) {
Variable* var = decl->proxy()->var(); Variable* var = decl->proxy()->var();
if (!var->is_global() || var->mode() == Variable::CONST) { if (!var->is_global() || var->mode() == Variable::CONST) {
...@@ -551,7 +528,7 @@ void CodeGenSelector::VisitBlock(Block* stmt) { ...@@ -551,7 +528,7 @@ void CodeGenSelector::VisitBlock(Block* stmt) {
void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) { void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
VisitAsEffect(stmt->expression()); ProcessExpression(stmt->expression(), Expression::kEffect);
} }
...@@ -576,7 +553,7 @@ void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) { ...@@ -576,7 +553,7 @@ void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) {
void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) { void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
VisitAsValue(stmt->expression()); ProcessExpression(stmt->expression(), Expression::kValue);
} }
...@@ -634,7 +611,6 @@ void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -634,7 +611,6 @@ void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) {
if (!expr->AllowsLazyCompilation()) { if (!expr->AllowsLazyCompilation()) {
BAILOUT("FunctionLiteral does not allow lazy compilation"); BAILOUT("FunctionLiteral does not allow lazy compilation");
} }
expr->set_location(location_);
} }
...@@ -671,17 +647,16 @@ void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) { ...@@ -671,17 +647,16 @@ void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
BAILOUT("non-parameter/non-local slot reference"); BAILOUT("non-parameter/non-local slot reference");
} }
} }
expr->set_location(location_);
} }
void CodeGenSelector::VisitLiteral(Literal* expr) { void CodeGenSelector::VisitLiteral(Literal* expr) {
expr->set_location(location_); /* Nothing to do. */
} }
void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) { void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {
expr->set_location(location_); /* Nothing to do. */
} }
...@@ -711,14 +686,13 @@ void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -711,14 +686,13 @@ void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::GETTER: // Fall through. case ObjectLiteral::Property::GETTER: // Fall through.
case ObjectLiteral::Property::SETTER: // Fall through. case ObjectLiteral::Property::SETTER: // Fall through.
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
VisitAsValue(property->key()); ProcessExpression(property->key(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
break; break;
} }
VisitAsValue(property->value()); ProcessExpression(property->value(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
} }
expr->set_location(location_);
} }
...@@ -728,10 +702,9 @@ void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -728,10 +702,9 @@ void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) {
Expression* subexpr = subexprs->at(i); Expression* subexpr = subexprs->at(i);
if (subexpr->AsLiteral() != NULL) continue; if (subexpr->AsLiteral() != NULL) continue;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
VisitAsValue(subexpr); ProcessExpression(subexpr, Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
} }
expr->set_location(location_);
} }
...@@ -758,9 +731,9 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) { ...@@ -758,9 +731,9 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) {
if (var == NULL) { if (var == NULL) {
Property* prop = expr->target()->AsProperty(); Property* prop = expr->target()->AsProperty();
if (prop == NULL) BAILOUT("non-variable, non-property assignment"); if (prop == NULL) BAILOUT("non-variable, non-property assignment");
VisitAsValue(prop->obj()); ProcessExpression(prop->obj(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
VisitAsValue(prop->key()); ProcessExpression(prop->key(), Expression::kValue);
} else if (!var->is_global()) { } else if (!var->is_global()) {
if (var->slot() == NULL) BAILOUT("Assigment with an unsupported LHS."); if (var->slot() == NULL) BAILOUT("Assigment with an unsupported LHS.");
Slot::Type type = var->slot()->type(); Slot::Type type = var->slot()->type();
...@@ -769,8 +742,7 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) { ...@@ -769,8 +742,7 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) {
} }
} }
VisitAsValue(expr->value()); ProcessExpression(expr->value(), Expression::kValue);
expr->set_location(location_);
} }
...@@ -780,10 +752,9 @@ void CodeGenSelector::VisitThrow(Throw* expr) { ...@@ -780,10 +752,9 @@ void CodeGenSelector::VisitThrow(Throw* expr) {
void CodeGenSelector::VisitProperty(Property* expr) { void CodeGenSelector::VisitProperty(Property* expr) {
VisitAsValue(expr->obj()); ProcessExpression(expr->obj(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
VisitAsValue(expr->key()); ProcessExpression(expr->key(), Expression::kValue);
expr->set_location(location_);
} }
...@@ -804,23 +775,21 @@ void CodeGenSelector::VisitCall(Call* expr) { ...@@ -804,23 +775,21 @@ void CodeGenSelector::VisitCall(Call* expr) {
} }
// Check all arguments to the call. (Relies on TEMP meaning STACK.) // Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < args->length(); i++) { for (int i = 0; i < args->length(); i++) {
VisitAsValue(args->at(i)); ProcessExpression(args->at(i), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
} }
expr->set_location(location_);
} }
void CodeGenSelector::VisitCallNew(CallNew* expr) { void CodeGenSelector::VisitCallNew(CallNew* expr) {
VisitAsValue(expr->expression()); ProcessExpression(expr->expression(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
// Check all arguments to the call // Check all arguments to the call
for (int i = 0; i < args->length(); i++) { for (int i = 0; i < args->length(); i++) {
VisitAsValue(args->at(i)); ProcessExpression(args->at(i), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
} }
expr->set_location(location_);
} }
...@@ -834,10 +803,9 @@ void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) { ...@@ -834,10 +803,9 @@ void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
} }
// Check all arguments to the call. (Relies on TEMP meaning STACK.) // Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < expr->arguments()->length(); i++) { for (int i = 0; i < expr->arguments()->length(); i++) {
VisitAsValue(expr->arguments()->at(i)); ProcessExpression(expr->arguments()->at(i), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
} }
expr->set_location(location_);
} }
...@@ -854,17 +822,15 @@ void CodeGenSelector::VisitCountOperation(CountOperation* expr) { ...@@ -854,17 +822,15 @@ void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
VisitAsEffect(expr->left()); ProcessExpression(expr->left(), Expression::kEffect);
CHECK_BAILOUT; CHECK_BAILOUT;
Visit(expr->right()); // Location is the same as the parent location. ProcessExpression(expr->right(), context_);
break; break;
case Token::OR: case Token::OR:
VisitAsValue(expr->left()); ProcessExpression(expr->left(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
// The location for the right subexpression is the same as for the ProcessExpression(expr->right(), context_);
// whole expression so we call Visit directly.
Visit(expr->right());
break; break;
case Token::ADD: case Token::ADD:
...@@ -878,15 +844,14 @@ void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -878,15 +844,14 @@ void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SHL: case Token::SHL:
case Token::SHR: case Token::SHR:
case Token::SAR: case Token::SAR:
VisitAsValue(expr->left()); ProcessExpression(expr->left(), Expression::kValue);
CHECK_BAILOUT; CHECK_BAILOUT;
VisitAsValue(expr->right()); ProcessExpression(expr->right(), Expression::kValue);
break; break;
default: default:
BAILOUT("Unsupported binary operation"); BAILOUT("Unsupported binary operation");
} }
expr->set_location(location_);
} }
......
...@@ -73,32 +73,19 @@ int FastCodeGenerator::SlotOffset(Slot* slot) { ...@@ -73,32 +73,19 @@ int FastCodeGenerator::SlotOffset(Slot* slot) {
// All platform macro assemblers in {ia32,x64,arm} have a push(Register) // All platform macro assemblers in {ia32,x64,arm} have a push(Register)
// function. // function.
void FastCodeGenerator::Move(Location destination, Register source) { void FastCodeGenerator::Move(Expression::Context context, Register source) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
masm_->push(source); masm_->push(source);
break; break;
} }
} }
// All platform macro assemblers in {ia32,x64,arm} have a pop(Register)
// function.
void FastCodeGenerator::Move(Register destination, Location source) {
switch (source.type()) {
case Location::kUninitialized: // Fall through.
case Location::kEffect:
UNREACHABLE();
case Location::kValue:
masm_->pop(destination);
}
}
void FastCodeGenerator::VisitDeclarations( void FastCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) { ZoneList<Declaration*>* declarations) {
int length = declarations->length(); int length = declarations->length();
...@@ -323,7 +310,7 @@ void FastCodeGenerator::VisitSlot(Slot* expr) { ...@@ -323,7 +310,7 @@ void FastCodeGenerator::VisitSlot(Slot* expr) {
void FastCodeGenerator::VisitLiteral(Literal* expr) { void FastCodeGenerator::VisitLiteral(Literal* expr) {
Move(expr->location(), expr); Move(expr->context(), expr);
} }
......
...@@ -51,16 +51,13 @@ class FastCodeGenerator: public AstVisitor { ...@@ -51,16 +51,13 @@ class FastCodeGenerator: public AstVisitor {
private: private:
int SlotOffset(Slot* slot); int SlotOffset(Slot* slot);
void Move(Location destination, Register source); void Move(Expression::Context destination, Register source);
void Move(Location destination, Slot* source); void Move(Expression::Context destination, Slot* source);
void Move(Location destination, Literal* source); void Move(Expression::Context destination, Literal* source);
void Move(Register destination, Location source);
void Move(Slot* destination, Location source);
// Drop the TOS, and store source to destination. // Drop the TOS, and store source to destination.
// If destination is TOS, just overwrite TOS with source. // If destination is TOS, just overwrite TOS with source.
void DropAndMove(Location destination, Register source); void DropAndMove(Expression::Context destination, Register source);
void VisitDeclarations(ZoneList<Declaration*>* declarations); void VisitDeclarations(ZoneList<Declaration*>* declarations);
Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun); Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun);
......
...@@ -108,52 +108,41 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { ...@@ -108,52 +108,41 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
} }
void FastCodeGenerator::Move(Location destination, Slot* source) { void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ push(Operand(ebp, SlotOffset(source))); __ push(Operand(ebp, SlotOffset(source)));
break; break;
} }
} }
void FastCodeGenerator::Move(Location destination, Literal* expr) { void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ push(Immediate(expr->handle())); __ push(Immediate(expr->handle()));
break; break;
} }
} }
void FastCodeGenerator::Move(Slot* destination, Location source) { void FastCodeGenerator::DropAndMove(Expression::Context context,
switch (source.type()) { Register source) {
case Location::kUninitialized: // Fall through. switch (context) {
case Location::kEffect: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kValue: case Expression::kEffect:
__ pop(Operand(ebp, SlotOffset(destination)));
break;
}
}
void FastCodeGenerator::DropAndMove(Location destination, Register source) {
switch (destination.type()) {
case Location::kUninitialized:
UNREACHABLE();
case Location::kEffect:
__ add(Operand(esp), Immediate(kPointerSize)); __ add(Operand(esp), Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
__ mov(Operand(esp, 0), source); __ mov(Operand(esp, 0), source);
break; break;
} }
...@@ -174,12 +163,12 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { ...@@ -174,12 +163,12 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement"); Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt); SetStatementPosition(stmt);
Expression* expr = stmt->expression(); Expression* expr = stmt->expression();
// Complete the statement based on the type of the subexpression.
if (expr->AsLiteral() != NULL) { if (expr->AsLiteral() != NULL) {
__ mov(eax, expr->AsLiteral()->handle()); __ mov(eax, expr->AsLiteral()->handle());
} else { } else {
ASSERT_EQ(Expression::kValue, expr->context());
Visit(expr); Visit(expr);
Move(eax, expr->location()); __ pop(eax);
} }
if (FLAG_trace) { if (FLAG_trace) {
...@@ -209,7 +198,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -209,7 +198,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
__ push(esi); __ push(esi);
__ push(Immediate(boilerplate)); __ push(Immediate(boilerplate));
__ CallRuntime(Runtime::kNewClosure, 2); __ CallRuntime(Runtime::kNewClosure, 2);
Move(expr->location(), eax); Move(expr->context(), eax);
} }
...@@ -230,10 +219,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { ...@@ -230,10 +219,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
// (eg, push/pop elimination). // (eg, push/pop elimination).
__ nop(); __ nop();
DropAndMove(expr->location(), eax); DropAndMove(expr->context(), eax);
} else { } else {
Comment cmnt(masm_, "Stack slot"); Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot()); Move(expr->context(), rewrite->AsSlot());
} }
} }
...@@ -261,7 +250,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -261,7 +250,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done: // Label done:
__ bind(&done); __ bind(&done);
Move(expr->location(), eax); Move(expr->context(), eax);
} }
...@@ -318,7 +307,8 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -318,7 +307,8 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) { if (key->handle()->IsSymbol()) {
Visit(value); Visit(value);
Move(eax, value->location()); ASSERT_EQ(Expression::kValue, value->context());
__ pop(eax);
__ mov(ecx, Immediate(key->handle())); __ mov(ecx, Immediate(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
...@@ -329,9 +319,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -329,9 +319,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
__ push(eax); __ push(eax);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3); __ CallRuntime(Runtime::kSetProperty, 3);
__ mov(eax, Operand(esp, 0)); // Restore result into eax. __ mov(eax, Operand(esp, 0)); // Restore result into eax.
break; break;
...@@ -339,25 +329,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -339,25 +329,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(eax); __ push(eax);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
__ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) : Smi::FromInt(1) :
Smi::FromInt(0))); Smi::FromInt(0)));
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4); __ CallRuntime(Runtime::kDefineAccessor, 4);
__ mov(eax, Operand(esp, 0)); // Restore result into eax. __ mov(eax, Operand(esp, 0)); // Restore result into eax.
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(eax); if (!result_saved) __ push(eax);
break; break;
} }
...@@ -412,7 +402,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -412,7 +402,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
result_saved = true; result_saved = true;
} }
Visit(subexpr); Visit(subexpr);
ASSERT(subexpr->location().is_value()); ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements. // Store the subexpression value in the array's elements.
__ pop(eax); // Subexpression value. __ pop(eax); // Subexpression value.
...@@ -425,13 +415,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -425,13 +415,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ RecordWrite(ebx, offset, eax, ecx); __ RecordWrite(ebx, offset, eax, ecx);
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(eax); if (!result_saved) __ push(eax);
break; break;
} }
...@@ -461,7 +451,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -461,7 +451,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment // NAMED property assignment
Visit(rhs); Visit(rhs);
Move(eax, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(eax);
__ mov(ecx, Immediate(literal_key->handle())); __ mov(ecx, Immediate(literal_key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
...@@ -470,7 +461,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -470,7 +461,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// KEYED property assignment // KEYED property assignment
Visit(prop->key()); Visit(prop->key());
Visit(rhs); Visit(rhs);
Move(eax, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(eax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
__ nop(); __ nop();
...@@ -478,7 +470,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -478,7 +470,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
__ add(Operand(esp), Immediate(kPointerSize)); __ add(Operand(esp), Immediate(kPointerSize));
} }
// Overwrite the receiver on the stack with the result if needed. // Overwrite the receiver on the stack with the result if needed.
DropAndMove(expr->location(), eax); DropAndMove(expr->context(), eax);
} else if (var->is_global()) { } else if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side // Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in eax, variable name in ecx, and the global object // value is passed in eax, variable name in ecx, and the global object
...@@ -488,7 +480,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -488,7 +480,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
if (rhs->AsLiteral() != NULL) { if (rhs->AsLiteral() != NULL) {
__ mov(eax, rhs->AsLiteral()->handle()); __ mov(eax, rhs->AsLiteral()->handle());
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
__ pop(eax); __ pop(eax);
} }
...@@ -497,7 +489,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -497,7 +489,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed. // Overwrite the global object on the stack with the result if needed.
DropAndMove(expr->location(), eax); DropAndMove(expr->context(), eax);
} else { } else {
// Local or parameter assignment. // Local or parameter assignment.
ASSERT(var->slot() != NULL); ASSERT(var->slot() != NULL);
...@@ -508,18 +500,18 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -508,18 +500,18 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// discarded result. Always perform the assignment. // discarded result. Always perform the assignment.
__ mov(eax, rhs->AsLiteral()->handle()); __ mov(eax, rhs->AsLiteral()->handle());
__ mov(Operand(ebp, SlotOffset(var->slot())), eax); __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
Move(expr->location(), eax); Move(expr->context(), eax);
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary. // Case 'var = temp'. Discard right-hand-side temporary.
Move(var->slot(), rhs->location()); __ pop(Operand(ebp, SlotOffset(var->slot())));
break; break;
case Location::kValue: case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack. // temporary on the stack.
__ mov(eax, Operand(esp, 0)); __ mov(eax, Operand(esp, 0));
...@@ -562,7 +554,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -562,7 +554,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
// Drop key left on the stack by IC. // Drop key left on the stack by IC.
__ add(Operand(esp), Immediate(kPointerSize)); __ add(Operand(esp), Immediate(kPointerSize));
} }
DropAndMove(expr->location(), eax); DropAndMove(expr->context(), eax);
} }
...@@ -579,7 +571,7 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -579,7 +571,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
// Record source position for debugger // Record source position for debugger
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
...@@ -590,35 +582,35 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -590,35 +582,35 @@ void FastCodeGenerator::VisitCall(Call* expr) {
// Restore context register. // Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS. // Discard the function left on TOS.
DropAndMove(expr->location(), eax); DropAndMove(expr->context(), eax);
} }
void FastCodeGenerator::VisitCallNew(CallNew* node) { void FastCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew"); Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function // According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the // expression in new calls must be evaluated before the
// arguments. // arguments.
// Push function on the stack. // Push function on the stack.
Visit(node->expression()); Visit(expr->expression());
ASSERT(node->expression()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->expression()->context());
// Push global object (receiver). // Push global object (receiver).
__ push(CodeGenerator::GlobalObject()); __ push(CodeGenerator::GlobalObject());
// Push the arguments ("left-to-right") on the stack. // Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = node->arguments(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
// If location is value, it is already on the stack, // If location is value, it is already on the stack,
// so nothing to do here. // so nothing to do here.
} }
// Call the construct call builtin that handles allocation and // Call the construct call builtin that handles allocation and
// constructor invocation. // constructor invocation.
SetSourcePosition(node->position()); SetSourcePosition(expr->position());
// Load function, arg_count into edi and eax. // Load function, arg_count into edi and eax.
__ Set(eax, Immediate(arg_count)); __ Set(eax, Immediate(arg_count));
...@@ -629,7 +621,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) { ...@@ -629,7 +621,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
__ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in eax, or pop it. // Replace function on TOS with result in eax, or pop it.
DropAndMove(node->location(), eax); DropAndMove(expr->context(), eax);
} }
...@@ -644,19 +636,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -644,19 +636,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
__ CallRuntime(function, arg_count); __ CallRuntime(function, arg_count);
Move(expr->location(), eax); Move(expr->context(), eax);
} }
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT(expr->left()->location().is_effect()); ASSERT_EQ(Expression::kValue, expr->left()->context());
ASSERT_EQ(expr->right()->location().type(), expr->location().type()); ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -677,8 +669,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -677,8 +669,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SHL: case Token::SHL:
case Token::SHR: case Token::SHR:
case Token::SAR: { case Token::SAR: {
ASSERT(expr->left()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->left()->context());
ASSERT(expr->right()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
...@@ -686,7 +678,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -686,7 +678,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
NO_OVERWRITE, NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS); NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub); __ CallStub(&stub);
Move(expr->location(), eax); Move(expr->context(), eax);
break; break;
} }
...@@ -711,7 +703,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -711,7 +703,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
left_true = &eval_right; left_true = &eval_right;
left_false = &done; left_false = &done;
} }
Location destination = expr->location(); Expression::Context context = expr->context();
Expression* left = expr->left(); Expression* left = expr->left();
Expression* right = expr->right(); Expression* right = expr->right();
...@@ -723,19 +715,19 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -723,19 +715,19 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
// need it as the value of the whole expression. // need it as the value of the whole expression.
if (left->AsLiteral() != NULL) { if (left->AsLiteral() != NULL) {
__ mov(eax, left->AsLiteral()->handle()); __ mov(eax, left->AsLiteral()->handle());
if (destination.is_value()) __ push(eax); if (context == Expression::kValue) __ push(eax);
} else { } else {
Visit(left); Visit(left);
ASSERT(left->location().is_value()); ASSERT_EQ(Expression::kValue, left->context());
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
// Pop the left-hand value into eax because we will not need it as the // Pop the left-hand value into eax because we will not need it as the
// final result. // final result.
__ pop(eax); __ pop(eax);
break; break;
case Location::kValue: case Expression::kValue:
// Copy the left-hand value into eax because we may need it as the // Copy the left-hand value into eax because we may need it as the
// final result. // final result.
__ mov(eax, Operand(esp, 0)); __ mov(eax, Operand(esp, 0));
...@@ -752,7 +744,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -752,7 +744,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
__ j(equal, left_true); __ j(equal, left_true);
__ cmp(eax, Factory::false_value()); // False is false. __ cmp(eax, Factory::false_value()); // False is false.
__ j(equal, left_false); __ j(equal, left_false);
ASSERT(kSmiTag == 0); ASSERT_EQ(0, kSmiTag);
__ test(eax, Operand(eax)); // The smi zero is false. __ test(eax, Operand(eax)); // The smi zero is false.
__ j(zero, left_false); __ j(zero, left_false);
__ test(eax, Immediate(kSmiTagMask)); // All other smis are true. __ test(eax, Immediate(kSmiTagMask)); // All other smis are true.
...@@ -771,12 +763,12 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -771,12 +763,12 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
__ bind(&eval_right); __ bind(&eval_right);
// Discard the left-hand value if present on the stack. // Discard the left-hand value if present on the stack.
if (destination.is_value()) { if (context == Expression::kValue) {
__ add(Operand(esp), Immediate(kPointerSize)); __ add(Operand(esp), Immediate(kPointerSize));
} }
// Save or discard the right-hand value as needed. // Save or discard the right-hand value as needed.
Visit(right); Visit(right);
ASSERT_EQ(destination.type(), right->location().type()); ASSERT_EQ(context, right->context());
__ bind(&done); __ bind(&done);
} }
......
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_LOCATION_H_
#define V8_LOCATION_H_
#include "utils.h"
namespace v8 {
namespace internal {
class Location BASE_EMBEDDED {
public:
enum Type {
kUninitialized,
kEffect,
kValue
};
static Location Uninitialized() { return Location(kUninitialized); }
static Location Effect() { return Location(kEffect); }
static Location Value() { return Location(kValue); }
bool is_effect() { return type_ == kEffect; }
bool is_value() { return type_ == kValue; }
Type type() { return type_; }
private:
explicit Location(Type type) : type_(type) {}
Type type_;
};
} } // namespace v8::internal
#endif // V8_LOCATION_H_
...@@ -116,52 +116,41 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { ...@@ -116,52 +116,41 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
} }
void FastCodeGenerator::Move(Location destination, Slot* source) { void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ push(Operand(rbp, SlotOffset(source))); __ push(Operand(rbp, SlotOffset(source)));
break; break;
} }
} }
void FastCodeGenerator::Move(Location destination, Literal* expr) { void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
break; break;
case Location::kValue: case Expression::kValue:
__ Push(expr->handle()); __ Push(expr->handle());
break; break;
} }
} }
void FastCodeGenerator::Move(Slot* destination, Location source) { void FastCodeGenerator::DropAndMove(Expression::Context context,
switch (source.type()) { Register source) {
case Location::kUninitialized: // Fall through. switch (context) {
case Location::kEffect: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kValue: case Expression::kEffect:
__ pop(Operand(rbp, SlotOffset(destination)));
break;
}
}
void FastCodeGenerator::DropAndMove(Location destination, Register source) {
switch (destination.type()) {
case Location::kUninitialized:
UNREACHABLE();
case Location::kEffect:
__ addq(rsp, Immediate(kPointerSize)); __ addq(rsp, Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
__ movq(Operand(rsp, 0), source); __ movq(Operand(rsp, 0), source);
break; break;
} }
...@@ -182,12 +171,12 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { ...@@ -182,12 +171,12 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement"); Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt); SetStatementPosition(stmt);
Expression* expr = stmt->expression(); Expression* expr = stmt->expression();
// Complete the statement based on the type of the subexpression.
if (expr->AsLiteral() != NULL) { if (expr->AsLiteral() != NULL) {
__ Move(rax, expr->AsLiteral()->handle()); __ Move(rax, expr->AsLiteral()->handle());
} else { } else {
Visit(expr); Visit(expr);
Move(rax, expr->location()); ASSERT_EQ(Expression::kValue, expr->context());
__ pop(rax);
} }
if (FLAG_trace) { if (FLAG_trace) {
...@@ -226,7 +215,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -226,7 +215,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
__ push(rsi); __ push(rsi);
__ Push(boilerplate); __ Push(boilerplate);
__ CallRuntime(Runtime::kNewClosure, 2); __ CallRuntime(Runtime::kNewClosure, 2);
Move(expr->location(), rax); Move(expr->context(), rax);
} }
...@@ -245,10 +234,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { ...@@ -245,10 +234,10 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
// A test rax instruction following the call is used by the IC to // A test rax instruction following the call is used by the IC to
// indicate that the inobject property case was inlined. Ensure there // indicate that the inobject property case was inlined. Ensure there
// is no test rax instruction here. // is no test rax instruction here.
DropAndMove(expr->location(), rax); DropAndMove(expr->context(), rax);
} else { } else {
Comment cmnt(masm_, "Stack slot"); Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot()); Move(expr->context(), rewrite->AsSlot());
} }
} }
...@@ -276,7 +265,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -276,7 +265,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done: // Label done:
__ bind(&done); __ bind(&done);
Move(expr->location(), rax); Move(expr->context(), rax);
} }
...@@ -329,7 +318,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -329,7 +318,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED: case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) { if (key->handle()->IsSymbol()) {
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ pop(rax); __ pop(rax);
__ Move(rcx, key->handle()); __ Move(rcx, key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
...@@ -341,9 +330,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -341,9 +330,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::PROTOTYPE: case ObjectLiteral::Property::PROTOTYPE:
__ push(rax); __ push(rax);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3); __ CallRuntime(Runtime::kSetProperty, 3);
__ movq(rax, Operand(rsp, 0)); // Restore result into rax. __ movq(rax, Operand(rsp, 0)); // Restore result into rax.
break; break;
...@@ -351,25 +340,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -351,25 +340,25 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::GETTER: case ObjectLiteral::Property::GETTER:
__ push(rax); __ push(rax);
Visit(key); Visit(key);
ASSERT(key->location().is_value()); ASSERT_EQ(Expression::kValue, key->context());
__ Push(property->kind() == ObjectLiteral::Property::SETTER ? __ Push(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) : Smi::FromInt(1) :
Smi::FromInt(0)); Smi::FromInt(0));
Visit(value); Visit(value);
ASSERT(value->location().is_value()); ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4); __ CallRuntime(Runtime::kDefineAccessor, 4);
__ movq(rax, Operand(rsp, 0)); // Restore result into rax. __ movq(rax, Operand(rsp, 0)); // Restore result into rax.
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ addq(rsp, Immediate(kPointerSize)); if (result_saved) __ addq(rsp, Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(rax); if (!result_saved) __ push(rax);
break; break;
} }
...@@ -424,7 +413,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -424,7 +413,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
result_saved = true; result_saved = true;
} }
Visit(subexpr); Visit(subexpr);
ASSERT(subexpr->location().is_value()); ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements. // Store the subexpression value in the array's elements.
__ pop(rax); // Subexpression value. __ pop(rax); // Subexpression value.
...@@ -437,13 +426,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -437,13 +426,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ RecordWrite(rbx, offset, rax, rcx); __ RecordWrite(rbx, offset, rax, rcx);
} }
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
if (result_saved) __ addq(rsp, Immediate(kPointerSize)); if (result_saved) __ addq(rsp, Immediate(kPointerSize));
break; break;
case Location::kValue: case Expression::kValue:
if (!result_saved) __ push(rax); if (!result_saved) __ push(rax);
break; break;
} }
...@@ -473,7 +462,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -473,7 +462,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment // NAMED property assignment
Visit(rhs); Visit(rhs);
Move(rax, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(rax);
__ Move(rcx, literal_key->handle()); __ Move(rcx, literal_key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
...@@ -482,7 +472,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -482,7 +472,8 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// KEYED property assignment // KEYED property assignment
Visit(prop->key()); Visit(prop->key());
Visit(rhs); Visit(rhs);
Move(rax, rhs->location()); ASSERT_EQ(Expression::kValue, rhs->context());
__ pop(rax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
__ nop(); __ nop();
...@@ -490,7 +481,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -490,7 +481,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
__ addq(rsp, Immediate(kPointerSize)); __ addq(rsp, Immediate(kPointerSize));
} }
// Overwrite the receiver on the stack with the result if needed. // Overwrite the receiver on the stack with the result if needed.
DropAndMove(expr->location(), rax); DropAndMove(expr->context(), rax);
} else if (var->is_global()) { } else if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side // Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in rax, variable name in rcx, and the global object // value is passed in rax, variable name in rcx, and the global object
...@@ -500,7 +491,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -500,7 +491,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
if (rhs->AsLiteral() != NULL) { if (rhs->AsLiteral() != NULL) {
__ Move(rax, rhs->AsLiteral()->handle()); __ Move(rax, rhs->AsLiteral()->handle());
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
__ pop(rax); __ pop(rax);
} }
...@@ -509,7 +500,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -509,7 +500,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed. // Overwrite the global object on the stack with the result if needed.
DropAndMove(expr->location(), rax); DropAndMove(expr->context(), rax);
} else { } else {
// Local or parameter assignment. // Local or parameter assignment.
...@@ -519,18 +510,18 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -519,18 +510,18 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
// discarded result. Always perform the assignment. // discarded result. Always perform the assignment.
__ Move(kScratchRegister, rhs->AsLiteral()->handle()); __ Move(kScratchRegister, rhs->AsLiteral()->handle());
__ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
Move(expr->location(), kScratchRegister); Move(expr->context(), kScratchRegister);
} else { } else {
ASSERT(rhs->location().is_value()); ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs); Visit(rhs);
switch (expr->location().type()) { switch (expr->context()) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary. // Case 'var = temp'. Discard right-hand-side temporary.
Move(var->slot(), rhs->location()); __ pop(Operand(rbp, SlotOffset(var->slot())));
break; break;
case Location::kValue: case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack. // temporary on the stack.
__ movq(kScratchRegister, Operand(rsp, 0)); __ movq(kScratchRegister, Operand(rsp, 0));
...@@ -574,7 +565,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -574,7 +565,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
// Drop key left on the stack by IC. // Drop key left on the stack by IC.
__ addq(rsp, Immediate(kPointerSize)); __ addq(rsp, Immediate(kPointerSize));
} }
DropAndMove(expr->location(), rax); DropAndMove(expr->context(), rax);
} }
...@@ -591,7 +582,7 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -591,7 +582,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
// Record source position for debugger // Record source position for debugger
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
...@@ -602,36 +593,36 @@ void FastCodeGenerator::VisitCall(Call* expr) { ...@@ -602,36 +593,36 @@ void FastCodeGenerator::VisitCall(Call* expr) {
// Restore context register. // Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS. // Discard the function left on TOS.
DropAndMove(expr->location(), rax); DropAndMove(expr->context(), rax);
} }
void FastCodeGenerator::VisitCallNew(CallNew* node) { void FastCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew"); Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function // According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the // expression in new calls must be evaluated before the
// arguments. // arguments.
// Push function on the stack. // Push function on the stack.
Visit(node->expression()); Visit(expr->expression());
ASSERT(node->expression()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->expression()->context());
// If location is value, already on the stack, // If location is value, already on the stack,
// Push global object (receiver). // Push global object (receiver).
__ push(CodeGenerator::GlobalObject()); __ push(CodeGenerator::GlobalObject());
// Push the arguments ("left-to-right") on the stack. // Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = node->arguments(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
// If location is value, it is already on the stack, // If location is value, it is already on the stack,
// so nothing to do here. // so nothing to do here.
} }
// Call the construct call builtin that handles allocation and // Call the construct call builtin that handles allocation and
// constructor invocation. // constructor invocation.
SetSourcePosition(node->position()); SetSourcePosition(expr->position());
// Load function, arg_count into rdi and rax. // Load function, arg_count into rdi and rax.
__ Set(rax, arg_count); __ Set(rax, arg_count);
...@@ -642,7 +633,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) { ...@@ -642,7 +633,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* node) {
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in rax, or pop it. // Replace function on TOS with result in rax, or pop it.
DropAndMove(node->location(), rax); DropAndMove(expr->context(), rax);
} }
...@@ -657,19 +648,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -657,19 +648,19 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
int arg_count = args->length(); int arg_count = args->length();
for (int i = 0; i < arg_count; i++) { for (int i = 0; i < arg_count; i++) {
Visit(args->at(i)); Visit(args->at(i));
ASSERT(args->at(i)->location().is_value()); ASSERT_EQ(Expression::kValue, args->at(i)->context());
} }
__ CallRuntime(function, arg_count); __ CallRuntime(function, arg_count);
Move(expr->location(), rax); Move(expr->context(), rax);
} }
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT(expr->left()->location().is_effect()); ASSERT_EQ(Expression::kEffect, expr->left()->context());
ASSERT_EQ(expr->right()->location().type(), expr->location().type()); ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -690,8 +681,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -690,8 +681,8 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SHL: case Token::SHL:
case Token::SHR: case Token::SHR:
case Token::SAR: { case Token::SAR: {
ASSERT(expr->left()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->left()->context());
ASSERT(expr->right()->location().is_value()); ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left()); Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
...@@ -699,7 +690,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -699,7 +690,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
NO_OVERWRITE, NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS); NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub); __ CallStub(&stub);
Move(expr->location(), rax); Move(expr->context(), rax);
break; break;
} }
...@@ -726,7 +717,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -726,7 +717,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
left_true = &eval_right; left_true = &eval_right;
left_false = &done; left_false = &done;
} }
Location destination = expr->location(); Expression::Context context = expr->context();
Expression* left = expr->left(); Expression* left = expr->left();
Expression* right = expr->right(); Expression* right = expr->right();
...@@ -738,19 +729,19 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -738,19 +729,19 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
// need it as the value of the whole expression. // need it as the value of the whole expression.
if (left->AsLiteral() != NULL) { if (left->AsLiteral() != NULL) {
__ Move(rax, left->AsLiteral()->handle()); __ Move(rax, left->AsLiteral()->handle());
if (destination.is_value()) __ push(rax); if (context == Expression::kValue) __ push(rax);
} else { } else {
Visit(left); Visit(left);
ASSERT(left->location().is_value()); ASSERT_EQ(Expression::kValue, left->context());
switch (destination.type()) { switch (context) {
case Location::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Location::kEffect: case Expression::kEffect:
// Pop the left-hand value into rax because we will not need it as the // Pop the left-hand value into rax because we will not need it as the
// final result. // final result.
__ pop(rax); __ pop(rax);
break; break;
case Location::kValue: case Expression::kValue:
// Copy the left-hand value into rax because we may need it as the // Copy the left-hand value into rax because we may need it as the
// final result. // final result.
__ movq(rax, Operand(rsp, 0)); __ movq(rax, Operand(rsp, 0));
...@@ -787,12 +778,12 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { ...@@ -787,12 +778,12 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
__ bind(&eval_right); __ bind(&eval_right);
// Discard the left-hand value if present on the stack. // Discard the left-hand value if present on the stack.
if (destination.is_value()) { if (context == Expression::kValue) {
__ addq(rsp, Immediate(kPointerSize)); __ addq(rsp, Immediate(kPointerSize));
} }
// Save or discard the right-hand value as needed. // Save or discard the right-hand value as needed.
Visit(right); Visit(right);
ASSERT_EQ(destination.type(), right->location().type()); ASSERT_EQ(context, right->context());
__ bind(&done); __ bind(&done);
} }
......
...@@ -293,7 +293,6 @@ ...@@ -293,7 +293,6 @@
'../../src/jsregexp.h', '../../src/jsregexp.h',
'../../src/list-inl.h', '../../src/list-inl.h',
'../../src/list.h', '../../src/list.h',
'../../src/location.h',
'../../src/log-inl.h', '../../src/log-inl.h',
'../../src/log-utils.cc', '../../src/log-utils.cc',
'../../src/log-utils.h', '../../src/log-utils.h',
......
...@@ -556,10 +556,6 @@ ...@@ -556,10 +556,6 @@
RelativePath="..\..\src\list.h" RelativePath="..\..\src\list.h"
> >
</File> </File>
<File
RelativePath="..\..\src\location.h"
>
</File>
<File <File
RelativePath="..\..\src\log.cc" RelativePath="..\..\src\log.cc"
> >
......
...@@ -560,10 +560,6 @@ ...@@ -560,10 +560,6 @@
RelativePath="..\..\src\list.h" RelativePath="..\..\src\list.h"
> >
</File> </File>
<File
RelativePath="..\..\src\location.h"
>
</File>
<File <File
RelativePath="..\..\src\log.cc" RelativePath="..\..\src\log.cc"
> >
......
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