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