Revision: 3312
Author: [email protected]
Date: Mon Nov 16 13:59:31 2009
Log: Step next should respect do/while condition block.

Condition block of do/while statements is a valid break location so it  
should have its own position. The block is represented by a regular  
Expression node so we cannot store the position in it, instead the position  
is stored in a separate field in DoWhileStatement AST node.

BUG=514
Review URL: http://codereview.chromium.org/385136
http://code.google.com/p/v8/source/detail?r=3312

Added:
  /branches/bleeding_edge/test/mjsunit/debug-stepnext-do-while.js
Modified:
  /branches/bleeding_edge/src/arm/codegen-arm.cc
  /branches/bleeding_edge/src/arm/codegen-arm.h
  /branches/bleeding_edge/src/ast.h
  /branches/bleeding_edge/src/codegen.cc
  /branches/bleeding_edge/src/codegen.h
  /branches/bleeding_edge/src/ia32/codegen-ia32.cc
  /branches/bleeding_edge/src/ia32/codegen-ia32.h
  /branches/bleeding_edge/src/parser.cc
  /branches/bleeding_edge/src/x64/codegen-x64.cc
  /branches/bleeding_edge/src/x64/codegen-x64.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/debug-stepnext-do-while.js     Mon Nov 
 
16 13:59:31 2009
@@ -0,0 +1,79 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var exception = null;
+var break_break_point_hit_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      if (break_break_point_hit_count == 0) {
+        assertEquals('    debugger;',
+                     event_data.sourceLineText());
+        assertEquals('runDoWhile', event_data.func().name());
+      } else if (break_break_point_hit_count == 1) {
+        assertEquals('  } while(condition());',
+                     event_data.sourceLineText());
+        assertEquals('runDoWhile', event_data.func().name());
+      }
+
+      break_break_point_hit_count++;
+      // Continue stepping until returned to bottom frame.
+      if (exec_state.frameCount() > 1) {
+        exec_state.prepareStep(Debug.StepAction.StepNext);
+      }
+
+    }
+  } catch(e) {
+    exception = e;
+  }
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function condition() {
+  return false;
+}
+
+function runDoWhile() {
+  do {
+    debugger;
+  } while(condition());
+};
+
+break_break_point_hit_count = 0;
+runDoWhile();
+assertNull(exception);
+assertEquals(4, break_break_point_hit_count);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc      Mon Nov 16 06:12:27 2009
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc      Mon Nov 16 13:59:31 2009
@@ -1583,6 +1583,8 @@
          node->continue_target()->Bind();
        }
        if (has_valid_frame()) {
+        Comment cmnt(masm_, "[ DoWhileCondition");
+        CodeForDoWhileConditionPosition(node);
          LoadConditionAndSpill(node->cond(), &body, node->break_target(),  
true);
          if (has_valid_frame()) {
            // A invalid frame here indicates that control did not
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h       Wed Nov  4 09:59:24 2009
+++ /branches/bleeding_edge/src/arm/codegen-arm.h       Mon Nov 16 13:59:31 2009
@@ -378,6 +378,7 @@
    void CodeForFunctionPosition(FunctionLiteral* fun);
    void CodeForReturnPosition(FunctionLiteral* fun);
    void CodeForStatementPosition(Statement* node);
+  void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
    void CodeForSourcePosition(int pos);

  #ifdef DEBUG
=======================================
--- /branches/bleeding_edge/src/ast.h   Wed Nov 11 01:00:09 2009
+++ /branches/bleeding_edge/src/ast.h   Mon Nov 16 13:59:31 2009
@@ -322,7 +322,7 @@
  class DoWhileStatement: public IterationStatement {
   public:
    explicit DoWhileStatement(ZoneStringList* labels)
-      : IterationStatement(labels), cond_(NULL) {
+      : IterationStatement(labels), cond_(NULL), condition_position_(-1) {
    }

    void Initialize(Expression* cond, Statement* body) {
@@ -333,9 +333,15 @@
    virtual void Accept(AstVisitor* v);

    Expression* cond() const { return cond_; }
+
+  // Position where condition expression starts. We need it to make
+  // the loop's condition a breakable location.
+  int condition_position() { return condition_position_; }
+  void set_condition_position(int pos) { condition_position_ = pos; }

   private:
    Expression* cond_;
+  int condition_position_;
  };


=======================================
--- /branches/bleeding_edge/src/codegen.cc      Wed Nov  4 09:59:24 2009
+++ /branches/bleeding_edge/src/codegen.cc      Mon Nov 16 13:59:31 2009
@@ -431,6 +431,9 @@
    if (FLAG_debug_info) RecordPositions(masm(), stmt->statement_pos());
  }

+void CodeGenerator::CodeForDoWhileConditionPosition(DoWhileStatement*  
stmt) {
+  if (FLAG_debug_info) RecordPositions(masm(), stmt->condition_position());
+}

  void CodeGenerator::CodeForSourcePosition(int pos) {
    if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
=======================================
--- /branches/bleeding_edge/src/codegen.h       Wed Nov  4 09:59:24 2009
+++ /branches/bleeding_edge/src/codegen.h       Mon Nov 16 13:59:31 2009
@@ -69,6 +69,7 @@
  //   CodeForFunctionPosition
  //   CodeForReturnPosition
  //   CodeForStatementPosition
+//   CodeForDoWhileConditionPosition
  //   CodeForSourcePosition


=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Fri Nov 13 04:32:57  
2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Mon Nov 16 13:59:31  
2009
@@ -2449,6 +2449,7 @@
    CodeForStatementPosition(node);
    Load(node->expression());
    Result return_value = frame_->Pop();
+  masm()->WriteRecordedPositions();
    if (function_return_is_shadowed_) {
      function_return_.Jump(&return_value);
    } else {
@@ -2712,6 +2713,8 @@
          node->continue_target()->Bind();
        }
        if (has_valid_frame()) {
+        Comment cmnt(masm_, "[ DoWhileCondition");
+        CodeForDoWhileConditionPosition(node);
          ControlDestination dest(&body, node->break_target(), false);
          LoadCondition(node->cond(), &dest, true);
        }
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Fri Nov 13 04:32:57 2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Mon Nov 16 13:59:31 2009
@@ -556,6 +556,7 @@
    void CodeForFunctionPosition(FunctionLiteral* fun);
    void CodeForReturnPosition(FunctionLiteral* fun);
    void CodeForStatementPosition(Statement* stmt);
+  void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
    void CodeForSourcePosition(int pos);

  #ifdef DEBUG
=======================================
--- /branches/bleeding_edge/src/parser.cc       Wed Nov 11 01:00:09 2009
+++ /branches/bleeding_edge/src/parser.cc       Mon Nov 16 13:59:31 2009
@@ -2542,6 +2542,12 @@
    Statement* body = ParseStatement(NULL, CHECK_OK);
    Expect(Token::WHILE, CHECK_OK);
    Expect(Token::LPAREN, CHECK_OK);
+
+  if (loop != NULL) {
+    int position = scanner().location().beg_pos;
+    loop->set_condition_position(position);
+  }
+
    Expression* cond = ParseExpression(true, CHECK_OK);
    Expect(Token::RPAREN, CHECK_OK);

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Fri Nov 13 04:32:57 2009
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Nov 16 13:59:31 2009
@@ -1318,6 +1318,8 @@
          node->continue_target()->Bind();
        }
        if (has_valid_frame()) {
+        Comment cmnt(masm_, "[ DoWhileCondition");
+        CodeForDoWhileConditionPosition(node);
          ControlDestination dest(&body, node->break_target(), false);
          LoadCondition(node->cond(), &dest, true);
        }
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Fri Nov 13 04:32:57 2009
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Mon Nov 16 13:59:31 2009
@@ -556,6 +556,7 @@
    void CodeForFunctionPosition(FunctionLiteral* fun);
    void CodeForReturnPosition(FunctionLiteral* fun);
    void CodeForStatementPosition(Statement* node);
+  void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
    void CodeForSourcePosition(int pos);

  #ifdef DEBUG

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to