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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 this.StepAction = { StepOut: 0, | 42 this.StepAction = { StepOut: 0, |
43 StepNext: 1, | 43 StepNext: 1, |
44 StepIn: 2, | 44 StepIn: 2, |
45 StepFrame: 3, | 45 StepFrame: 3, |
46 }; | 46 }; |
47 | 47 |
48 // The different types of scripts matching enum ScriptType in objects.h. | 48 // The different types of scripts matching enum ScriptType in objects.h. |
49 this.ScriptType = { Native: 0, | 49 this.ScriptType = { Native: 0, |
50 Extension: 1, | 50 Extension: 1, |
51 Normal: 2, | 51 Normal: 2, |
52 Wasm: 3}; | 52 Wasm: 3, |
| 53 Inspector: 4, |
| 54 }; |
53 | 55 |
54 // A copy of the scope types from runtime-debug.cc. | 56 // A copy of the scope types from runtime-debug.cc. |
55 // NOTE: these constants should be backward-compatible, so | 57 // NOTE: these constants should be backward-compatible, so |
56 // add new ones to the end of this list. | 58 // add new ones to the end of this list. |
57 this.ScopeType = { Global: 0, | 59 this.ScopeType = { Global: 0, |
58 Local: 1, | 60 Local: 1, |
59 With: 2, | 61 With: 2, |
60 Closure: 3, | 62 Closure: 3, |
61 Catch: 4, | 63 Catch: 4, |
62 Block: 5, | 64 Block: 5, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 assertEquals(this.ScriptBreakPointType.ScriptId, type); | 155 assertEquals(this.ScriptBreakPointType.ScriptId, type); |
154 return this.setScriptBreakPointById(scriptid, opt_line, opt_column, | 156 return this.setScriptBreakPointById(scriptid, opt_line, opt_column, |
155 opt_condition); | 157 opt_condition); |
156 } | 158 } |
157 | 159 |
158 setScriptBreakPointById(scriptid, opt_line, opt_column, opt_condition) { | 160 setScriptBreakPointById(scriptid, opt_line, opt_column, opt_condition) { |
159 const loc = %ScriptLocationFromLine2(scriptid, opt_line, opt_column, 0); | 161 const loc = %ScriptLocationFromLine2(scriptid, opt_line, opt_column, 0); |
160 return this.setBreakPointAtLocation(scriptid, loc, opt_condition); | 162 return this.setBreakPointAtLocation(scriptid, loc, opt_condition); |
161 } | 163 } |
162 | 164 |
163 clearBreakPoint(breakid) { | 165 setBreakPointByScriptIdAndPosition(scriptid, position) { |
164 assertTrue(this.breakpoints.has(breakid)); | 166 const loc = %ScriptPositionInfo2(scriptid, position, false); |
| 167 return this.setBreakPointAtLocation(scriptid, loc, undefined); |
| 168 } |
| 169 |
| 170 clearBreakPoint(breakpoint) { |
| 171 assertTrue(this.breakpoints.has(breakpoint)); |
| 172 const breakid = breakpoint.id; |
165 const {msgid, msg} = this.createMessage( | 173 const {msgid, msg} = this.createMessage( |
166 "Debugger.removeBreakpoint", { breakpointId : breakid }); | 174 "Debugger.removeBreakpoint", { breakpointId : breakid }); |
167 this.sendMessage(msg); | 175 this.sendMessage(msg); |
168 this.takeReplyChecked(msgid); | 176 this.takeReplyChecked(msgid); |
169 this.breakpoints.delete(breakid); | 177 this.breakpoints.delete(breakid); |
170 } | 178 } |
171 | 179 |
172 clearAllBreakPoints() { | 180 clearAllBreakPoints() { |
173 for (let breakid of this.breakpoints) { | 181 for (let breakpoint of this.breakpoints) { |
174 this.clearBreakPoint(breakid); | 182 this.clearBreakPoint(breakpoint); |
175 } | 183 } |
176 this.breakpoints.clear(); | 184 this.breakpoints.clear(); |
177 } | 185 } |
178 | 186 |
179 showBreakPoints(f, opt_position_alignment) { | 187 showBreakPoints(f, opt_position_alignment) { |
180 if (!%IsFunction(f)) throw new Error("Not passed a Function"); | 188 if (!%IsFunction(f)) throw new Error("Not passed a Function"); |
181 | 189 |
182 const source = %FunctionGetSourceCode(f); | 190 const source = %FunctionGetSourceCode(f); |
183 const offset = %FunctionGetScriptSourcePosition(f); | 191 const offset = %FunctionGetScriptSourcePosition(f); |
184 const position_alignment = opt_position_alignment === undefined | 192 const position_alignment = opt_position_alignment === undefined |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 lineNumber : loc.line, | 348 lineNumber : loc.line, |
341 columnNumber : loc.column, | 349 columnNumber : loc.column, |
342 }, | 350 }, |
343 condition : opt_condition, | 351 condition : opt_condition, |
344 }; | 352 }; |
345 | 353 |
346 const {msgid, msg} = this.createMessage("Debugger.setBreakpoint", params); | 354 const {msgid, msg} = this.createMessage("Debugger.setBreakpoint", params); |
347 this.sendMessage(msg); | 355 this.sendMessage(msg); |
348 | 356 |
349 const reply = this.takeReplyChecked(msgid); | 357 const reply = this.takeReplyChecked(msgid); |
350 assertTrue(reply.result !== undefined); | 358 const result = reply.result; |
351 const breakid = reply.result.breakpointId; | 359 assertTrue(result !== undefined); |
| 360 const breakid = result.breakpointId; |
352 assertTrue(breakid !== undefined); | 361 assertTrue(breakid !== undefined); |
353 | 362 |
354 this.breakpoints.add(breakid); | 363 const actualLoc = %ScriptLocationFromLine2(scriptid, |
| 364 result.actualLocation.lineNumber, result.actualLocation.columnNumber, |
| 365 0); |
355 | 366 |
356 return breakid; | 367 const breakpoint = { id : result.breakpointId, |
| 368 actual_position : actualLoc.position, |
| 369 } |
| 370 |
| 371 this.breakpoints.add(breakpoint); |
| 372 return breakpoint; |
357 } | 373 } |
358 | 374 |
359 execStatePrepareStep(action) { | 375 execStatePrepareStep(action) { |
360 switch(action) { | 376 switch(action) { |
361 case this.StepAction.StepOut: this.stepOut(); break; | 377 case this.StepAction.StepOut: this.stepOut(); break; |
362 case this.StepAction.StepNext: this.stepOver(); break; | 378 case this.StepAction.StepNext: this.stepOver(); break; |
363 case this.StepAction.StepIn: this.stepInto(); break; | 379 case this.StepAction.StepIn: this.stepInto(); break; |
364 default: %AbortJS("Unsupported StepAction"); break; | 380 default: %AbortJS("Unsupported StepAction"); break; |
365 } | 381 } |
366 } | 382 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 setVariableValue(frame, scope_index, name, value) { | 427 setVariableValue(frame, scope_index, name, value) { |
412 const frameid = frame.callFrameId; | 428 const frameid = frame.callFrameId; |
413 const {msgid, msg} = this.createMessage( | 429 const {msgid, msg} = this.createMessage( |
414 "Debugger.setVariableValue", | 430 "Debugger.setVariableValue", |
415 { callFrameId : frameid, | 431 { callFrameId : frameid, |
416 scopeNumber : scope_index, | 432 scopeNumber : scope_index, |
417 variableName : name, | 433 variableName : name, |
418 newValue : { value : value } | 434 newValue : { value : value } |
419 }); | 435 }); |
420 this.sendMessage(msg); | 436 this.sendMessage(msg); |
421 this.takeReplyChecked(msgid); | 437 const reply = this.takeReplyChecked(msgid); |
| 438 if (reply.error) { |
| 439 throw new Error("Failed to set variable value"); |
| 440 } |
422 } | 441 } |
423 | 442 |
424 execStateScope(frame, scope_index) { | 443 execStateScope(frame, scope_index) { |
425 const scope = frame.scopeChain[scope_index]; | 444 const scope = frame.scopeChain[scope_index]; |
426 return { scopeType : () => this.execStateScopeType(scope.type), | 445 return { scopeType : () => this.execStateScopeType(scope.type), |
427 scopeObject : () => this.execStateScopeObject(scope.object), | 446 scopeObject : () => this.execStateScopeObject(scope.object), |
428 setVariableValue : | 447 setVariableValue : |
429 (name, value) => this.setVariableValue(frame, scope_index, | 448 (name, value) => this.setVariableValue(frame, scope_index, |
430 name, value) | 449 name, value) |
431 }; | 450 }; |
(...skipping 16 matching lines...) Expand all Loading... |
448 } | 467 } |
449 | 468 |
450 obj[key] = value; | 469 obj[key] = value; |
451 }) | 470 }) |
452 | 471 |
453 return obj; | 472 return obj; |
454 } | 473 } |
455 | 474 |
456 getProperties(objectId) { | 475 getProperties(objectId) { |
457 const {msgid, msg} = this.createMessage( | 476 const {msgid, msg} = this.createMessage( |
458 "Runtime.getProperties", { objectId : objectId }); | 477 "Runtime.getProperties", { objectId : objectId, ownProperties: true }); |
459 this.sendMessage(msg); | 478 this.sendMessage(msg); |
460 const reply = this.takeReplyChecked(msgid); | 479 const reply = this.takeReplyChecked(msgid); |
461 return reply.result.result; | 480 return reply.result.result; |
462 } | 481 } |
463 | 482 |
464 getLocalScopeDetails(frame) { | 483 getLocalScopeDetails(frame) { |
465 const scopes = frame.scopeChain; | 484 const scopes = frame.scopeChain; |
466 for (let i = 0; i < scopes.length; i++) { | 485 for (let i = 0; i < scopes.length; i++) { |
467 const scope = scopes[i] | 486 const scope = scopes[i] |
468 if (scope.type == "local") { | 487 if (scope.type == "local") { |
(...skipping 25 matching lines...) Expand all Loading... |
494 switch (local.value.type) { | 513 switch (local.value.type) { |
495 case "undefined": localValue = undefined; break; | 514 case "undefined": localValue = undefined; break; |
496 default: localValue = local.value.value; break; | 515 default: localValue = local.value.value; break; |
497 } | 516 } |
498 | 517 |
499 return { value : () => localValue }; | 518 return { value : () => localValue }; |
500 } | 519 } |
501 | 520 |
502 reconstructRemoteObject(obj) { | 521 reconstructRemoteObject(obj) { |
503 let value = obj.value; | 522 let value = obj.value; |
504 if (obj.type == "object") { | 523 let isUndefined = false; |
505 if (obj.subtype == "error") { | 524 |
506 const desc = obj.description; | 525 switch (obj.type) { |
507 switch (obj.className) { | 526 case "object": { |
508 case "EvalError": throw new EvalError(desc); | 527 switch (obj.subtype) { |
509 case "RangeError": throw new RangeError(desc); | 528 case "error": { |
510 case "ReferenceError": throw new ReferenceError(desc); | 529 const desc = obj.description; |
511 case "SyntaxError": throw new SyntaxError(desc); | 530 switch (obj.className) { |
512 case "TypeError": throw new TypeError(desc); | 531 case "EvalError": throw new EvalError(desc); |
513 case "URIError": throw new URIError(desc); | 532 case "RangeError": throw new RangeError(desc); |
514 default: throw new Error(desc); | 533 case "ReferenceError": throw new ReferenceError(desc); |
| 534 case "SyntaxError": throw new SyntaxError(desc); |
| 535 case "TypeError": throw new TypeError(desc); |
| 536 case "URIError": throw new URIError(desc); |
| 537 default: throw new Error(desc); |
| 538 } |
| 539 break; |
| 540 } |
| 541 case "array": { |
| 542 const array = []; |
| 543 const props = this.propertiesToObject( |
| 544 this.getProperties(obj.objectId)); |
| 545 for (let i = 0; i < props.length; i++) { |
| 546 array[i] = props[i]; |
| 547 } |
| 548 value = array; |
| 549 break; |
| 550 } |
| 551 case "null": { |
| 552 value = null; |
| 553 break; |
| 554 } |
| 555 default: { |
| 556 value = this.propertiesToObject(this.getProperties(obj.objectId)); |
| 557 break; |
| 558 } |
515 } | 559 } |
516 } else if (obj.subtype == "array") { | 560 break; |
517 const array = []; | 561 } |
518 const props = this.propertiesToObject( | 562 case "undefined": { |
519 this.getProperties(obj.objectId)); | 563 value = undefined; |
520 for (let i = 0; i < props.length; i++) { | 564 isUndefined = true; |
521 array[i] = props[i]; | 565 break; |
522 } | 566 } |
523 value = array; | 567 case "string": |
| 568 case "number": |
| 569 case "boolean": { |
| 570 break; |
| 571 } |
| 572 default: { |
| 573 break; |
524 } | 574 } |
525 } | 575 } |
526 | 576 |
527 return { value : () => value, | 577 return { value : () => value, |
528 isUndefined : () => obj.type == "undefined" | 578 isUndefined : () => isUndefined |
529 }; | 579 }; |
530 } | 580 } |
531 | 581 |
532 evaluateOnCallFrame(frame, expr) { | 582 evaluateOnCallFrame(frame, expr) { |
533 const frameid = frame.callFrameId; | 583 const frameid = frame.callFrameId; |
534 const {msgid, msg} = this.createMessage( | 584 const {msgid, msg} = this.createMessage( |
535 "Debugger.evaluateOnCallFrame", | 585 "Debugger.evaluateOnCallFrame", |
536 { callFrameId : frameid, | 586 { callFrameId : frameid, |
537 expression : expr | 587 expression : expr |
538 }); | 588 }); |
(...skipping 29 matching lines...) Expand all Loading... |
568 | 618 |
569 return { sourceColumn : () => loc.column, | 619 return { sourceColumn : () => loc.column, |
570 sourceLine : () => loc.line + 1, | 620 sourceLine : () => loc.line + 1, |
571 sourceLineText : () => loc.sourceText, | 621 sourceLineText : () => loc.sourceText, |
572 evaluate : (expr) => this.evaluateOnCallFrame(frame, expr), | 622 evaluate : (expr) => this.evaluateOnCallFrame(frame, expr), |
573 functionName : () => frame.functionName, | 623 functionName : () => frame.functionName, |
574 func : () => func, | 624 func : () => func, |
575 localCount : () => this.execStateFrameLocalCount(frame), | 625 localCount : () => this.execStateFrameLocalCount(frame), |
576 localName : (ix) => this.execStateFrameLocalName(frame, ix), | 626 localName : (ix) => this.execStateFrameLocalName(frame, ix), |
577 localValue: (ix) => this.execStateFrameLocalValue(frame, ix), | 627 localValue: (ix) => this.execStateFrameLocalValue(frame, ix), |
| 628 receiver : () => this.evaluateOnCallFrame(frame, "this"), |
578 restart : () => this.execStateFrameRestart(frame), | 629 restart : () => this.execStateFrameRestart(frame), |
579 scopeCount : () => frame.scopeChain.length, | 630 scopeCount : () => frame.scopeChain.length, |
580 scope : (index) => this.execStateScope(frame, index), | 631 scope : (index) => this.execStateScope(frame, index), |
581 allScopes : allScopes.bind(this) | 632 allScopes : allScopes.bind(this) |
582 }; | 633 }; |
583 } | 634 } |
584 | 635 |
585 eventDataException(params) { | 636 eventDataException(params) { |
586 switch (params.data.type) { | 637 switch (params.data.type) { |
587 case "string": { | 638 case "string": { |
588 return params.data.value; | 639 return params.data.value; |
589 } | 640 } |
590 case "object": { | 641 case "object": { |
591 const props = this.getProperties(params.data.objectId); | 642 const props = this.getProperties(params.data.objectId); |
592 return this.propertiesToObject(props); | 643 return this.propertiesToObject(props); |
593 } | 644 } |
594 default: { | 645 default: { |
595 return undefined; | 646 return undefined; |
596 } | 647 } |
597 } | 648 } |
598 } | 649 } |
599 | 650 |
600 eventDataScriptSource(id) { | 651 eventDataScriptSource(id) { |
601 const {msgid, msg} = this.createMessage( | 652 const {msgid, msg} = this.createMessage( |
602 "Debugger.getScriptSource", { scriptId : id }); | 653 "Debugger.getScriptSource", { scriptId : String(id) }); |
603 this.sendMessage(msg); | 654 this.sendMessage(msg); |
604 const reply = this.takeReplyChecked(msgid); | 655 const reply = this.takeReplyChecked(msgid); |
605 return reply.result.scriptSource; | 656 return reply.result.scriptSource; |
606 } | 657 } |
607 | 658 |
608 eventDataScriptSetSource(id, src) { | 659 eventDataScriptSetSource(id, src) { |
609 const {msgid, msg} = this.createMessage( | 660 const {msgid, msg} = this.createMessage( |
610 "Debugger.setScriptSource", { scriptId : id, scriptSource : src }); | 661 "Debugger.setScriptSource", { scriptId : id, scriptSource : src }); |
611 this.sendMessage(msg); | 662 this.sendMessage(msg); |
612 this.takeReplyChecked(msgid); | 663 this.takeReplyChecked(msgid); |
613 } | 664 } |
614 | 665 |
615 eventDataScript(params) { | 666 eventDataScript(params) { |
616 const id = params.scriptId; | 667 const id = parseInt(params.scriptId); |
617 const name = params.url ? params.url : undefined; | 668 const name = params.url ? params.url : undefined; |
618 | 669 |
619 return { id : () => id, | 670 return { id : () => id, |
620 name : () => name, | 671 name : () => name, |
621 source : () => this.eventDataScriptSource(id), | 672 source : () => this.eventDataScriptSource(id), |
622 setSource : (src) => this.eventDataScriptSetSource(id, src) | 673 setSource : (src) => this.eventDataScriptSetSource(id, src) |
623 }; | 674 }; |
624 } | 675 } |
625 | 676 |
626 // --- Message handlers. ----------------------------------------------------- | 677 // --- Message handlers. ----------------------------------------------------- |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 debug.instance = new DebugWrapper(); | 764 debug.instance = new DebugWrapper(); |
714 debug.instance.enable(); | 765 debug.instance.enable(); |
715 } | 766 } |
716 return debug.instance; | 767 return debug.instance; |
717 }}); | 768 }}); |
718 | 769 |
719 Object.defineProperty(debug, 'ScopeType', { get: function() { | 770 Object.defineProperty(debug, 'ScopeType', { get: function() { |
720 const instance = debug.Debug; | 771 const instance = debug.Debug; |
721 return instance.ScopeType; | 772 return instance.ScopeType; |
722 }}); | 773 }}); |
OLD | NEW |