From 5e2f3adfd00cb51e2cd51f2ff74087d9192516ce Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Tue, 24 Mar 2009 08:29:24 +0000 Subject: [PATCH] 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 --- src/codegen-arm.cc | 7 +++++-- src/codegen-ia32.cc | 7 +++++-- test/mjsunit/{bugs/bug-284.js => regress/regress-284.js} | 13 +++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) rename test/mjsunit/{bugs/bug-284.js => regress/regress-284.js} (88%) diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index bc905a4..43fab95 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -2016,14 +2016,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { CheckStack(); // TODO(1222600): ignore if body contains calls. 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(); + frame_->SpillAll(); frame_->EmitPop(r0); __ add(r0, r0, Operand(Smi::FromInt(1))); frame_->EmitPush(r0); entry.Jump(); - // Cleanup. + // Cleanup. No need to spill because VirtualFrame::Drop is safe for + // any frame. node->break_target()->Bind(); frame_->Drop(5); diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index 2b19fe1..61dfa67 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -2683,14 +2683,17 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { CheckStack(); // TODO(1222600): ignore if body contains calls. 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(); + frame_->SpillAll(); frame_->EmitPop(eax); __ add(Operand(eax), Immediate(Smi::FromInt(1))); frame_->EmitPush(eax); entry.Jump(); - // Cleanup. + // Cleanup. No need to spill because VirtualFrame::Drop is safe for + // any frame. node->break_target()->Bind(); frame_->Drop(5); diff --git a/test/mjsunit/bugs/bug-284.js b/test/mjsunit/regress/regress-284.js similarity index 88% rename from test/mjsunit/bugs/bug-284.js rename to test/mjsunit/regress/regress-284.js index 2e29d0b..ecfdeea 100644 --- a/test/mjsunit/bugs/bug-284.js +++ b/test/mjsunit/regress/regress-284.js @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // 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() { var result; for (var key in [0]) { @@ -35,3 +37,14 @@ function continueWithinLoop() { }; assertEquals("hopla", continueWithinLoop()); + +function breakWithinLoop() { + var result; + for (var key in [0]) { + result = "hopla"; + break; + } + return result; +}; + +assertEquals("hopla", continueWithinLoop()); -- 2.7.4