| 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 // Dart core library. | 4 // Dart core library. |
| 5 | 5 |
| 6 // VM implementation of int. | 6 // VM implementation of int. |
| 7 | 7 |
| 8 @patch class int { | 8 @patch |
| 9 | 9 class int { |
| 10 @patch const factory int.fromEnvironment(String name, | 10 @patch |
| 11 {int defaultValue}) | 11 const factory int.fromEnvironment(String name, {int defaultValue}) |
| 12 native "Integer_fromEnvironment"; | 12 native "Integer_fromEnvironment"; |
| 13 | 13 |
| 14 | |
| 15 static int _tryParseSmi(String str, int first, int last) { | 14 static int _tryParseSmi(String str, int first, int last) { |
| 16 assert(first <= last); | 15 assert(first <= last); |
| 17 var ix = first; | 16 var ix = first; |
| 18 var sign = 1; | 17 var sign = 1; |
| 19 var c = str.codeUnitAt(ix); | 18 var c = str.codeUnitAt(ix); |
| 20 // Check for leading '+' or '-'. | 19 // Check for leading '+' or '-'. |
| 21 if ((c == 0x2b) || (c == 0x2d)) { | 20 if ((c == 0x2b) || (c == 0x2d)) { |
| 22 ix++; | 21 ix++; |
| 23 sign = 0x2c - c; // -1 for '-', +1 for '+'. | 22 sign = 0x2c - c; // -1 for '-', +1 for '+'. |
| 24 if (ix > last) { | 23 if (ix > last) { |
| 25 return null; // Empty. | 24 return null; // Empty. |
| 26 } | 25 } |
| 27 } | 26 } |
| 28 var smiLimit = internal.is64Bit ? 18 : 9; | 27 var smiLimit = internal.is64Bit ? 18 : 9; |
| 29 if ((last - ix) >= smiLimit) { | 28 if ((last - ix) >= smiLimit) { |
| 30 return null; // May not fit into a Smi. | 29 return null; // May not fit into a Smi. |
| 31 } | 30 } |
| 32 var result = 0; | 31 var result = 0; |
| 33 for (int i = ix; i <= last; i++) { | 32 for (int i = ix; i <= last; i++) { |
| 34 var c = 0x30 ^ str.codeUnitAt(i); | 33 var c = 0x30 ^ str.codeUnitAt(i); |
| 35 if (9 < c) { | 34 if (9 < c) { |
| 36 return null; | 35 return null; |
| 37 } | 36 } |
| 38 result = 10 * result + c; | 37 result = 10 * result + c; |
| 39 } | 38 } |
| 40 return sign * result; | 39 return sign * result; |
| 41 } | 40 } |
| 42 | 41 |
| 43 @patch static int parse(String source, | 42 @patch |
| 44 { int radix, | 43 static int parse(String source, {int radix, int onError(String source)}) { |
| 45 int onError(String source) }) { | |
| 46 if (source == null) throw new ArgumentError("The source must not be null"); | 44 if (source == null) throw new ArgumentError("The source must not be null"); |
| 47 if (source.isEmpty) return _throwFormatException(onError, source, 0, radix); | 45 if (source.isEmpty) return _throwFormatException(onError, source, 0, radix); |
| 48 if (radix == null || radix == 10) { | 46 if (radix == null || radix == 10) { |
| 49 // Try parsing immediately, without trimming whitespace. | 47 // Try parsing immediately, without trimming whitespace. |
| 50 int result = _tryParseSmi(source, 0, source.length - 1); | 48 int result = _tryParseSmi(source, 0, source.length - 1); |
| 51 if (result != null) return result; | 49 if (result != null) return result; |
| 52 } else if (radix < 2 || radix > 36) { | 50 } else if (radix < 2 || radix > 36) { |
| 53 throw new RangeError("Radix $radix not in range 2..36"); | 51 throw new RangeError("Radix $radix not in range 2..36"); |
| 54 } | 52 } |
| 55 // Split here so improve odds of parse being inlined and the checks omitted. | 53 // Split here so improve odds of parse being inlined and the checks omitted. |
| 56 return _parse(source, radix, onError); | 54 return _parse(source, radix, onError); |
| 57 } | 55 } |
| 58 | 56 |
| 59 static int _parse(String source, int radix, onError) { | 57 static int _parse(String source, int radix, onError) { |
| 60 int end = source._lastNonWhitespace() + 1; | 58 int end = source._lastNonWhitespace() + 1; |
| 61 if (end == 0) { | 59 if (end == 0) { |
| 62 return _throwFormatException(onError, source, source.length, radix); | 60 return _throwFormatException(onError, source, source.length, radix); |
| 63 } | 61 } |
| 64 int start = source._firstNonWhitespace(); | 62 int start = source._firstNonWhitespace(); |
| 65 | 63 |
| 66 int first = source.codeUnitAt(start); | 64 int first = source.codeUnitAt(start); |
| 67 int sign = 1; | 65 int sign = 1; |
| 68 if (first == 0x2b /* + */ || first == 0x2d /* - */) { | 66 if (first == 0x2b /* + */ || first == 0x2d /* - */) { |
| 69 sign = 0x2c - first; // -1 if '-', +1 if '+'. | 67 sign = 0x2c - first; // -1 if '-', +1 if '+'. |
| 70 start++; | 68 start++; |
| 71 if (start == end) { | 69 if (start == end) { |
| 72 return _throwFormatException(onError, source, end, radix); | 70 return _throwFormatException(onError, source, end, radix); |
| 73 } | 71 } |
| 74 first = source.codeUnitAt(start); | 72 first = source.codeUnitAt(start); |
| 75 } | 73 } |
| 76 if (radix == null) { | 74 if (radix == null) { |
| 77 // check for 0x prefix. | 75 // check for 0x prefix. |
| 78 int index = start; | 76 int index = start; |
| 79 if (first == 0x30 /* 0 */) { | 77 if (first == 0x30 /* 0 */) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 102 } | 100 } |
| 103 | 101 |
| 104 static int _throwFormatException(onError, source, index, radix) { | 102 static int _throwFormatException(onError, source, index, radix) { |
| 105 if (onError != null) return onError(source); | 103 if (onError != null) return onError(source); |
| 106 if (radix == null) { | 104 if (radix == null) { |
| 107 throw new FormatException("Invalid number", source, index); | 105 throw new FormatException("Invalid number", source, index); |
| 108 } | 106 } |
| 109 throw new FormatException("Invalid radix-$radix number", source, index); | 107 throw new FormatException("Invalid radix-$radix number", source, index); |
| 110 } | 108 } |
| 111 | 109 |
| 112 static int _parseRadix(String source, int radix, | 110 static int _parseRadix( |
| 113 int start, int end, int sign) { | 111 String source, int radix, int start, int end, int sign) { |
| 114 int tableIndex = (radix - 2) * 4 + (internal.is64Bit ? 2 : 0); | 112 int tableIndex = (radix - 2) * 4 + (internal.is64Bit ? 2 : 0); |
| 115 int blockSize = _PARSE_LIMITS[tableIndex]; | 113 int blockSize = _PARSE_LIMITS[tableIndex]; |
| 116 int length = end - start; | 114 int length = end - start; |
| 117 if (length <= blockSize) { | 115 if (length <= blockSize) { |
| 118 _Smi smi = _parseBlock(source, radix, start, end); | 116 _Smi smi = _parseBlock(source, radix, start, end); |
| 119 if (smi != null) return sign * smi; | 117 if (smi != null) return sign * smi; |
| 120 return null; | 118 return null; |
| 121 } | 119 } |
| 122 | 120 |
| 123 // Often cheaper than: int smallBlockSize = length % blockSize; | 121 // Often cheaper than: int smallBlockSize = length % blockSize; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 result = radix * result + digit; | 163 result = radix * result + digit; |
| 166 } | 164 } |
| 167 } | 165 } |
| 168 return result; | 166 return result; |
| 169 } | 167 } |
| 170 | 168 |
| 171 // For each radix, 2-36, how many digits are guaranteed to fit in a smi, | 169 // For each radix, 2-36, how many digits are guaranteed to fit in a smi, |
| 172 // and magnitude of such a block (radix ** digit-count). | 170 // and magnitude of such a block (radix ** digit-count). |
| 173 // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2 | 171 // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2 |
| 174 static const _PARSE_LIMITS = const [ | 172 static const _PARSE_LIMITS = const [ |
| 175 30, 1073741824, 62, 4611686018427387904, /* radix: 2 */ | 173 30, 1073741824, 62, 4611686018427387904, // radix: 2 |
| 176 18, 387420489, 39, 4052555153018976267, | 174 18, 387420489, 39, 4052555153018976267, |
| 177 15, 1073741824, 30, 1152921504606846976, | 175 15, 1073741824, 30, 1152921504606846976, |
| 178 12, 244140625, 26, 1490116119384765625, /* radix: 5 */ | 176 12, 244140625, 26, 1490116119384765625, // radix: 5 |
| 179 11, 362797056, 23, 789730223053602816, | 177 11, 362797056, 23, 789730223053602816, |
| 180 10, 282475249, 22, 3909821048582988049, | 178 10, 282475249, 22, 3909821048582988049, |
| 181 10, 1073741824, 20, 1152921504606846976, | 179 10, 1073741824, 20, 1152921504606846976, |
| 182 9, 387420489, 19, 1350851717672992089, | 180 9, 387420489, 19, 1350851717672992089, |
| 183 9, 1000000000, 18, 1000000000000000000, /* radix: 10 */ | 181 9, 1000000000, 18, 1000000000000000000, // radix: 10 |
| 184 8, 214358881, 17, 505447028499293771, | 182 8, 214358881, 17, 505447028499293771, |
| 185 8, 429981696, 17, 2218611106740436992, | 183 8, 429981696, 17, 2218611106740436992, |
| 186 8, 815730721, 16, 665416609183179841, | 184 8, 815730721, 16, 665416609183179841, |
| 187 7, 105413504, 16, 2177953337809371136, | 185 7, 105413504, 16, 2177953337809371136, |
| 188 7, 170859375, 15, 437893890380859375, /* radix: 15 */ | 186 7, 170859375, 15, 437893890380859375, // radix: 15 |
| 189 7, 268435456, 15, 1152921504606846976, | 187 7, 268435456, 15, 1152921504606846976, |
| 190 7, 410338673, 15, 2862423051509815793, | 188 7, 410338673, 15, 2862423051509815793, |
| 191 7, 612220032, 14, 374813367582081024, | 189 7, 612220032, 14, 374813367582081024, |
| 192 7, 893871739, 14, 799006685782884121, | 190 7, 893871739, 14, 799006685782884121, |
| 193 6, 64000000, 14, 1638400000000000000, /* radix: 20 */ | 191 6, 64000000, 14, 1638400000000000000, // radix: 20 |
| 194 6, 85766121, 14, 3243919932521508681, | 192 6, 85766121, 14, 3243919932521508681, |
| 195 6, 113379904, 13, 282810057883082752, | 193 6, 113379904, 13, 282810057883082752, |
| 196 6, 148035889, 13, 504036361936467383, | 194 6, 148035889, 13, 504036361936467383, |
| 197 6, 191102976, 13, 876488338465357824, | 195 6, 191102976, 13, 876488338465357824, |
| 198 6, 244140625, 13, 1490116119384765625, /* radix: 25 */ | 196 6, 244140625, 13, 1490116119384765625, // radix: 25 |
| 199 6, 308915776, 13, 2481152873203736576, | 197 6, 308915776, 13, 2481152873203736576, |
| 200 6, 387420489, 13, 4052555153018976267, | 198 6, 387420489, 13, 4052555153018976267, |
| 201 6, 481890304, 12, 232218265089212416, | 199 6, 481890304, 12, 232218265089212416, |
| 202 6, 594823321, 12, 353814783205469041, | 200 6, 594823321, 12, 353814783205469041, |
| 203 6, 729000000, 12, 531441000000000000, /* radix: 30 */ | 201 6, 729000000, 12, 531441000000000000, // radix: 30 |
| 204 6, 887503681, 12, 787662783788549761, | 202 6, 887503681, 12, 787662783788549761, |
| 205 6, 1073741824, 12, 1152921504606846976, | 203 6, 1073741824, 12, 1152921504606846976, |
| 206 5, 39135393, 12, 1667889514952984961, | 204 5, 39135393, 12, 1667889514952984961, |
| 207 5, 45435424, 12, 2386420683693101056, | 205 5, 45435424, 12, 2386420683693101056, |
| 208 5, 52521875, 12, 3379220508056640625, /* radix: 35 */ | 206 5, 52521875, 12, 3379220508056640625, // radix: 35 |
| 209 5, 60466176, 11, 131621703842267136, | 207 5, 60466176, 11, 131621703842267136, |
| 210 ]; | 208 ]; |
| 211 } | 209 } |
| OLD | NEW |