Fix issue 284.

The problem was continuing out of the body of a for/in (where we do
register allocation) to the loop update (where we do not).  Variables
allocated to registers where not preserved.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1585 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d4e66137
...@@ -2016,14 +2016,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -2016,14 +2016,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
CheckStack(); // TODO(1222600): ignore if body contains calls. CheckStack(); // TODO(1222600): ignore if body contains calls.
VisitAndSpill(node->body()); VisitAndSpill(node->body());
// Next. // Next. Reestablish a spilled frame in case we are coming here via
// a continue in the body.
node->continue_target()->Bind(); node->continue_target()->Bind();
frame_->SpillAll();
frame_->EmitPop(r0); frame_->EmitPop(r0);
__ add(r0, r0, Operand(Smi::FromInt(1))); __ add(r0, r0, Operand(Smi::FromInt(1)));
frame_->EmitPush(r0); frame_->EmitPush(r0);
entry.Jump(); entry.Jump();
// Cleanup. // Cleanup. No need to spill because VirtualFrame::Drop is safe for
// any frame.
node->break_target()->Bind(); node->break_target()->Bind();
frame_->Drop(5); frame_->Drop(5);
......
...@@ -2683,14 +2683,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -2683,14 +2683,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
CheckStack(); // TODO(1222600): ignore if body contains calls. CheckStack(); // TODO(1222600): ignore if body contains calls.
VisitAndSpill(node->body()); VisitAndSpill(node->body());
// Next. // Next. Reestablish a spilled frame in case we are coming here via
// a continue in the body.
node->continue_target()->Bind(); node->continue_target()->Bind();
frame_->SpillAll();
frame_->EmitPop(eax); frame_->EmitPop(eax);
__ add(Operand(eax), Immediate(Smi::FromInt(1))); __ add(Operand(eax), Immediate(Smi::FromInt(1)));
frame_->EmitPush(eax); frame_->EmitPush(eax);
entry.Jump(); entry.Jump();
// Cleanup. // Cleanup. No need to spill because VirtualFrame::Drop is safe for
// any frame.
node->break_target()->Bind(); node->break_target()->Bind();
frame_->Drop(5); frame_->Drop(5);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// See http://code.google.com/p/v8/issues/detail?id=284
function continueWithinLoop() { function continueWithinLoop() {
var result; var result;
for (var key in [0]) { for (var key in [0]) {
...@@ -35,3 +37,14 @@ function continueWithinLoop() { ...@@ -35,3 +37,14 @@ function continueWithinLoop() {
}; };
assertEquals("hopla", continueWithinLoop()); assertEquals("hopla", continueWithinLoop());
function breakWithinLoop() {
var result;
for (var key in [0]) {
result = "hopla";
break;
}
return result;
};
assertEquals("hopla", continueWithinLoop());
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