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 // dart2js regression test where the SSA backend would use the wrong | 5 // dart2js regression test where the SSA backend would use the wrong |
6 // type for an instruction: when doing a speculative type propagation, | 6 // type for an instruction: when doing a speculative type propagation, |
7 // if an instruction gets analyzed multiple times, we used to save the | 7 // if an instruction gets analyzed multiple times, we used to save the |
8 // last inferred type, which could be speculative, instead of the | 8 // last inferred type, which could be speculative, instead of the |
9 // first inferred type, which is the actual, non-speculative, type. | 9 // first inferred type, which is the actual, non-speculative, type. |
10 // | 10 // |
11 // Because we are doing speculative type propagation at the very end, | 11 // Because we are doing speculative type propagation at the very end, |
12 // before emitting the bailout version, the only place where we might | 12 // before emitting the bailout version, the only place where we might |
13 // do wrong optimizations is during the codegen. It turns out that the | 13 // do wrong optimizations is during the codegen. It turns out that the |
14 // codegen optimizes '==' comparisons on null to '===' in case it knows | 14 // codegen optimizes '==' comparisons on null to '===' in case it knows |
15 // the receiver cannot be null. So in the following example, the | 15 // the receiver cannot be null. So in the following example, the |
16 // [:e == null:] comparison in [foo] got wrongly generated to a | 16 // [:e == null:] comparison in [foo] got wrongly generated to a |
17 // JavaScript identity check (that is, using '==='). But this | 17 // JavaScript identity check (that is, using '==='). But this |
18 // comparison does not work for undefined, which the DOM sometimes | 18 // comparison does not work for undefined, which the DOM sometimes |
19 // returns. | 19 // returns. |
20 | 20 |
21 import "package:expect/expect.dart"; | 21 import "native_testing.dart"; |
22 import 'dart:_foreign_helper' show JS; | |
23 | 22 |
24 var a = 42; | 23 var a = 42; |
25 var b = 0; | 24 var b = 0; |
26 | 25 |
27 foo(e) { | 26 foo(e) { |
28 // Loop to force a bailout. | 27 // Loop to force a bailout. |
29 for (int i = 0; i < b; i++) { | 28 for (int i = 0; i < b; i++) { |
30 a = e[i]; // Will desire a readable primitive. | 29 a = e[i]; // Will desire a readable primitive. |
31 } | 30 } |
32 // Our heuristics for '==' on an indexable primitive is that it's | 31 // Our heuristics for '==' on an indexable primitive is that it's |
33 // more common to do it on string, so we'll want e to be a string. | 32 // more common to do it on string, so we'll want e to be a string. |
34 return a == e || e == null; | 33 return a == e || e == null; |
35 } | 34 } |
36 | 35 |
37 main() { | 36 main() { |
38 Expect.isTrue(foo(JS('', 'void 0'))); | 37 Expect.isTrue(foo(JS('', 'void 0'))); |
39 } | 38 } |
OLD | NEW |