| 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 |