Chromium Code Reviews| 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 |