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
29// Get the Debug object exposed from the debug context global object.
30Debug = debug.Debug
31
32listenerComplete = false;
33exception = false;
34
35// The base part of all evaluate requests.
36var base_request = '"seq":0,"type":"request","command":"evaluate"'
37
38function safeEval(code) {
39  try {
40    return eval('(' + code + ')');
41  } catch (e) {
42    assertEquals(void 0, e);
43    return undefined;
44  }
45}
46
47function testRequest(exec_state, arguments, success, result) {
48  // Get the debug command processor in paused state.
49  var dcp = exec_state.debugCommandProcessor(false);
50
51  // Generate request with the supplied arguments.
52  var request;
53  if (arguments) {
54    request = '{' + base_request + ',"arguments":' + arguments + '}';
55  } else {
56    request = '{' + base_request + '}'
57  }
58  var response = safeEval(dcp.processDebugJSONRequest(request));
59  if (success) {
60    assertTrue(response.success, request + ' -> ' + response.message);
61    assertEquals(result, response.body.value);
62  } else {
63    assertFalse(response.success, request + ' -> ' + response.message);
64  }
65  assertFalse(response.running, request + ' -> expected not running');
66}
67
68
69// Event listener which evaluates with break disabled.
70function listener(event, exec_state, event_data, data) {
71  try {
72    if (event == Debug.DebugEvent.Break)
73    {
74      // Call functions with break using the FrameMirror directly.
75      assertEquals(1, exec_state.evaluateGlobal('f()', true).value());
76      assertEquals(2, exec_state.evaluateGlobal('g()', true).value());
77      assertEquals(1, exec_state.frame(0).evaluate('f()', true).value());
78      assertEquals(2, exec_state.frame(0).evaluate('g()', true).value());
79
80      // Call functions with break using the JSON protocol. Tests that argument
81      // disable_break is default true.
82      testRequest(exec_state, '{"expression":"f()"}', true, 1);
83      testRequest(exec_state, '{"expression":"f()","frame":0}',  true, 1);
84      testRequest(exec_state, '{"expression":"g()"}', true, 2);
85      testRequest(exec_state, '{"expression":"g()","frame":0}',  true, 2);
86
87      // Call functions with break using the JSON protocol. Tests passing
88      // argument disable_break is default true.
89      testRequest(exec_state, '{"expression":"f()","disable_break":true}', true, 1);
90      testRequest(exec_state, '{"expression":"f()","frame":0,"disable_break":true}',
91                  true, 1);
92      testRequest(exec_state, '{"expression":"g()","disable_break":true}', true, 2);
93      testRequest(exec_state, '{"expression":"g()","frame":0,"disable_break":true}',
94                  true, 2);
95
96      // Indicate that all was processed.
97      listenerComplete = true;
98    }
99  } catch (e) {
100    exception = e
101  };
102};
103
104
105// Event listener which evaluates with break enabled one time and the second
106// time evaluates with break disabled.
107var break_count = 0;
108function listener_recurse(event, exec_state, event_data, data) {
109  try {
110    if (event == Debug.DebugEvent.Break)
111    {
112      break_count++;
113
114      // Call functions with break using the FrameMirror directly.
115      if (break_count == 1) {
116        // First break event evaluates with break enabled.
117        assertEquals(1, exec_state.frame(0).evaluate('f()', false).value());
118        listenerComplete = true;
119      } else {
120        // Second break event evaluates with break disabled.
121        assertEquals(2, break_count);
122        assertFalse(listenerComplete);
123        assertEquals(1, exec_state.frame(0).evaluate('f()', true).value());
124      }
125    }
126  } catch (e) {
127    exception = e
128  };
129};
130
131// Add the debug event listener.
132Debug.setListener(listener);
133
134// Test functions - one with break point and one with debugger statement.
135function f() {
136  return 1;
137};
138
139function g() {
140  debugger;
141  return 2;
142};
143
144Debug.setBreakPoint(f, 2, 0);
145
146// Cause a debug break event.
147debugger;
148
149assertFalse(exception, "exception in listener")
150// Make sure that the debug event listener vas invoked.
151assertTrue(listenerComplete);
152
153// Remove the debug event listener.
154Debug.setListener(null);
155
156// Set debug event listener wich uses recursive breaks.
157Debug.setListener(listener_recurse);
158listenerComplete = false;
159
160Debug.setBreakPoint(f, 2, 0);
161
162debugger;
163
164assertFalse(exception, "exception in listener")
165// Make sure that the debug event listener vas invoked.
166assertTrue(listenerComplete);
167assertEquals(2, break_count);
168