Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: runtime/lib/convert_patch.dart

Issue 183193002: Optimize VM parsing of JSON String and number literals. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: One more part extracted. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 import "dart:typed_data"; 5 import "dart:typed_data";
6 6
7 // JSON conversion. 7 // JSON conversion.
8 8
9 patch _parseJson(String json, reviver(var key, var value)) { 9 patch _parseJson(String json, reviver(var key, var value)) {
10 _BuildJsonListener listener; 10 _BuildJsonListener listener;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 fail(position); 384 fail(position);
385 } 385 }
386 listener.handleNull(); 386 listener.handleNull();
387 return position + 4; 387 return position + 4;
388 } 388 }
389 389
390 int parseString(int position) { 390 int parseString(int position) {
391 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' 391 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
392 // Initial position is right after first '"'. 392 // Initial position is right after first '"'.
393 int start = position; 393 int start = position;
394 int char; 394 while (position < source.length) {
395 do { 395 int char = source.codeUnitAt(position);
396 if (position == source.length) { 396 if (char <= BACKSLASH) { // BACKSLASH is larger than QUOTE.
Søren Gjesse 2014/03/24 08:33:57 and SPACE :-)
Lasse Reichstein Nielsen 2014/03/24 12:13:49 SPACE is *obviously* smaller than anything :) But
397 fail(start - 1, "Unterminated string"); 397 if (char == BACKSLASH) {
398 } 398 return parseStringWithEscapes(start, position);
399 char = source.codeUnitAt(position); 399 }
400 if (char == QUOTE) { 400 if (char == QUOTE) {
401 listener.handleString(source.substring(start, position)); 401 listener.handleString(source.substring(start, position));
402 return position + 1; 402 return position + 1;
403 } 403 }
404 if (char < SPACE) { 404 if (char < SPACE) {
405 fail(position, "Control character in string"); 405 fail(position, "Control character in string");
406 }
406 } 407 }
407 position++; 408 position++;
408 } while (char != BACKSLASH); 409 }
410 fail(start - 1, "Unterminated string");
411 }
412
413 int parseStringWithEscapes(string, position) {
Lasse Reichstein Nielsen 2014/03/07 10:40:27 string -> start.
Lasse Reichstein Nielsen 2014/03/24 08:30:54 string -> source even.
409 // Backslash escape detected. Collect character codes for rest of string. 414 // Backslash escape detected. Collect character codes for rest of string.
410 int firstEscape = position - 1; 415 int firstEscape = position - 1;
411 List<int> chars = <int>[]; 416 List<int> chars = <int>[];
412 while (true) { 417 while (true) {
413 if (position == source.length) { 418 if (position == source.length) {
414 fail(start - 1, "Unterminated string"); 419 fail(start - 1, "Unterminated string");
415 } 420 }
416 char = source.codeUnitAt(position); 421 char = source.codeUnitAt(position);
417 switch (char) { 422 switch (char) {
418 case CHAR_b: char = BACKSPACE; break; 423 case CHAR_b: char = BACKSPACE; break;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 return position + 1; 470 return position + 1;
466 } 471 }
467 if (char < SPACE) { 472 if (char < SPACE) {
468 fail(position, "Control character in string"); 473 fail(position, "Control character in string");
469 } 474 }
470 } while (char != BACKSLASH); 475 } while (char != BACKSLASH);
471 position++; 476 position++;
472 } 477 }
473 } 478 }
474 479
475 int _handleLiteral(start, position, isDouble) {
476 String literal = source.substring(start, position);
477 // This correctly creates -0 for doubles.
478 num value = (isDouble ? double.parse(literal) : int.parse(literal));
479 listener.handleNumber(value);
480 return position;
481 }
482
483 int parseNumber(int char, int position) { 480 int parseNumber(int char, int position) {
484 // Format: 481 // Format:
485 // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)? 482 // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
486 int start = position; 483 int start = position;
487 int length = source.length; 484 int length = source.length;
485 int intValue = 0; // Collect int value while parsing.
486 int intSign = 1;
488 bool isDouble = false; 487 bool isDouble = false;
489 if (char == MINUS) { 488 // Break this block when the end of the number literal is reached.
490 position++; 489 // At that time, position points to the next character, and isDouble
491 if (position == length) fail(position, "Missing expected digit"); 490 // is set if the literal contains a decimal point or an exponential.
492 char = source.codeUnitAt(position); 491 parsing: {
493 } 492 if (char == MINUS) {
494 if (char < CHAR_0 || char > CHAR_9) { 493 intSign = -1;
495 fail(position, "Missing expected digit");
496 }
497 if (char == CHAR_0) {
498 position++;
499 if (position == length) return _handleLiteral(start, position, false);
500 char = source.codeUnitAt(position);
501 if (CHAR_0 <= char && char <= CHAR_9) {
502 fail(position);
503 }
504 } else {
505 do {
506 position++;
507 if (position == length) return _handleLiteral(start, position, false);
508 char = source.codeUnitAt(position);
509 } while (CHAR_0 <= char && char <= CHAR_9);
510 }
511 if (char == DECIMALPOINT) {
512 isDouble = true;
513 position++;
514 if (position == length) fail(position, "Missing expected digit");
515 char = source.codeUnitAt(position);
516 if (char < CHAR_0 || char > CHAR_9) fail(position);
517 do {
518 position++;
519 if (position == length) return _handleLiteral(start, position, true);
520 char = source.codeUnitAt(position);
521 } while (CHAR_0 <= char && char <= CHAR_9);
522 }
523 if (char == CHAR_e || char == CHAR_E) {
524 isDouble = true;
525 position++;
526 if (position == length) fail(position, "Missing expected digit");
527 char = source.codeUnitAt(position);
528 if (char == PLUS || char == MINUS) {
529 position++; 494 position++;
530 if (position == length) fail(position, "Missing expected digit"); 495 if (position == length) fail(position, "Missing expected digit");
531 char = source.codeUnitAt(position); 496 char = source.codeUnitAt(position);
532 } 497 }
533 if (char < CHAR_0 || char > CHAR_9) { 498 if (char < CHAR_0 || char > CHAR_9) {
534 fail(position, "Missing expected digit"); 499 fail(position, "Missing expected digit");
535 } 500 }
536 do { 501 if (char == CHAR_0) {
537 position++; 502 position++;
538 if (position == length) return _handleLiteral(start, position, true); 503 if (position == length) break parsing;
539 char = source.codeUnitAt(position); 504 char = source.codeUnitAt(position);
540 } while (CHAR_0 <= char && char <= CHAR_9); 505 if (CHAR_0 <= char && char <= CHAR_9) {
506 fail(position);
507 }
508 } else {
509 do {
510 intValue = intValue * 10 + (char - CHAR_0);
511 position++;
512 if (position == length) break parsing;
513 char = source.codeUnitAt(position);
514 } while (CHAR_0 <= char && char <= CHAR_9);
515 }
516 if (char == DECIMALPOINT) {
517 isDouble = true;
518 position++;
519 if (position == length) fail(position, "Missing expected digit");
520 char = source.codeUnitAt(position);
521 if (char < CHAR_0 || char > CHAR_9) fail(position);
522 do {
523 position++;
524 if (position == length) break parsing;
525 char = source.codeUnitAt(position);
526 } while (CHAR_0 <= char && char <= CHAR_9);
527 }
528 if (char == CHAR_e || char == CHAR_E) {
529 isDouble = true;
530 position++;
531 if (position == length) fail(position, "Missing expected digit");
532 char = source.codeUnitAt(position);
533 if (char == PLUS || char == MINUS) {
534 position++;
535 if (position == length) fail(position, "Missing expected digit");
536 char = source.codeUnitAt(position);
537 }
538 if (char < CHAR_0 || char > CHAR_9) {
539 fail(position, "Missing expected digit");
540 }
541 do {
542 position++;
543 if (position == length) break parsing;
544 char = source.codeUnitAt(position);
545 } while (CHAR_0 <= char && char <= CHAR_9);
546 }
541 } 547 }
542 return _handleLiteral(start, position, isDouble); 548 if (!isDouble) {
549 listener.handleNumber(intSign * intValue);
550 return position;
551 }
552 // Consider whether we can have an int/double.parse that works on part of
553 // a string, to avoid creating the substring.
554 String literal = source.substring(start, position);
555 // This correctly creates -0.0 for doubles.
556 listener.handleNumber(double.parse(literal));
Søren Gjesse 2014/03/24 08:33:57 There is no simpler way to create the double now y
Lasse Reichstein Nielsen 2014/03/24 12:13:49 In simple cases, there probably is. Parsing a doub
557 return position;
543 } 558 }
544 559
545 void fail(int position, [String message]) { 560 void fail(int position, [String message]) {
546 if (message == null) message = "Unexpected character"; 561 if (message == null) message = "Unexpected character";
547 listener.fail(source, position, message); 562 listener.fail(source, position, message);
548 // If the listener didn't throw, do it here. 563 // If the listener didn't throw, do it here.
549 String slice; 564 String slice;
550 int sliceEnd = position + 20; 565 int sliceEnd = position + 20;
551 if (sliceEnd > source.length) { 566 if (sliceEnd > source.length) {
552 slice = "'${source.substring(position)}'"; 567 slice = "'${source.substring(position)}'";
553 } else { 568 } else {
554 slice = "'${source.substring(position, sliceEnd)}...'"; 569 slice = "'${source.substring(position, sliceEnd)}...'";
555 } 570 }
556 throw new FormatException("Unexpected character at $position: $slice"); 571 throw new FormatException("Unexpected character at $position: $slice");
557 } 572 }
558 } 573 }
559 574
560 // UTF-8 conversion. 575 // UTF-8 conversion.
561 576
562 patch class _Utf8Encoder { 577 patch class _Utf8Encoder {
563 /* patch */ static List<int> _createBuffer(int size) => new Uint8List(size); 578 /* patch */ static List<int> _createBuffer(int size) => new Uint8List(size);
564 } 579 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698