From af466d80a6ffaa61f476d2652368a18dfc4818ff Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Fri, 19 Nov 2010 12:08:52 +0000 Subject: [PATCH] Add more tests of breaks in infinite loops Move stack check in do while loops to before the continue target to enable breaks even if continue was always used in the loop. Review URL: http://codereview.chromium.org/5184007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5862 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/full-codegen.cc | 2 +- test/cctest/test-debug.cc | 67 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/full-codegen.cc b/src/full-codegen.cc index 8592472..19971a2 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -882,12 +882,12 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { Visit(stmt->body()); // Check stack before looping. + __ bind(loop_statement.continue_target()); __ StackLimitCheck(&stack_limit_hit); __ bind(&stack_check_success); // Record the position of the do while condition and make sure it is // possible to break on the condition. - __ bind(loop_statement.continue_target()); SetExpressionPosition(stmt->cond(), stmt->condition_position()); VisitForControl(stmt->cond(), &body, diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index 748e3e8..7791185 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -6900,26 +6900,71 @@ TEST(DebugEventBreakData) { // Test that setting the terminate execution flag during debug break processing. +static void TestDebugBreakInLoop(const char* loop_head, + const char** loop_bodies, + const char* loop_tail) { + // Receive 100 breaks for each test and then terminate JavaScript execution. + static int count = 0; + + for (int i = 0; loop_bodies[i] != NULL; i++) { + count++; + max_break_point_hit_count = count * 100; + terminate_after_max_break_point_hit = true; + + EmbeddedVector buffer; + OS::SNPrintF(buffer, + "function f() {%s%s%s}", + loop_head, loop_bodies[i], loop_tail); + + // Function with infinite loop. + CompileRun(buffer.start()); + + // Set the debug break to enter the debugger as soon as possible. + v8::Debug::DebugBreak(); + + // Call function with infinite loop. + CompileRun("f();"); + CHECK_EQ(count * 100, break_point_hit_count); + + CHECK(!v8::V8::IsExecutionTerminating()); + } +} + + TEST(DebugBreakLoop) { v8::HandleScope scope; DebugLocalContext env; - // Receive 100 breaks and terminate. - max_break_point_hit_count = 100; - terminate_after_max_break_point_hit = true; - // Register a debug event listener which sets the break flag and counts. v8::Debug::SetDebugEventListener(DebugEventBreakMax); - // Function with infinite loop. - CompileRun("function f() { while (true) { } }"); + CompileRun("var a = 1;"); + CompileRun("function g() { }"); + CompileRun("function h() { }"); + + const char* loop_bodies[] = { + "", + "g()", + "if (a == 0) { g() }", + "if (a == 1) { g() }", + "if (a == 0) { g() } else { h() }", + "if (a == 0) { continue }", + "if (a == 1) { continue }", + "switch (a) { case 1: g(); }", + "switch (a) { case 1: continue; }", + "switch (a) { case 1: g(); break; default: h() }", + "switch (a) { case 1: continue; break; default: h() }", + NULL + }; + + TestDebugBreakInLoop("while (true) {", loop_bodies, "}"); + TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}"); - // Set the debug break to enter the debugger as soon as possible. - v8::Debug::DebugBreak(); + TestDebugBreakInLoop("do {", loop_bodies, "} while (true)"); + TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)"); - // Call function with infinite loop. - CompileRun("f();"); - CHECK_EQ(100, break_point_hit_count); + TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); + TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); -- 2.7.4