First step of refactoring expression contexts in the toplevel code

generator.

Contexts are no longer stored in the AST but in the code generator's
state.  This means that the running the code generator selector is not
required to use the toplevel code generator (for instance, if we
already know that we can and should use it).

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3645 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 712d108e
...@@ -662,13 +662,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -662,13 +662,13 @@ 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);
Apply(expr->context(), r0); Apply(context_, r0);
} }
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy"); Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), expr->context()); EmitVariableLoad(expr->var(), context_);
} }
...@@ -768,7 +768,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -768,7 +768,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);
Apply(expr->context(), r0); Apply(context_, r0);
} }
...@@ -840,9 +840,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -840,9 +840,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), r0); Apply(context_, r0);
} }
} }
...@@ -893,9 +893,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -893,9 +893,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), r0); Apply(context_, r0);
} }
} }
...@@ -1007,7 +1007,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { ...@@ -1007,7 +1007,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ pop(r0); __ pop(r0);
} }
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} }
...@@ -1042,7 +1042,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { ...@@ -1042,7 +1042,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
} }
// Receiver and key are still on stack. // Receiver and key are still on stack.
DropAndApply(2, expr->context(), r0); DropAndApply(2, context_, r0);
} }
...@@ -1056,12 +1056,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -1056,12 +1056,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC. // Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} else { } else {
VisitForValue(expr->key(), kStack); VisitForValue(expr->key(), kStack);
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC. // Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), r0); DropAndApply(2, context_, r0);
} }
} }
...@@ -1083,7 +1083,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr, ...@@ -1083,7 +1083,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS. // Discard the function left on TOS.
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} }
...@@ -1101,7 +1101,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) { ...@@ -1101,7 +1101,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) {
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS. // Discard the function left on TOS.
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} }
...@@ -1207,7 +1207,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) { ...@@ -1207,7 +1207,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
__ 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.
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} }
...@@ -1237,11 +1237,11 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -1237,11 +1237,11 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS. // Discard the function left on TOS.
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} else { } else {
// Call the C runtime function. // Call the C runtime function.
__ CallRuntime(expr->function(), arg_count); __ CallRuntime(expr->function(), arg_count);
Apply(expr->context(), r0); Apply(context_, r0);
} }
} }
...@@ -1250,9 +1250,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1250,9 +1250,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::VOID: { case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)"); Comment cmnt(masm_, "[ UnaryOperation (VOID)");
ASSERT_EQ(Expression::kEffect, expr->expression()->context()); VisitForEffect(expr->expression());
Visit(expr->expression()); switch (context_) {
switch (expr->context()) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1289,14 +1288,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1289,14 +1288,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
case Token::NOT: { case Token::NOT: {
Comment cmnt(masm_, "[ UnaryOperation (NOT)"); Comment cmnt(masm_, "[ UnaryOperation (NOT)");
ASSERT_EQ(Expression::kTest, expr->expression()->context());
Label materialize_true, materialize_false, done; Label materialize_true, materialize_false, done;
// Initially assume a pure test context. Notice that the labels are // Initially assume a pure test context. Notice that the labels are
// swapped. // swapped.
Label* if_true = false_label_; Label* if_true = false_label_;
Label* if_false = true_label_; Label* if_false = true_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1318,14 +1315,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1318,14 +1315,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
VisitForControl(expr->expression(), if_true, if_false); VisitForControl(expr->expression(), if_true, if_false);
Apply(expr->context(), if_false, if_true); // Labels swapped. Apply(context_, if_false, if_true); // Labels swapped.
break; break;
} }
case Token::TYPEOF: { case Token::TYPEOF: {
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
ASSERT_EQ(Expression::kValue, expr->expression()->context());
VariableProxy* proxy = expr->expression()->AsVariableProxy(); VariableProxy* proxy = expr->expression()->AsVariableProxy();
if (proxy != NULL && if (proxy != NULL &&
!proxy->var()->is_this() && !proxy->var()->is_this() &&
...@@ -1352,7 +1347,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1352,7 +1347,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} }
__ CallRuntime(Runtime::kTypeof, 1); __ CallRuntime(Runtime::kTypeof, 1);
Apply(expr->context(), r0); Apply(context_, r0);
break; break;
} }
...@@ -1373,9 +1368,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1373,9 +1368,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// In case of a property we use the uninitialized expression context // In case of a property we use the uninitialized expression context
// of the key to detect a named property. // of the key to detect a named property.
if (prop != NULL) { if (prop != NULL) {
assign_type = (prop->key()->context() == Expression::kUninitialized) assign_type =
? NAMED_PROPERTY (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
: KEYED_PROPERTY;
} }
// Evaluate expression and get value. // Evaluate expression and get value.
...@@ -1388,8 +1382,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1388,8 +1382,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
location_ = saved_location; location_ = saved_location;
} else { } else {
// Reserve space for result of postfix operation. // Reserve space for result of postfix operation.
if (expr->is_postfix() && expr->context() != Expression::kEffect) { if (expr->is_postfix() && context_ != Expression::kEffect) {
ASSERT(expr->context() != Expression::kUninitialized);
__ mov(ip, Operand(Smi::FromInt(0))); __ mov(ip, Operand(Smi::FromInt(0)));
__ push(ip); __ push(ip);
} }
...@@ -1408,7 +1401,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1408,7 +1401,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Save result for postfix expressions. // Save result for postfix expressions.
if (expr->is_postfix()) { if (expr->is_postfix()) {
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Expression::kEffect: case Expression::kEffect:
...@@ -1451,12 +1444,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1451,12 +1444,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Expression::kEffect); Expression::kEffect);
// For all contexts except kEffect: We have the result on // For all contexts except kEffect: We have the result on
// top of the stack. // top of the stack.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
expr->context()); context_);
} }
break; break;
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
...@@ -1465,11 +1458,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1465,11 +1458,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(1); // Result is on the stack under the receiver. __ Drop(1); // Result is on the stack under the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(1, expr->context(), r0); DropAndApply(1, context_, r0);
} }
break; break;
} }
...@@ -1478,11 +1471,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1478,11 +1471,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(2); // Result is on the stack under the key and the receiver. __ Drop(2); // Result is on the stack under the key and the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(2, expr->context(), r0); DropAndApply(2, context_, r0);
} }
break; break;
} }
...@@ -1494,9 +1487,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1494,9 +1487,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation"); Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT_EQ(Expression::kEffect, expr->left()->context()); VisitForEffect(expr->left());
ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -1518,7 +1509,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1518,7 +1509,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SAR: case Token::SAR:
VisitForValue(expr->left(), kStack); VisitForValue(expr->left(), kStack);
VisitForValue(expr->right(), kAccumulator); VisitForValue(expr->right(), kAccumulator);
EmitBinaryOp(expr->op(), expr->context()); EmitBinaryOp(expr->op(), context_);
break; break;
default: default:
...@@ -1536,7 +1527,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1536,7 +1527,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Initially assume we are in a test context. // Initially assume we are in a test context.
Label* if_true = true_label_; Label* if_true = true_label_;
Label* if_false = false_label_; Label* if_false = false_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1638,13 +1629,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1638,13 +1629,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Convert the result of the comparison into one expected for this // Convert the result of the comparison into one expected for this
// expression's context. // expression's context.
Apply(expr->context(), if_true, if_false); Apply(context_, if_true, if_false);
} }
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
Apply(expr->context(), r0); Apply(context_, r0);
} }
......
...@@ -180,8 +180,6 @@ class Expression: public AstNode { ...@@ -180,8 +180,6 @@ class Expression: public AstNode {
kTestValue kTestValue
}; };
Expression() : context_(kUninitialized) {}
virtual Expression* AsExpression() { return this; } virtual Expression* AsExpression() { return this; }
virtual bool IsValidJSON() { return false; } virtual bool IsValidJSON() { return false; }
...@@ -200,12 +198,8 @@ class Expression: public AstNode { ...@@ -200,12 +198,8 @@ class Expression: public AstNode {
// Static type information for this expression. // Static type information for this expression.
StaticType* type() { return &type_; } StaticType* type() { return &type_; }
Context context() { return context_; }
void set_context(Context context) { context_ = context; }
private: private:
StaticType type_; StaticType type_;
Context context_;
}; };
......
This diff is collapsed.
...@@ -165,68 +165,65 @@ void FastCodeGenerator::SetSourcePosition(int pos) { ...@@ -165,68 +165,65 @@ void FastCodeGenerator::SetSourcePosition(int pos) {
void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
#ifdef DEBUG
Expression::Context expected = Expression::kUninitialized;
switch (expr->context()) {
case Expression::kUninitialized:
UNREACHABLE();
case Expression::kEffect:
case Expression::kTest:
// The value of the left subexpression is not needed.
expected = Expression::kTest;
break;
case Expression::kValue:
// The value of the left subexpression is needed and its specific
// context depends on the operator.
expected = (expr->op() == Token::OR)
? Expression::kValueTest
: Expression::kTestValue;
break;
case Expression::kValueTest:
// The value of the left subexpression is needed for OR.
expected = (expr->op() == Token::OR)
? Expression::kValueTest
: Expression::kTest;
break;
case Expression::kTestValue:
// The value of the left subexpression is needed for AND.
expected = (expr->op() == Token::OR)
? Expression::kTest
: Expression::kTestValue;
break;
}
ASSERT_EQ(expected, expr->left()->context());
ASSERT_EQ(expr->context(), expr->right()->context());
#endif
Label eval_right, done; Label eval_right, done;
// Set up the appropriate context for the left subexpression based // Set up the appropriate context for the left subexpression based
// on the operation and our own context. Initially assume we can // on the operation and our own context. Initially assume we can
// inherit both true and false labels from our context. // inherit both true and false labels from our context.
Label* if_true = true_label_;
Label* if_false = false_label_;
if (expr->op() == Token::OR) { if (expr->op() == Token::OR) {
// If we are not in some kind of a test context, we did not inherit a switch (context_) {
// true label from our context. Use the end of the expression. case Expression::kUninitialized:
if (expr->context() == Expression::kEffect || UNREACHABLE();
expr->context() == Expression::kValue) { case Expression::kEffect:
if_true = &done; VisitForControl(expr->left(), &done, &eval_right);
break;
case Expression::kValue:
VisitForValueControl(expr->left(),
location_,
&done,
&eval_right);
break;
case Expression::kTest:
VisitForControl(expr->left(), true_label_, &eval_right);
break;
case Expression::kValueTest:
VisitForValueControl(expr->left(),
location_,
true_label_,
&eval_right);
break;
case Expression::kTestValue:
VisitForControl(expr->left(), true_label_, &eval_right);
break;
} }
// The false label is the label of the right subexpression.
if_false = &eval_right;
} else { } else {
ASSERT_EQ(Token::AND, expr->op()); ASSERT_EQ(Token::AND, expr->op());
// The true label is the label of the right subexpression. switch (context_) {
if_true = &eval_right; case Expression::kUninitialized:
// If we are not in some kind of a test context, we did not inherit a UNREACHABLE();
// false label from our context. Use the end of the expression. case Expression::kEffect:
if (expr->context() == Expression::kEffect || VisitForControl(expr->left(), &eval_right, &done);
expr->context() == Expression::kValue) { break;
if_false = &done; case Expression::kValue:
VisitForControlValue(expr->left(),
location_,
&eval_right,
&done);
break;
case Expression::kTest:
VisitForControl(expr->left(), &eval_right, false_label_);
break;
case Expression::kValueTest:
VisitForControl(expr->left(), &eval_right, false_label_);
break;
case Expression::kTestValue:
VisitForControlValue(expr->left(),
location_,
&eval_right,
false_label_);
break;
} }
} }
VisitForControl(expr->left(), if_true, if_false);
__ bind(&eval_right); __ bind(&eval_right);
Visit(expr->right()); Visit(expr->right());
...@@ -247,7 +244,7 @@ void FastCodeGenerator::VisitBlock(Block* stmt) { ...@@ -247,7 +244,7 @@ void FastCodeGenerator::VisitBlock(Block* stmt) {
void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
Comment cmnt(masm_, "[ ExpressionStatement"); Comment cmnt(masm_, "[ ExpressionStatement");
SetStatementPosition(stmt); SetStatementPosition(stmt);
Visit(stmt->expression()); VisitForEffect(stmt->expression());
} }
...@@ -446,7 +443,6 @@ void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { ...@@ -446,7 +443,6 @@ void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
// that scope again afterwards. // that scope again afterwards.
Label try_handler_setup, catch_entry, done; Label try_handler_setup, catch_entry, done;
__ Call(&try_handler_setup); __ Call(&try_handler_setup);
// Try handler code, exception in result register. // Try handler code, exception in result register.
...@@ -558,27 +554,20 @@ void FastCodeGenerator::VisitFunctionBoilerplateLiteral( ...@@ -558,27 +554,20 @@ void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
void FastCodeGenerator::VisitConditional(Conditional* expr) { void FastCodeGenerator::VisitConditional(Conditional* expr) {
Comment cmnt(masm_, "[ Conditional"); Comment cmnt(masm_, "[ Conditional");
ASSERT_EQ(Expression::kTest, expr->condition()->context());
ASSERT_EQ(expr->context(), expr->then_expression()->context());
ASSERT_EQ(expr->context(), expr->else_expression()->context());
Label true_case, false_case, done; Label true_case, false_case, done;
VisitForControl(expr->condition(), &true_case, &false_case); VisitForControl(expr->condition(), &true_case, &false_case);
__ bind(&true_case); __ bind(&true_case);
Visit(expr->then_expression()); Visit(expr->then_expression());
// If control flow falls through Visit, jump to done. // If control flow falls through Visit, jump to done.
if (expr->context() == Expression::kEffect || if (context_ == Expression::kEffect || context_ == Expression::kValue) {
expr->context() == Expression::kValue) {
__ jmp(&done); __ jmp(&done);
} }
__ bind(&false_case); __ bind(&false_case);
Visit(expr->else_expression()); Visit(expr->else_expression());
// If control flow falls through Visit, merge it with true case here. // If control flow falls through Visit, merge it with true case here.
if (expr->context() == Expression::kEffect || if (context_ == Expression::kEffect || context_ == Expression::kValue) {
expr->context() == Expression::kValue) {
__ bind(&done); __ bind(&done);
} }
} }
...@@ -592,24 +581,20 @@ void FastCodeGenerator::VisitSlot(Slot* expr) { ...@@ -592,24 +581,20 @@ void FastCodeGenerator::VisitSlot(Slot* expr) {
void FastCodeGenerator::VisitLiteral(Literal* expr) { void FastCodeGenerator::VisitLiteral(Literal* expr) {
Comment cmnt(masm_, "[ Literal"); Comment cmnt(masm_, "[ Literal");
Apply(expr->context(), expr); Apply(context_, expr);
} }
void FastCodeGenerator::VisitAssignment(Assignment* expr) { void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Comment cmnt(masm_, "[ Assignment"); Comment cmnt(masm_, "[ Assignment");
// Left-hand side can only be a property, a global or a (parameter or local) // Left-hand side can only be a property, a global or a (parameter or local)
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
LhsKind assign_type = VARIABLE; LhsKind assign_type = VARIABLE;
Property* prop = expr->target()->AsProperty(); Property* prop = expr->target()->AsProperty();
// In case of a property we use the uninitialized expression context
// of the key to detect a named property.
if (prop != NULL) { if (prop != NULL) {
assign_type = (prop->key()->context() == Expression::kUninitialized) assign_type =
? NAMED_PROPERTY (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
: KEYED_PROPERTY;
} }
// Evaluate LHS expression. // Evaluate LHS expression.
...@@ -667,7 +652,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -667,7 +652,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
switch (assign_type) { switch (assign_type) {
case VARIABLE: case VARIABLE:
EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
expr->context()); context_);
break; break;
case NAMED_PROPERTY: case NAMED_PROPERTY:
EmitNamedPropertyAssignment(expr); EmitNamedPropertyAssignment(expr);
...@@ -683,14 +668,11 @@ void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { ...@@ -683,14 +668,11 @@ void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
// Call runtime routine to allocate the catch extension object and // Call runtime routine to allocate the catch extension object and
// assign the exception value to the catch variable. // assign the exception value to the catch variable.
Comment cmnt(masm_, "[ CatchExtensionObject"); Comment cmnt(masm_, "[ CatchExtensionObject");
VisitForValue(expr->key(), kStack); VisitForValue(expr->key(), kStack);
VisitForValue(expr->value(), kStack); VisitForValue(expr->value(), kStack);
// Create catch extension object. // Create catch extension object.
__ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
Apply(context_, result_register());
__ push(result_register());
} }
......
...@@ -250,23 +250,70 @@ class FastCodeGenerator: public AstVisitor { ...@@ -250,23 +250,70 @@ class FastCodeGenerator: public AstVisitor {
// register. // register.
MemOperand EmitSlotSearch(Slot* slot, Register scratch); MemOperand EmitSlotSearch(Slot* slot, Register scratch);
void VisitForEffect(Expression* expr) {
Expression::Context saved_context = context_;
context_ = Expression::kEffect;
Visit(expr);
context_ = saved_context;
}
void VisitForValue(Expression* expr, Location where) { void VisitForValue(Expression* expr, Location where) {
ASSERT(expr->context() == Expression::kValue); Expression::Context saved_context = context_;
Location saved_location = location_; Location saved_location = location_;
context_ = Expression::kValue;
location_ = where; location_ = where;
Visit(expr); Visit(expr);
context_ = saved_context;
location_ = saved_location; location_ = saved_location;
} }
void VisitForControl(Expression* expr, Label* if_true, Label* if_false) { void VisitForControl(Expression* expr, Label* if_true, Label* if_false) {
ASSERT(expr->context() == Expression::kTest || Expression::Context saved_context = context_;
expr->context() == Expression::kValueTest || Label* saved_true = true_label_;
expr->context() == Expression::kTestValue); Label* saved_false = false_label_;
context_ = Expression::kTest;
true_label_ = if_true;
false_label_ = if_false;
Visit(expr);
context_ = saved_context;
true_label_ = saved_true;
false_label_ = saved_false;
}
void VisitForValueControl(Expression* expr,
Location where,
Label* if_true,
Label* if_false) {
Expression::Context saved_context = context_;
Location saved_location = location_;
Label* saved_true = true_label_; Label* saved_true = true_label_;
Label* saved_false = false_label_; Label* saved_false = false_label_;
context_ = Expression::kValueTest;
location_ = where;
true_label_ = if_true; true_label_ = if_true;
false_label_ = if_false; false_label_ = if_false;
Visit(expr); Visit(expr);
context_ = saved_context;
location_ = saved_location;
true_label_ = saved_true;
false_label_ = saved_false;
}
void VisitForControlValue(Expression* expr,
Location where,
Label* if_true,
Label* if_false) {
Expression::Context saved_context = context_;
Location saved_location = location_;
Label* saved_true = true_label_;
Label* saved_false = false_label_;
context_ = Expression::kTestValue;
location_ = where;
true_label_ = if_true;
false_label_ = if_false;
Visit(expr);
context_ = saved_context;
location_ = saved_location;
true_label_ = saved_true; true_label_ = saved_true;
false_label_ = saved_false; false_label_ = saved_false;
} }
...@@ -356,6 +403,7 @@ class FastCodeGenerator: public AstVisitor { ...@@ -356,6 +403,7 @@ class FastCodeGenerator: public AstVisitor {
NestedStatement* nesting_stack_; NestedStatement* nesting_stack_;
int loop_depth_; int loop_depth_;
Expression::Context context_;
Location location_; Location location_;
Label* true_label_; Label* true_label_;
Label* false_label_; Label* false_label_;
......
...@@ -775,13 +775,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -775,13 +775,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
__ push(esi); __ push(esi);
__ push(Immediate(boilerplate)); __ push(Immediate(boilerplate));
__ CallRuntime(Runtime::kNewClosure, 2); __ CallRuntime(Runtime::kNewClosure, 2);
Apply(expr->context(), eax); Apply(context_, eax);
} }
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy"); Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), expr->context()); EmitVariableLoad(expr->var(), context_);
} }
...@@ -885,7 +885,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -885,7 +885,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done: // Label done:
__ bind(&done); __ bind(&done);
Apply(expr->context(), eax); Apply(context_, eax);
} }
...@@ -951,9 +951,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -951,9 +951,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), eax); Apply(context_, eax);
} }
} }
...@@ -1001,9 +1001,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -1001,9 +1001,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), eax); Apply(context_, eax);
} }
} }
...@@ -1117,7 +1117,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { ...@@ -1117,7 +1117,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ pop(eax); __ pop(eax);
} }
DropAndApply(1, expr->context(), eax); DropAndApply(1, context_, eax);
} }
...@@ -1153,7 +1153,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { ...@@ -1153,7 +1153,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
} }
// Receiver and key are still on stack. // Receiver and key are still on stack.
DropAndApply(2, expr->context(), eax); DropAndApply(2, context_, eax);
} }
...@@ -1167,12 +1167,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -1167,12 +1167,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC. // Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), eax); DropAndApply(1, context_, eax);
} else { } else {
VisitForValue(expr->key(), kStack); VisitForValue(expr->key(), kStack);
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC. // Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), eax); DropAndApply(2, context_, eax);
} }
} }
...@@ -1194,7 +1194,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr, ...@@ -1194,7 +1194,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
__ call(ic, mode); __ call(ic, mode);
// Restore context register. // Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
Apply(expr->context(), eax); Apply(context_, eax);
} }
...@@ -1211,7 +1211,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) { ...@@ -1211,7 +1211,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) {
__ CallStub(&stub); __ CallStub(&stub);
// Restore context register. // Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
DropAndApply(1, expr->context(), eax); DropAndApply(1, context_, eax);
} }
...@@ -1317,7 +1317,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) { ...@@ -1317,7 +1317,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
__ 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.
DropAndApply(1, expr->context(), eax); DropAndApply(1, context_, eax);
} }
...@@ -1349,7 +1349,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -1349,7 +1349,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Call the C runtime function. // Call the C runtime function.
__ CallRuntime(expr->function(), arg_count); __ CallRuntime(expr->function(), arg_count);
} }
Apply(expr->context(), eax); Apply(context_, eax);
} }
...@@ -1357,9 +1357,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1357,9 +1357,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::VOID: { case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)"); Comment cmnt(masm_, "[ UnaryOperation (VOID)");
ASSERT_EQ(Expression::kEffect, expr->expression()->context()); VisitForEffect(expr->expression());
Visit(expr->expression()); switch (context_) {
switch (expr->context()) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1396,14 +1395,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1396,14 +1395,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
case Token::NOT: { case Token::NOT: {
Comment cmnt(masm_, "[ UnaryOperation (NOT)"); Comment cmnt(masm_, "[ UnaryOperation (NOT)");
ASSERT_EQ(Expression::kTest, expr->expression()->context());
Label materialize_true, materialize_false, done; Label materialize_true, materialize_false, done;
// Initially assume a pure test context. Notice that the labels are // Initially assume a pure test context. Notice that the labels are
// swapped. // swapped.
Label* if_true = false_label_; Label* if_true = false_label_;
Label* if_false = true_label_; Label* if_false = true_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1425,14 +1422,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1425,14 +1422,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
VisitForControl(expr->expression(), if_true, if_false); VisitForControl(expr->expression(), if_true, if_false);
Apply(expr->context(), if_false, if_true); // Labels swapped. Apply(context_, if_false, if_true); // Labels swapped.
break; break;
} }
case Token::TYPEOF: { case Token::TYPEOF: {
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
ASSERT_EQ(Expression::kValue, expr->expression()->context());
VariableProxy* proxy = expr->expression()->AsVariableProxy(); VariableProxy* proxy = expr->expression()->AsVariableProxy();
if (proxy != NULL && if (proxy != NULL &&
!proxy->var()->is_this() && !proxy->var()->is_this() &&
...@@ -1458,7 +1453,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1458,7 +1453,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} }
__ CallRuntime(Runtime::kTypeof, 1); __ CallRuntime(Runtime::kTypeof, 1);
Apply(expr->context(), eax); Apply(context_, eax);
break; break;
} }
...@@ -1479,9 +1474,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1479,9 +1474,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// In case of a property we use the uninitialized expression context // In case of a property we use the uninitialized expression context
// of the key to detect a named property. // of the key to detect a named property.
if (prop != NULL) { if (prop != NULL) {
assign_type = (prop->key()->context() == Expression::kUninitialized) assign_type =
? NAMED_PROPERTY (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
: KEYED_PROPERTY;
} }
// Evaluate expression and get value. // Evaluate expression and get value.
...@@ -1494,8 +1488,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1494,8 +1488,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
location_ = saved_location; location_ = saved_location;
} else { } else {
// Reserve space for result of postfix operation. // Reserve space for result of postfix operation.
if (expr->is_postfix() && expr->context() != Expression::kEffect) { if (expr->is_postfix() && context_ != Expression::kEffect) {
ASSERT(expr->context() != Expression::kUninitialized);
__ push(Immediate(Smi::FromInt(0))); __ push(Immediate(Smi::FromInt(0)));
} }
VisitForValue(prop->obj(), kStack); VisitForValue(prop->obj(), kStack);
...@@ -1513,7 +1506,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1513,7 +1506,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Save result for postfix expressions. // Save result for postfix expressions.
if (expr->is_postfix()) { if (expr->is_postfix()) {
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Expression::kEffect: case Expression::kEffect:
...@@ -1557,12 +1550,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1557,12 +1550,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Expression::kEffect); Expression::kEffect);
// For all contexts except kEffect: We have the result on // For all contexts except kEffect: We have the result on
// top of the stack. // top of the stack.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
expr->context()); context_);
} }
break; break;
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
...@@ -1574,11 +1567,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1574,11 +1567,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ nop(); __ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(1); // Result is on the stack under the receiver. __ Drop(1); // Result is on the stack under the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(1, expr->context(), eax); DropAndApply(1, context_, eax);
} }
break; break;
} }
...@@ -1590,11 +1583,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1590,11 +1583,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ nop(); __ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(2); // Result is on the stack under the key and the receiver. __ Drop(2); // Result is on the stack under the key and the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(2, expr->context(), eax); DropAndApply(2, context_, eax);
} }
break; break;
} }
...@@ -1606,9 +1599,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1606,9 +1599,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation"); Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT_EQ(Expression::kEffect, expr->left()->context()); VisitForEffect(expr->left());
ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -1630,7 +1621,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1630,7 +1621,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SAR: case Token::SAR:
VisitForValue(expr->left(), kStack); VisitForValue(expr->left(), kStack);
VisitForValue(expr->right(), kAccumulator); VisitForValue(expr->right(), kAccumulator);
EmitBinaryOp(expr->op(), expr->context()); EmitBinaryOp(expr->op(), context_);
break; break;
default: default:
...@@ -1648,7 +1639,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1648,7 +1639,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Initially assume we are in a test context. // Initially assume we are in a test context.
Label* if_true = true_label_; Label* if_true = true_label_;
Label* if_false = false_label_; Label* if_false = false_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1750,13 +1741,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1750,13 +1741,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Convert the result of the comparison into one expected for this // Convert the result of the comparison into one expected for this
// expression's context. // expression's context.
Apply(expr->context(), if_true, if_false); Apply(context_, if_true, if_false);
} }
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
Apply(expr->context(), eax); Apply(context_, eax);
} }
......
...@@ -778,13 +778,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -778,13 +778,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
__ push(rsi); __ push(rsi);
__ Push(boilerplate); __ Push(boilerplate);
__ CallRuntime(Runtime::kNewClosure, 2); __ CallRuntime(Runtime::kNewClosure, 2);
Apply(expr->context(), rax); Apply(context_, rax);
} }
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy"); Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), expr->context()); EmitVariableLoad(expr->var(), context_);
} }
...@@ -886,7 +886,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -886,7 +886,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ Push(expr->flags()); __ Push(expr->flags());
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
__ bind(&done); __ bind(&done);
Apply(expr->context(), rax); Apply(context_, rax);
} }
...@@ -953,9 +953,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -953,9 +953,9 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), rax); Apply(context_, rax);
} }
} }
...@@ -1003,9 +1003,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -1003,9 +1003,9 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} }
if (result_saved) { if (result_saved) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} else { } else {
Apply(expr->context(), rax); Apply(context_, rax);
} }
} }
...@@ -1117,7 +1117,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { ...@@ -1117,7 +1117,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ pop(rax); __ pop(rax);
} }
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} }
...@@ -1153,7 +1153,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { ...@@ -1153,7 +1153,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
} }
// Receiver and key are still on stack. // Receiver and key are still on stack.
DropAndApply(2, expr->context(), rax); DropAndApply(2, context_, rax);
} }
...@@ -1167,12 +1167,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) { ...@@ -1167,12 +1167,12 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC. // Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} else { } else {
VisitForValue(expr->key(), kStack); VisitForValue(expr->key(), kStack);
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC. // Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), rax); DropAndApply(2, context_, rax);
} }
} }
...@@ -1196,7 +1196,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr, ...@@ -1196,7 +1196,7 @@ void FastCodeGenerator::EmitCallWithIC(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.
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} }
...@@ -1214,7 +1214,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) { ...@@ -1214,7 +1214,7 @@ void FastCodeGenerator::EmitCallWithStub(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.
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} }
...@@ -1323,7 +1323,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) { ...@@ -1323,7 +1323,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
__ 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.
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} }
...@@ -1352,10 +1352,10 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -1352,10 +1352,10 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* 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.
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} else { } else {
__ CallRuntime(expr->function(), arg_count); __ CallRuntime(expr->function(), arg_count);
Apply(expr->context(), rax); Apply(context_, rax);
} }
} }
...@@ -1364,9 +1364,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1364,9 +1364,8 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) { switch (expr->op()) {
case Token::VOID: { case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)"); Comment cmnt(masm_, "[ UnaryOperation (VOID)");
ASSERT_EQ(Expression::kEffect, expr->expression()->context()); VisitForEffect(expr->expression());
Visit(expr->expression()); switch (context_) {
switch (expr->context()) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1403,14 +1402,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1403,14 +1402,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
case Token::NOT: { case Token::NOT: {
Comment cmnt(masm_, "[ UnaryOperation (NOT)"); Comment cmnt(masm_, "[ UnaryOperation (NOT)");
ASSERT_EQ(Expression::kTest, expr->expression()->context());
Label materialize_true, materialize_false, done; Label materialize_true, materialize_false, done;
// Initially assume a pure test context. Notice that the labels are // Initially assume a pure test context. Notice that the labels are
// swapped. // swapped.
Label* if_true = false_label_; Label* if_true = false_label_;
Label* if_false = true_label_; Label* if_false = true_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1432,14 +1429,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1432,14 +1429,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break; break;
} }
VisitForControl(expr->expression(), if_true, if_false); VisitForControl(expr->expression(), if_true, if_false);
Apply(expr->context(), if_false, if_true); // Labels swapped. Apply(context_, if_false, if_true); // Labels swapped.
break; break;
} }
case Token::TYPEOF: { case Token::TYPEOF: {
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
ASSERT_EQ(Expression::kValue, expr->expression()->context());
VariableProxy* proxy = expr->expression()->AsVariableProxy(); VariableProxy* proxy = expr->expression()->AsVariableProxy();
if (proxy != NULL && if (proxy != NULL &&
!proxy->var()->is_this() && !proxy->var()->is_this() &&
...@@ -1465,7 +1460,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1465,7 +1460,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} }
__ CallRuntime(Runtime::kTypeof, 1); __ CallRuntime(Runtime::kTypeof, 1);
Apply(expr->context(), rax); Apply(context_, rax);
break; break;
} }
...@@ -1486,9 +1481,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1486,9 +1481,8 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// In case of a property we use the uninitialized expression context // In case of a property we use the uninitialized expression context
// of the key to detect a named property. // of the key to detect a named property.
if (prop != NULL) { if (prop != NULL) {
assign_type = (prop->key()->context() == Expression::kUninitialized) assign_type =
? NAMED_PROPERTY (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
: KEYED_PROPERTY;
} }
// Evaluate expression and get value. // Evaluate expression and get value.
...@@ -1501,8 +1495,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1501,8 +1495,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
location_ = saved_location; location_ = saved_location;
} else { } else {
// Reserve space for result of postfix operation. // Reserve space for result of postfix operation.
if (expr->is_postfix() && expr->context() != Expression::kEffect) { if (expr->is_postfix() && context_ != Expression::kEffect) {
ASSERT(expr->context() != Expression::kUninitialized);
__ Push(Smi::FromInt(0)); __ Push(Smi::FromInt(0));
} }
VisitForValue(prop->obj(), kStack); VisitForValue(prop->obj(), kStack);
...@@ -1520,7 +1513,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1520,7 +1513,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Save result for postfix expressions. // Save result for postfix expressions.
if (expr->is_postfix()) { if (expr->is_postfix()) {
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
case Expression::kEffect: case Expression::kEffect:
...@@ -1564,12 +1557,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1564,12 +1557,12 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Expression::kEffect); Expression::kEffect);
// For all contexts except kEffect: We have the result on // For all contexts except kEffect: We have the result on
// top of the stack. // top of the stack.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
expr->context()); context_);
} }
break; break;
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
...@@ -1581,11 +1574,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1581,11 +1574,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ nop(); __ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(1); // Result is on the stack under the receiver. __ Drop(1); // Result is on the stack under the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(1, expr->context(), rax); DropAndApply(1, context_, rax);
} }
break; break;
} }
...@@ -1597,11 +1590,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -1597,11 +1590,11 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ nop(); __ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
__ Drop(2); // Result is on the stack under the key and the receiver. __ Drop(2); // Result is on the stack under the key and the receiver.
if (expr->context() != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(expr->context()); ApplyTOS(context_);
} }
} else { } else {
DropAndApply(2, expr->context(), rax); DropAndApply(2, context_, rax);
} }
break; break;
} }
...@@ -1612,9 +1605,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1612,9 +1605,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation"); Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) { switch (expr->op()) {
case Token::COMMA: case Token::COMMA:
ASSERT_EQ(Expression::kEffect, expr->left()->context()); VisitForEffect(expr->left());
ASSERT_EQ(expr->context(), expr->right()->context());
Visit(expr->left());
Visit(expr->right()); Visit(expr->right());
break; break;
...@@ -1636,7 +1627,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { ...@@ -1636,7 +1627,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SAR: case Token::SAR:
VisitForValue(expr->left(), kStack); VisitForValue(expr->left(), kStack);
VisitForValue(expr->right(), kAccumulator); VisitForValue(expr->right(), kAccumulator);
EmitBinaryOp(expr->op(), expr->context()); EmitBinaryOp(expr->op(), context_);
break; break;
default: default:
...@@ -1654,7 +1645,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1654,7 +1645,7 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Initially assume we are in a test context. // Initially assume we are in a test context.
Label* if_true = true_label_; Label* if_true = true_label_;
Label* if_false = false_label_; Label* if_false = false_label_;
switch (expr->context()) { switch (context_) {
case Expression::kUninitialized: case Expression::kUninitialized:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1753,13 +1744,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -1753,13 +1744,13 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Convert the result of the comparison into one expected for this // Convert the result of the comparison into one expected for this
// expression's context. // expression's context.
Apply(expr->context(), if_true, if_false); Apply(context_, if_true, if_false);
} }
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
Apply(expr->context(), rax); Apply(context_, rax);
} }
......
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