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), |
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( |
| 265 this.execStateScope.bind(this)) |
241 }; | 266 }; |
242 } | 267 } |
243 | 268 |
244 // --- Message handlers. ----------------------------------------------------- | 269 // --- Message handlers. ----------------------------------------------------- |
245 | 270 |
246 dispatchMessage(message) { | 271 dispatchMessage(message) { |
247 const method = message.method; | 272 const method = message.method; |
248 if (method == "Debugger.paused") { | 273 if (method == "Debugger.paused") { |
249 this.handleDebuggerPaused(message); | 274 this.handleDebuggerPaused(message); |
250 } else if (method == "Debugger.scriptParsed") { | 275 } else if (method == "Debugger.scriptParsed") { |
251 this.handleDebuggerScriptParsed(message); | 276 this.handleDebuggerScriptParsed(message); |
252 } | 277 } |
253 } | 278 } |
254 | 279 |
255 handleDebuggerPaused(message) { | 280 handleDebuggerPaused(message) { |
256 const params = message.params; | 281 const params = message.params; |
257 | 282 |
| 283 var debugEvent; |
| 284 switch (params.reason) { |
| 285 case "exception": |
| 286 case "promiseRejection": |
| 287 debugEvent = this.DebugEvent.Exception; |
| 288 break; |
| 289 default: |
| 290 // TODO(jgruber): More granularity. |
| 291 debugEvent = this.DebugEvent.Break; |
| 292 break; |
| 293 } |
| 294 |
258 // Skip break events in this file. | 295 // Skip break events in this file. |
259 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; | 296 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; |
260 | 297 |
261 // TODO(jgruber): Arguments as needed. | 298 // TODO(jgruber): Arguments as needed. |
262 let execState = { frames : params.callFrames, | 299 let execState = { frames : params.callFrames, |
263 prepareStep : this.execStatePrepareStep.bind(this), | 300 prepareStep : this.execStatePrepareStep.bind(this), |
264 frame : (index) => this.execStateFrame( | 301 frame : (index) => this.execStateFrame( |
265 index ? params.callFrames[index] | 302 index ? params.callFrames[index] |
266 : params.callFrames[0]), | 303 : params.callFrames[0]), |
267 frameCount : () => params.callFrames.length | 304 frameCount : () => params.callFrames.length |
268 }; | 305 }; |
269 let eventData = this.execStateFrame(params.callFrames[0]); | 306 let eventData = this.execStateFrame(params.callFrames[0]); |
270 this.invokeListener(this.DebugEvent.Break, execState, eventData); | 307 this.invokeListener(debugEvent, execState, eventData); |
271 } | 308 } |
272 | 309 |
273 handleDebuggerScriptParsed(message) { | 310 handleDebuggerScriptParsed(message) { |
274 const params = message.params; | 311 const params = message.params; |
275 let eventData = { scriptId : params.scriptId, | 312 let eventData = { scriptId : params.scriptId, |
276 eventType : this.DebugEvent.AfterCompile | 313 eventType : this.DebugEvent.AfterCompile |
277 } | 314 } |
278 | 315 |
279 // TODO(jgruber): Arguments as needed. Still completely missing exec_state, | 316 // TODO(jgruber): Arguments as needed. Still completely missing exec_state, |
280 // and eventData used to contain the script mirror instead of its id. | 317 // and eventData used to contain the script mirror instead of its id. |
281 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData, | 318 this.invokeListener(this.DebugEvent.AfterCompile, undefined, eventData, |
282 undefined); | 319 undefined); |
283 } | 320 } |
284 | 321 |
285 invokeListener(event, exec_state, event_data, data) { | 322 invokeListener(event, exec_state, event_data, data) { |
286 if (this.listener) { | 323 if (this.listener) { |
287 this.listener(event, exec_state, event_data, data); | 324 this.listener(event, exec_state, event_data, data); |
288 } | 325 } |
289 } | 326 } |
290 } | 327 } |
291 | 328 |
292 // Simulate the debug object generated by --expose-debug-as debug. | 329 // Simulate the debug object generated by --expose-debug-as debug. |
293 var debug = { instance : undefined }; | 330 var debug = { instance : undefined }; |
| 331 |
294 Object.defineProperty(debug, 'Debug', { get: function() { | 332 Object.defineProperty(debug, 'Debug', { get: function() { |
295 if (!debug.instance) { | 333 if (!debug.instance) { |
296 debug.instance = new DebugWrapper(); | 334 debug.instance = new DebugWrapper(); |
297 debug.instance.enable(); | 335 debug.instance.enable(); |
298 } | 336 } |
299 return debug.instance; | 337 return debug.instance; |
300 }}); | 338 }}); |
| 339 |
| 340 Object.defineProperty(debug, 'ScopeType', { get: function() { |
| 341 const instance = debug.Debug; |
| 342 return instance.ScopeType; |
| 343 }}); |
OLD | NEW |