Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 { | 71 { |
| 72 if (typeof obj === "number" && obj === 0 && 1 / obj < 0) | 72 if (typeof obj === "number" && obj === 0 && 1 / obj < 0) |
| 73 return "-0"; // Negative zero. | 73 return "-0"; // Negative zero. |
| 74 return "" + obj; | 74 return "" + obj; |
| 75 } | 75 } |
| 76 | 76 |
| 77 /** | 77 /** |
| 78 * Please use this bind, not the one from Function.prototype | 78 * Please use this bind, not the one from Function.prototype |
| 79 * @param {function(...)} func | 79 * @param {function(...)} func |
| 80 * @param {Object} thisObject | 80 * @param {Object} thisObject |
| 81 * @param {...number} var_args | 81 * @param {...} var_args |
| 82 */ | 82 */ |
| 83 function bind(func, thisObject, var_args) | 83 function bind(func, thisObject, var_args) |
| 84 { | 84 { |
| 85 var args = slice(arguments, 2); | 85 var args = slice(arguments, 2); |
| 86 | 86 |
| 87 /** | 87 /** |
| 88 * @param {...number} var_args | 88 * @param {...} var_args |
| 89 */ | 89 */ |
| 90 function bound(var_args) | 90 function bound(var_args) |
| 91 { | 91 { |
| 92 return func.apply(thisObject, args.concat(slice(arguments))); | 92 return func.apply(thisObject, args.concat(slice(arguments))); |
| 93 } | 93 } |
| 94 bound.toString = function() { | 94 bound.toString = function() |
| 95 { | |
| 95 return "bound: " + func; | 96 return "bound: " + func; |
| 96 }; | 97 }; |
| 97 return bound; | 98 return bound; |
| 98 } | 99 } |
| 99 | 100 |
| 100 /** | 101 /** |
| 101 * @constructor | 102 * @constructor |
| 102 */ | 103 */ |
| 103 var InjectedScript = function() | 104 var InjectedScript = function() |
| 104 { | 105 { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 return this._createThrownValue(e, objectGroup); | 532 return this._createThrownValue(e, objectGroup); |
| 532 } | 533 } |
| 533 }, | 534 }, |
| 534 | 535 |
| 535 /** | 536 /** |
| 536 * Resolves a value from CallArgument description. | 537 * Resolves a value from CallArgument description. |
| 537 * @param {RuntimeAgent.CallArgument} callArgumentJson | 538 * @param {RuntimeAgent.CallArgument} callArgumentJson |
| 538 * @return {*} resolved value | 539 * @return {*} resolved value |
| 539 * @throws {string} error message | 540 * @throws {string} error message |
| 540 */ | 541 */ |
| 541 _resolveCallArgument: function(callArgumentJson) { | 542 _resolveCallArgument: function(callArgumentJson) |
| 543 { | |
| 542 var objectId = callArgumentJson.objectId; | 544 var objectId = callArgumentJson.objectId; |
| 543 if (objectId) { | 545 if (objectId) { |
| 544 var parsedArgId = this._parseObjectId(objectId); | 546 var parsedArgId = this._parseObjectId(objectId); |
| 545 if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScri ptId) | 547 if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScri ptId) |
| 546 throw "Arguments should belong to the same JavaScript world as t he target object."; | 548 throw "Arguments should belong to the same JavaScript world as t he target object."; |
| 547 | 549 |
| 548 var resolvedArg = this._objectForId(parsedArgId); | 550 var resolvedArg = this._objectForId(parsedArgId); |
| 549 if (!this._isDefined(resolvedArg)) | 551 if (!this._isDefined(resolvedArg)) |
| 550 throw "Could not find object with given id"; | 552 throw "Could not find object with given id"; |
| 551 | 553 |
| 552 return resolvedArg; | 554 return resolvedArg; |
| 553 } else if ("value" in callArgumentJson) { | 555 } else if ("value" in callArgumentJson) { |
| 554 return callArgumentJson.value; | 556 return callArgumentJson.value; |
| 555 } | 557 } |
| 556 return undefined; | 558 return undefined; |
| 557 }, | 559 }, |
| 558 | 560 |
| 559 /** | 561 /** |
| 560 * @param {Function} evalFunction | 562 * @param {Function} evalFunction |
| 561 * @param {Object} object | 563 * @param {Object} object |
| 562 * @param {string} objectGroup | 564 * @param {string} objectGroup |
| 563 * @param {boolean} isEvalOnCallFrame | 565 * @param {boolean} isEvalOnCallFrame |
| 564 * @param {boolean} injectCommandLineAPI | 566 * @param {boolean} injectCommandLineAPI |
| 565 * @param {boolean} returnByValue | 567 * @param {boolean} returnByValue |
| 566 * @param {boolean} generatePreview | 568 * @param {boolean} generatePreview |
| 569 * @param {!Object=} contextExtension | |
| 567 * @return {*} | 570 * @return {*} |
| 568 */ | 571 */ |
| 569 _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, is EvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview) | 572 _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, is EvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview, contextEx tension) |
| 570 { | 573 { |
| 571 try { | 574 try { |
| 572 return { wasThrown: false, | 575 return { wasThrown: false, |
| 573 result: this._wrapObject(this._evaluateOn(evalFunction, obj ect, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGr oup, returnByValue, generatePreview) }; | 576 result: this._wrapObject(this._evaluateOn(evalFunction, obj ect, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI, contextEx tension), objectGroup, returnByValue, generatePreview) }; |
| 574 } catch (e) { | 577 } catch (e) { |
| 575 return this._createThrownValue(e, objectGroup); | 578 return this._createThrownValue(e, objectGroup); |
| 576 } | 579 } |
| 577 }, | 580 }, |
| 578 | 581 |
| 579 /** | 582 /** |
| 580 * @param {*} value | 583 * @param {*} value |
| 581 * @param {string} objectGroup | 584 * @param {string} objectGroup |
| 582 * @return {Object} | 585 * @return {Object} |
| 583 */ | 586 */ |
| 584 _createThrownValue: function(value, objectGroup) | 587 _createThrownValue: function(value, objectGroup) |
| 585 { | 588 { |
| 586 var remoteObject = this._wrapObject(value, objectGroup); | 589 var remoteObject = this._wrapObject(value, objectGroup); |
| 587 try { | 590 try { |
| 588 remoteObject.description = toStringDescription(value); | 591 remoteObject.description = toStringDescription(value); |
| 589 } catch (e) {} | 592 } catch (e) {} |
| 590 return { wasThrown: true, result: remoteObject }; | 593 return { wasThrown: true, result: remoteObject }; |
| 591 }, | 594 }, |
| 592 | 595 |
| 593 /** | 596 /** |
| 594 * @param {Function} evalFunction | 597 * @param {Function} evalFunction |
| 595 * @param {Object} object | 598 * @param {Object} object |
| 596 * @param {string} objectGroup | 599 * @param {string} objectGroup |
| 597 * @param {string} expression | 600 * @param {string} expression |
| 598 * @param {boolean} isEvalOnCallFrame | 601 * @param {boolean} isEvalOnCallFrame |
| 599 * @param {boolean} injectCommandLineAPI | 602 * @param {boolean} injectCommandLineAPI |
| 603 * @param {!Object=} contextExtension | |
| 600 * @return {*} | 604 * @return {*} |
| 601 */ | 605 */ |
| 602 _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalO nCallFrame, injectCommandLineAPI) | 606 _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalO nCallFrame, injectCommandLineAPI, contextExtension) |
| 603 { | 607 { |
| 604 // Only install command line api object for the time of evaluation. | 608 // Only install command line api object for the time of evaluation. |
| 605 // Surround the expression in with statements to inject our command line API so that | 609 // Surround the expression in with statements to inject our command line API so that |
| 606 // the window object properties still take more precedent than our API f unctions. | 610 // the window object properties still take more precedent than our API f unctions. |
| 607 | 611 |
| 608 try { | 612 try { |
| 609 if (injectCommandLineAPI && inspectedWindow.console) { | 613 if (injectCommandLineAPI && inspectedWindow.console) { |
| 610 inspectedWindow.console._commandLineAPI = new CommandLineAPI(thi s._commandLineAPIImpl, isEvalOnCallFrame ? object : null); | 614 inspectedWindow.console._commandLineAPI = new CommandLineAPI(thi s._commandLineAPIImpl, isEvalOnCallFrame ? object : null); |
| 611 expression = "with ((console && console._commandLineAPI) || { __ proto__: null }) {\n" + expression + "\n}"; | 615 expression = "with ((console && console._commandLineAPI) || { __ proto__: null }) {\n" + expression + "\n}"; |
| 612 } | 616 } |
| 613 var result = evalFunction.call(object, expression); | 617 var result = evalFunction.call(object, expression, contextExtension) ; |
| 614 if (objectGroup === "console") | 618 if (objectGroup === "console") |
| 615 this._lastResult = result; | 619 this._lastResult = result; |
| 616 return result; | 620 return result; |
| 617 } finally { | 621 } finally { |
| 618 if (injectCommandLineAPI && inspectedWindow.console) | 622 if (injectCommandLineAPI && inspectedWindow.console) |
| 619 delete inspectedWindow.console._commandLineAPI; | 623 delete inspectedWindow.console._commandLineAPI; |
| 620 } | 624 } |
| 621 }, | 625 }, |
| 622 | 626 |
| 623 /** | 627 /** |
| 624 * @param {Object} callFrame | 628 * @param {?Object} callFrame |
| 625 * @return {!Array.<InjectedScript.CallFrameProxy>|boolean} | 629 * @param {number} asyncOrdinal |
| 630 * @return {!Array.<!InjectedScript.CallFrameProxy>|boolean} | |
| 626 */ | 631 */ |
| 627 wrapCallFrames: function(callFrame) | 632 wrapCallFrames: function(callFrame, asyncOrdinal) |
| 628 { | 633 { |
| 629 if (!callFrame) | 634 if (!callFrame) |
| 630 return false; | 635 return false; |
| 631 | 636 |
| 632 var result = []; | 637 var result = []; |
| 633 var depth = 0; | 638 var depth = 0; |
| 634 do { | 639 do { |
| 635 result.push(new InjectedScript.CallFrameProxy(depth++, callFrame)); | 640 result.push(new InjectedScript.CallFrameProxy(depth++, callFrame, as yncOrdinal)); |
| 636 callFrame = callFrame.caller; | 641 callFrame = callFrame.caller; |
| 637 } while (callFrame); | 642 } while (callFrame); |
| 638 return result; | 643 return result; |
| 639 }, | 644 }, |
| 640 | 645 |
| 641 /** | 646 /** |
| 642 * @param {Object} topCallFrame | 647 * @param {!Object} topCallFrame |
| 648 * @param {!Array.<!Object>} asyncCallStacks | |
| 643 * @param {string} callFrameId | 649 * @param {string} callFrameId |
| 644 * @param {string} expression | 650 * @param {string} expression |
| 645 * @param {string} objectGroup | 651 * @param {string} objectGroup |
| 646 * @param {boolean} injectCommandLineAPI | 652 * @param {boolean} injectCommandLineAPI |
| 647 * @param {boolean} returnByValue | 653 * @param {boolean} returnByValue |
| 648 * @param {boolean} generatePreview | 654 * @param {boolean} generatePreview |
| 649 * @return {*} | 655 * @return {*} |
| 650 */ | 656 */ |
| 651 evaluateOnCallFrame: function(topCallFrame, callFrameId, expression, objectG roup, injectCommandLineAPI, returnByValue, generatePreview) | 657 evaluateOnCallFrame: function(topCallFrame, asyncCallStacks, callFrameId, ex pression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview) |
| 652 { | 658 { |
| 653 var callFrame = this.callFrameForId(topCallFrame, callFrameId); | 659 var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")"); |
| 660 var callFrame = this._callFrameForParsedId(topCallFrame, parsedCallFrame Id, asyncCallStacks); | |
| 654 if (!callFrame) | 661 if (!callFrame) |
| 655 return "Could not find call frame with given id"; | 662 return "Could not find call frame with given id"; |
| 663 if (parsedCallFrameId["asyncOrdinal"]) | |
| 664 return this._evaluateAndWrap(topCallFrame.evaluateGlobal, topCallFra me, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generate Preview, InjectedScript.CallFrameProxy._toProtoChainedScope(callFrame)); | |
|
yurys
2014/01/21 11:56:52
Why do we use topCallFrame as object argument but
aandrey
2014/01/21 13:30:22
We can evaluate only on the call frames of the cur
yurys
2014/01/21 13:54:43
Sound like we should have a version of evaluateGlo
| |
| 656 return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generatePreview); | 665 return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generatePreview); |
| 657 }, | 666 }, |
| 658 | 667 |
| 659 /** | 668 /** |
| 660 * @param {Object} topCallFrame | 669 * @param {!Object} topCallFrame |
| 661 * @param {string} callFrameId | 670 * @param {string} callFrameId |
| 662 * @return {*} | 671 * @return {*} |
| 663 */ | 672 */ |
| 664 restartFrame: function(topCallFrame, callFrameId) | 673 restartFrame: function(topCallFrame, callFrameId) |
| 665 { | 674 { |
| 666 var callFrame = this.callFrameForId(topCallFrame, callFrameId); | 675 var callFrame = this.callFrameForId(topCallFrame, callFrameId); |
| 667 if (!callFrame) | 676 if (!callFrame) |
| 668 return "Could not find call frame with given id"; | 677 return "Could not find call frame with given id"; |
| 669 var result = callFrame.restart(); | 678 var result = callFrame.restart(); |
| 670 if (result === false) | 679 if (result === false) |
| 671 result = "Restart frame is not supported"; | 680 result = "Restart frame is not supported"; |
| 672 return result; | 681 return result; |
| 673 }, | 682 }, |
| 674 | 683 |
| 675 /** | 684 /** |
| 676 * @param {Object} topCallFrame | 685 * @param {!Object} topCallFrame |
| 677 * @param {string} callFrameId | 686 * @param {string} callFrameId |
| 678 * @return {*} a stepIn position array ready for protocol JSON or a string e rror | 687 * @return {*} a stepIn position array ready for protocol JSON or a string e rror |
| 679 */ | 688 */ |
| 680 getStepInPositions: function(topCallFrame, callFrameId) | 689 getStepInPositions: function(topCallFrame, callFrameId) |
| 681 { | 690 { |
| 682 var callFrame = this.callFrameForId(topCallFrame, callFrameId); | 691 var callFrame = this.callFrameForId(topCallFrame, callFrameId); |
| 683 if (!callFrame) | 692 if (!callFrame) |
| 684 return "Could not find call frame with given id"; | 693 return "Could not find call frame with given id"; |
| 685 var stepInPositionsUnpacked = JSON.parse(callFrame.stepInPositions); | 694 var stepInPositionsUnpacked = JSON.parse(callFrame.stepInPositions); |
| 686 if (typeof stepInPositionsUnpacked !== "object") | 695 if (typeof stepInPositionsUnpacked !== "object") |
| 687 return "Step in positions not available"; | 696 return "Step in positions not available"; |
| 688 return stepInPositionsUnpacked; | 697 return stepInPositionsUnpacked; |
| 689 }, | 698 }, |
| 690 | 699 |
| 691 /** | 700 /** |
| 692 * Either callFrameId or functionObjectId must be specified. | 701 * Either callFrameId or functionObjectId must be specified. |
| 693 * @param {Object} topCallFrame | 702 * @param {!Object} topCallFrame |
| 694 * @param {string|boolean} callFrameId or false | 703 * @param {string|boolean} callFrameId or false |
| 695 * @param {string|boolean} functionObjectId or false | 704 * @param {string|boolean} functionObjectId or false |
| 696 * @param {number} scopeNumber | 705 * @param {number} scopeNumber |
| 697 * @param {string} variableName | 706 * @param {string} variableName |
| 698 * @param {string} newValueJsonString RuntimeAgent.CallArgument structure se rialized as string | 707 * @param {string} newValueJsonString RuntimeAgent.CallArgument structure se rialized as string |
| 699 * @return {string|undefined} undefined if success or an error message | 708 * @return {string|undefined} undefined if success or an error message |
| 700 */ | 709 */ |
| 701 setVariableValue: function(topCallFrame, callFrameId, functionObjectId, scop eNumber, variableName, newValueJsonString) | 710 setVariableValue: function(topCallFrame, callFrameId, functionObjectId, scop eNumber, variableName, newValueJsonString) |
| 702 { | 711 { |
| 703 var setter; | 712 var setter; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 727 } | 736 } |
| 728 try { | 737 try { |
| 729 setter(scopeNumber, variableName, resolvedValue); | 738 setter(scopeNumber, variableName, resolvedValue); |
| 730 } catch (e) { | 739 } catch (e) { |
| 731 return "Failed to change variable value: " + e; | 740 return "Failed to change variable value: " + e; |
| 732 } | 741 } |
| 733 return undefined; | 742 return undefined; |
| 734 }, | 743 }, |
| 735 | 744 |
| 736 /** | 745 /** |
| 737 * @param {Object} topCallFrame | 746 * @param {!Object} topCallFrame |
| 738 * @param {string} callFrameId | 747 * @param {string} callFrameId |
| 739 * @return {Object} | 748 * @return {?Object} |
| 740 */ | 749 */ |
| 741 callFrameForId: function(topCallFrame, callFrameId) | 750 callFrameForId: function(topCallFrame, callFrameId) |
| 742 { | 751 { |
| 743 var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")"); | 752 var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")"); |
| 753 return this._callFrameForParsedId(topCallFrame, parsedCallFrameId, []); | |
| 754 }, | |
| 755 | |
| 756 /** | |
| 757 * @param {!Object} topCallFrame | |
| 758 * @param {!Object} parsedCallFrameId | |
| 759 * @param {!Array.<!Object>} asyncCallStacks | |
| 760 * @return {?Object} | |
| 761 */ | |
| 762 _callFrameForParsedId: function(topCallFrame, parsedCallFrameId, asyncCallSt acks) | |
| 763 { | |
| 764 var asyncOrdinal = parsedCallFrameId["asyncOrdinal"] || 0; // 1-based in dex | |
|
yurys
2014/01/21 11:56:52
You don't really need "|| 0" part.
aandrey
2014/01/21 13:30:22
Done.
| |
| 765 if (asyncOrdinal) | |
| 766 topCallFrame = asyncCallStacks[asyncOrdinal - 1]; | |
| 767 var callFrame = topCallFrame; | |
| 744 var ordinal = parsedCallFrameId["ordinal"]; | 768 var ordinal = parsedCallFrameId["ordinal"]; |
| 745 var callFrame = topCallFrame; | |
| 746 while (--ordinal >= 0 && callFrame) | 769 while (--ordinal >= 0 && callFrame) |
| 747 callFrame = callFrame.caller; | 770 callFrame = callFrame.caller; |
| 748 return callFrame; | 771 return callFrame; |
| 749 }, | 772 }, |
| 750 | 773 |
| 751 /** | 774 /** |
| 752 * @param {Object} objectId | 775 * @param {Object} objectId |
| 753 * @return {Object} | 776 * @return {Object} |
| 754 */ | 777 */ |
| 755 _objectForId: function(objectId) | 778 _objectForId: function(objectId) |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1107 var rightHalf = maxLength - leftHalf - 1; | 1130 var rightHalf = maxLength - leftHalf - 1; |
| 1108 return string.substr(0, leftHalf) + "\u2026" + string.substr(string. length - rightHalf, rightHalf); | 1131 return string.substr(0, leftHalf) + "\u2026" + string.substr(string. length - rightHalf, rightHalf); |
| 1109 } | 1132 } |
| 1110 return string.substr(0, maxLength) + "\u2026"; | 1133 return string.substr(0, maxLength) + "\u2026"; |
| 1111 } | 1134 } |
| 1112 } | 1135 } |
| 1113 /** | 1136 /** |
| 1114 * @constructor | 1137 * @constructor |
| 1115 * @param {number} ordinal | 1138 * @param {number} ordinal |
| 1116 * @param {!Object} callFrame | 1139 * @param {!Object} callFrame |
| 1140 * @param {number} asyncOrdinal | |
| 1117 */ | 1141 */ |
| 1118 InjectedScript.CallFrameProxy = function(ordinal, callFrame) | 1142 InjectedScript.CallFrameProxy = function(ordinal, callFrame, asyncOrdinal) |
| 1119 { | 1143 { |
| 1120 this.callFrameId = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + in jectedScriptId + "}"; | 1144 this.callFrameId = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + in jectedScriptId + (asyncOrdinal ? ",\"asyncOrdinal\":" + asyncOrdinal : "") + "}" ; |
| 1121 this.functionName = (callFrame.type === "function" ? callFrame.functionName : ""); | 1145 this.functionName = (callFrame.type === "function" ? callFrame.functionName : ""); |
| 1122 this.location = { scriptId: toString(callFrame.sourceID), lineNumber: callFr ame.line, columnNumber: callFrame.column }; | 1146 this.location = { scriptId: toString(callFrame.sourceID), lineNumber: callFr ame.line, columnNumber: callFrame.column }; |
| 1123 this.scopeChain = this._wrapScopeChain(callFrame); | 1147 this.scopeChain = this._wrapScopeChain(callFrame); |
| 1124 this.this = injectedScript._wrapObject(callFrame.thisObject, "backtrace"); | 1148 this.this = injectedScript._wrapObject(callFrame.thisObject, "backtrace"); |
| 1125 if (callFrame.isAtReturn) | 1149 if (callFrame.isAtReturn) |
| 1126 this.returnValue = injectedScript._wrapObject(callFrame.returnValue, "ba cktrace"); | 1150 this.returnValue = injectedScript._wrapObject(callFrame.returnValue, "ba cktrace"); |
| 1127 } | 1151 } |
| 1128 | 1152 |
| 1129 InjectedScript.CallFrameProxy.prototype = { | 1153 InjectedScript.CallFrameProxy.prototype = { |
| 1130 /** | 1154 /** |
| 1131 * @param {Object} callFrame | 1155 * @param {Object} callFrame |
| 1132 * @return {!Array.<DebuggerAgent.Scope>} | 1156 * @return {!Array.<DebuggerAgent.Scope>} |
| 1133 */ | 1157 */ |
| 1134 _wrapScopeChain: function(callFrame) | 1158 _wrapScopeChain: function(callFrame) |
| 1135 { | 1159 { |
| 1136 var scopeChain = callFrame.scopeChain; | 1160 var scopeChain = callFrame.scopeChain; |
| 1137 var scopeChainProxy = []; | 1161 var scopeChainProxy = []; |
| 1138 for (var i = 0; i < scopeChain.length; i++) { | 1162 for (var i = 0; i < scopeChain.length; ++i) { |
| 1139 var scope = InjectedScript.CallFrameProxy._createScopeJson(callFrame .scopeType(i), scopeChain[i], "backtrace"); | 1163 var scope = InjectedScript.CallFrameProxy._createScopeJson(callFrame .scopeType(i), scopeChain[i], "backtrace"); |
| 1140 scopeChainProxy.push(scope); | 1164 scopeChainProxy.push(scope); |
| 1141 } | 1165 } |
| 1142 return scopeChainProxy; | 1166 return scopeChainProxy; |
| 1143 } | 1167 } |
| 1144 } | 1168 } |
| 1145 | 1169 |
| 1146 /** | 1170 /** |
| 1147 * @param {number} scopeTypeCode | 1171 * @param {number} scopeTypeCode |
| 1148 * @param {*} scopeObject | 1172 * @param {*} scopeObject |
| 1149 * @param {string} groupId | 1173 * @param {string} groupId |
| 1150 * @return {!DebuggerAgent.Scope} | 1174 * @return {!DebuggerAgent.Scope} |
| 1151 */ | 1175 */ |
| 1152 InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb ject, groupId) { | 1176 InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb ject, groupId) |
| 1177 { | |
| 1153 const GLOBAL_SCOPE = 0; | 1178 const GLOBAL_SCOPE = 0; |
| 1154 const LOCAL_SCOPE = 1; | 1179 const LOCAL_SCOPE = 1; |
| 1155 const WITH_SCOPE = 2; | 1180 const WITH_SCOPE = 2; |
| 1156 const CLOSURE_SCOPE = 3; | 1181 const CLOSURE_SCOPE = 3; |
| 1157 const CATCH_SCOPE = 4; | 1182 const CATCH_SCOPE = 4; |
| 1158 | 1183 |
| 1159 /** @type {!Object.<number, string>} */ | 1184 /** @type {!Object.<number, string>} */ |
| 1160 var scopeTypeNames = {}; | 1185 var scopeTypeNames = {}; |
| 1161 scopeTypeNames[GLOBAL_SCOPE] = "global"; | 1186 scopeTypeNames[GLOBAL_SCOPE] = "global"; |
| 1162 scopeTypeNames[LOCAL_SCOPE] = "local"; | 1187 scopeTypeNames[LOCAL_SCOPE] = "local"; |
| 1163 scopeTypeNames[WITH_SCOPE] = "with"; | 1188 scopeTypeNames[WITH_SCOPE] = "with"; |
| 1164 scopeTypeNames[CLOSURE_SCOPE] = "closure"; | 1189 scopeTypeNames[CLOSURE_SCOPE] = "closure"; |
| 1165 scopeTypeNames[CATCH_SCOPE] = "catch"; | 1190 scopeTypeNames[CATCH_SCOPE] = "catch"; |
| 1166 | 1191 |
| 1167 return { | 1192 return { |
| 1168 object: injectedScript._wrapObject(scopeObject, groupId), | 1193 object: injectedScript._wrapObject(scopeObject, groupId), |
| 1169 type: /** @type {DebuggerAgent.ScopeType} */ (scopeTypeNames[scopeTypeCo de]) | 1194 type: /** @type {DebuggerAgent.ScopeType} */ (scopeTypeNames[scopeTypeCo de]) |
| 1170 }; | 1195 }; |
| 1171 } | 1196 } |
| 1172 | 1197 |
| 1173 /** | 1198 /** |
| 1199 * @param {!Object} callFrame | |
| 1200 * @return {!Object} | |
| 1201 */ | |
| 1202 InjectedScript.CallFrameProxy._toProtoChainedScope = function(callFrame) | |
| 1203 { | |
| 1204 /** | |
| 1205 * @this {Object} | |
| 1206 */ | |
| 1207 function getter(name) | |
| 1208 { | |
| 1209 return this[name]; | |
| 1210 } | |
| 1211 | |
| 1212 function addProperties(object) | |
| 1213 { | |
| 1214 for (var o = object; injectedScript._isDefined(o); o = o.__proto__) { | |
| 1215 var names = Object.getOwnPropertyNames(/** @type {!Object} */ (o)); | |
| 1216 for (var i = 0, n = names.length; i < n; ++i) { | |
| 1217 var name = names[i]; | |
| 1218 if (name in proxy || name === "__proto__") | |
| 1219 continue; | |
| 1220 Object.prototype.__defineGetter__.call(proxy, name, bind(getter, object, name)); | |
|
yurys
2014/01/21 11:56:52
Why not simply copy the value: proxy[name] = o[nam
aandrey
2014/01/21 13:30:22
To avoid side effects.
For example, accessing wind
yurys
2014/01/21 13:54:43
I'm concerned about the performance here. We may e
| |
| 1221 } | |
| 1222 } | |
| 1223 return proxy; | |
| 1224 } | |
| 1225 | |
| 1226 var proxy = { __proto__: null }; | |
| 1227 | |
| 1228 var scopeChain = callFrame.scopeChain; | |
| 1229 for (var i = 0; i < scopeChain.length; ++i) | |
| 1230 addProperties(scopeChain[i]); | |
| 1231 | |
| 1232 return proxy; | |
| 1233 } | |
| 1234 | |
| 1235 /** | |
| 1174 * @constructor | 1236 * @constructor |
| 1175 * @param {CommandLineAPIImpl} commandLineAPIImpl | 1237 * @param {CommandLineAPIImpl} commandLineAPIImpl |
| 1176 * @param {Object} callFrame | 1238 * @param {Object} callFrame |
| 1177 */ | 1239 */ |
| 1178 function CommandLineAPI(commandLineAPIImpl, callFrame) | 1240 function CommandLineAPI(commandLineAPIImpl, callFrame) |
| 1179 { | 1241 { |
| 1180 /** | 1242 /** |
| 1181 * @param {string} member | 1243 * @param {string} member |
| 1182 * @return {boolean} | 1244 * @return {boolean} |
| 1183 */ | 1245 */ |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1441 undebug: function(fn) | 1503 undebug: function(fn) |
| 1442 { | 1504 { |
| 1443 InjectedScriptHost.undebugFunction(fn); | 1505 InjectedScriptHost.undebugFunction(fn); |
| 1444 }, | 1506 }, |
| 1445 | 1507 |
| 1446 monitor: function(fn) | 1508 monitor: function(fn) |
| 1447 { | 1509 { |
| 1448 InjectedScriptHost.monitorFunction(fn); | 1510 InjectedScriptHost.monitorFunction(fn); |
| 1449 }, | 1511 }, |
| 1450 | 1512 |
| 1451 unmonitor: function(fn) { | 1513 unmonitor: function(fn) |
| 1514 { | |
| 1452 InjectedScriptHost.unmonitorFunction(fn); | 1515 InjectedScriptHost.unmonitorFunction(fn); |
| 1453 }, | 1516 }, |
| 1454 | 1517 |
| 1455 table: function(data, opt_columns) | 1518 table: function(data, opt_columns) |
| 1456 { | 1519 { |
| 1457 inspectedWindow.console.table.apply(inspectedWindow.console, arguments); | 1520 inspectedWindow.console.table.apply(inspectedWindow.console, arguments); |
| 1458 }, | 1521 }, |
| 1459 | 1522 |
| 1460 /** | 1523 /** |
| 1461 * @param {number} num | 1524 * @param {number} num |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1497 */ | 1560 */ |
| 1498 _logEvent: function(event) | 1561 _logEvent: function(event) |
| 1499 { | 1562 { |
| 1500 inspectedWindow.console.log(event.type, event); | 1563 inspectedWindow.console.log(event.type, event); |
| 1501 } | 1564 } |
| 1502 } | 1565 } |
| 1503 | 1566 |
| 1504 injectedScript._commandLineAPIImpl = new CommandLineAPIImpl(); | 1567 injectedScript._commandLineAPIImpl = new CommandLineAPIImpl(); |
| 1505 return injectedScript; | 1568 return injectedScript; |
| 1506 }) | 1569 }) |
| OLD | NEW |