}
-void FastCodeGenerator::Move(Location destination, Slot* source) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ ldr(ip, MemOperand(fp, SlotOffset(source)));
__ push(ip);
break;
}
-void FastCodeGenerator::Move(Location destination, Literal* expr) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ mov(ip, Operand(expr->handle()));
__ push(ip);
break;
}
-void FastCodeGenerator::Move(Slot* destination, Location source) {
- switch (source.type()) {
- case Location::kUninitialized: // Fall through.
- case Location::kEffect:
+void FastCodeGenerator::DropAndMove(Expression::Context context,
+ Register source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kValue:
- __ 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:
+ case Expression::kEffect:
__ pop();
break;
- case Location::kValue:
+ case Expression::kValue:
__ str(source, MemOperand(sp));
break;
}
if (expr->AsLiteral() != NULL) {
__ mov(r0, Operand(expr->AsLiteral()->handle()));
} else {
+ ASSERT_EQ(Expression::kValue, expr->context());
Visit(expr);
- Move(r0, expr->location());
+ __ pop(r0);
}
if (FLAG_trace) {
__ mov(r0, Operand(boilerplate));
__ stm(db_w, sp, cp.bit() | r0.bit());
__ CallRuntime(Runtime::kNewClosure, 2);
- Move(expr->location(), r0);
+ Move(expr->context(), r0);
}
__ mov(r2, Operand(expr->name()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
- DropAndMove(expr->location(), r0);
+ DropAndMove(expr->context(), r0);
} else {
Comment cmnt(masm_, "Stack slot");
- Move(expr->location(), rewrite->AsSlot());
+ Move(expr->context(), rewrite->AsSlot());
}
}
__ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
__ bind(&done);
- Move(expr->location(), r0);
+ Move(expr->context(), r0);
}
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Visit(value);
- Move(r0, value->location());
+ ASSERT_EQ(Expression::kValue, value->context());
+ __ pop(r0);
__ mov(r2, Operand(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
case ObjectLiteral::Property::PROTOTYPE:
__ push(r0);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3);
__ ldr(r0, MemOperand(sp)); // Restore result into r0
break;
case ObjectLiteral::Property::SETTER:
__ push(r0);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
__ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) :
Smi::FromInt(0)));
__ push(r1);
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4);
__ ldr(r0, MemOperand(sp)); // Restore result into r0
break;
}
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ pop();
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(r0);
break;
}
result_saved = true;
}
Visit(subexpr);
- ASSERT(subexpr->location().is_value());
+ ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements.
__ pop(r0); // Subexpression value.
__ RecordWrite(r1, r2, r0);
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ pop();
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(r0);
break;
}
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment
Visit(rhs);
- Move(r0, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(r0);
__ mov(r2, Operand(literal_key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// KEYED property assignment
Visit(prop->key());
Visit(rhs);
- Move(r0, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(r0);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Drop key from the stack
__ pop();
}
// Overwrite the receiver on the stack with the result if needed.
- DropAndMove(expr->location(), r0);
+ DropAndMove(expr->context(), r0);
} else if (var->is_global()) {
// 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
if (rhs->AsLiteral() != NULL) {
__ mov(r0, Operand(rhs->AsLiteral()->handle()));
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
__ pop(r0);
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- DropAndMove(expr->location(), r0);
+ DropAndMove(expr->context(), r0);
} else {
// Local or parameter assignment.
// discarded result. Always perform the assignment.
__ mov(ip, Operand(rhs->AsLiteral()->handle()));
__ str(ip, MemOperand(fp, SlotOffset(var->slot())));
- Move(expr->location(), ip);
+ Move(expr->context(), ip);
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
// Load right-hand side into ip.
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary.
__ pop(ip);
break;
- case Location::kValue:
+ case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack.
__ ldr(ip, MemOperand(sp));
// Drop key and receiver left on the stack by IC.
__ pop();
}
- DropAndMove(expr->location(), r0);
+ DropAndMove(expr->context(), r0);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; 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
SetSourcePosition(expr->position());
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
// Restore context register.
__ 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");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
// arguments.
// Push function on the stack.
- Visit(node->expression());
- ASSERT(node->expression()->location().is_value());
+ Visit(expr->expression());
+ ASSERT_EQ(Expression::kValue, expr->expression()->context());
// Push global object (receiver).
__ ldr(r0, CodeGenerator::GlobalObject());
__ push(r0);
// Push the arguments ("left-to-right") on the stack.
- ZoneList<Expression*>* args = node->arguments();
+ ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; 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,
// so nothing to do here.
}
// Call the construct call builtin that handles allocation and
// constructor invocation.
- SetSourcePosition(node->position());
+ SetSourcePosition(expr->position());
// Load function, arg_count into r1 and r0.
__ mov(r0, Operand(arg_count));
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in r0, or pop it.
- DropAndMove(node->location(), r0);
+ DropAndMove(expr->context(), r0);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Visit(args->at(i));
- ASSERT(args->at(i)->location().is_value());
+ ASSERT_EQ(Expression::kValue, args->at(i)->context());
}
__ CallRuntime(function, arg_count);
- Move(expr->location(), r0);
+ Move(expr->context(), r0);
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) {
case Token::COMMA:
- ASSERT(expr->left()->location().is_effect());
- ASSERT_EQ(expr->right()->location().type(), expr->location().type());
+ ASSERT_EQ(Expression::kEffect, expr->left()->context());
+ ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right());
break;
case Token::SHL:
case Token::SHR:
case Token::SAR: {
- ASSERT(expr->left()->location().is_value());
- ASSERT(expr->right()->location().is_value());
+ ASSERT_EQ(Expression::kValue, expr->left()->context());
+ ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left());
Visit(expr->right());
GenericBinaryOpStub stub(expr->op(),
NO_OVERWRITE);
__ CallStub(&stub);
- Move(expr->location(), r0);
+ Move(expr->context(), r0);
break;
}
// (let (temp = e0) !temp ? temp : e1).
Label done;
- Location destination = expr->location();
+ Expression::Context context = expr->context();
Expression* left = expr->left();
Expression* right = expr->right();
if (left->AsLiteral() != NULL) {
__ mov(r0, Operand(left->AsLiteral()->handle()));
__ push(r0);
- if (destination.is_value()) __ push(r0);
+ if (context == Expression::kValue) __ push(r0);
} else {
Visit(left);
- ASSERT(left->location().is_value());
- if (destination.is_value()) {
+ ASSERT_EQ(Expression::kValue, left->context());
+ if (context == Expression::kValue) {
__ ldr(r0, MemOperand(sp));
__ push(r0);
}
__ b(eq, &done);
// 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.
Visit(right);
- ASSERT_EQ(destination.type(), right->location().type());
+ ASSERT_EQ(context, right->context());
__ bind(&done);
}
#ifndef V8_AST_H_
#define V8_AST_H_
-#include "location.h"
#include "execution.h"
#include "factory.h"
#include "jsregexp.h"
class Expression: public AstNode {
public:
- Expression() : location_(Location::Uninitialized()) {}
+ enum Context {
+ kUninitialized,
+ kEffect,
+ kValue
+ };
+
+ Expression() : context_(kUninitialized) {}
virtual Expression* AsExpression() { return this; }
// Static type information for this expression.
SmiAnalysis* type() { return &type_; }
- Location location() { return location_; }
- void set_location(Location loc) { location_ = loc; }
+ Context context() { return context_; }
+ void set_context(Context context) { context_ = context; }
private:
SmiAnalysis type_;
- Location location_;
+ Context context_;
};
CodeGenSelector()
: has_supported_syntax_(true),
- location_(Location::Uninitialized()) {
+ context_(Expression::kUninitialized) {
}
CodeGenTag Select(FunctionLiteral* fun);
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 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.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
bool has_supported_syntax_;
- // The desired location of the currently visited expression.
- Location location_;
+ // The desired expression context of the currently visited expression.
+ Expression::Context context_;
DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
};
}
-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) {
Variable* var = decl->proxy()->var();
if (!var->is_global() || var->mode() == Variable::CONST) {
void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
- VisitAsEffect(stmt->expression());
+ ProcessExpression(stmt->expression(), Expression::kEffect);
}
void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
- VisitAsValue(stmt->expression());
+ ProcessExpression(stmt->expression(), Expression::kValue);
}
if (!expr->AllowsLazyCompilation()) {
BAILOUT("FunctionLiteral does not allow lazy compilation");
}
- expr->set_location(location_);
}
BAILOUT("non-parameter/non-local slot reference");
}
}
- expr->set_location(location_);
}
void CodeGenSelector::VisitLiteral(Literal* expr) {
- expr->set_location(location_);
+ /* Nothing to do. */
}
void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {
- expr->set_location(location_);
+ /* Nothing to do. */
}
case ObjectLiteral::Property::GETTER: // Fall through.
case ObjectLiteral::Property::SETTER: // Fall through.
case ObjectLiteral::Property::PROTOTYPE:
- VisitAsValue(property->key());
+ ProcessExpression(property->key(), Expression::kValue);
CHECK_BAILOUT;
break;
}
- VisitAsValue(property->value());
+ ProcessExpression(property->value(), Expression::kValue);
CHECK_BAILOUT;
}
- expr->set_location(location_);
}
Expression* subexpr = subexprs->at(i);
if (subexpr->AsLiteral() != NULL) continue;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
- VisitAsValue(subexpr);
+ ProcessExpression(subexpr, Expression::kValue);
CHECK_BAILOUT;
}
- expr->set_location(location_);
}
if (var == NULL) {
Property* prop = expr->target()->AsProperty();
if (prop == NULL) BAILOUT("non-variable, non-property assignment");
- VisitAsValue(prop->obj());
+ ProcessExpression(prop->obj(), Expression::kValue);
CHECK_BAILOUT;
- VisitAsValue(prop->key());
+ ProcessExpression(prop->key(), Expression::kValue);
} else if (!var->is_global()) {
if (var->slot() == NULL) BAILOUT("Assigment with an unsupported LHS.");
Slot::Type type = var->slot()->type();
}
}
- VisitAsValue(expr->value());
- expr->set_location(location_);
+ ProcessExpression(expr->value(), Expression::kValue);
}
void CodeGenSelector::VisitProperty(Property* expr) {
- VisitAsValue(expr->obj());
+ ProcessExpression(expr->obj(), Expression::kValue);
CHECK_BAILOUT;
- VisitAsValue(expr->key());
- expr->set_location(location_);
+ ProcessExpression(expr->key(), Expression::kValue);
}
}
// Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < args->length(); i++) {
- VisitAsValue(args->at(i));
+ ProcessExpression(args->at(i), Expression::kValue);
CHECK_BAILOUT;
}
- expr->set_location(location_);
}
void CodeGenSelector::VisitCallNew(CallNew* expr) {
- VisitAsValue(expr->expression());
+ ProcessExpression(expr->expression(), Expression::kValue);
CHECK_BAILOUT;
ZoneList<Expression*>* args = expr->arguments();
// Check all arguments to the call
for (int i = 0; i < args->length(); i++) {
- VisitAsValue(args->at(i));
+ ProcessExpression(args->at(i), Expression::kValue);
CHECK_BAILOUT;
}
- expr->set_location(location_);
}
}
// Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < expr->arguments()->length(); i++) {
- VisitAsValue(expr->arguments()->at(i));
+ ProcessExpression(expr->arguments()->at(i), Expression::kValue);
CHECK_BAILOUT;
}
- expr->set_location(location_);
}
void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) {
case Token::COMMA:
- VisitAsEffect(expr->left());
+ ProcessExpression(expr->left(), Expression::kEffect);
CHECK_BAILOUT;
- Visit(expr->right()); // Location is the same as the parent location.
+ ProcessExpression(expr->right(), context_);
break;
case Token::OR:
- VisitAsValue(expr->left());
+ ProcessExpression(expr->left(), Expression::kValue);
CHECK_BAILOUT;
- // The location for the right subexpression is the same as for the
- // whole expression so we call Visit directly.
- Visit(expr->right());
+ ProcessExpression(expr->right(), context_);
break;
case Token::ADD:
case Token::SHL:
case Token::SHR:
case Token::SAR:
- VisitAsValue(expr->left());
+ ProcessExpression(expr->left(), Expression::kValue);
CHECK_BAILOUT;
- VisitAsValue(expr->right());
+ ProcessExpression(expr->right(), Expression::kValue);
break;
default:
BAILOUT("Unsupported binary operation");
}
- expr->set_location(location_);
}
// All platform macro assemblers in {ia32,x64,arm} have a push(Register)
// function.
-void FastCodeGenerator::Move(Location destination, Register source) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Register source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
masm_->push(source);
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(
ZoneList<Declaration*>* declarations) {
int length = declarations->length();
void FastCodeGenerator::VisitLiteral(Literal* expr) {
- Move(expr->location(), expr);
+ Move(expr->context(), expr);
}
private:
int SlotOffset(Slot* slot);
- void Move(Location destination, Register source);
- void Move(Location destination, Slot* source);
- void Move(Location destination, Literal* source);
-
- void Move(Register destination, Location source);
- void Move(Slot* destination, Location source);
+ void Move(Expression::Context destination, Register source);
+ void Move(Expression::Context destination, Slot* source);
+ void Move(Expression::Context destination, Literal* source);
// Drop the TOS, and store source to destination.
// 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);
Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun);
}
-void FastCodeGenerator::Move(Location destination, Slot* source) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ push(Operand(ebp, SlotOffset(source)));
break;
}
}
-void FastCodeGenerator::Move(Location destination, Literal* expr) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ push(Immediate(expr->handle()));
break;
}
}
-void FastCodeGenerator::Move(Slot* destination, Location source) {
- switch (source.type()) {
- case Location::kUninitialized: // Fall through.
- case Location::kEffect:
+void FastCodeGenerator::DropAndMove(Expression::Context context,
+ Register source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kValue:
- __ pop(Operand(ebp, SlotOffset(destination)));
- break;
- }
-}
-
-
-void FastCodeGenerator::DropAndMove(Location destination, Register source) {
- switch (destination.type()) {
- case Location::kUninitialized:
- UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
__ add(Operand(esp), Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
__ mov(Operand(esp, 0), source);
break;
}
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
Expression* expr = stmt->expression();
- // Complete the statement based on the type of the subexpression.
if (expr->AsLiteral() != NULL) {
__ mov(eax, expr->AsLiteral()->handle());
} else {
+ ASSERT_EQ(Expression::kValue, expr->context());
Visit(expr);
- Move(eax, expr->location());
+ __ pop(eax);
}
if (FLAG_trace) {
__ push(esi);
__ push(Immediate(boilerplate));
__ CallRuntime(Runtime::kNewClosure, 2);
- Move(expr->location(), eax);
+ Move(expr->context(), eax);
}
// (eg, push/pop elimination).
__ nop();
- DropAndMove(expr->location(), eax);
+ DropAndMove(expr->context(), eax);
} else {
Comment cmnt(masm_, "Stack slot");
- Move(expr->location(), rewrite->AsSlot());
+ Move(expr->context(), rewrite->AsSlot());
}
}
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done:
__ bind(&done);
- Move(expr->location(), eax);
+ Move(expr->context(), eax);
}
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Visit(value);
- Move(eax, value->location());
+ ASSERT_EQ(Expression::kValue, value->context());
+ __ pop(eax);
__ mov(ecx, Immediate(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
case ObjectLiteral::Property::PROTOTYPE:
__ push(eax);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3);
__ mov(eax, Operand(esp, 0)); // Restore result into eax.
break;
case ObjectLiteral::Property::GETTER:
__ push(eax);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
__ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) :
Smi::FromInt(0)));
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4);
__ mov(eax, Operand(esp, 0)); // Restore result into eax.
break;
default: UNREACHABLE();
}
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(eax);
break;
}
result_saved = true;
}
Visit(subexpr);
- ASSERT(subexpr->location().is_value());
+ ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements.
__ pop(eax); // Subexpression value.
__ RecordWrite(ebx, offset, eax, ecx);
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(eax);
break;
}
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment
Visit(rhs);
- Move(eax, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(eax);
__ mov(ecx, Immediate(literal_key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// KEYED property assignment
Visit(prop->key());
Visit(rhs);
- Move(eax, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(eax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ add(Operand(esp), Immediate(kPointerSize));
}
// Overwrite the receiver on the stack with the result if needed.
- DropAndMove(expr->location(), eax);
+ DropAndMove(expr->context(), eax);
} else if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in eax, variable name in ecx, and the global object
if (rhs->AsLiteral() != NULL) {
__ mov(eax, rhs->AsLiteral()->handle());
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
__ pop(eax);
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- DropAndMove(expr->location(), eax);
+ DropAndMove(expr->context(), eax);
} else {
// Local or parameter assignment.
ASSERT(var->slot() != NULL);
// discarded result. Always perform the assignment.
__ mov(eax, rhs->AsLiteral()->handle());
__ mov(Operand(ebp, SlotOffset(var->slot())), eax);
- Move(expr->location(), eax);
+ Move(expr->context(), eax);
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary.
- Move(var->slot(), rhs->location());
+ __ pop(Operand(ebp, SlotOffset(var->slot())));
break;
- case Location::kValue:
+ case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack.
__ mov(eax, Operand(esp, 0));
// Drop key left on the stack by IC.
__ add(Operand(esp), Immediate(kPointerSize));
}
- DropAndMove(expr->location(), eax);
+ DropAndMove(expr->context(), eax);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; 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
SetSourcePosition(expr->position());
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
// 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");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
// arguments.
// Push function on the stack.
- Visit(node->expression());
- ASSERT(node->expression()->location().is_value());
+ Visit(expr->expression());
+ ASSERT_EQ(Expression::kValue, expr->expression()->context());
// Push global object (receiver).
__ push(CodeGenerator::GlobalObject());
// Push the arguments ("left-to-right") on the stack.
- ZoneList<Expression*>* args = node->arguments();
+ ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; 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,
// so nothing to do here.
}
// Call the construct call builtin that handles allocation and
// constructor invocation.
- SetSourcePosition(node->position());
+ SetSourcePosition(expr->position());
// Load function, arg_count into edi and eax.
__ Set(eax, Immediate(arg_count));
__ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in eax, or pop it.
- DropAndMove(node->location(), eax);
+ DropAndMove(expr->context(), eax);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Visit(args->at(i));
- ASSERT(args->at(i)->location().is_value());
+ ASSERT_EQ(Expression::kValue, args->at(i)->context());
}
__ CallRuntime(function, arg_count);
- Move(expr->location(), eax);
+ Move(expr->context(), eax);
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) {
case Token::COMMA:
- ASSERT(expr->left()->location().is_effect());
- ASSERT_EQ(expr->right()->location().type(), expr->location().type());
+ ASSERT_EQ(Expression::kValue, expr->left()->context());
+ ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right());
break;
case Token::SHL:
case Token::SHR:
case Token::SAR: {
- ASSERT(expr->left()->location().is_value());
- ASSERT(expr->right()->location().is_value());
+ ASSERT_EQ(Expression::kValue, expr->left()->context());
+ ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left());
Visit(expr->right());
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub);
- Move(expr->location(), eax);
+ Move(expr->context(), eax);
break;
}
left_true = &eval_right;
left_false = &done;
}
- Location destination = expr->location();
+ Expression::Context context = expr->context();
Expression* left = expr->left();
Expression* right = expr->right();
// need it as the value of the whole expression.
if (left->AsLiteral() != NULL) {
__ mov(eax, left->AsLiteral()->handle());
- if (destination.is_value()) __ push(eax);
+ if (context == Expression::kValue) __ push(eax);
} else {
Visit(left);
- ASSERT(left->location().is_value());
- switch (destination.type()) {
- case Location::kUninitialized:
+ ASSERT_EQ(Expression::kValue, left->context());
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
// Pop the left-hand value into eax because we will not need it as the
// final result.
__ pop(eax);
break;
- case Location::kValue:
+ case Expression::kValue:
// Copy the left-hand value into eax because we may need it as the
// final result.
__ mov(eax, Operand(esp, 0));
__ j(equal, left_true);
__ cmp(eax, Factory::false_value()); // False is false.
__ j(equal, left_false);
- ASSERT(kSmiTag == 0);
+ ASSERT_EQ(0, kSmiTag);
__ test(eax, Operand(eax)); // The smi zero is false.
__ j(zero, left_false);
__ test(eax, Immediate(kSmiTagMask)); // All other smis are true.
__ bind(&eval_right);
// Discard the left-hand value if present on the stack.
- if (destination.is_value()) {
+ if (context == Expression::kValue) {
__ add(Operand(esp), Immediate(kPointerSize));
}
// Save or discard the right-hand value as needed.
Visit(right);
- ASSERT_EQ(destination.type(), right->location().type());
+ ASSERT_EQ(context, right->context());
__ bind(&done);
}
+++ /dev/null
-// 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_
}
-void FastCodeGenerator::Move(Location destination, Slot* source) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ push(Operand(rbp, SlotOffset(source)));
break;
}
}
-void FastCodeGenerator::Move(Location destination, Literal* expr) {
- switch (destination.type()) {
- case Location::kUninitialized:
+void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
break;
- case Location::kValue:
+ case Expression::kValue:
__ Push(expr->handle());
break;
}
}
-void FastCodeGenerator::Move(Slot* destination, Location source) {
- switch (source.type()) {
- case Location::kUninitialized: // Fall through.
- case Location::kEffect:
+void FastCodeGenerator::DropAndMove(Expression::Context context,
+ Register source) {
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kValue:
- __ pop(Operand(rbp, SlotOffset(destination)));
- break;
- }
-}
-
-
-void FastCodeGenerator::DropAndMove(Location destination, Register source) {
- switch (destination.type()) {
- case Location::kUninitialized:
- UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
__ addq(rsp, Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
__ movq(Operand(rsp, 0), source);
break;
}
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
Expression* expr = stmt->expression();
- // Complete the statement based on the type of the subexpression.
if (expr->AsLiteral() != NULL) {
__ Move(rax, expr->AsLiteral()->handle());
} else {
Visit(expr);
- Move(rax, expr->location());
+ ASSERT_EQ(Expression::kValue, expr->context());
+ __ pop(rax);
}
if (FLAG_trace) {
__ push(rsi);
__ Push(boilerplate);
__ CallRuntime(Runtime::kNewClosure, 2);
- Move(expr->location(), rax);
+ Move(expr->context(), rax);
}
// A test rax instruction following the call is used by the IC to
// indicate that the inobject property case was inlined. Ensure there
// is no test rax instruction here.
- DropAndMove(expr->location(), rax);
+ DropAndMove(expr->context(), rax);
} else {
Comment cmnt(masm_, "Stack slot");
- Move(expr->location(), rewrite->AsSlot());
+ Move(expr->context(), rewrite->AsSlot());
}
}
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done:
__ bind(&done);
- Move(expr->location(), rax);
+ Move(expr->context(), rax);
}
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ pop(rax);
__ Move(rcx, key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
case ObjectLiteral::Property::PROTOTYPE:
__ push(rax);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kSetProperty, 3);
__ movq(rax, Operand(rsp, 0)); // Restore result into rax.
break;
case ObjectLiteral::Property::GETTER:
__ push(rax);
Visit(key);
- ASSERT(key->location().is_value());
+ ASSERT_EQ(Expression::kValue, key->context());
__ Push(property->kind() == ObjectLiteral::Property::SETTER ?
Smi::FromInt(1) :
Smi::FromInt(0));
Visit(value);
- ASSERT(value->location().is_value());
+ ASSERT_EQ(Expression::kValue, value->context());
__ CallRuntime(Runtime::kDefineAccessor, 4);
__ movq(rax, Operand(rsp, 0)); // Restore result into rax.
break;
default: UNREACHABLE();
}
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ addq(rsp, Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(rax);
break;
}
result_saved = true;
}
Visit(subexpr);
- ASSERT(subexpr->location().is_value());
+ ASSERT_EQ(Expression::kValue, subexpr->context());
// Store the subexpression value in the array's elements.
__ pop(rax); // Subexpression value.
__ RecordWrite(rbx, offset, rax, rcx);
}
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
if (result_saved) __ addq(rsp, Immediate(kPointerSize));
break;
- case Location::kValue:
+ case Expression::kValue:
if (!result_saved) __ push(rax);
break;
}
!String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
// NAMED property assignment
Visit(rhs);
- Move(rax, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(rax);
__ Move(rcx, literal_key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// KEYED property assignment
Visit(prop->key());
Visit(rhs);
- Move(rax, rhs->location());
+ ASSERT_EQ(Expression::kValue, rhs->context());
+ __ pop(rax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ addq(rsp, Immediate(kPointerSize));
}
// Overwrite the receiver on the stack with the result if needed.
- DropAndMove(expr->location(), rax);
+ DropAndMove(expr->context(), rax);
} else if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in rax, variable name in rcx, and the global object
if (rhs->AsLiteral() != NULL) {
__ Move(rax, rhs->AsLiteral()->handle());
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
__ pop(rax);
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- DropAndMove(expr->location(), rax);
+ DropAndMove(expr->context(), rax);
} else {
// Local or parameter assignment.
// discarded result. Always perform the assignment.
__ Move(kScratchRegister, rhs->AsLiteral()->handle());
__ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
- Move(expr->location(), kScratchRegister);
+ Move(expr->context(), kScratchRegister);
} else {
- ASSERT(rhs->location().is_value());
+ ASSERT_EQ(Expression::kValue, rhs->context());
Visit(rhs);
- switch (expr->location().type()) {
- case Location::kUninitialized:
+ switch (expr->context()) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
// Case 'var = temp'. Discard right-hand-side temporary.
- Move(var->slot(), rhs->location());
+ __ pop(Operand(rbp, SlotOffset(var->slot())));
break;
- case Location::kValue:
+ case Expression::kValue:
// Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
// temporary on the stack.
__ movq(kScratchRegister, Operand(rsp, 0));
// Drop key left on the stack by IC.
__ addq(rsp, Immediate(kPointerSize));
}
- DropAndMove(expr->location(), rax);
+ DropAndMove(expr->context(), rax);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; 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
SetSourcePosition(expr->position());
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// 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");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
// arguments.
// Push function on the stack.
- Visit(node->expression());
- ASSERT(node->expression()->location().is_value());
+ Visit(expr->expression());
+ ASSERT_EQ(Expression::kValue, expr->expression()->context());
// If location is value, already on the stack,
// Push global object (receiver).
__ push(CodeGenerator::GlobalObject());
// Push the arguments ("left-to-right") on the stack.
- ZoneList<Expression*>* args = node->arguments();
+ ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; 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,
// so nothing to do here.
}
// Call the construct call builtin that handles allocation and
// constructor invocation.
- SetSourcePosition(node->position());
+ SetSourcePosition(expr->position());
// Load function, arg_count into rdi and rax.
__ Set(rax, arg_count);
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
// Replace function on TOS with result in rax, or pop it.
- DropAndMove(node->location(), rax);
+ DropAndMove(expr->context(), rax);
}
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Visit(args->at(i));
- ASSERT(args->at(i)->location().is_value());
+ ASSERT_EQ(Expression::kValue, args->at(i)->context());
}
__ CallRuntime(function, arg_count);
- Move(expr->location(), rax);
+ Move(expr->context(), rax);
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) {
case Token::COMMA:
- ASSERT(expr->left()->location().is_effect());
- ASSERT_EQ(expr->right()->location().type(), expr->location().type());
+ ASSERT_EQ(Expression::kEffect, expr->left()->context());
+ ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right());
break;
case Token::SHL:
case Token::SHR:
case Token::SAR: {
- ASSERT(expr->left()->location().is_value());
- ASSERT(expr->right()->location().is_value());
+ ASSERT_EQ(Expression::kValue, expr->left()->context());
+ ASSERT_EQ(Expression::kValue, expr->right()->context());
Visit(expr->left());
Visit(expr->right());
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub);
- Move(expr->location(), rax);
+ Move(expr->context(), rax);
break;
}
left_true = &eval_right;
left_false = &done;
}
- Location destination = expr->location();
+ Expression::Context context = expr->context();
Expression* left = expr->left();
Expression* right = expr->right();
// need it as the value of the whole expression.
if (left->AsLiteral() != NULL) {
__ Move(rax, left->AsLiteral()->handle());
- if (destination.is_value()) __ push(rax);
+ if (context == Expression::kValue) __ push(rax);
} else {
Visit(left);
- ASSERT(left->location().is_value());
- switch (destination.type()) {
- case Location::kUninitialized:
+ ASSERT_EQ(Expression::kValue, left->context());
+ switch (context) {
+ case Expression::kUninitialized:
UNREACHABLE();
- case Location::kEffect:
+ case Expression::kEffect:
// Pop the left-hand value into rax because we will not need it as the
// final result.
__ pop(rax);
break;
- case Location::kValue:
+ case Expression::kValue:
// Copy the left-hand value into rax because we may need it as the
// final result.
__ movq(rax, Operand(rsp, 0));
__ bind(&eval_right);
// Discard the left-hand value if present on the stack.
- if (destination.is_value()) {
+ if (context == Expression::kValue) {
__ addq(rsp, Immediate(kPointerSize));
}
// Save or discard the right-hand value as needed.
Visit(right);
- ASSERT_EQ(destination.type(), right->location().type());
+ ASSERT_EQ(context, right->context());
__ bind(&done);
}
'../../src/jsregexp.h',
'../../src/list-inl.h',
'../../src/list.h',
- '../../src/location.h',
'../../src/log-inl.h',
'../../src/log-utils.cc',
'../../src/log-utils.h',
RelativePath="..\..\src\list.h"
>
</File>
- <File
- RelativePath="..\..\src\location.h"
- >
- </File>
<File
RelativePath="..\..\src\log.cc"
>
RelativePath="..\..\src\list.h"
>
</File>
- <File
- RelativePath="..\..\src\location.h"
- >
- </File>
<File
RelativePath="..\..\src\log.cc"
>