• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --expose-debug-as debug --nocrankshaft
29// Get the Debug object exposed from the debug context global object.
30Debug = debug.Debug
31
32function DebuggerStatement() {
33  debugger;  /*pause*/
34}
35
36function TestCase(fun, frame_number) {
37  var exception = false;
38  var codeSnippet = undefined;
39  var resultPositions = undefined;
40
41  function listener(event, exec_state, event_data, data) {
42    try {
43      if (event == Debug.DebugEvent.Break ||
44          event == Debug.DebugEvent.Exception) {
45        Debug.setListener(null);
46        assertHasLineMark(/pause/, exec_state.frame(0));
47        assertHasLineMark(/positions/, exec_state.frame(frame_number));
48        var frame = exec_state.frame(frame_number);
49        codeSnippet = frame.sourceLineText();
50        resultPositions = frame.stepInPositions();
51      }
52    } catch (e) {
53      exception = e
54    }
55
56    function assertHasLineMark(mark, frame) {
57        var line = frame.sourceLineText();
58        if (!mark.exec(frame.sourceLineText())) {
59            throw new Error("Line " + line + " should contain mark " + mark);
60        }
61    }
62  }
63
64  Debug.setListener(listener);
65
66  fun();
67
68  Debug.setListener(null);
69
70  assertTrue(!exception, exception);
71
72  var expectedPositions = {};
73  var markPattern = new RegExp("/\\*#\\*/", "g");
74
75  var matchResult;
76  while ( (matchResult = markPattern.exec(codeSnippet)) ) {
77    expectedPositions[matchResult.index] = true;
78  }
79
80  print(codeSnippet);
81
82  var decoratedResult = codeSnippet;
83
84  function replaceStringRange(s, pos, substitute) {
85   return s.substring(0, pos) + substitute +
86       s.substring(pos + substitute.length);
87  }
88
89  var markLength = 5;
90  var unexpectedPositionFound = false;
91
92  for (var i = 0; i < resultPositions.length; i++) {
93    var col = resultPositions[i].position.column - markLength;
94    if (expectedPositions[col]) {
95      delete expectedPositions[col];
96      decoratedResult = replaceStringRange(decoratedResult, col, "*YES*");
97    } else {
98      decoratedResult = replaceStringRange(decoratedResult, col, "!BAD!");
99      unexpectedPositionFound = true;
100    }
101  }
102
103  print(decoratedResult);
104
105  for (var n in expectedPositions) {
106    assertTrue(false, "Some positions are not reported: " + decoratedResult);
107    break;
108  }
109  assertFalse(unexpectedPositionFound, "Found unexpected position: " +
110      decoratedResult);
111}
112
113function TestCaseWithDebugger(fun) {
114  TestCase(fun, 1);
115}
116
117function TestCaseWithBreakpoint(fun, line_number, frame_number) {
118  var breakpointId = Debug.setBreakPoint(fun, line_number);
119  TestCase(fun, frame_number);
120  Debug.clearBreakPoint(breakpointId);
121}
122
123function TestCaseWithException(fun, frame_number) {
124  Debug.setBreakOnException();
125  TestCase(fun, frame_number);
126  Debug.clearBreakOnException();
127}
128
129
130// Test cases.
131
132// Step in position, when the function call that we are standing at is already
133// being executed.
134var fun = function() {
135  function g(p) {
136    throw String(p); /*pause*/
137  }
138  try {
139    var res = [ g(1), /*#*/g(2) ]; /*positions*/
140  } catch (e) {
141  }
142};
143TestCaseWithBreakpoint(fun, 2, 1);
144TestCaseWithException(fun, 1);
145
146
147// Step in position, when the function call that we are standing at is raising
148// an exception.
149var fun = function() {
150  var o = {
151    g: function(p) {
152      throw p;
153    }
154  };
155  try {
156    var res = [ /*#*/f(1), /*#*/g(2) ]; /*pause, positions*/
157  } catch (e) {
158  }
159};
160TestCaseWithException(fun, 0);
161
162
163// Step-in position, when already paused almost on the first call site.
164var fun = function() {
165  function g(p) {
166    throw p;
167  }
168  try {
169    var res = [ /*#*/g(Math.rand), /*#*/g(2) ]; /*pause, positions*/
170  } catch (e) {
171  }
172};
173TestCaseWithBreakpoint(fun, 5, 0);
174
175// Step-in position, when already paused on the first call site.
176var fun = function() {
177  function g() {
178    throw "Debug";
179  }
180  try {
181    var res = [ /*#*/g(), /*#*/g() ]; /*pause, positions*/
182  } catch (e) {
183  }
184};
185TestCaseWithBreakpoint(fun, 5, 0);
186
187
188// Method calls.
189var fun = function() {
190  var data = {
191    a: function() {}
192  };
193  var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ]; /*positions*/
194};
195TestCaseWithDebugger(fun);
196
197// Function call on a value.
198var fun = function() {
199  function g(p) {
200      return g;
201  }
202  var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ]; /*positions*/
203};
204TestCaseWithDebugger(fun);
205
206// Local function call, closure function call,
207// local function construction call.
208var fun = (function(p) {
209  return function() {
210    function f(a, b) {
211    }
212    var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f())); /*positions*/
213  };
214})(Object);
215TestCaseWithDebugger(fun);
216
217// Global function, global object construction, calls before pause point.
218var fun = (function(p) {
219  return function() {
220    var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ]; /*positions*/
221  };
222})(Object);
223TestCaseWithDebugger(fun);
224