OLD | NEW |
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 library _js_helper; | 5 library _js_helper; |
6 | 6 |
7 import 'dart:_async_await_error_codes' as async_error_codes; | 7 import 'dart:_async_await_error_codes' as async_error_codes; |
8 | 8 |
9 import 'dart:_js_embedded_names' show | 9 import 'dart:_js_embedded_names' show |
10 DEFERRED_LIBRARY_URIS, | 10 DEFERRED_LIBRARY_URIS, |
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 static void update(cache, String key, value) { | 1381 static void update(cache, String key, value) { |
1382 JS('void', '#[#] = #', cache, key, value); | 1382 JS('void', '#[#] = #', cache, key, value); |
1383 } | 1383 } |
1384 } | 1384 } |
1385 | 1385 |
1386 /** | 1386 /** |
1387 * Called by generated code to throw an illegal-argument exception, | 1387 * Called by generated code to throw an illegal-argument exception, |
1388 * for example, if a non-integer index is given to an optimized | 1388 * for example, if a non-integer index is given to an optimized |
1389 * indexed access. | 1389 * indexed access. |
1390 */ | 1390 */ |
1391 @NoInline() | |
1392 iae(argument) { | 1391 iae(argument) { |
1393 throw _argumentError(argument); | 1392 throw _argumentError(argument); |
1394 } | 1393 } |
1395 | 1394 |
1396 /** | 1395 /** |
1397 * Called by generated code to throw an index-out-of-range exception, for | 1396 * Called by generated code to throw an index-out-of-range exception, |
1398 * example, if a bounds check fails in an optimized indexed access. This may | 1397 * for example, if a bounds check fails in an optimized indexed |
1399 * also be called when the index is not an integer, in which case it throws an | 1398 * access. This may also be called when the index is not an integer, in |
1400 * illegal-argument exception instead, like [iae], or when the receiver is null. | 1399 * which case it throws an illegal-argument exception instead, like |
| 1400 * [iae], or when the receiver is null. |
1401 */ | 1401 */ |
1402 @NoInline() | |
1403 ioore(receiver, index) { | 1402 ioore(receiver, index) { |
1404 if (receiver == null) receiver.length; // Force a NoSuchMethodError. | 1403 if (receiver == null) receiver.length; // Force a NoSuchMethodError. |
1405 throw diagnoseIndexError(receiver, index); | 1404 if (index is !int) iae(index); |
| 1405 throw new RangeError.value(index); |
1406 } | 1406 } |
1407 | 1407 |
1408 /** | |
1409 * Diagnoses an indexing error. Returns the ArgumentError or RangeError that | |
1410 * describes the problem. | |
1411 */ | |
1412 @NoInline() | |
1413 Error diagnoseIndexError(indexable, index) { | |
1414 if (index is !int) return new ArgumentError.value(index, 'index'); | |
1415 int length = indexable.length; | |
1416 // The following returns the same error that would be thrown by calling | |
1417 // [RangeError.checkValidIndex] with no optional parameters provided. | |
1418 if (index < 0 || index >= length) { | |
1419 return new RangeError.index(index, indexable, 'index', null, length); | |
1420 } | |
1421 // The above should always match, but if it does not, use the following. | |
1422 return new RangeError.value(index, 'index'); | |
1423 } | |
1424 | |
1425 | |
1426 stringLastIndexOfUnchecked(receiver, element, start) | 1408 stringLastIndexOfUnchecked(receiver, element, start) |
1427 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); | 1409 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); |
1428 | 1410 |
1429 | 1411 |
1430 /// 'factory' for constructing ArgumentError.value to keep the call sites small. | 1412 /// 'factory' for constructing ArgumentError.value to keep the call sites small. |
1431 @NoInline() | 1413 @NoInline() |
1432 ArgumentError _argumentError(object) { | 1414 ArgumentError _argumentError(object) { |
1433 return new ArgumentError.value(object); | 1415 return new ArgumentError.value(object); |
1434 } | 1416 } |
1435 | 1417 |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2026 // nothing. | 2008 // nothing. |
2027 return saveStackTrace( | 2009 return saveStackTrace( |
2028 new UnknownJsTypeError(message is String ? message : '')); | 2010 new UnknownJsTypeError(message is String ? message : '')); |
2029 } | 2011 } |
2030 | 2012 |
2031 if (JS('bool', r'# instanceof RangeError', ex)) { | 2013 if (JS('bool', r'# instanceof RangeError', ex)) { |
2032 if (message is String && contains(message, 'call stack')) { | 2014 if (message is String && contains(message, 'call stack')) { |
2033 return new StackOverflowError(); | 2015 return new StackOverflowError(); |
2034 } | 2016 } |
2035 | 2017 |
2036 // In general, a RangeError is thrown when trying to pass a number as an | 2018 // In general, a RangeError is thrown when trying to pass a number |
2037 // argument to a function that does not allow a range that includes that | 2019 // as an argument to a function that does not allow a range that |
2038 // number. Translate to a Dart RangeError with the same message. | 2020 // includes that number. |
2039 String message = tryStringifyException(ex); | 2021 return saveStackTrace(new ArgumentError()); |
2040 if (message is String) { | |
2041 message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message); | |
2042 } | |
2043 return saveStackTrace(new RangeError(message)); | |
2044 } | 2022 } |
2045 | 2023 |
2046 // Check for the Firefox specific stack overflow signal. | 2024 // Check for the Firefox specific stack overflow signal. |
2047 if (JS('bool', | 2025 if (JS('bool', |
2048 r'typeof InternalError == "function" && # instanceof InternalError', | 2026 r'typeof InternalError == "function" && # instanceof InternalError', |
2049 ex)) { | 2027 ex)) { |
2050 if (message is String && message == 'too much recursion') { | 2028 if (message is String && message == 'too much recursion') { |
2051 return new StackOverflowError(); | 2029 return new StackOverflowError(); |
2052 } | 2030 } |
2053 } | 2031 } |
2054 | 2032 |
2055 // Just return the exception. We should not wrap it because in case | 2033 // Just return the exception. We should not wrap it because in case |
2056 // the exception comes from the DOM, it is a JavaScript | 2034 // the exception comes from the DOM, it is a JavaScript |
2057 // object backed by a native Dart class. | 2035 // object backed by a native Dart class. |
2058 return ex; | 2036 return ex; |
2059 } | 2037 } |
2060 | 2038 |
2061 String tryStringifyException(ex) { | |
2062 // Since this function is called from [unwrapException] which is called from | |
2063 // code injected into a catch-clause, use JavaScript try-catch to avoid a | |
2064 // potential loop if stringifying crashes. | |
2065 return JS('String', r''' | |
2066 (function(ex) { | |
2067 try { | |
2068 return String(ex); | |
2069 } catch (e) {} | |
2070 return null; | |
2071 })(#) | |
2072 ''', ex); | |
2073 } | |
2074 | |
2075 /** | 2039 /** |
2076 * Called by generated code to fetch the stack trace from an | 2040 * Called by generated code to fetch the stack trace from an |
2077 * exception. Should never return null. | 2041 * exception. Should never return null. |
2078 */ | 2042 */ |
2079 StackTrace getTraceFromException(exception) { | 2043 StackTrace getTraceFromException(exception) { |
2080 if (exception is ExceptionAndStackTrace) { | 2044 if (exception is ExceptionAndStackTrace) { |
2081 return exception.stackTrace; | 2045 return exception.stackTrace; |
2082 } | 2046 } |
2083 if (exception == null) return new _StackTrace(exception); | 2047 if (exception == null) return new _StackTrace(exception); |
2084 _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); | 2048 _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); |
(...skipping 2043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4128 // This is a function that will return a helper function that does the | 4092 // This is a function that will return a helper function that does the |
4129 // iteration of the sync*. | 4093 // iteration of the sync*. |
4130 // | 4094 // |
4131 // Each invocation should give a body with fresh state. | 4095 // Each invocation should give a body with fresh state. |
4132 final dynamic /* js function */ _outerHelper; | 4096 final dynamic /* js function */ _outerHelper; |
4133 | 4097 |
4134 SyncStarIterable(this._outerHelper); | 4098 SyncStarIterable(this._outerHelper); |
4135 | 4099 |
4136 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 4100 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
4137 } | 4101 } |
OLD | NEW |