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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 const elem = serialized_scope[i]; | 443 const elem = serialized_scope[i]; |
444 if (elem.name == prop) { | 444 if (elem.name == prop) { |
445 found = elem; | 445 found = elem; |
446 break; | 446 break; |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 if (found == null) return { isUndefined : () => true }; | 450 if (found == null) return { isUndefined : () => true }; |
451 | 451 |
452 const val = { value : () => found.value.value }; | 452 const val = { value : () => found.value.value }; |
| 453 // Not undefined in the sense that we did find a property, even though |
| 454 // the value can be 'undefined'. |
453 return { value : () => val, | 455 return { value : () => val, |
454 isUndefined : () => found.value.type == "undefined" | 456 isUndefined : () => false, |
455 }; | 457 }; |
456 } | 458 } |
457 | 459 |
458 // Returns an array of property descriptors of the scope object. | 460 // Returns an array of property descriptors of the scope object. |
459 // This is in contrast to the original API, which simply passed object | 461 // This is in contrast to the original API, which simply passed object |
460 // mirrors. | 462 // mirrors. |
461 execStateScopeObject(obj) { | 463 execStateScopeObject(obj) { |
462 const serialized_scope = this.getProperties(obj.objectId); | 464 const serialized_scope = this.getProperties(obj.objectId); |
463 const scope = this.propertiesToObject(serialized_scope); | 465 const scope = this.propertiesToObject(serialized_scope); |
464 return { value : () => scope, | 466 return { value : () => scope, |
465 property : (prop) => | 467 property : (prop) => |
466 this.execStateScopeObjectProperty(serialized_scope, prop) | 468 this.execStateScopeObjectProperty(serialized_scope, prop), |
| 469 properties : () => serialized_scope.map(elem => elem.value), |
| 470 propertyNames : () => serialized_scope.map(elem => elem.name) |
467 }; | 471 }; |
468 } | 472 } |
469 | 473 |
| 474 execStateScopeDetails(scope) { |
| 475 var start_position; |
| 476 var end_position |
| 477 const start = scope.startLocation; |
| 478 const end = scope.endLocation; |
| 479 if (start) { |
| 480 start_position = %ScriptLocationFromLine2( |
| 481 parseInt(start.scriptId), start.lineNumber, start.columnNumber, 0) |
| 482 .position; |
| 483 } |
| 484 if (end) { |
| 485 end_position = %ScriptLocationFromLine2( |
| 486 parseInt(end.scriptId), end.lineNumber, end.columnNumber, 0) |
| 487 .position; |
| 488 } |
| 489 return { name : () => scope.name, |
| 490 startPosition : () => start_position, |
| 491 endPosition : () => end_position |
| 492 }; |
| 493 } |
| 494 |
470 setVariableValue(frame, scope_index, name, value) { | 495 setVariableValue(frame, scope_index, name, value) { |
471 const frameid = frame.callFrameId; | 496 const frameid = frame.callFrameId; |
472 const {msgid, msg} = this.createMessage( | 497 const {msgid, msg} = this.createMessage( |
473 "Debugger.setVariableValue", | 498 "Debugger.setVariableValue", |
474 { callFrameId : frameid, | 499 { callFrameId : frameid, |
475 scopeNumber : scope_index, | 500 scopeNumber : scope_index, |
476 variableName : name, | 501 variableName : name, |
477 newValue : { value : value } | 502 newValue : { value : value } |
478 }); | 503 }); |
479 this.sendMessage(msg); | 504 this.sendMessage(msg); |
480 const reply = this.takeReplyChecked(msgid); | 505 const reply = this.takeReplyChecked(msgid); |
481 if (reply.error) { | 506 if (reply.error) { |
482 throw new Error("Failed to set variable value"); | 507 throw new Error("Failed to set variable value"); |
483 } | 508 } |
484 } | 509 } |
485 | 510 |
486 execStateScope(frame, scope_index) { | 511 execStateScope(frame, scope_index) { |
487 const scope = frame.scopeChain[scope_index]; | 512 const scope = frame.scopeChain[scope_index]; |
488 return { scopeType : () => this.execStateScopeType(scope.type), | 513 return { scopeType : () => this.execStateScopeType(scope.type), |
| 514 scopeIndex : () => scope_index, |
| 515 frameIndex : () => frame.callFrameId, |
489 scopeObject : () => this.execStateScopeObject(scope.object), | 516 scopeObject : () => this.execStateScopeObject(scope.object), |
490 setVariableValue : | 517 setVariableValue : |
491 (name, value) => this.setVariableValue(frame, scope_index, | 518 (name, value) => this.setVariableValue(frame, scope_index, |
492 name, value) | 519 name, value), |
| 520 details : () => this.execStateScopeDetails(scope) |
493 }; | 521 }; |
494 } | 522 } |
495 | 523 |
496 // Takes a list of properties as produced by getProperties and turns them | 524 // Takes a list of properties as produced by getProperties and turns them |
497 // into an object. | 525 // into an object. |
498 propertiesToObject(props) { | 526 propertiesToObject(props) { |
499 const obj = {} | 527 const obj = {} |
500 props.forEach((elem) => { | 528 props.forEach((elem) => { |
501 const key = elem.name; | 529 const key = elem.name; |
502 | 530 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 { callFrameId : frameid, | 680 { callFrameId : frameid, |
653 expression : expr | 681 expression : expr |
654 }); | 682 }); |
655 this.sendMessage(msg); | 683 this.sendMessage(msg); |
656 const reply = this.takeReplyChecked(msgid); | 684 const reply = this.takeReplyChecked(msgid); |
657 | 685 |
658 const result = reply.result.result; | 686 const result = reply.result.result; |
659 return this.reconstructRemoteObject(result); | 687 return this.reconstructRemoteObject(result); |
660 } | 688 } |
661 | 689 |
| 690 frameReceiver(frame) { |
| 691 return this.reconstructRemoteObject(frame.this); |
| 692 } |
| 693 |
| 694 frameReturnValue(frame) { |
| 695 return this.reconstructRemoteObject(frame.returnValue); |
| 696 } |
| 697 |
662 execStateFrameRestart(frame) { | 698 execStateFrameRestart(frame) { |
663 const frameid = frame.callFrameId; | 699 const frameid = frame.callFrameId; |
664 const {msgid, msg} = this.createMessage( | 700 const {msgid, msg} = this.createMessage( |
665 "Debugger.restartFrame", { callFrameId : frameid }); | 701 "Debugger.restartFrame", { callFrameId : frameid }); |
666 this.sendMessage(msg); | 702 this.sendMessage(msg); |
667 this.takeReplyChecked(msgid); | 703 this.takeReplyChecked(msgid); |
668 } | 704 } |
669 | 705 |
670 execStateFrame(frame) { | 706 execStateFrame(frame) { |
671 const scriptid = parseInt(frame.location.scriptId); | 707 const scriptid = parseInt(frame.location.scriptId); |
672 const line = frame.location.lineNumber; | 708 const line = frame.location.lineNumber; |
673 const column = frame.location.columnNumber; | 709 const column = frame.location.columnNumber; |
674 const loc = %ScriptLocationFromLine2(scriptid, line, column, 0); | 710 const loc = %ScriptLocationFromLine2(scriptid, line, column, 0); |
675 const func = { name : () => frame.functionName }; | 711 const func = { name : () => frame.functionName }; |
676 const index = JSON.parse(frame.callFrameId).ordinal; | 712 const index = JSON.parse(frame.callFrameId).ordinal; |
677 | 713 |
678 function allScopes() { | 714 function allScopes() { |
679 const scopes = []; | 715 const scopes = []; |
680 for (let i = 0; i < frame.scopeChain.length; i++) { | 716 for (let i = 0; i < frame.scopeChain.length; i++) { |
681 scopes.push(this.execStateScope(frame, i)); | 717 scopes.push(this.execStateScope(frame, i)); |
682 } | 718 } |
683 return scopes; | 719 return scopes; |
684 }; | 720 } |
685 | 721 |
686 return { sourceColumn : () => column, | 722 return { sourceColumn : () => column, |
687 sourceLine : () => line + 1, | 723 sourceLine : () => line + 1, |
688 sourceLineText : () => loc.sourceText, | 724 sourceLineText : () => loc.sourceText, |
| 725 sourcePosition : () => loc.position, |
689 evaluate : (expr) => this.evaluateOnCallFrame(frame, expr), | 726 evaluate : (expr) => this.evaluateOnCallFrame(frame, expr), |
690 functionName : () => frame.functionName, | 727 functionName : () => frame.functionName, |
691 func : () => func, | 728 func : () => func, |
692 index : () => index, | 729 index : () => index, |
693 localCount : () => this.execStateFrameLocalCount(frame), | 730 localCount : () => this.execStateFrameLocalCount(frame), |
694 localName : (ix) => this.execStateFrameLocalName(frame, ix), | 731 localName : (ix) => this.execStateFrameLocalName(frame, ix), |
695 localValue: (ix) => this.execStateFrameLocalValue(frame, ix), | 732 localValue: (ix) => this.execStateFrameLocalValue(frame, ix), |
696 receiver : () => this.evaluateOnCallFrame(frame, "this"), | 733 receiver : () => this.frameReceiver(frame), |
697 restart : () => this.execStateFrameRestart(frame), | 734 restart : () => this.execStateFrameRestart(frame), |
| 735 returnValue : () => this.frameReturnValue(frame), |
698 scopeCount : () => frame.scopeChain.length, | 736 scopeCount : () => frame.scopeChain.length, |
699 scope : (index) => this.execStateScope(frame, index), | 737 scope : (index) => this.execStateScope(frame, index), |
700 allScopes : allScopes.bind(this) | 738 allScopes : allScopes.bind(this) |
701 }; | 739 }; |
702 } | 740 } |
703 | 741 |
| 742 execStateEvaluateGlobal(expr) { |
| 743 const {msgid, msg} = this.createMessage( |
| 744 "Runtime.evaluate", { expression : expr }); |
| 745 this.sendMessage(msg); |
| 746 const reply = this.takeReplyChecked(msgid); |
| 747 |
| 748 const result = reply.result.result; |
| 749 return this.reconstructRemoteObject(result); |
| 750 } |
| 751 |
704 eventDataException(params) { | 752 eventDataException(params) { |
705 switch (params.data.type) { | 753 switch (params.data.type) { |
706 case "string": { | 754 case "string": { |
707 return params.data.value; | 755 return params.data.value; |
708 } | 756 } |
709 case "object": { | 757 case "object": { |
710 const props = this.getProperties(params.data.objectId); | 758 const props = this.getProperties(params.data.objectId); |
711 return this.propertiesToObject(props); | 759 return this.propertiesToObject(props); |
712 } | 760 } |
713 default: { | 761 default: { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 debugEvent = this.DebugEvent.Break; | 817 debugEvent = this.DebugEvent.Break; |
770 break; | 818 break; |
771 } | 819 } |
772 | 820 |
773 // Skip break events in this file. | 821 // Skip break events in this file. |
774 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; | 822 if (params.callFrames[0].location.scriptId == this.thisScriptId) return; |
775 | 823 |
776 // TODO(jgruber): Arguments as needed. | 824 // TODO(jgruber): Arguments as needed. |
777 let execState = { frames : params.callFrames, | 825 let execState = { frames : params.callFrames, |
778 prepareStep : this.execStatePrepareStep.bind(this), | 826 prepareStep : this.execStatePrepareStep.bind(this), |
| 827 evaluateGlobal : |
| 828 (expr) => this.execStateEvaluateGlobal(expr), |
779 frame : (index) => this.execStateFrame( | 829 frame : (index) => this.execStateFrame( |
780 index ? params.callFrames[index] | 830 index ? params.callFrames[index] |
781 : params.callFrames[0]), | 831 : params.callFrames[0]), |
782 frameCount : () => params.callFrames.length | 832 frameCount : () => params.callFrames.length |
783 }; | 833 }; |
784 | 834 |
785 let eventData = this.execStateFrame(params.callFrames[0]); | 835 let eventData = this.execStateFrame(params.callFrames[0]); |
786 if (debugEvent == this.DebugEvent.Exception) { | 836 if (debugEvent == this.DebugEvent.Exception) { |
787 eventData.uncaught = () => params.data.uncaught; | 837 eventData.uncaught = () => params.data.uncaught; |
788 eventData.exception = () => this.eventDataException(params); | 838 eventData.exception = () => this.eventDataException(params); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 debug.instance = new DebugWrapper(); | 882 debug.instance = new DebugWrapper(); |
833 debug.instance.enable(); | 883 debug.instance.enable(); |
834 } | 884 } |
835 return debug.instance; | 885 return debug.instance; |
836 }}); | 886 }}); |
837 | 887 |
838 Object.defineProperty(debug, 'ScopeType', { get: function() { | 888 Object.defineProperty(debug, 'ScopeType', { get: function() { |
839 const instance = debug.Debug; | 889 const instance = debug.Debug; |
840 return instance.ScopeType; | 890 return instance.ScopeType; |
841 }}); | 891 }}); |
OLD | NEW |