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

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/js_helper.dart

Issue 1180713003: Better messages for optimized index errors. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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 unified diff | Download patch
OLDNEW
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
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()
1391 iae(argument) { 1392 iae(argument) {
1392 throw _argumentError(argument); 1393 throw _argumentError(argument);
1393 } 1394 }
1394 1395
1395 /** 1396 /**
1396 * Called by generated code to throw an index-out-of-range exception, 1397 * Called by generated code to throw an index-out-of-range exception, for
1397 * for example, if a bounds check fails in an optimized indexed 1398 * example, if a bounds check fails in an optimized indexed access. This may
1398 * access. This may also be called when the index is not an integer, in 1399 * also be called when the index is not an integer, in which case it throws an
1399 * which case it throws an illegal-argument exception instead, like 1400 * illegal-argument exception instead, like [iae], or when the receiver is null.
1400 * [iae], or when the receiver is null.
1401 */ 1401 */
1402 @NoInline()
1402 ioore(receiver, index) { 1403 ioore(receiver, index) {
1403 if (receiver == null) receiver.length; // Force a NoSuchMethodError. 1404 if (receiver == null) receiver.length; // Force a NoSuchMethodError.
1404 if (index is !int) iae(index); 1405 throw diagnoseIndexError(receiver, 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
1408 stringLastIndexOfUnchecked(receiver, element, start) 1426 stringLastIndexOfUnchecked(receiver, element, start)
1409 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); 1427 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start);
1410 1428
1411 1429
1412 /// 'factory' for constructing ArgumentError.value to keep the call sites small. 1430 /// 'factory' for constructing ArgumentError.value to keep the call sites small.
1413 @NoInline() 1431 @NoInline()
1414 ArgumentError _argumentError(object) { 1432 ArgumentError _argumentError(object) {
1415 return new ArgumentError.value(object); 1433 return new ArgumentError.value(object);
1416 } 1434 }
1417 1435
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 // nothing. 2026 // nothing.
2009 return saveStackTrace( 2027 return saveStackTrace(
2010 new UnknownJsTypeError(message is String ? message : '')); 2028 new UnknownJsTypeError(message is String ? message : ''));
2011 } 2029 }
2012 2030
2013 if (JS('bool', r'# instanceof RangeError', ex)) { 2031 if (JS('bool', r'# instanceof RangeError', ex)) {
2014 if (message is String && contains(message, 'call stack')) { 2032 if (message is String && contains(message, 'call stack')) {
2015 return new StackOverflowError(); 2033 return new StackOverflowError();
2016 } 2034 }
2017 2035
2018 // In general, a RangeError is thrown when trying to pass a number 2036 // In general, a RangeError is thrown when trying to pass a number as an
2019 // as an argument to a function that does not allow a range that 2037 // argument to a function that does not allow a range that includes that
2020 // includes that number. 2038 // number. Translate to a Dart ArgumentError with the same message.
2021 return saveStackTrace(new ArgumentError()); 2039 // TODO(sra): Translate to RangeError.
2040 String message = tryStringifyException(ex);
2041 if (message is String) {
2042 message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message);
2043 }
2044 return saveStackTrace(new ArgumentError(message));
2022 } 2045 }
2023 2046
2024 // Check for the Firefox specific stack overflow signal. 2047 // Check for the Firefox specific stack overflow signal.
2025 if (JS('bool', 2048 if (JS('bool',
2026 r'typeof InternalError == "function" && # instanceof InternalError', 2049 r'typeof InternalError == "function" && # instanceof InternalError',
2027 ex)) { 2050 ex)) {
2028 if (message is String && message == 'too much recursion') { 2051 if (message is String && message == 'too much recursion') {
2029 return new StackOverflowError(); 2052 return new StackOverflowError();
2030 } 2053 }
2031 } 2054 }
2032 2055
2033 // Just return the exception. We should not wrap it because in case 2056 // Just return the exception. We should not wrap it because in case
2034 // the exception comes from the DOM, it is a JavaScript 2057 // the exception comes from the DOM, it is a JavaScript
2035 // object backed by a native Dart class. 2058 // object backed by a native Dart class.
2036 return ex; 2059 return ex;
2037 } 2060 }
2038 2061
2062 String tryStringifyException(ex) {
2063 // Since this function is called from [unwrapException] which is called from
2064 // code injected into a catch-clause, use JavaScript try-catch to avoid a
2065 // potential loop if stringifying crashes.
2066 return JS('String|Null', r'''
2067 (function(ex) {
2068 try {
2069 return String(ex);
2070 } catch (e) {}
2071 return null;
2072 })(#)
2073 ''', ex);
2074 }
2075
2039 /** 2076 /**
2040 * Called by generated code to fetch the stack trace from an 2077 * Called by generated code to fetch the stack trace from an
2041 * exception. Should never return null. 2078 * exception. Should never return null.
2042 */ 2079 */
2043 StackTrace getTraceFromException(exception) { 2080 StackTrace getTraceFromException(exception) {
2044 if (exception is ExceptionAndStackTrace) { 2081 if (exception is ExceptionAndStackTrace) {
2045 return exception.stackTrace; 2082 return exception.stackTrace;
2046 } 2083 }
2047 if (exception == null) return new _StackTrace(exception); 2084 if (exception == null) return new _StackTrace(exception);
2048 _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); 2085 _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception);
(...skipping 2043 matching lines...) Expand 10 before | Expand all | Expand 10 after
4092 // This is a function that will return a helper function that does the 4129 // This is a function that will return a helper function that does the
4093 // iteration of the sync*. 4130 // iteration of the sync*.
4094 // 4131 //
4095 // Each invocation should give a body with fresh state. 4132 // Each invocation should give a body with fresh state.
4096 final dynamic /* js function */ _outerHelper; 4133 final dynamic /* js function */ _outerHelper;
4097 4134
4098 SyncStarIterable(this._outerHelper); 4135 SyncStarIterable(this._outerHelper);
4099 4136
4100 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); 4137 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper));
4101 } 4138 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/js_lib/js_array.dart ('k') | sdk/lib/_internal/compiler/js_lib/js_string.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698