Fix issue 979.

The issue is caused when deoptimizing to an internal AST ID in a
postfix increment or decrement operation on variable.  This could
happen for a global variable.  In that case, the optimized code was
not properly simulating an extra stack slot in the unoptimized code to
hold the original value.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6025 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 88dfadd0
...@@ -4533,26 +4533,25 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -4533,26 +4533,25 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
VISIT_FOR_VALUE(target); VISIT_FOR_VALUE(target);
HValue* value = Pop(); // Match the full code generator stack by simulating an extra stack
HInstruction* instr = BuildIncrement(value, inc); // element for postfix operations in a non-effect context.
AddInstruction(instr); bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
HValue* before = has_extra ? Top() : Pop();
if (expr->is_prefix()) { HInstruction* after = BuildIncrement(before, inc);
Push(instr); AddInstruction(after);
} else { Push(after);
Push(value);
}
if (var->is_global()) { if (var->is_global()) {
HandleGlobalVariableAssignment(var, HandleGlobalVariableAssignment(var,
instr, after,
expr->position(), expr->position(),
expr->AssignmentId()); expr->AssignmentId());
} else { } else {
ASSERT(var->IsStackAllocated()); ASSERT(var->IsStackAllocated());
Bind(var, instr); Bind(var, after);
} }
ast_context()->ReturnValue(Pop()); Drop(has_extra ? 2 : 1);
ast_context()->ReturnValue(expr->is_postfix() ? before : after);
} else if (prop != NULL) { } else if (prop != NULL) {
prop->RecordTypeFeedback(oracle()); prop->RecordTypeFeedback(oracle());
...@@ -4561,7 +4560,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -4561,7 +4560,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Named property. // Named property.
// Match the full code generator stack by simulating an extra stack // Match the full code generator stack by simulating an extra stack
// element for postfix operations in a value context. // element for postfix operations in a non-effect context.
bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
if (has_extra) Push(graph_->GetConstantUndefined()); if (has_extra) Push(graph_->GetConstantUndefined());
...@@ -4602,7 +4601,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -4602,7 +4601,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Keyed property. // Keyed property.
// Match the full code generator stack by simulate an extra stack element // Match the full code generator stack by simulate an extra stack element
// for postfix operations in a value context. // for postfix operations in a non-effect context.
bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
if (has_extra) Push(graph_->GetConstantUndefined()); if (has_extra) Push(graph_->GetConstantUndefined());
......
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