Index: tests/compiler/dart2js_extra/js_array_index_error_test.dart |
diff --git a/tests/compiler/dart2js_extra/js_array_index_error_test.dart b/tests/compiler/dart2js_extra/js_array_index_error_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..edc934dfef4f17e447136c75501ca350acb0b3a7 |
--- /dev/null |
+++ b/tests/compiler/dart2js_extra/js_array_index_error_test.dart |
@@ -0,0 +1,220 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+// Test that optimized JSArray indexers enerate the same error as dyncamically |
+// dispatched calls. |
+ |
+import 'package:expect/expect.dart'; |
+ |
+@NoInline() @AssumeDynamic() |
+confuse(x) => x; |
+ |
+ |
+Error getError(action()) { |
+ try { |
+ action(); |
+ Expect.fail('must throw'); |
Lasse Reichstein Nielsen
2015/09/11 06:16:57
Move this outside the try/catch, otherwise you'll
sra1
2015/09/11 17:33:34
Done.
|
+ } catch (e) { |
+ return e; |
+ } |
+} |
+ |
+indexErrorContainsIndex() { |
+ fault(i) { |
Lasse Reichstein Nielsen
2015/09/11 06:16:58
You could write this as:
fault(i) => () => confu
sra1
2015/09/11 17:33:34
Done.
|
+ return confuse([])[i]; |
+ } |
+ |
+ var e1 = getError(() => fault(1234)); |
+ var e2 = getError(() => fault(1234000)); |
+ var e3 = getError(() => fault(1234000000000)); |
+ |
+ Expect.equals('$e1', '$e2'.replaceAll('000', '')); |
+ Expect.equals('$e1', '$e3'.replaceAll('000', '')); |
+ Expect.equals('$e1'.length + 3, '$e2'.length); |
+ Expect.equals('$e1'.length + 9, '$e3'.length); |
+} |
+ |
+indexEmpty() { |
+ fault1() { |
+ // Single indexing might go via one-shot interceptor that might have an |
+ // accelerated path. |
+ return confuse([])[0]; |
+ } |
+ |
+ fault2() { |
+ var a = []; |
+ while (confuse(false)) a.add(1); |
+ // Easily inferred type and open coded indexer. |
+ return a[0]; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([]); |
+ // Multiple indexing might go via shared interceptor. |
+ return [a[0], a[1], a[2]]; |
+ } |
+ |
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
+ |
+indexHugeEmpty() { |
+ int HUGE; |
+ |
+ fault1() { |
+ return confuse([])[HUGE]; |
+ } |
+ |
+ fault2() { |
+ var a = []; |
+ while (confuse(false)) a.add(1); |
+ return a[HUGE]; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([]); |
+ return [a[HUGE], a[1], a[2]]; |
+ } |
+ |
+ HUGE = 1000000000000; |
Lasse Reichstein Nielsen
2015/09/11 06:16:57
Why not initialize HUGE above?
If there is a reaso
sra1
2015/09/11 17:33:34
Done.
|
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
+ |
+indexNonempty() { |
+ fault1() { |
+ // Single indexing might go via one-shot interceptor that might have an |
+ // accelerated path. |
+ return confuse([1])[1]; |
+ } |
+ |
+ fault2() { |
+ var a = [1]; |
+ while (confuse(false)) a.add(1); |
+ // Easily inferred type and open coded indexer. |
+ return a[1]; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([1]); |
+ // Multiple indexing might go via shared interceptor. |
+ return [a[0], a[1], a[2]]; |
+ } |
+ |
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
Lasse Reichstein Nielsen
2015/09/11 06:16:57
Could these tests be parameterized with (list, ind
sra1
2015/09/11 17:33:34
I'm wary that making the code general will inhibit
|
+ |
+indexHugeNonempty() { |
+ int HUGE; |
+ |
+ fault1() { |
+ return confuse([1])[HUGE]; |
+ } |
+ |
+ fault2() { |
+ var a = [1]; |
+ while (confuse(false)) a.add(1); |
+ return a[HUGE]; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([1]); |
+ return [a[HUGE], a[1], a[2]]; |
+ } |
+ |
+ HUGE = 1000000000000; |
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
+ |
+indexSetEmpty() { |
+ fault1() { |
+ // Single indexing might go via one-shot interceptor that has an accelerated |
+ // path. |
+ confuse([])[0] = 0; |
+ } |
+ |
+ fault2() { |
+ var a = []; |
+ while (confuse(false)) a.add(1); |
+ // Easily inferred type and open coded indexer. |
+ a[0] = 0; |
+ return a; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([]); |
+ // Multiple indexing might go via shared interceptor. |
+ a[0] = 0; |
+ a[1] = 0; |
+ a[2] = 0; |
+ return a; |
+ } |
+ |
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
+ |
+indexSetNonempty() { |
Lasse Reichstein Nielsen
2015/09/11 06:16:57
No Huge version of indexSet tests?
sra1
2015/09/11 17:33:34
Added in the 'variable' tests.
|
+ fault1() { |
+ // Single indexing might go via one-shot interceptor that has an accelerated |
+ // path. |
+ confuse([1])[1] = 0; |
+ } |
+ |
+ fault2() { |
+ var a = [1]; |
+ while (confuse(false)) a.add(1); |
+ // Easily inferred type and open coded indexer. |
+ a[1] = 0; |
+ return a; |
+ } |
+ |
+ fault3() { |
+ var a = confuse([1]); |
+ // Multiple indexing might go via shared interceptor. |
+ a[0] = 0; |
+ a[1] = 0; |
+ a[2] = 0; |
+ return a; |
+ } |
+ |
+ var e1 = getError(fault1); |
+ var e2 = getError(fault2); |
+ var e3 = getError(fault3); |
+ |
+ Expect.equals('$e1', '$e2'); |
+ Expect.equals('$e1', '$e3'); |
+} |
+ |
+main() { |
+ indexErrorContainsIndex(); |
+ indexEmpty(); |
+ indexHugeEmpty(); |
+ indexNonempty(); |
+ indexHugeNonempty(); |
+ indexSetEmpty(); |
+ indexSetNonempty(); |
Lasse Reichstein Nielsen
2015/09/11 06:16:57
Maybe also test negative indices.
sra1
2015/09/11 17:33:34
Done.
|
+} |