17f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Copyright 2010 the V8 project authors. All rights reserved.
27f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Redistribution and use in source and binary forms, with or without
37f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// modification, are permitted provided that the following conditions are
47f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// met:
57f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//
67f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//     * Redistributions of source code must retain the above copyright
77f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       notice, this list of conditions and the following disclaimer.
87f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//     * Redistributions in binary form must reproduce the above
97f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       copyright notice, this list of conditions and the following
107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       disclaimer in the documentation and/or other materials provided
117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       with the distribution.
127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//     * Neither the name of Google Inc. nor the names of its
137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       contributors may be used to endorse or promote products derived
147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//       from this software without specific prior written permission.
157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//
167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Flags: --expose-debug-as debug
297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Get the Debug object exposed from the debug context global object.
307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochDebug = debug.Debug
317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction ParsedResponse(json) {
347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  this.response_ = eval('(' + json + ')');
357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  this.refs_ = [];
367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (this.response_.refs) {
377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    for (var i = 0; i < this.response_.refs.length; i++) {
387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      this.refs_[this.response_.refs[i].handle] = this.response_.refs[i];
397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochParsedResponse.prototype.response = function() {
457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return this.response_;
467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochParsedResponse.prototype.body = function() {
507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return this.response_.body;
517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochParsedResponse.prototype.running = function() {
557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return this.response_.running;
567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochParsedResponse.prototype.lookup = function(handle) {
607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return this.refs_[handle];
617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochlistener_complete = false;
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochexception = false;
667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbreak_count = 0;
677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochexpected_return_value = 0;
687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochdebugger_source_position = 0;
697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Listener which expects to do four steps to reach returning from the function.
717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction listener(event, exec_state, event_data, data) {
727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  try {
737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (event == Debug.DebugEvent.Break)
747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    {
757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      break_count++;
767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (break_count < 4) {
777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        assertFalse(exec_state.frame(0).isAtReturn())
787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        switch (break_count) {
797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          case 1:
807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            // Collect the position of the debugger statement.
817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            debugger_source_position = exec_state.frame(0).sourcePosition();
827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            break;
837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          case 2:
847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            // Position now at the if statement.
857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            assertEquals(debugger_source_position + 10,
867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                         exec_state.frame(0).sourcePosition());
877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            break;
887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          case 3:
897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            // Position now at either of the returns.
907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            if (expected_return_value == 1) {
917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch              assertEquals(debugger_source_position + 19,
927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                           exec_state.frame(0).sourcePosition());
937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            } else {
947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch              assertEquals(debugger_source_position + 38,
957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                           exec_state.frame(0).sourcePosition());
967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            }
977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            break;
987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          default:
997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            fail("Unexpected");
1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        }
1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        exec_state.prepareStep(Debug.StepAction.StepIn, 1);
1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      } else {
1037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        // Position at the end of the function.
104bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch        assertEquals(debugger_source_position + 50,
1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        exec_state.frame(0).sourcePosition());
106589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        // Just about to return from the function.
1087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        assertTrue(exec_state.frame(0).isAtReturn())
1097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        assertEquals(expected_return_value,
1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                     exec_state.frame(0).returnValue().value());
111589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        // Check the same using the JSON commands.
1137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        var dcp = exec_state.debugCommandProcessor(false);
1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        var request = '{"seq":0,"type":"request","command":"backtrace"}';
1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        var resp = dcp.processDebugJSONRequest(request);
1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        response = new ParsedResponse(resp);
1177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        frames = response.body().frames;
1187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        assertTrue(frames[0].atReturn);
1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        assertEquals(expected_return_value,
1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                     response.lookup(frames[0].returnValue.ref).value);
121589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        listener_complete = true;
1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      }
1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } catch (e) {
1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    exception = e
1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  };
1287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch};
1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Add the debug event listener.
1317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochDebug.setListener(listener);
1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Four steps from the debugger statement in this function will position us at
1347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// the function return.
135589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch//             0         1         2         3         4         5
1367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch//             0123456789012345678901234567890123456789012345678901
1377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochfunction f(x) {debugger; if (x) { return 1; } else { return 2; } };
1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Call f expecting different return values.
1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbreak_count = 0;
1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochexpected_return_value = 2;
1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochlistener_complete = false;
1447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochf();
1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertFalse(exception, "exception in listener")
1467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertTrue(listener_complete);
1477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertEquals(4, break_count);
1487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbreak_count = 0;
1507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochexpected_return_value = 1;
1517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochlistener_complete = false;
1527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochf(true);
1537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertFalse(exception, "exception in listener")
1547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertTrue(listener_complete);
1557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertEquals(4, break_count);
1567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbreak_count = 0;
1587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochexpected_return_value = 2;
1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochlistener_complete = false;
1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochf(false);
1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertFalse(exception, "exception in listener")
1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertTrue(listener_complete);
1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochassertEquals(4, break_count);
164