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

Unified Diff: sdk/lib/_internal/compiler/implementation/lib/js_helper.dart

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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
Index: sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 39e1c5c8f651b7254d2ac1d00b522d3925ff7525..fb7d66d84798eb3f5c4e20cc2409af6d10d53a32 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -339,19 +339,6 @@ String S(value) {
return res;
}
-class ListIterator<T> implements Iterator<T> {
- int i;
- List<T> list;
- ListIterator(List<T> this.list) : i = 0;
- bool get hasNext => i < JS('int', r'#.length', list);
- T next() {
- if (!hasNext) throw new StateError("No more elements");
- var value = JS('', r'#[#]', list, i);
- i += 1;
- return value;
- }
-}
-
createInvocationMirror(name, internalName, type, arguments, argumentNames) =>
new JSInvocationMirror(name, internalName, type, arguments, argumentNames);
@@ -461,37 +448,97 @@ class Primitives {
JS('void', "throw 'Unable to print message: ' + String(#)", string);
}
- static int parseInt(String string) {
- checkString(string);
+ static void _throwFormatException(String string) {
+ throw new FormatException(string);
+ }
+
+ static int parseInt(String source,
+ int radix,
+ int handleError(String source)) {
+ if (handleError == null) handleError = _throwFormatException;
+
+ checkString(source);
var match = JS('=List|Null',
- r'/^\s*[+-]?(?:0(x)[a-f0-9]+|\d+)\s*$/i.exec(#)',
- string);
- if (match == null) {
- throw new FormatException(string);
+ r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(#)',
+ source);
+ int digitsIndex = 1;
+ int hexIndex = 2;
+ int decimalIndex = 3;
+ int nonDecimalHexIndex = 4;
+ if (radix == null) {
+ radix = 10;
+ if (match != null) {
+ if (match[hexIndex] != null) {
+ // Cannot fail because we know that the digits are all hex.
+ return JS('num', r'parseInt(#, 16)', source);
+ }
+ if (match[decimalIndex] != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return JS('num', r'parseInt(#, 10)', source);
+ }
+ return handleError(source);
+ }
+ } else {
+ if (radix is! int) throw new ArgumentError("Radix is not an integer");
+ if (radix < 2 || radix > 36) {
+ throw new RangeError("Radix $radix not in range 2..36");
+ }
+ if (match != null) {
+ if (radix == 10 && match[decimalIndex] != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return JS('num', r'parseInt(#, 10)', source);
+ }
+ if (radix < 10 || match[decimalIndex] == null) {
+ // We know that the characters must be ASCII as otherwise the
+ // regexp wouldn't have matched. Calling toLowerCase is thus
+ // guaranteed to be a safe operation. If it wasn't ASCII, then
+ // "İ" would become "i", and we would accept it for radices greater
+ // than 18.
+ int maxCharCode;
+ if (radix <= 10) {
+ // Allow all digits less than the radix. For example 0, 1, 2 for
+ // radix 3.
+ // "0".charCodeAt(0) + radix - 1;
+ maxCharCode = 0x30 + radix - 1;
+ } else {
+ // Characters are located after the digits in ASCII. Therefore we
+ // only check for the character code. The regexp above made already
+ // sure that the string does not contain anything but digits or
+ // characters.
+ // "0".charCodeAt(0) + radix - 1;
+ maxCharCode = 0x61 + radix - 10 - 1;
+ }
+ String digitsPart = match[digitsIndex].toLowerCase();
+ for (int i = 0; i < digitsPart.length; i++) {
+ if (digitsPart.charCodeAt(i) > maxCharCode) {
+ return handleError(source);
+ }
+ }
+ }
+ }
}
- var base = 10;
- if (match[1] != null) base = 16;
- var result = JS('num', r'parseInt(#, #)', string, base);
- if (result.isNaN) throw new FormatException(string);
- return result;
+ if (match == null) return handleError(source);
+ return JS('num', r'parseInt(#, #)', source, radix);
}
- static double parseDouble(String string) {
- checkString(string);
+ static double parseDouble(String source, int handleError(String source)) {
+ checkString(source);
+ if (handleError == null) handleError = _throwFormatException;
// Notice that JS parseFloat accepts garbage at the end of the string.
- // Accept, ignoring leading and trailing whitespace:
+ // Accept only:
// - NaN
// - [+/-]Infinity
- // - a Dart double literal
+ // - a Dart double literal
+ // We do not allow leading or trailing whitespace.
if (!JS('bool',
r'/^\s*(?:NaN|[+-]?(?:Infinity|'
r'(?:\.\d+|\d+(?:\.\d+)?)(?:[eE][+-]?\d+)?))\s*$/.test(#)',
- string)) {
- throw new FormatException(string);
+ source)) {
+ return handleError(source);
}
- var result = JS('num', r'parseFloat(#)', string);
- if (result.isNaN && string != 'NaN') {
- throw new FormatException(string);
+ var result = JS('num', r'parseFloat(#)', source);
+ if (result.isNaN && source != 'NaN') {
+ return handleError(source);
}
return result;
}
@@ -520,14 +567,17 @@ class Primitives {
return "Instance of '$name'";
}
- static List newList(length) {
+ static List newGrowableList(length) {
+ // TODO(sra): For good concrete type analysis we need the JS-type to
+ // specifically name the JavaScript Array implementation. 'List' matches
+ // all the dart:html types that implement List<T>.
+ return JS('Object', r'new Array(#)', length);
+ }
+
+ static List newFixedList(length) {
// TODO(sra): For good concrete type analysis we need the JS-type to
// specifically name the JavaScript Array implementation. 'List' matches
// all the dart:html types that implement List<T>.
- if (length == null) return JS('=List', r'new Array()');
- if ((length is !int) || (length < 0)) {
- throw new ArgumentError(length);
- }
var result = JS('=List', r'new Array(#)', length);
JS('void', r'#.fixed$length = #', result, true);
return result;
@@ -855,37 +905,6 @@ checkString(value) {
}
class MathNatives {
- static int parseInt(str) {
- checkString(str);
- if (!JS('bool',
- r'/^\s*[+-]?(?:0[xX][abcdefABCDEF0-9]+|\d+)\s*$/.test(#)',
- str)) {
- throw new FormatException(str);
- }
- var trimmed = str.trim();
- var base = 10;;
- if ((trimmed.length > 2 && (trimmed[1] == 'x' || trimmed[1] == 'X')) ||
- (trimmed.length > 3 && (trimmed[2] == 'x' || trimmed[2] == 'X'))) {
- base = 16;
- }
- var ret = JS('num', r'parseInt(#, #)', trimmed, base);
- if (ret.isNaN) throw new FormatException(str);
- return ret;
- }
-
- static double parseDouble(String str) {
- checkString(str);
- var ret = JS('num', r'parseFloat(#)', str);
- if (ret == 0 && (str.startsWith("0x") || str.startsWith("0X"))) {
- // TODO(ahe): This is unspecified, but tested by co19.
- ret = JS('num', r'parseInt(#)', str);
- }
- if (ret.isNaN && str != 'NaN' && str != '-NaN') {
- throw new FormatException(str);
- }
- return ret;
- }
-
static double sqrt(num value)
=> JS('double', r'Math.sqrt(#)', checkNum(value));
@@ -1084,11 +1103,12 @@ class StackTrace {
* a list of key, value, key, value, ..., etc.
*/
makeLiteralMap(List keyValuePairs) {
- Iterator iterator = keyValuePairs.iterator();
+ Iterator iterator = keyValuePairs.iterator;
Map result = new LinkedHashMap();
- while (iterator.hasNext) {
- String key = iterator.next();
- var value = iterator.next();
+ while (iterator.moveNext()) {
+ String key = iterator.current;
+ iterator.moveNext();
+ var value = iterator.current;
result[key] = value;
}
return result;

Powered by Google App Engine
This is Rietveld 408576698