OLD | NEW |
---|---|
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. |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 | 213 |
214 execStatePrepareStep(action) { | 214 execStatePrepareStep(action) { |
215 switch(action) { | 215 switch(action) { |
216 case this.StepAction.StepOut: this.stepOut(); break; | 216 case this.StepAction.StepOut: this.stepOut(); break; |
217 case this.StepAction.StepNext: this.stepOver(); break; | 217 case this.StepAction.StepNext: this.stepOver(); break; |
218 case this.StepAction.StepIn: this.stepInto(); break; | 218 case this.StepAction.StepIn: this.stepInto(); break; |
219 default: %AbortJS("Unsupported StepAction"); break; | 219 default: %AbortJS("Unsupported StepAction"); break; |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 execStateScopeType(type) { | |
224 switch (type) { | |
225 case "global": return this.ScopeType.Global; | |
226 case "local": return this.ScopeType.Local; | |
227 case "with": return this.ScopeType.With; | |
228 case "closure": return this.ScopeType.Closure; | |
229 case "catch": return this.ScopeType.Catch; | |
230 case "block": return this.ScopeType.Block; | |
231 case "script": return this.ScopeType.Script; | |
232 default: %AbortJS("Unexpected scope type"); | |
233 } | |
234 } | |
235 | |
236 // Returns an array of property descriptors of the scope object. | |
237 // This is in contrast to the original API, which simply passed object | |
238 // mirrors. | |
239 execStateScopeObject(obj) { | |
240 const {msgid, msg} = this.createMessage( | |
241 "Runtime.getProperties", { objectId : obj.objectId }); | |
242 this.sendMessage(msg); | |
243 const reply = this.takeReplyChecked(msgid); | |
244 return { value : () => reply.result.result }; | |
245 } | |
246 | |
223 execStateScope(scope) { | 247 execStateScope(scope) { |
224 // TODO(jgruber): Mapping | 248 return { scopeType : () => this.execStateScopeType(scope.type), |
Yang
2016/11/08 13:37:33
Just curious: do we need to specify 'this' explici
jgruber
2016/11/08 13:58:35
We do :/
$ out/debug/d8 <<< 'class Foo { x() { pr
| |
225 return { scopeType: () => scope.type, | 249 scopeObject : () => this.execStateScopeObject(scope.object) |
226 scopeObject: () => scope.object | |
227 }; | 250 }; |
228 } | 251 } |
229 | 252 |
230 execStateFrame(frame) { | 253 execStateFrame(frame) { |
231 const scriptid = parseInt(frame.location.scriptId); | 254 const scriptid = parseInt(frame.location.scriptId); |
232 const line = frame.location.lineNumber; | 255 const line = frame.location.lineNumber; |
233 const column = frame.location.columnNumber; | 256 const column = frame.location.columnNumber; |
234 const loc = %ScriptLocationFromLine2(scriptid, line, column, 0); | 257 const loc = %ScriptLocationFromLine2(scriptid, line, column, 0); |
235 const func = { name : () => frame.functionName }; | 258 const func = { name : () => frame.functionName }; |
236 return { sourceLineText : () => loc.sourceText, | 259 return { sourceLineText : () => loc.sourceText, |
237 functionName : () => frame.functionName, | 260 functionName : () => frame.functionName, |
238 func : () => func, | 261 func : () => func, |
239 scopeCount : () => frame.scopeChain.length, | 262 scopeCount : () => frame.scopeChain.length, |
240 scope : (index) => this.execStateScope(frame.scopeChain[index]) | 263 scope : (index) => this.execStateScope(frame.scopeChain[index]) |
264 , allScopes : () => frame.scopeChain.map(this.execStateScope.bind(thi s)) | |
Yang
2016/11/08 13:37:33
formatting (comma, and 80-char limit) :)
jgruber
2016/11/08 13:58:35
Done, ty.
| |
241 }; | 265 }; |
242 } | 266 } |
243 | 267 |
244 // --- Message handlers. ----------------------------------------------------- | 268 // --- Message handlers. ----------------------------------------------------- |
245 | 269 |
246 dispatchMessage(message) { | 270 dispatchMessage(message) { |
247 const method = message.method; | 271 const method = message.method; |
248 if (method == "Debugger.paused") { | 272 if (method == "Debugger.paused") { |
249 this.handleDebuggerPaused(message); | 273 this.handleDebuggerPaused(message); |
250 } else if (method == "Debugger.scriptParsed") { | 274 } else if (method == "Debugger.scriptParsed") { |
251 this.handleDebuggerScriptParsed(message); | 275 this.handleDebuggerScriptParsed(message); |
252 } | 276 } |
253 } | 277 } |
254 | 278 |
255 handleDebuggerPaused(message) { | 279 handleDebuggerPaused(message) { |
256 const params = message.params; | 280 const params = message.params; |
257 | 281 |
282 var debugEvent; | |
283 switch (params.reason) { | |
284 case "exception": | |
285 case "promiseRejection": | |
286 debugEvent = this.DebugEvent.Exception; | |
287 break; | |
288 default: | |
289 // TODO(jgruber): More granularity. | |
290 debugEvent = this.DebugEvent.Break; | |
291 break; | |
292 } | |
293 | |
258 // Skip break events in this file. | 294 // Skip break events in this file. |
259 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; | 295 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; |
260 | 296 |
261 // TODO(jgruber): Arguments as needed. | 297 // TODO(jgruber): Arguments as needed. |
262 let execState = { frames : params.callFrames, | 298 let execState = { frames : params.callFrames, |
263 prepareStep : this.execStatePrepareStep.bind(this), | 299 prepareStep : this.execStatePrepareStep.bind(this), |
264 frame : (index) => this.execStateFrame( | 300 frame : (index) => this.execStateFrame( |
265 index ? params.callFrames[index] | 301 index ? params.callFrames[index] |
266 : params.callFrames[0]), | 302 : params.callFrames[0]), |
267 frameCount : () => params.callFrames.length | 303 frameCount : () => params.callFrames.length |
268 }; | 304 }; |
269 let eventData = this.execStateFrame(params.callFrames[0]); | 305 let eventData = this.execStateFrame(params.callFrames[0]); |
270 this.invokeListener(this.DebugEvent.Break, execState, eventData); | 306 this.invokeListener(debugEvent, execState, eventData); |
271 } | 307 } |
272 | 308 |
273 handleDebuggerScriptParsed(message) { | 309 handleDebuggerScriptParsed(message) { |
274 const params = message.params; | 310 const params = message.params; |
275 let eventData = { scriptId : params.scriptId, | 311 let eventData = { scriptId : params.scriptId, |
276 eventType : this.DebugEvent.AfterCompile | 312 eventType : this.DebugEvent.AfterCompile |
277 } | 313 } |
278 | 314 |
279 // TODO(jgruber): Arguments as needed. Still completely missing exec_state, | 315 // TODO(jgruber): Arguments as needed. Still completely missing exec_state, |
280 // and eventData used to contain the script mirror instead of its id. | 316 // and eventData used to contain the script mirror instead of its id. |
281 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData, | 317 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData, |
282 undefined); | 318 undefined); |
283 } | 319 } |
284 | 320 |
285 invokeListener(event, exec_state, event_data, data) { | 321 invokeListener(event, exec_state, event_data, data) { |
286 if (this.listener) { | 322 if (this.listener) { |
287 this.listener(event, exec_state, event_data, data); | 323 this.listener(event, exec_state, event_data, data); |
288 } | 324 } |
289 } | 325 } |
290 } | 326 } |
291 | 327 |
292 // Simulate the debug object generated by --expose-debug-as debug. | 328 // Simulate the debug object generated by --expose-debug-as debug. |
293 var debug = { instance : undefined }; | 329 var debug = { instance : undefined }; |
330 | |
294 Object.defineProperty(debug, 'Debug', { get: function() { | 331 Object.defineProperty(debug, 'Debug', { get: function() { |
295 if (!debug.instance) { | 332 if (!debug.instance) { |
296 debug.instance = new DebugWrapper(); | 333 debug.instance = new DebugWrapper(); |
297 debug.instance.enable(); | 334 debug.instance.enable(); |
298 } | 335 } |
299 return debug.instance; | 336 return debug.instance; |
300 }}); | 337 }}); |
338 | |
339 Object.defineProperty(debug, 'ScopeType', { get: function() { | |
340 const instance = debug.Debug; | |
341 return instance.ScopeType; | |
342 }}); | |
OLD | NEW |