| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Simple interactive debugger shell that connects to the Dart VM's debugger | 5 // Simple interactive debugger shell that connects to the Dart VM's debugger |
| 6 // connection port. | 6 // connection port. |
| 7 | 7 |
| 8 #import("dart:io"); | 8 #import("dart:io"); |
| 9 #import("dart:json"); | 9 #import("dart:json"); |
| 10 #import("dart:math", prefix: "Math"); | 10 #import("dart:math", prefix: "Math"); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 } | 405 } |
| 406 | 406 |
| 407 | 407 |
| 408 void processVmData(String data) { | 408 void processVmData(String data) { |
| 409 final printMessages = false; | 409 final printMessages = false; |
| 410 if (vmData == null || vmData.length == 0) { | 410 if (vmData == null || vmData.length == 0) { |
| 411 vmData = data; | 411 vmData = data; |
| 412 } else { | 412 } else { |
| 413 vmData = vmData.concat(data); | 413 vmData = vmData.concat(data); |
| 414 } | 414 } |
| 415 int msg_len = JSON.length(vmData); | 415 int msg_len = jsonObjectLength(vmData); |
| 416 if (printMessages && msg_len == 0) { | 416 if (printMessages && msg_len == 0) { |
| 417 print("have partial or illegal json message" | 417 print("have partial or illegal json message" |
| 418 " of ${vmData.length} chars:\n'$vmData'"); | 418 " of ${vmData.length} chars:\n'$vmData'"); |
| 419 return; | 419 return; |
| 420 } | 420 } |
| 421 while (msg_len > 0 && msg_len <= vmData.length) { | 421 while (msg_len > 0 && msg_len <= vmData.length) { |
| 422 if (msg_len == vmData.length) { | 422 if (msg_len == vmData.length) { |
| 423 if (printMessages) { print("have one full message:\n$vmData"); } | 423 if (printMessages) { print("have one full message:\n$vmData"); } |
| 424 processVmMessage(vmData); | 424 processVmMessage(vmData); |
| 425 vmData = null; | 425 vmData = null; |
| 426 return; | 426 return; |
| 427 } | 427 } |
| 428 if (printMessages) { print("at least one message: '$vmData'"); } | 428 if (printMessages) { print("at least one message: '$vmData'"); } |
| 429 var msg = vmData.substring(0, msg_len); | 429 var msg = vmData.substring(0, msg_len); |
| 430 if (printMessages) { print("first message: $msg"); } | 430 if (printMessages) { print("first message: $msg"); } |
| 431 processVmMessage(msg); | 431 processVmMessage(msg); |
| 432 vmData = vmData.substring(msg_len); | 432 vmData = vmData.substring(msg_len); |
| 433 msg_len = JSON.length(vmData); | 433 msg_len = jsonObjectLength(vmData); |
| 434 } | 434 } |
| 435 if (printMessages) { print("leftover vm data '$vmData'"); } | 435 if (printMessages) { print("leftover vm data '$vmData'"); } |
| 436 } | 436 } |
| 437 | 437 |
| 438 /** |
| 439 * Skip past a JSON object value. |
| 440 * The object value must start with '{' and continues to the |
| 441 * matching '}'. No attempt is made to otherwise validate the contents |
| 442 * as JSON. If it is invalid, a later [JSON.parse] will fail. |
| 443 */ |
| 444 int jsonObjectLength(String string) { |
| 445 int skipWhitespace(int index) { |
| 446 while (index < string.length) { |
| 447 String char = string[index]; |
| 448 if (char != " " && char != "\n" && char != "\r" && char != "\t") break; |
| 449 index++; |
| 450 } |
| 451 return index; |
| 452 } |
| 453 int skipString(int index) { |
| 454 assert(string[index - 1] == '"'); |
| 455 while (index < string.length) { |
| 456 String char = string[index]; |
| 457 if (char == '"') return index + 1; |
| 458 if (char == @'\') index++; |
| 459 if (index == string.length) return index; |
| 460 index++; |
| 461 } |
| 462 return index; |
| 463 } |
| 464 int index = 0; |
| 465 index = skipWhitespace(index); |
| 466 // Bail out if the first non-whitespace character isn't '{'. |
| 467 if (index == string.length || string[index] != '{') return 0; |
| 468 int nexting = 0; |
| 469 while (index < string.length) { |
| 470 String char = string[index++]; |
| 471 if (char == '{') { |
| 472 nexting++; |
| 473 } else if (char == '}') { |
| 474 nexting--; |
| 475 if (nexting == 0) return index; |
| 476 } else if (char == '"') { |
| 477 // Strings can contain braces. Skip their content. |
| 478 index = skipString(index); |
| 479 } |
| 480 } |
| 481 return 0; |
| 482 } |
| 483 |
| 438 | 484 |
| 439 void main() { | 485 void main() { |
| 440 outstandingCommands = new Map<int, Completer>(); | 486 outstandingCommands = new Map<int, Completer>(); |
| 441 vmSock = new Socket("127.0.0.1", 5858); | 487 vmSock = new Socket("127.0.0.1", 5858); |
| 442 vmStream = new SocketOutputStream(vmSock); | 488 vmStream = new SocketOutputStream(vmSock); |
| 443 var stdinStream = new StringInputStream(stdin); | 489 var stdinStream = new StringInputStream(stdin); |
| 444 stdinStream.onLine = () { | 490 stdinStream.onLine = () { |
| 445 processCommand(stdinStream.readLine()); | 491 processCommand(stdinStream.readLine()); |
| 446 }; | 492 }; |
| 447 var vmInStream = new SocketInputStream(vmSock); | 493 var vmInStream = new SocketInputStream(vmSock); |
| 448 vmInStream.onData = () { | 494 vmInStream.onData = () { |
| 449 String s = decodeUtf8(vmInStream.read()); | 495 String s = decodeUtf8(vmInStream.read()); |
| 450 processVmData(s); | 496 processVmData(s); |
| 451 }; | 497 }; |
| 452 vmInStream.onError = (err) { | 498 vmInStream.onError = (err) { |
| 453 print("Error in debug connection: $err"); | 499 print("Error in debug connection: $err"); |
| 454 quitShell(); | 500 quitShell(); |
| 455 }; | 501 }; |
| 456 vmInStream.onClosed = () { | 502 vmInStream.onClosed = () { |
| 457 print("VM debugger connection closed"); | 503 print("VM debugger connection closed"); |
| 458 quitShell(); | 504 quitShell(); |
| 459 }; | 505 }; |
| 460 } | 506 } |
| OLD | NEW |