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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/lib/convert_patch.dart
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index 93da46140cb3fac8b3477af430d4d278bd61a3d0..c3e14c757e80e45452a6693cca779df41bc1216b 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -391,21 +391,26 @@ class _JsonParser {
// Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
// Initial position is right after first '"'.
int start = position;
- int char;
- do {
- if (position == source.length) {
- fail(start - 1, "Unterminated string");
- }
- char = source.codeUnitAt(position);
- if (char == QUOTE) {
- listener.handleString(source.substring(start, position));
- return position + 1;
- }
- if (char < SPACE) {
- fail(position, "Control character in string");
+ while (position < source.length) {
+ int char = source.codeUnitAt(position);
+ 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
+ if (char == BACKSLASH) {
+ return parseStringWithEscapes(start, position);
+ }
+ if (char == QUOTE) {
+ listener.handleString(source.substring(start, position));
+ return position + 1;
+ }
+ if (char < SPACE) {
+ fail(position, "Control character in string");
+ }
}
position++;
- } while (char != BACKSLASH);
+ }
+ fail(start - 1, "Unterminated string");
+ }
+
+ 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.
// Backslash escape detected. Collect character codes for rest of string.
int firstEscape = position - 1;
List<int> chars = <int>[];
@@ -472,74 +477,84 @@ class _JsonParser {
}
}
- int _handleLiteral(start, position, isDouble) {
- String literal = source.substring(start, position);
- // This correctly creates -0 for doubles.
- num value = (isDouble ? double.parse(literal) : int.parse(literal));
- listener.handleNumber(value);
- return position;
- }
-
int parseNumber(int char, int position) {
// Format:
// '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
int start = position;
int length = source.length;
+ int intValue = 0; // Collect int value while parsing.
+ int intSign = 1;
bool isDouble = false;
- if (char == MINUS) {
- position++;
- if (position == length) fail(position, "Missing expected digit");
- char = source.codeUnitAt(position);
- }
- if (char < CHAR_0 || char > CHAR_9) {
- fail(position, "Missing expected digit");
- }
- if (char == CHAR_0) {
- position++;
- if (position == length) return _handleLiteral(start, position, false);
- char = source.codeUnitAt(position);
- if (CHAR_0 <= char && char <= CHAR_9) {
- fail(position);
- }
- } else {
- do {
+ // Break this block when the end of the number literal is reached.
+ // At that time, position points to the next character, and isDouble
+ // is set if the literal contains a decimal point or an exponential.
+ parsing: {
+ if (char == MINUS) {
+ intSign = -1;
position++;
- if (position == length) return _handleLiteral(start, position, false);
+ if (position == length) fail(position, "Missing expected digit");
char = source.codeUnitAt(position);
- } while (CHAR_0 <= char && char <= CHAR_9);
- }
- if (char == DECIMALPOINT) {
- isDouble = true;
- position++;
- if (position == length) fail(position, "Missing expected digit");
- char = source.codeUnitAt(position);
- if (char < CHAR_0 || char > CHAR_9) fail(position);
- do {
+ }
+ if (char < CHAR_0 || char > CHAR_9) {
+ fail(position, "Missing expected digit");
+ }
+ if (char == CHAR_0) {
position++;
- if (position == length) return _handleLiteral(start, position, true);
+ if (position == length) break parsing;
char = source.codeUnitAt(position);
- } while (CHAR_0 <= char && char <= CHAR_9);
- }
- if (char == CHAR_e || char == CHAR_E) {
- isDouble = true;
- position++;
- if (position == length) fail(position, "Missing expected digit");
- char = source.codeUnitAt(position);
- if (char == PLUS || char == MINUS) {
+ if (CHAR_0 <= char && char <= CHAR_9) {
+ fail(position);
+ }
+ } else {
+ do {
+ intValue = intValue * 10 + (char - CHAR_0);
+ position++;
+ if (position == length) break parsing;
+ char = source.codeUnitAt(position);
+ } while (CHAR_0 <= char && char <= CHAR_9);
+ }
+ if (char == DECIMALPOINT) {
+ isDouble = true;
position++;
if (position == length) fail(position, "Missing expected digit");
char = source.codeUnitAt(position);
+ if (char < CHAR_0 || char > CHAR_9) fail(position);
+ do {
+ position++;
+ if (position == length) break parsing;
+ char = source.codeUnitAt(position);
+ } while (CHAR_0 <= char && char <= CHAR_9);
}
- if (char < CHAR_0 || char > CHAR_9) {
- fail(position, "Missing expected digit");
- }
- do {
+ if (char == CHAR_e || char == CHAR_E) {
+ isDouble = true;
position++;
- if (position == length) return _handleLiteral(start, position, true);
+ if (position == length) fail(position, "Missing expected digit");
char = source.codeUnitAt(position);
- } while (CHAR_0 <= char && char <= CHAR_9);
+ if (char == PLUS || char == MINUS) {
+ position++;
+ if (position == length) fail(position, "Missing expected digit");
+ char = source.codeUnitAt(position);
+ }
+ if (char < CHAR_0 || char > CHAR_9) {
+ fail(position, "Missing expected digit");
+ }
+ do {
+ position++;
+ if (position == length) break parsing;
+ char = source.codeUnitAt(position);
+ } while (CHAR_0 <= char && char <= CHAR_9);
+ }
}
- return _handleLiteral(start, position, isDouble);
+ if (!isDouble) {
+ listener.handleNumber(intSign * intValue);
+ return position;
+ }
+ // Consider whether we can have an int/double.parse that works on part of
+ // a string, to avoid creating the substring.
+ String literal = source.substring(start, position);
+ // This correctly creates -0.0 for doubles.
+ 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
+ return position;
}
void fail(int position, [String message]) {
« 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