Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: test/debugger/test-api.js

Issue 2466273005: [debugger] Further stepping support in test wrapper (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/debugger/debugger/debug-step-4.js ('k') | test/mjsunit/debug-step-end-of-script.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 "use strict"; 5 "use strict";
6 6
7 // If true, prints all messages sent and received by inspector. 7 // If true, prints all messages sent and received by inspector.
8 const printProtocolMessages = false; 8 const printProtocolMessages = false;
9 9
10 // The active wrapper instance. 10 // The active wrapper instance.
11 let activeWrapper = undefined; 11 let activeWrapper = undefined;
12 12
13 // Receiver function called by inspector, delegating to active wrapper. 13 // Receiver function called by inspector, delegating to active wrapper.
14 function receive(message) { 14 function receive(message) {
15 activeWrapper.receiveMessage(message); 15 activeWrapper.receiveMessage(message);
16 } 16 }
17 17
18 class DebugWrapper { 18 class DebugWrapper {
19 constructor() { 19 constructor() {
20 // Message dictionary storing {id, message} pairs. 20 // Message dictionary storing {id, message} pairs.
21 this.receivedMessages = {}; 21 this.receivedMessages = new Map();
22 22
23 // Each message dispatched by the Debug wrapper is assigned a unique number 23 // Each message dispatched by the Debug wrapper is assigned a unique number
24 // using nextMessageId. 24 // using nextMessageId.
25 this.nextMessageId = 0; 25 this.nextMessageId = 0;
26 26
27 // The listener method called on certain events. 27 // The listener method called on certain events.
28 this.listener = undefined; 28 this.listener = undefined;
29 29
30 // TODO(jgruber): Determine which of these are still required and possible. 30 // TODO(jgruber): Determine which of these are still required and possible.
31 // Debug events which can occur in the V8 JavaScript engine. 31 // Debug events which can occur in the V8 JavaScript engine.
32 this.DebugEvent = { Break: 1 32 this.DebugEvent = { Break: 1
33 , Exception: 2 33 , Exception: 2
34 , NewFunction: 3 34 , NewFunction: 3
35 , BeforeCompile: 4 35 , BeforeCompile: 4
36 , AfterCompile: 5 36 , AfterCompile: 5
37 , CompileError: 6 37 , CompileError: 6
38 , AsyncTaskEvent: 7 38 , AsyncTaskEvent: 7
39 }; 39 };
40 40
41 // The different types of steps.
42 this.StepAction = { StepOut: 0
43 , StepNext: 1
44 , StepIn: 2
45 , StepFrame: 3
46 };
47
48 // A copy of the scope types from runtime-debug.cc.
49 // NOTE: these constants should be backward-compatible, so
50 // add new ones to the end of this list.
51 this.ScopeType = { Global: 0
52 , Local: 1
53 , With: 2
54 , Closure: 3
55 , Catch: 4
56 , Block: 5
57 , Script: 6
58 , Eval: 7
59 , Module: 8
60 };
61
62 // Store the current script id so we can skip corresponding break events.
63 this.thisScriptId = %FunctionGetScriptId(receive);
64
41 // Register as the active wrapper. 65 // Register as the active wrapper.
42 assertTrue(activeWrapper === undefined); 66 assertTrue(activeWrapper === undefined);
43 activeWrapper = this; 67 activeWrapper = this;
44 } 68 }
45 69
46 enable() { this.sendMessageForMethodChecked("Debugger.enable"); } 70 enable() { this.sendMessageForMethodChecked("Debugger.enable"); }
47 disable() { this.sendMessageForMethodChecked("Debugger.disable"); } 71 disable() { this.sendMessageForMethodChecked("Debugger.disable"); }
48 72
49 setListener(listener) { this.listener = listener; } 73 setListener(listener) { this.listener = listener; }
50 74
(...skipping 18 matching lines...) Expand all
69 93
70 const {msgid, msg} = this.createMessage( 94 const {msgid, msg} = this.createMessage(
71 "Debugger.setBreakpoint", 95 "Debugger.setBreakpoint",
72 { location : { scriptId : scriptid.toString() 96 { location : { scriptId : scriptid.toString()
73 , lineNumber : loc.line 97 , lineNumber : loc.line
74 , columnNumber : loc.column 98 , columnNumber : loc.column
75 } 99 }
76 }); 100 });
77 this.sendMessage(msg); 101 this.sendMessage(msg);
78 102
79 const reply = this.receivedMessages[msgid]; 103 const reply = this.takeReplyChecked(msgid);
104 assertTrue(reply.result !== undefined);
80 const breakid = reply.result.breakpointId; 105 const breakid = reply.result.breakpointId;
81 assertTrue(breakid !== undefined); 106 assertTrue(breakid !== undefined);
82 107
83 return breakid; 108 return breakid;
84 } 109 }
85 110
86 clearBreakPoint(breakid) { 111 clearBreakPoint(breakid) {
87 const {msgid, msg} = this.createMessage( 112 const {msgid, msg} = this.createMessage(
88 "Debugger.removeBreakpoint", { breakpointId : breakid }); 113 "Debugger.removeBreakpoint", { breakpointId : breakid });
89 this.sendMessage(msg); 114 this.sendMessage(msg);
90 assertTrue(this.receivedMessages[msgid] !== undefined); 115 this.takeReplyChecked(msgid);
91 } 116 }
92 117
93 // Returns the serialized result of the given expression. For example: 118 // Returns the serialized result of the given expression. For example:
94 // {"type":"number", "value":33, "description":"33"}. 119 // {"type":"number", "value":33, "description":"33"}.
95 evaluate(frameid, expression) { 120 evaluate(frameid, expression) {
96 const {msgid, msg} = this.createMessage( 121 const {msgid, msg} = this.createMessage(
97 "Debugger.evaluateOnCallFrame", 122 "Debugger.evaluateOnCallFrame",
98 { callFrameId : frameid 123 { callFrameId : frameid
99 , expression : expression 124 , expression : expression
100 }); 125 });
101 this.sendMessage(msg); 126 this.sendMessage(msg);
102 127
103 const reply = this.receivedMessages[msgid]; 128 const reply = this.takeReplyChecked(msgid);
104 return reply.result.result; 129 return reply.result.result;
105 } 130 }
106 131
107 // --- Internal methods. ----------------------------------------------------- 132 // --- Internal methods. -----------------------------------------------------
108 133
109 getNextMessageId() { 134 getNextMessageId() {
110 return this.nextMessageId++; 135 return this.nextMessageId++;
111 } 136 }
112 137
113 createMessage(method, params) { 138 createMessage(method, params) {
(...skipping 18 matching lines...) Expand all
132 } 157 }
133 158
134 sendMessage(message) { 159 sendMessage(message) {
135 if (printProtocolMessages) print(message); 160 if (printProtocolMessages) print(message);
136 send(message); 161 send(message);
137 } 162 }
138 163
139 sendMessageForMethodChecked(method) { 164 sendMessageForMethodChecked(method) {
140 const {msgid, msg} = this.createMessage(method); 165 const {msgid, msg} = this.createMessage(method);
141 this.sendMessage(msg); 166 this.sendMessage(msg);
142 assertTrue(this.receivedMessages[msgid] !== undefined); 167 this.takeReplyChecked(msgid);
168 }
169
170 takeReplyChecked(msgid) {
171 const reply = this.receivedMessages[msgid];
172 assertTrue(reply !== undefined);
173 delete this.receivedMessages[msgid];
Yang 2016/11/02 10:36:04 I don't think this is how to use a Map. You would
jgruber 2016/11/07 11:35:11 Done.
174 return reply;
175 }
176
177 execStatePrepareStep(action) {
178 switch(action) {
179 case this.StepAction.StepOut: this.stepOut(); break;
180 case this.StepAction.StepNext: this.stepOver(); break;
181 case this.StepAction.StepIn: this.stepInto(); break;
182 default: %AbortJS("Unsupported StepAction"); break;
183 }
184 }
185
186 execStateScope(scope) {
187 // TODO(jgruber): Mapping
188 return { scopeType: () => scope.type
189 , scopeObject: () => scope.object
Yang 2016/11/02 10:36:04 Can we have the comma on the previous line? Elsewh
jgruber 2016/11/07 11:35:11 Dang, thought I could sneak some nice haskell-styl
190 };
191 }
192
193 execStateFrame(frame) {
194 const scriptid = parseInt(frame.location.scriptId);
195 const line = frame.location.lineNumber;
196 const column = frame.location.columnNumber;
197 const loc = %ScriptLocationFromLine2(scriptid, line, column, 0);
198 const func = { name : () => frame.functionName };
199 return { sourceLineText : () => loc.sourceText
200 , functionName : () => frame.functionName
201 , func : () => func
202 , scopeCount : () => frame.scopeChain.length
203 , scope : (index) => this.execStateScope(frame.scopeChain[index])
204 };
143 } 205 }
144 206
145 // --- Message handlers. ----------------------------------------------------- 207 // --- Message handlers. -----------------------------------------------------
146 208
147 dispatchMessage(message) { 209 dispatchMessage(message) {
148 const method = message.method; 210 const method = message.method;
149 if (method == "Debugger.paused") { 211 if (method == "Debugger.paused") {
150 this.handleDebuggerPaused(message); 212 this.handleDebuggerPaused(message);
151 } else if (method == "Debugger.scriptParsed") { 213 } else if (method == "Debugger.scriptParsed") {
152 this.handleDebuggerScriptParsed(message); 214 this.handleDebuggerScriptParsed(message);
153 } 215 }
154 } 216 }
155 217
156 handleDebuggerPaused(message) { 218 handleDebuggerPaused(message) {
157 const params = message.params; 219 const params = message.params;
158 220
221 // Skip break events in this file.
222 if (params.callFrames[0].location.scriptId == this.thisScriptId) return;
223
159 // TODO(jgruber): Arguments as needed. 224 // TODO(jgruber): Arguments as needed.
160 let execState = { frames: params.callFrames }; 225 let execState = { frames : params.callFrames
161 this.invokeListener(this.DebugEvent.Break, execState); 226 , prepareStep : this.execStatePrepareStep.bind(this)
227 , frame : (index) => this.execStateFrame(index ? params.call Frames[index] : params.callFrames[0])
228 , frameCount : () => params.callFrames.length
Yang 2016/11/02 10:36:04 80-char limit.
jgruber 2016/11/07 11:35:11 Done.
229 };
230 let eventData = this.execStateFrame(params.callFrames[0]);
231 this.invokeListener(this.DebugEvent.Break, execState, eventData);
162 } 232 }
163 233
164 handleDebuggerScriptParsed(message) { 234 handleDebuggerScriptParsed(message) {
165 const params = message.params; 235 const params = message.params;
166 let eventData = { scriptId : params.scriptId 236 let eventData = { scriptId : params.scriptId
167 , eventType : this.DebugEvent.AfterCompile 237 , eventType : this.DebugEvent.AfterCompile
168 } 238 }
169 239
170 // TODO(jgruber): Arguments as needed. Still completely missing exec_state, 240 // TODO(jgruber): Arguments as needed. Still completely missing exec_state,
171 // and eventData used to contain the script mirror instead of its id. 241 // and eventData used to contain the script mirror instead of its id.
172 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData, 242 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData,
173 undefined); 243 undefined);
174 } 244 }
175 245
176 invokeListener(event, exec_state, event_data, data) { 246 invokeListener(event, exec_state, event_data, data) {
177 if (this.listener) { 247 if (this.listener) {
178 this.listener(event, exec_state, event_data, data); 248 this.listener(event, exec_state, event_data, data);
179 } 249 }
180 } 250 }
181 } 251 }
252
253 // Simulate the debug object generated by --expose-debug-as debug.
254 var debug = { instance : undefined };
255 Object.defineProperty(debug, 'Debug', { get: function() {
256 if (!debug.instance) {
257 debug.instance = new DebugWrapper();
258 debug.instance.enable();
259 }
260 return debug.instance;
261 }});
OLDNEW
« no previous file with comments | « test/debugger/debugger/debug-step-4.js ('k') | test/mjsunit/debug-step-end-of-script.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698