PageRenderTime 66ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/src/third_party/v8-3.25/src/d8.js

https://github.com/Dazzed/mongo
JavaScript | 2253 lines | 1628 code | 329 blank | 296 comment | 397 complexity | 071605b553f38805cb6c5822dc3f6e90 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. // Copyright 2008 the V8 project authors. All rights reserved.
  2. // Redistribution and use in source and binary forms, with or without
  3. // modification, are permitted provided that the following conditions are
  4. // met:
  5. //
  6. // * Redistributions of source code must retain the above copyright
  7. // notice, this list of conditions and the following disclaimer.
  8. // * Redistributions in binary form must reproduce the above
  9. // copyright notice, this list of conditions and the following
  10. // disclaimer in the documentation and/or other materials provided
  11. // with the distribution.
  12. // * Neither the name of Google Inc. nor the names of its
  13. // contributors may be used to endorse or promote products derived
  14. // from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. "use strict";
  28. String.prototype.startsWith = function (str) {
  29. if (str.length > this.length) {
  30. return false;
  31. }
  32. return this.substr(0, str.length) == str;
  33. };
  34. function log10(num) {
  35. return Math.log(num)/Math.log(10);
  36. }
  37. function ToInspectableObject(obj) {
  38. if (!obj && typeof obj === 'object') {
  39. return UNDEFINED;
  40. } else {
  41. return Object(obj);
  42. }
  43. }
  44. function GetCompletions(global, last, full) {
  45. var full_tokens = full.split();
  46. full = full_tokens.pop();
  47. var parts = full.split('.');
  48. parts.pop();
  49. var current = global;
  50. for (var i = 0; i < parts.length; i++) {
  51. var part = parts[i];
  52. var next = current[part];
  53. if (!next) {
  54. return [];
  55. }
  56. current = next;
  57. }
  58. var result = [];
  59. current = ToInspectableObject(current);
  60. while (typeof current !== 'undefined') {
  61. var mirror = new $debug.ObjectMirror(current);
  62. var properties = mirror.properties();
  63. for (var i = 0; i < properties.length; i++) {
  64. var name = properties[i].name();
  65. if (typeof name === 'string' && name.startsWith(last)) {
  66. result.push(name);
  67. }
  68. }
  69. current = ToInspectableObject(Object.getPrototypeOf(current));
  70. }
  71. return result;
  72. }
  73. // Global object holding debugger related constants and state.
  74. var Debug = {};
  75. // Debug events which can occour in the V8 JavaScript engine. These originate
  76. // from the API include file v8-debug.h.
  77. Debug.DebugEvent = { Break: 1,
  78. Exception: 2,
  79. NewFunction: 3,
  80. BeforeCompile: 4,
  81. AfterCompile: 5 };
  82. // The different types of scripts matching enum ScriptType in objects.h.
  83. Debug.ScriptType = { Native: 0,
  84. Extension: 1,
  85. Normal: 2 };
  86. // The different types of script compilations matching enum
  87. // Script::CompilationType in objects.h.
  88. Debug.ScriptCompilationType = { Host: 0,
  89. Eval: 1,
  90. JSON: 2 };
  91. // The different types of scopes matching constants runtime.cc.
  92. Debug.ScopeType = { Global: 0,
  93. Local: 1,
  94. With: 2,
  95. Closure: 3,
  96. Catch: 4,
  97. Block: 5 };
  98. // Current debug state.
  99. var kNoFrame = -1;
  100. Debug.State = {
  101. currentFrame: kNoFrame,
  102. displaySourceStartLine: -1,
  103. displaySourceEndLine: -1,
  104. currentSourceLine: -1
  105. };
  106. var trace_compile = false; // Tracing all compile events?
  107. var trace_debug_json = false; // Tracing all debug json packets?
  108. var last_cmd = '';
  109. var repeat_cmd_line = '';
  110. var is_running = true;
  111. // Global variable used to store whether a handle was requested.
  112. var lookup_handle = null;
  113. // Copied from debug-delay.js. This is needed below:
  114. function ScriptTypeFlag(type) {
  115. return (1 << type);
  116. }
  117. // Process a debugger JSON message into a display text and a running status.
  118. // This function returns an object with properties "text" and "running" holding
  119. // this information.
  120. function DebugMessageDetails(message) {
  121. if (trace_debug_json) {
  122. print("received: '" + message + "'");
  123. }
  124. // Convert the JSON string to an object.
  125. var response = new ProtocolPackage(message);
  126. is_running = response.running();
  127. if (response.type() == 'event') {
  128. return DebugEventDetails(response);
  129. } else {
  130. return DebugResponseDetails(response);
  131. }
  132. }
  133. function DebugEventDetails(response) {
  134. var details = {text:'', running:false};
  135. // Get the running state.
  136. details.running = response.running();
  137. var body = response.body();
  138. var result = '';
  139. switch (response.event()) {
  140. case 'break':
  141. if (body.breakpoints) {
  142. result += 'breakpoint';
  143. if (body.breakpoints.length > 1) {
  144. result += 's';
  145. }
  146. result += ' #';
  147. for (var i = 0; i < body.breakpoints.length; i++) {
  148. if (i > 0) {
  149. result += ', #';
  150. }
  151. result += body.breakpoints[i];
  152. }
  153. } else {
  154. result += 'break';
  155. }
  156. result += ' in ';
  157. result += body.invocationText;
  158. result += ', ';
  159. result += SourceInfo(body);
  160. result += '\n';
  161. result += SourceUnderline(body.sourceLineText, body.sourceColumn);
  162. Debug.State.currentSourceLine = body.sourceLine;
  163. Debug.State.displaySourceStartLine = -1;
  164. Debug.State.displaySourceEndLine = -1;
  165. Debug.State.currentFrame = 0;
  166. details.text = result;
  167. break;
  168. case 'exception':
  169. if (body.uncaught) {
  170. result += 'Uncaught: ';
  171. } else {
  172. result += 'Exception: ';
  173. }
  174. result += '"';
  175. result += body.exception.text;
  176. result += '"';
  177. if (body.sourceLine >= 0) {
  178. result += ', ';
  179. result += SourceInfo(body);
  180. result += '\n';
  181. result += SourceUnderline(body.sourceLineText, body.sourceColumn);
  182. Debug.State.currentSourceLine = body.sourceLine;
  183. Debug.State.displaySourceStartLine = -1;
  184. Debug.State.displaySourceEndLine = -1;
  185. Debug.State.currentFrame = 0;
  186. } else {
  187. result += ' (empty stack)';
  188. Debug.State.currentSourceLine = -1;
  189. Debug.State.displaySourceStartLine = -1;
  190. Debug.State.displaySourceEndLine = -1;
  191. Debug.State.currentFrame = kNoFrame;
  192. }
  193. details.text = result;
  194. break;
  195. case 'afterCompile':
  196. if (trace_compile) {
  197. result = 'Source ' + body.script.name + ' compiled:\n';
  198. var source = body.script.source;
  199. if (!(source[source.length - 1] == '\n')) {
  200. result += source;
  201. } else {
  202. result += source.substring(0, source.length - 1);
  203. }
  204. }
  205. details.text = result;
  206. break;
  207. case 'scriptCollected':
  208. details.text = result;
  209. break;
  210. default:
  211. details.text = 'Unknown debug event ' + response.event();
  212. }
  213. return details;
  214. }
  215. function SourceInfo(body) {
  216. var result = '';
  217. if (body.script) {
  218. if (body.script.name) {
  219. result += body.script.name;
  220. } else {
  221. result += '[unnamed]';
  222. }
  223. }
  224. result += ' line ';
  225. result += body.sourceLine + 1;
  226. result += ' column ';
  227. result += body.sourceColumn + 1;
  228. return result;
  229. }
  230. function SourceUnderline(source_text, position) {
  231. if (!source_text) {
  232. return;
  233. }
  234. // Create an underline with a caret pointing to the source position. If the
  235. // source contains a tab character the underline will have a tab character in
  236. // the same place otherwise the underline will have a space character.
  237. var underline = '';
  238. for (var i = 0; i < position; i++) {
  239. if (source_text[i] == '\t') {
  240. underline += '\t';
  241. } else {
  242. underline += ' ';
  243. }
  244. }
  245. underline += '^';
  246. // Return the source line text with the underline beneath.
  247. return source_text + '\n' + underline;
  248. }
  249. // Converts a text command to a JSON request.
  250. function DebugCommandToJSONRequest(cmd_line) {
  251. var result = new DebugRequest(cmd_line).JSONRequest();
  252. if (trace_debug_json && result) {
  253. print("sending: '" + result + "'");
  254. }
  255. return result;
  256. }
  257. function DebugRequest(cmd_line) {
  258. // If the very first character is a { assume that a JSON request have been
  259. // entered as a command. Converting that to a JSON request is trivial.
  260. if (cmd_line && cmd_line.length > 0 && cmd_line.charAt(0) == '{') {
  261. this.request_ = cmd_line;
  262. return;
  263. }
  264. // Check for a simple carriage return to repeat the last command:
  265. var is_repeating = false;
  266. if (cmd_line == '\n') {
  267. if (is_running) {
  268. cmd_line = 'break'; // Not in debugger mode, break with a frame request.
  269. } else {
  270. cmd_line = repeat_cmd_line; // use command to repeat.
  271. is_repeating = true;
  272. }
  273. }
  274. if (!is_running) { // Only save the command if in debugger mode.
  275. repeat_cmd_line = cmd_line; // save last command.
  276. }
  277. // Trim string for leading and trailing whitespace.
  278. cmd_line = cmd_line.replace(/^\s+|\s+$/g, '');
  279. // Find the command.
  280. var pos = cmd_line.indexOf(' ');
  281. var cmd;
  282. var args;
  283. if (pos == -1) {
  284. cmd = cmd_line;
  285. args = '';
  286. } else {
  287. cmd = cmd_line.slice(0, pos);
  288. args = cmd_line.slice(pos).replace(/^\s+|\s+$/g, '');
  289. }
  290. if ((cmd === undefined) || !cmd) {
  291. this.request_ = UNDEFINED;
  292. return;
  293. }
  294. last_cmd = cmd;
  295. // Switch on command.
  296. switch (cmd) {
  297. case 'continue':
  298. case 'c':
  299. this.request_ = this.continueCommandToJSONRequest_(args);
  300. break;
  301. case 'step':
  302. case 's':
  303. this.request_ = this.stepCommandToJSONRequest_(args, 'in');
  304. break;
  305. case 'stepi':
  306. case 'si':
  307. this.request_ = this.stepCommandToJSONRequest_(args, 'min');
  308. break;
  309. case 'next':
  310. case 'n':
  311. this.request_ = this.stepCommandToJSONRequest_(args, 'next');
  312. break;
  313. case 'finish':
  314. case 'fin':
  315. this.request_ = this.stepCommandToJSONRequest_(args, 'out');
  316. break;
  317. case 'backtrace':
  318. case 'bt':
  319. this.request_ = this.backtraceCommandToJSONRequest_(args);
  320. break;
  321. case 'frame':
  322. case 'f':
  323. this.request_ = this.frameCommandToJSONRequest_(args);
  324. break;
  325. case 'scopes':
  326. this.request_ = this.scopesCommandToJSONRequest_(args);
  327. break;
  328. case 'scope':
  329. this.request_ = this.scopeCommandToJSONRequest_(args);
  330. break;
  331. case 'disconnect':
  332. case 'exit':
  333. case 'quit':
  334. this.request_ = this.disconnectCommandToJSONRequest_(args);
  335. break;
  336. case 'up':
  337. this.request_ =
  338. this.frameCommandToJSONRequest_('' +
  339. (Debug.State.currentFrame + 1));
  340. break;
  341. case 'down':
  342. case 'do':
  343. this.request_ =
  344. this.frameCommandToJSONRequest_('' +
  345. (Debug.State.currentFrame - 1));
  346. break;
  347. case 'set':
  348. case 'print':
  349. case 'p':
  350. this.request_ = this.printCommandToJSONRequest_(args);
  351. break;
  352. case 'dir':
  353. this.request_ = this.dirCommandToJSONRequest_(args);
  354. break;
  355. case 'references':
  356. this.request_ = this.referencesCommandToJSONRequest_(args);
  357. break;
  358. case 'instances':
  359. this.request_ = this.instancesCommandToJSONRequest_(args);
  360. break;
  361. case 'list':
  362. case 'l':
  363. this.request_ = this.listCommandToJSONRequest_(args);
  364. break;
  365. case 'source':
  366. this.request_ = this.sourceCommandToJSONRequest_(args);
  367. break;
  368. case 'scripts':
  369. case 'script':
  370. case 'scr':
  371. this.request_ = this.scriptsCommandToJSONRequest_(args);
  372. break;
  373. case 'break':
  374. case 'b':
  375. this.request_ = this.breakCommandToJSONRequest_(args);
  376. break;
  377. case 'breakpoints':
  378. case 'bb':
  379. this.request_ = this.breakpointsCommandToJSONRequest_(args);
  380. break;
  381. case 'clear':
  382. case 'delete':
  383. case 'd':
  384. this.request_ = this.clearCommandToJSONRequest_(args);
  385. break;
  386. case 'threads':
  387. this.request_ = this.threadsCommandToJSONRequest_(args);
  388. break;
  389. case 'cond':
  390. this.request_ = this.changeBreakpointCommandToJSONRequest_(args, 'cond');
  391. break;
  392. case 'enable':
  393. case 'en':
  394. this.request_ =
  395. this.changeBreakpointCommandToJSONRequest_(args, 'enable');
  396. break;
  397. case 'disable':
  398. case 'dis':
  399. this.request_ =
  400. this.changeBreakpointCommandToJSONRequest_(args, 'disable');
  401. break;
  402. case 'ignore':
  403. this.request_ =
  404. this.changeBreakpointCommandToJSONRequest_(args, 'ignore');
  405. break;
  406. case 'info':
  407. case 'inf':
  408. this.request_ = this.infoCommandToJSONRequest_(args);
  409. break;
  410. case 'flags':
  411. this.request_ = this.v8FlagsToJSONRequest_(args);
  412. break;
  413. case 'gc':
  414. this.request_ = this.gcToJSONRequest_(args);
  415. break;
  416. case 'trace':
  417. case 'tr':
  418. // Return undefined to indicate command handled internally (no JSON).
  419. this.request_ = UNDEFINED;
  420. this.traceCommand_(args);
  421. break;
  422. case 'help':
  423. case '?':
  424. this.helpCommand_(args);
  425. // Return undefined to indicate command handled internally (no JSON).
  426. this.request_ = UNDEFINED;
  427. break;
  428. default:
  429. throw new Error('Unknown command "' + cmd + '"');
  430. }
  431. }
  432. DebugRequest.prototype.JSONRequest = function() {
  433. return this.request_;
  434. };
  435. function RequestPacket(command) {
  436. this.seq = 0;
  437. this.type = 'request';
  438. this.command = command;
  439. }
  440. RequestPacket.prototype.toJSONProtocol = function() {
  441. // Encode the protocol header.
  442. var json = '{';
  443. json += '"seq":' + this.seq;
  444. json += ',"type":"' + this.type + '"';
  445. if (this.command) {
  446. json += ',"command":' + StringToJSON_(this.command);
  447. }
  448. if (this.arguments) {
  449. json += ',"arguments":';
  450. // Encode the arguments part.
  451. if (this.arguments.toJSONProtocol) {
  452. json += this.arguments.toJSONProtocol();
  453. } else {
  454. json += SimpleObjectToJSON_(this.arguments);
  455. }
  456. }
  457. json += '}';
  458. return json;
  459. };
  460. DebugRequest.prototype.createRequest = function(command) {
  461. return new RequestPacket(command);
  462. };
  463. // Create a JSON request for the evaluation command.
  464. DebugRequest.prototype.makeEvaluateJSONRequest_ = function(expression) {
  465. lookup_handle = null;
  466. // Check if the expression is a handle id in the form #<handle>#.
  467. var handle_match = expression.match(/^#([0-9]*)#$/);
  468. if (handle_match) {
  469. // Remember the handle requested in a global variable.
  470. lookup_handle = parseInt(handle_match[1]);
  471. // Build a lookup request.
  472. var request = this.createRequest('lookup');
  473. request.arguments = {};
  474. request.arguments.handles = [ lookup_handle ];
  475. return request.toJSONProtocol();
  476. } else {
  477. // Build an evaluate request.
  478. var request = this.createRequest('evaluate');
  479. request.arguments = {};
  480. request.arguments.expression = expression;
  481. // Request a global evaluation if there is no current frame.
  482. if (Debug.State.currentFrame == kNoFrame) {
  483. request.arguments.global = true;
  484. }
  485. return request.toJSONProtocol();
  486. }
  487. };
  488. // Create a JSON request for the references/instances command.
  489. DebugRequest.prototype.makeReferencesJSONRequest_ = function(handle, type) {
  490. // Build a references request.
  491. var handle_match = handle.match(/^#([0-9]*)#$/);
  492. if (handle_match) {
  493. var request = this.createRequest('references');
  494. request.arguments = {};
  495. request.arguments.type = type;
  496. request.arguments.handle = parseInt(handle_match[1]);
  497. return request.toJSONProtocol();
  498. } else {
  499. throw new Error('Invalid object id.');
  500. }
  501. };
  502. // Create a JSON request for the continue command.
  503. DebugRequest.prototype.continueCommandToJSONRequest_ = function(args) {
  504. var request = this.createRequest('continue');
  505. return request.toJSONProtocol();
  506. };
  507. // Create a JSON request for the step command.
  508. DebugRequest.prototype.stepCommandToJSONRequest_ = function(args, type) {
  509. // Requesting a step is through the continue command with additional
  510. // arguments.
  511. var request = this.createRequest('continue');
  512. request.arguments = {};
  513. // Process arguments if any.
  514. // Only process args if the command is 'step' which is indicated by type being
  515. // set to 'in'. For all other commands, ignore the args.
  516. if (args && args.length > 0) {
  517. args = args.split(/\s+/g);
  518. if (args.length > 2) {
  519. throw new Error('Invalid step arguments.');
  520. }
  521. if (args.length > 0) {
  522. // Check if we have a gdb stype step command. If so, the 1st arg would
  523. // be the step count. If it's not a number, then assume that we're
  524. // parsing for the legacy v8 step command.
  525. var stepcount = Number(args[0]);
  526. if (stepcount == Number.NaN) {
  527. // No step count at arg 1. Process as legacy d8 step command:
  528. if (args.length == 2) {
  529. var stepcount = parseInt(args[1]);
  530. if (isNaN(stepcount) || stepcount <= 0) {
  531. throw new Error('Invalid step count argument "' + args[0] + '".');
  532. }
  533. request.arguments.stepcount = stepcount;
  534. }
  535. // Get the step action.
  536. switch (args[0]) {
  537. case 'in':
  538. case 'i':
  539. request.arguments.stepaction = 'in';
  540. break;
  541. case 'min':
  542. case 'm':
  543. request.arguments.stepaction = 'min';
  544. break;
  545. case 'next':
  546. case 'n':
  547. request.arguments.stepaction = 'next';
  548. break;
  549. case 'out':
  550. case 'o':
  551. request.arguments.stepaction = 'out';
  552. break;
  553. default:
  554. throw new Error('Invalid step argument "' + args[0] + '".');
  555. }
  556. } else {
  557. // gdb style step commands:
  558. request.arguments.stepaction = type;
  559. request.arguments.stepcount = stepcount;
  560. }
  561. }
  562. } else {
  563. // Default is step of the specified type.
  564. request.arguments.stepaction = type;
  565. }
  566. return request.toJSONProtocol();
  567. };
  568. // Create a JSON request for the backtrace command.
  569. DebugRequest.prototype.backtraceCommandToJSONRequest_ = function(args) {
  570. // Build a backtrace request from the text command.
  571. var request = this.createRequest('backtrace');
  572. // Default is to show top 10 frames.
  573. request.arguments = {};
  574. request.arguments.fromFrame = 0;
  575. request.arguments.toFrame = 10;
  576. args = args.split(/\s*[ ]+\s*/g);
  577. if (args.length == 1 && args[0].length > 0) {
  578. var frameCount = parseInt(args[0]);
  579. if (frameCount > 0) {
  580. // Show top frames.
  581. request.arguments.fromFrame = 0;
  582. request.arguments.toFrame = frameCount;
  583. } else {
  584. // Show bottom frames.
  585. request.arguments.fromFrame = 0;
  586. request.arguments.toFrame = -frameCount;
  587. request.arguments.bottom = true;
  588. }
  589. } else if (args.length == 2) {
  590. var fromFrame = parseInt(args[0]);
  591. var toFrame = parseInt(args[1]);
  592. if (isNaN(fromFrame) || fromFrame < 0) {
  593. throw new Error('Invalid start frame argument "' + args[0] + '".');
  594. }
  595. if (isNaN(toFrame) || toFrame < 0) {
  596. throw new Error('Invalid end frame argument "' + args[1] + '".');
  597. }
  598. if (fromFrame > toFrame) {
  599. throw new Error('Invalid arguments start frame cannot be larger ' +
  600. 'than end frame.');
  601. }
  602. // Show frame range.
  603. request.arguments.fromFrame = fromFrame;
  604. request.arguments.toFrame = toFrame + 1;
  605. } else if (args.length > 2) {
  606. throw new Error('Invalid backtrace arguments.');
  607. }
  608. return request.toJSONProtocol();
  609. };
  610. // Create a JSON request for the frame command.
  611. DebugRequest.prototype.frameCommandToJSONRequest_ = function(args) {
  612. // Build a frame request from the text command.
  613. var request = this.createRequest('frame');
  614. args = args.split(/\s*[ ]+\s*/g);
  615. if (args.length > 0 && args[0].length > 0) {
  616. request.arguments = {};
  617. request.arguments.number = args[0];
  618. }
  619. return request.toJSONProtocol();
  620. };
  621. // Create a JSON request for the scopes command.
  622. DebugRequest.prototype.scopesCommandToJSONRequest_ = function(args) {
  623. // Build a scopes request from the text command.
  624. var request = this.createRequest('scopes');
  625. return request.toJSONProtocol();
  626. };
  627. // Create a JSON request for the scope command.
  628. DebugRequest.prototype.scopeCommandToJSONRequest_ = function(args) {
  629. // Build a scope request from the text command.
  630. var request = this.createRequest('scope');
  631. args = args.split(/\s*[ ]+\s*/g);
  632. if (args.length > 0 && args[0].length > 0) {
  633. request.arguments = {};
  634. request.arguments.number = args[0];
  635. }
  636. return request.toJSONProtocol();
  637. };
  638. // Create a JSON request for the print command.
  639. DebugRequest.prototype.printCommandToJSONRequest_ = function(args) {
  640. // Build an evaluate request from the text command.
  641. if (args.length == 0) {
  642. throw new Error('Missing expression.');
  643. }
  644. return this.makeEvaluateJSONRequest_(args);
  645. };
  646. // Create a JSON request for the dir command.
  647. DebugRequest.prototype.dirCommandToJSONRequest_ = function(args) {
  648. // Build an evaluate request from the text command.
  649. if (args.length == 0) {
  650. throw new Error('Missing expression.');
  651. }
  652. return this.makeEvaluateJSONRequest_(args);
  653. };
  654. // Create a JSON request for the references command.
  655. DebugRequest.prototype.referencesCommandToJSONRequest_ = function(args) {
  656. // Build an evaluate request from the text command.
  657. if (args.length == 0) {
  658. throw new Error('Missing object id.');
  659. }
  660. return this.makeReferencesJSONRequest_(args, 'referencedBy');
  661. };
  662. // Create a JSON request for the instances command.
  663. DebugRequest.prototype.instancesCommandToJSONRequest_ = function(args) {
  664. // Build an evaluate request from the text command.
  665. if (args.length == 0) {
  666. throw new Error('Missing object id.');
  667. }
  668. // Build a references request.
  669. return this.makeReferencesJSONRequest_(args, 'constructedBy');
  670. };
  671. // Create a JSON request for the list command.
  672. DebugRequest.prototype.listCommandToJSONRequest_ = function(args) {
  673. // Default is ten lines starting five lines before the current location.
  674. if (Debug.State.displaySourceEndLine == -1) {
  675. // If we list forwards, we will start listing after the last source end
  676. // line. Set it to start from 5 lines before the current location.
  677. Debug.State.displaySourceEndLine = Debug.State.currentSourceLine - 5;
  678. // If we list backwards, we will start listing backwards from the last
  679. // source start line. Set it to start from 1 lines before the current
  680. // location.
  681. Debug.State.displaySourceStartLine = Debug.State.currentSourceLine + 1;
  682. }
  683. var from = Debug.State.displaySourceEndLine + 1;
  684. var lines = 10;
  685. // Parse the arguments.
  686. args = args.split(/\s*,\s*/g);
  687. if (args == '') {
  688. } else if ((args.length == 1) && (args[0] == '-')) {
  689. from = Debug.State.displaySourceStartLine - lines;
  690. } else if (args.length == 2) {
  691. from = parseInt(args[0]);
  692. lines = parseInt(args[1]) - from + 1; // inclusive of the ending line.
  693. } else {
  694. throw new Error('Invalid list arguments.');
  695. }
  696. Debug.State.displaySourceStartLine = from;
  697. Debug.State.displaySourceEndLine = from + lines - 1;
  698. var sourceArgs = '' + from + ' ' + lines;
  699. return this.sourceCommandToJSONRequest_(sourceArgs);
  700. };
  701. // Create a JSON request for the source command.
  702. DebugRequest.prototype.sourceCommandToJSONRequest_ = function(args) {
  703. // Build a evaluate request from the text command.
  704. var request = this.createRequest('source');
  705. // Default is ten lines starting five lines before the current location.
  706. var from = Debug.State.currentSourceLine - 5;
  707. var lines = 10;
  708. // Parse the arguments.
  709. args = args.split(/\s*[ ]+\s*/g);
  710. if (args.length > 1 && args[0].length > 0 && args[1].length > 0) {
  711. from = parseInt(args[0]) - 1;
  712. lines = parseInt(args[1]);
  713. } else if (args.length > 0 && args[0].length > 0) {
  714. from = parseInt(args[0]) - 1;
  715. }
  716. if (from < 0) from = 0;
  717. if (lines < 0) lines = 10;
  718. // Request source arround current source location.
  719. request.arguments = {};
  720. request.arguments.fromLine = from;
  721. request.arguments.toLine = from + lines;
  722. return request.toJSONProtocol();
  723. };
  724. // Create a JSON request for the scripts command.
  725. DebugRequest.prototype.scriptsCommandToJSONRequest_ = function(args) {
  726. // Build a evaluate request from the text command.
  727. var request = this.createRequest('scripts');
  728. // Process arguments if any.
  729. if (args && args.length > 0) {
  730. args = args.split(/\s*[ ]+\s*/g);
  731. if (args.length > 1) {
  732. throw new Error('Invalid scripts arguments.');
  733. }
  734. request.arguments = {};
  735. switch (args[0]) {
  736. case 'natives':
  737. request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Native);
  738. break;
  739. case 'extensions':
  740. request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Extension);
  741. break;
  742. case 'all':
  743. request.arguments.types =
  744. ScriptTypeFlag(Debug.ScriptType.Normal) |
  745. ScriptTypeFlag(Debug.ScriptType.Native) |
  746. ScriptTypeFlag(Debug.ScriptType.Extension);
  747. break;
  748. default:
  749. // If the arg is not one of the know one aboves, then it must be a
  750. // filter used for filtering the results:
  751. request.arguments.filter = args[0];
  752. break;
  753. }
  754. }
  755. return request.toJSONProtocol();
  756. };
  757. // Create a JSON request for the break command.
  758. DebugRequest.prototype.breakCommandToJSONRequest_ = function(args) {
  759. // Build a evaluate request from the text command.
  760. // Process arguments if any.
  761. if (args && args.length > 0) {
  762. var target = args;
  763. var type = 'function';
  764. var line;
  765. var column;
  766. var condition;
  767. var pos;
  768. var request = this.createRequest('setbreakpoint');
  769. // Break the args into target spec and condition if appropriate.
  770. // Check for breakpoint condition.
  771. pos = args.indexOf(' ');
  772. if (pos > 0) {
  773. target = args.substring(0, pos);
  774. condition = args.substring(pos + 1, args.length);
  775. }
  776. // Check for script breakpoint (name:line[:column]). If no ':' in break
  777. // specification it is considered a function break point.
  778. pos = target.indexOf(':');
  779. if (pos > 0) {
  780. var tmp = target.substring(pos + 1, target.length);
  781. target = target.substring(0, pos);
  782. if (target[0] == '/' && target[target.length - 1] == '/') {
  783. type = 'scriptRegExp';
  784. target = target.substring(1, target.length - 1);
  785. } else {
  786. type = 'script';
  787. }
  788. // Check for both line and column.
  789. pos = tmp.indexOf(':');
  790. if (pos > 0) {
  791. column = parseInt(tmp.substring(pos + 1, tmp.length)) - 1;
  792. line = parseInt(tmp.substring(0, pos)) - 1;
  793. } else {
  794. line = parseInt(tmp) - 1;
  795. }
  796. } else if (target[0] == '#' && target[target.length - 1] == '#') {
  797. type = 'handle';
  798. target = target.substring(1, target.length - 1);
  799. } else {
  800. type = 'function';
  801. }
  802. request.arguments = {};
  803. request.arguments.type = type;
  804. request.arguments.target = target;
  805. request.arguments.line = line;
  806. request.arguments.column = column;
  807. request.arguments.condition = condition;
  808. } else {
  809. var request = this.createRequest('suspend');
  810. }
  811. return request.toJSONProtocol();
  812. };
  813. DebugRequest.prototype.breakpointsCommandToJSONRequest_ = function(args) {
  814. if (args && args.length > 0) {
  815. throw new Error('Unexpected arguments.');
  816. }
  817. var request = this.createRequest('listbreakpoints');
  818. return request.toJSONProtocol();
  819. };
  820. // Create a JSON request for the clear command.
  821. DebugRequest.prototype.clearCommandToJSONRequest_ = function(args) {
  822. // Build a evaluate request from the text command.
  823. var request = this.createRequest('clearbreakpoint');
  824. // Process arguments if any.
  825. if (args && args.length > 0) {
  826. request.arguments = {};
  827. request.arguments.breakpoint = parseInt(args);
  828. } else {
  829. throw new Error('Invalid break arguments.');
  830. }
  831. return request.toJSONProtocol();
  832. };
  833. // Create a JSON request for the change breakpoint command.
  834. DebugRequest.prototype.changeBreakpointCommandToJSONRequest_ =
  835. function(args, command) {
  836. var request;
  837. // Check for exception breaks first:
  838. // en[able] exc[eptions] [all|unc[aught]]
  839. // en[able] [all|unc[aught]] exc[eptions]
  840. // dis[able] exc[eptions] [all|unc[aught]]
  841. // dis[able] [all|unc[aught]] exc[eptions]
  842. if ((command == 'enable' || command == 'disable') &&
  843. args && args.length > 1) {
  844. var nextPos = args.indexOf(' ');
  845. var arg1 = (nextPos > 0) ? args.substring(0, nextPos) : args;
  846. var excType = null;
  847. // Check for:
  848. // en[able] exc[eptions] [all|unc[aught]]
  849. // dis[able] exc[eptions] [all|unc[aught]]
  850. if (arg1 == 'exc' || arg1 == 'exception' || arg1 == 'exceptions') {
  851. var arg2 = (nextPos > 0) ?
  852. args.substring(nextPos + 1, args.length) : 'all';
  853. if (!arg2) {
  854. arg2 = 'all'; // if unspecified, set for all.
  855. } else if (arg2 == 'unc') { // check for short cut.
  856. arg2 = 'uncaught';
  857. }
  858. excType = arg2;
  859. // Check for:
  860. // en[able] [all|unc[aught]] exc[eptions]
  861. // dis[able] [all|unc[aught]] exc[eptions]
  862. } else if (arg1 == 'all' || arg1 == 'unc' || arg1 == 'uncaught') {
  863. var arg2 = (nextPos > 0) ?
  864. args.substring(nextPos + 1, args.length) : null;
  865. if (arg2 == 'exc' || arg1 == 'exception' || arg1 == 'exceptions') {
  866. excType = arg1;
  867. if (excType == 'unc') {
  868. excType = 'uncaught';
  869. }
  870. }
  871. }
  872. // If we matched one of the command formats, then excType will be non-null:
  873. if (excType) {
  874. // Build a evaluate request from the text command.
  875. request = this.createRequest('setexceptionbreak');
  876. request.arguments = {};
  877. request.arguments.type = excType;
  878. request.arguments.enabled = (command == 'enable');
  879. return request.toJSONProtocol();
  880. }
  881. }
  882. // Build a evaluate request from the text command.
  883. request = this.createRequest('changebreakpoint');
  884. // Process arguments if any.
  885. if (args && args.length > 0) {
  886. request.arguments = {};
  887. var pos = args.indexOf(' ');
  888. var breakpointArg = args;
  889. var otherArgs;
  890. if (pos > 0) {
  891. breakpointArg = args.substring(0, pos);
  892. otherArgs = args.substring(pos + 1, args.length);
  893. }
  894. request.arguments.breakpoint = parseInt(breakpointArg);
  895. switch(command) {
  896. case 'cond':
  897. request.arguments.condition = otherArgs ? otherArgs : null;
  898. break;
  899. case 'enable':
  900. request.arguments.enabled = true;
  901. break;
  902. case 'disable':
  903. request.arguments.enabled = false;
  904. break;
  905. case 'ignore':
  906. request.arguments.ignoreCount = parseInt(otherArgs);
  907. break;
  908. default:
  909. throw new Error('Invalid arguments.');
  910. }
  911. } else {
  912. throw new Error('Invalid arguments.');
  913. }
  914. return request.toJSONProtocol();
  915. };
  916. // Create a JSON request for the disconnect command.
  917. DebugRequest.prototype.disconnectCommandToJSONRequest_ = function(args) {
  918. var request;
  919. request = this.createRequest('disconnect');
  920. return request.toJSONProtocol();
  921. };
  922. // Create a JSON request for the info command.
  923. DebugRequest.prototype.infoCommandToJSONRequest_ = function(args) {
  924. var request;
  925. if (args && (args == 'break' || args == 'br')) {
  926. // Build a evaluate request from the text command.
  927. request = this.createRequest('listbreakpoints');
  928. last_cmd = 'info break';
  929. } else if (args && (args == 'locals' || args == 'lo')) {
  930. // Build a evaluate request from the text command.
  931. request = this.createRequest('frame');
  932. last_cmd = 'info locals';
  933. } else if (args && (args == 'args' || args == 'ar')) {
  934. // Build a evaluate request from the text command.
  935. request = this.createRequest('frame');
  936. last_cmd = 'info args';
  937. } else {
  938. throw new Error('Invalid info arguments.');
  939. }
  940. return request.toJSONProtocol();
  941. };
  942. DebugRequest.prototype.v8FlagsToJSONRequest_ = function(args) {
  943. var request;
  944. request = this.createRequest('v8flags');
  945. request.arguments = {};
  946. request.arguments.flags = args;
  947. return request.toJSONProtocol();
  948. };
  949. DebugRequest.prototype.gcToJSONRequest_ = function(args) {
  950. var request;
  951. if (!args) {
  952. args = 'all';
  953. }
  954. var args = args.split(/\s+/g);
  955. var cmd = args[0];
  956. switch(cmd) {
  957. case 'all':
  958. case 'quick':
  959. case 'full':
  960. case 'young':
  961. case 'old':
  962. case 'compact':
  963. case 'sweep':
  964. case 'scavenge': {
  965. if (cmd == 'young') { cmd = 'quick'; }
  966. else if (cmd == 'old') { cmd = 'full'; }
  967. request = this.createRequest('gc');
  968. request.arguments = {};
  969. request.arguments.type = cmd;
  970. break;
  971. }
  972. // Else fall thru to the default case below to report the error.
  973. default:
  974. throw new Error('Missing arguments after ' + cmd + '.');
  975. }
  976. return request.toJSONProtocol();
  977. };
  978. // Create a JSON request for the threads command.
  979. DebugRequest.prototype.threadsCommandToJSONRequest_ = function(args) {
  980. // Build a threads request from the text command.
  981. var request = this.createRequest('threads');
  982. return request.toJSONProtocol();
  983. };
  984. // Handle the trace command.
  985. DebugRequest.prototype.traceCommand_ = function(args) {
  986. // Process arguments.
  987. if (args && args.length > 0) {
  988. if (args == 'compile') {
  989. trace_compile = !trace_compile;
  990. print('Tracing of compiled scripts ' + (trace_compile ? 'on' : 'off'));
  991. } else if (args === 'debug json' || args === 'json' || args === 'packets') {
  992. trace_debug_json = !trace_debug_json;
  993. print('Tracing of debug json packets ' +
  994. (trace_debug_json ? 'on' : 'off'));
  995. } else {
  996. throw new Error('Invalid trace arguments.');
  997. }
  998. } else {
  999. throw new Error('Invalid trace arguments.');
  1000. }
  1001. };
  1002. // Handle the help command.
  1003. DebugRequest.prototype.helpCommand_ = function(args) {
  1004. // Help os quite simple.
  1005. if (args && args.length > 0) {
  1006. print('warning: arguments to \'help\' are ignored');
  1007. }
  1008. print('Note: <> denotes symbollic values to be replaced with real values.');
  1009. print('Note: [] denotes optional parts of commands, or optional options / arguments.');
  1010. print(' e.g. d[elete] - you get the same command if you type d or delete.');
  1011. print('');
  1012. print('[break] - break as soon as possible');
  1013. print('b[reak] location [condition]');
  1014. print(' - break on named function: location is a function name');
  1015. print(' - break on function: location is #<id>#');
  1016. print(' - break on script position: location is name:line[:column]');
  1017. print('');
  1018. print('clear <breakpoint #> - deletes the specified user defined breakpoint');
  1019. print('d[elete] <breakpoint #> - deletes the specified user defined breakpoint');
  1020. print('dis[able] <breakpoint #> - disables the specified user defined breakpoint');
  1021. print('dis[able] exc[eptions] [[all] | unc[aught]]');
  1022. print(' - disables breaking on exceptions');
  1023. print('en[able] <breakpoint #> - enables the specified user defined breakpoint');
  1024. print('en[able] exc[eptions] [[all] | unc[aught]]');
  1025. print(' - enables breaking on exceptions');
  1026. print('');
  1027. print('b[ack]t[race] [n] | [-n] | [from to]');
  1028. print(' - prints the stack back trace');
  1029. print('f[rame] - prints info about the current frame context');
  1030. print('f[rame] <frame #> - set context to specified frame #');
  1031. print('scopes');
  1032. print('scope <scope #>');
  1033. print('');
  1034. print('up - set context to caller of current frame');
  1035. print('do[wn] - set context to callee of current frame');
  1036. print('inf[o] br[eak] - prints info about breakpoints in use');
  1037. print('inf[o] ar[gs] - prints info about arguments of the current function');
  1038. print('inf[o] lo[cals] - prints info about locals in the current function');
  1039. print('');
  1040. print('step [in | next | out| min [step count]]');
  1041. print('c[ontinue] - continue executing after a breakpoint');
  1042. print('s[tep] [<N>] - step into the next N callees (default N is 1)');
  1043. print('s[tep]i [<N>] - step into the next N callees (default N is 1)');
  1044. print('n[ext] [<N>] - step over the next N callees (default N is 1)');
  1045. print('fin[ish] [<N>] - step out of N frames (default N is 1)');
  1046. print('');
  1047. print('p[rint] <expression> - prints the result of the specified expression');
  1048. print('dir <expression> - prints the object structure of the result');
  1049. print('set <var> = <expression> - executes the specified statement');
  1050. print('');
  1051. print('l[ist] - list the source code around for the current pc');
  1052. print('l[ist] [- | <start>,<end>] - list the specified range of source code');
  1053. print('source [from line [num lines]]');
  1054. print('scr[ipts] [native|extensions|all]');
  1055. print('scr[ipts] [<filter text>] - list scripts with the specified text in its description');
  1056. print('');
  1057. print('gc - runs the garbage collector');
  1058. print('');
  1059. print('trace compile');
  1060. // hidden command: trace debug json - toggles tracing of debug json packets
  1061. print('');
  1062. print('disconnect|exit|quit - disconnects and quits the debugger');
  1063. print('help - prints this help information');
  1064. };
  1065. function formatHandleReference_(value) {
  1066. if (value.handle() >= 0) {
  1067. return '#' + value.handle() + '#';
  1068. } else {
  1069. return '#Transient#';
  1070. }
  1071. }
  1072. function formatObject_(value, include_properties) {
  1073. var result = '';
  1074. result += formatHandleReference_(value);
  1075. result += ', type: object';
  1076. result += ', constructor ';
  1077. var ctor = value.constructorFunctionValue();
  1078. result += formatHandleReference_(ctor);
  1079. result += ', __proto__ ';
  1080. var proto = value.protoObjectValue();
  1081. result += formatHandleReference_(proto);
  1082. result += ', ';
  1083. result += value.propertyCount();
  1084. result += ' properties.';
  1085. if (include_properties) {
  1086. result += '\n';
  1087. for (var i = 0; i < value.propertyCount(); i++) {
  1088. result += ' ';
  1089. result += value.propertyName(i);
  1090. result += ': ';
  1091. var property_value = value.propertyValue(i);
  1092. if (property_value instanceof ProtocolReference) {
  1093. result += '<no type>';
  1094. } else {
  1095. if (property_value && property_value.type()) {
  1096. result += property_value.type();
  1097. } else {
  1098. result += '<no type>';
  1099. }
  1100. }
  1101. result += ' ';
  1102. result += formatHandleReference_(property_value);
  1103. result += '\n';
  1104. }
  1105. }
  1106. return result;
  1107. }
  1108. function formatScope_(scope) {
  1109. var result = '';
  1110. var index = scope.index;
  1111. result += '#' + (index <= 9 ? '0' : '') + index;
  1112. result += ' ';
  1113. switch (scope.type) {
  1114. case Debug.ScopeType.Global:
  1115. result += 'Global, ';
  1116. result += '#' + scope.object.ref + '#';
  1117. break;
  1118. case Debug.ScopeType.Local:
  1119. result += 'Local';
  1120. break;
  1121. case Debug.ScopeType.With:
  1122. result += 'With, ';
  1123. result += '#' + scope.object.ref + '#';
  1124. break;
  1125. case Debug.ScopeType.Catch:
  1126. result += 'Catch, ';
  1127. result += '#' + scope.object.ref + '#';
  1128. break;
  1129. case Debug.ScopeType.Closure:
  1130. result += 'Closure';
  1131. break;
  1132. default:
  1133. result += 'UNKNOWN';
  1134. }
  1135. return result;
  1136. }
  1137. function refObjectToString_(protocolPackage, handle) {
  1138. var value = protocolPackage.lookup(handle);
  1139. var result = '';
  1140. if (value.isString()) {
  1141. result = '"' + value.value() + '"';
  1142. } else if (value.isPrimitive()) {
  1143. result = value.valueString();
  1144. } else if (value.isObject()) {
  1145. result += formatObject_(value, true);
  1146. }
  1147. return result;
  1148. }
  1149. // Rounds number 'num' to 'length' decimal places.
  1150. function roundNumber(num, length) {
  1151. var factor = Math.pow(10, length);
  1152. return Math.round(num * factor) / factor;
  1153. }
  1154. // Convert a JSON response to text for display in a text based debugger.
  1155. function DebugResponseDetails(response) {
  1156. var details = { text: '', running: false };
  1157. try {
  1158. if (!response.success()) {
  1159. details.text = response.message();
  1160. return details;
  1161. }
  1162. // Get the running state.
  1163. details.running = response.running();
  1164. var body = response.body();
  1165. var result = '';
  1166. switch (response.command()) {
  1167. case 'suspend':
  1168. details.text = 'stopped';
  1169. break;
  1170. case 'setbreakpoint':
  1171. result = 'set breakpoint #';
  1172. result += body.breakpoint;
  1173. details.text = result;
  1174. break;
  1175. case 'clearbreakpoint':
  1176. result = 'cleared breakpoint #';
  1177. result += body.breakpoint;
  1178. details.text = result;
  1179. break;
  1180. case 'changebreakpoint':
  1181. result = 'successfully changed breakpoint';
  1182. details.text = result;
  1183. break;
  1184. case 'listbreakpoints':
  1185. result = 'breakpoints: (' + body.breakpoints.length + ')';
  1186. for (var i = 0; i < body.breakpoints.length; i++) {
  1187. var breakpoint = body.breakpoints[i];
  1188. result += '\n id=' + breakpoint.number;
  1189. result += ' type=' + breakpoint.type;
  1190. if (breakpoint.script_id) {
  1191. result += ' script_id=' + breakpoint.script_id;
  1192. }
  1193. if (breakpoint.script_name) {
  1194. result += ' script_name=' + breakpoint.script_name;
  1195. }
  1196. if (breakpoint.script_regexp) {
  1197. result += ' script_regexp=' + breakpoint.script_regexp;
  1198. }
  1199. result += ' line=' + (breakpoint.line + 1);
  1200. if (breakpoint.column != null) {
  1201. result += ' column=' + (breakpoint.column + 1);
  1202. }
  1203. if (breakpoint.groupId) {
  1204. result += ' groupId=' + breakpoint.groupId;
  1205. }
  1206. if (breakpoint.ignoreCount) {
  1207. result += ' ignoreCount=' + breakpoint.ignoreCount;
  1208. }
  1209. if (breakpoint.active === false) {
  1210. result += ' inactive';
  1211. }
  1212. if (breakpoint.condition) {
  1213. result += ' condition=' + breakpoint.condition;
  1214. }
  1215. result += ' hit_count=' + breakpoint.hit_count;
  1216. }
  1217. if (body.breakpoints.length === 0) {
  1218. result = "No user defined breakpoints\n";
  1219. } else {
  1220. result += '\n';
  1221. }
  1222. if (body.breakOnExceptions) {
  1223. result += '* breaking on ALL exceptions is enabled\n';
  1224. } else if (body.breakOnUncaughtExceptions) {
  1225. result += '* breaking on UNCAUGHT exceptions is enabled\n';
  1226. } else {
  1227. result += '* all exception breakpoints are disabled\n';
  1228. }
  1229. details.text = result;
  1230. break;
  1231. case 'setexceptionbreak':
  1232. result = 'Break on ' + body.type + ' exceptions: ';
  1233. result += body.enabled ? 'enabled' : 'disabled';
  1234. details.text = result;
  1235. break;
  1236. case 'backtrace':
  1237. if (body.totalFrames == 0) {
  1238. result = '(empty stack)';
  1239. } else {
  1240. var result = 'Frames #' + body.fromFrame + ' to #' +
  1241. (body.toFrame - 1) + ' of ' + body.totalFrames + '\n';
  1242. for (i = 0; i < body.frames.length; i++) {
  1243. if (i != 0) result += '\n';
  1244. result += body.frames[i].text;
  1245. }
  1246. }
  1247. details.text = result;
  1248. break;
  1249. case 'frame':
  1250. if (last_cmd === 'info locals') {
  1251. var locals = body.locals;
  1252. if (locals.length === 0) {
  1253. result = 'No locals';
  1254. } else {
  1255. for (var i = 0; i < locals.length; i++) {
  1256. var local = locals[i];
  1257. result += local.name + ' = ';
  1258. result += refObjectToString_(response, local.value.ref);
  1259. result += '\n';
  1260. }
  1261. }
  1262. } else if (last_cmd === 'info args') {
  1263. var args = body.arguments;
  1264. if (args.length === 0) {
  1265. result = 'No arguments';
  1266. } else {
  1267. for (var i = 0; i < args.length; i++) {
  1268. var arg = args[i];
  1269. result += arg.name + ' = ';
  1270. result += refObjectToString_(response, arg.value.ref);
  1271. result += '\n';
  1272. }
  1273. }
  1274. } else {
  1275. result = SourceUnderline(body.sourceLineText,
  1276. body.column);
  1277. Debug.State.currentSourceLine = body.line;
  1278. Debug.State.currentFrame = body.index;
  1279. Debug.State.displaySourceStartLine = -1;
  1280. Debug.State.displaySourceEndLine = -1;
  1281. }
  1282. details.text = result;
  1283. break;
  1284. case 'scopes':
  1285. if (body.totalScopes == 0) {
  1286. result = '(no scopes)';
  1287. } else {
  1288. result = 'Scopes #' + body.fromScope + ' to #' +
  1289. (body.toScope - 1) + ' of ' + body.totalScopes + '\n';
  1290. for (i = 0; i < body.scopes.length; i++) {
  1291. if (i != 0) {
  1292. result += '\n';
  1293. }
  1294. result += formatScope_(body.scopes[i]);
  1295. }
  1296. }
  1297. details.text = result;
  1298. break;
  1299. case 'scope':
  1300. result += formatScope_(body);
  1301. result += '\n';
  1302. var scope_object_value = response.lookup(body.object.ref);
  1303. result += formatObject_(scope_object_value, true);
  1304. details.text = result;
  1305. break;
  1306. case 'evaluate':
  1307. case 'lookup':
  1308. case 'getobj':
  1309. if (last_cmd == 'p' || last_cmd == 'print') {
  1310. result = body.text;
  1311. } else {
  1312. var value;
  1313. if (lookup_handle) {
  1314. value = response.bodyValue(lookup_handle);
  1315. } else {
  1316. value = response.bodyValue();
  1317. }
  1318. if (value.isObject()) {
  1319. result += formatObject_(value, true);
  1320. } else {
  1321. result += 'type: ';
  1322. result += value.type();
  1323. if (!value.isUndefined() && !value.isNull()) {
  1324. result += ', ';
  1325. if (value.isString()) {
  1326. result += '"';
  1327. }
  1328. result += value.value();
  1329. if (value.isString()) {
  1330. result += '"';
  1331. }
  1332. }
  1333. result += '\n';
  1334. }
  1335. }
  1336. details.text = result;
  1337. break;
  1338. case 'references':
  1339. var count = body.length;
  1340. result += 'found ' + count + ' objects';
  1341. result += '\n';
  1342. for (var i = 0; i < count; i++) {
  1343. var value = response.bodyValue(i);
  1344. result += formatObject_(value, false);
  1345. result += '\n';
  1346. }
  1347. details.text = result;
  1348. break;
  1349. case 'source':
  1350. // Get the source from the response.
  1351. var source = body.source;
  1352. var from_line = body.fromLine + 1;
  1353. var lines = source.split('\n');
  1354. var maxdigits = 1 + Math.floor(log10(from_line + lines.length));
  1355. if (maxdigits < 3) {
  1356. maxdigits = 3;
  1357. }
  1358. var result = '';
  1359. for (var num = 0; num < lines.length; num++) {
  1360. // Check if there's an extra newline at the end.
  1361. if (num == (lines.length - 1) && lines[num].length == 0) {
  1362. break;
  1363. }
  1364. var current_line = from_line + num;
  1365. var spacer = maxdigits - (1 + Math.floor(log10(current_line)));
  1366. if (current_line == Debug.State.currentSourceLine + 1) {
  1367. for (var i = 0; i < maxdigits; i++) {
  1368. result += '>';
  1369. }
  1370. result += ' ';
  1371. } else {
  1372. for (var i = 0; i < spacer; i++) {
  1373. result += ' ';
  1374. }
  1375. result += current_line + ': ';
  1376. }
  1377. result += lines[num];
  1378. result += '\n';
  1379. }
  1380. details.text = result;
  1381. break;
  1382. case 'scripts':
  1383. var result = '';
  1384. for (i = 0; i < body.length; i++) {
  1385. if (i != 0) result += '\n';
  1386. if (body[i].id) {
  1387. result += body[i].id;
  1388. } else {
  1389. result += '[no id]';
  1390. }
  1391. result += ', ';
  1392. if (body[i].name) {
  1393. result += body[i].name;
  1394. } else {
  1395. if (body[i].compilationType == Debug.ScriptCompilationType.Eval
  1396. && body[i].evalFromScript
  1397. ) {
  1398. result += 'eval from ';
  1399. var script_value = response.lookup(body[i].evalFromScript.ref);
  1400. result += ' ' + script_value.field('name');
  1401. result += ':' + (body[i].evalFromLocation.line + 1);
  1402. result += ':' + body[i].evalFromLocation.column;
  1403. } else if (body[i].compilationType ==
  1404. Debug.ScriptCompilationType.JSON) {
  1405. result += 'JSON ';
  1406. } else { // body[i].compilation == Debug.ScriptCompilationType.Host
  1407. result += '[unnamed] ';
  1408. }
  1409. }
  1410. result += ' (lines: ';
  1411. result += body[i].lineCount;
  1412. result += ', length: ';
  1413. result += body[i].sourceLength;
  1414. if (body[i].type == Debug.ScriptType.Native) {
  1415. result += ', native';
  1416. } else if (body[i].type == Debug.ScriptType.Extension) {
  1417. result += ', extension';
  1418. }
  1419. result += '), [';
  1420. var sourceStart = body[i].sourceStart;
  1421. if (sourceStart.length > 40) {
  1422. sourceStart = sourceStart.substring(0, 37) + '...';
  1423. }

Large files files are truncated, but you can click here to view the full file