| 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 |