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 'dart:_foreign_helper' show JS; | 22 import 'dart:_foreign_helper' show JS; |
22 | 23 |
23 var a = 42; | 24 var a = 42; |
24 var b = 0; | 25 var b = 0; |
25 | 26 |
26 foo(e) { | 27 foo(e) { |
27 // Loop to force a bailout. | 28 // Loop to force a bailout. |
28 for (int i = 0; i < b; i++) { | 29 for (int i = 0; i < b; i++) { |
29 a = e[i]; // Will desire a readable primitive. | 30 a = e[i]; // Will desire a readable primitive. |
30 } | 31 } |
31 // Our heuristics for '==' on an indexable primitive is that it's | 32 // Our heuristics for '==' on an indexable primitive is that it's |
32 // more common to do it on string, so we'll want e to be a string. | 33 // more common to do it on string, so we'll want e to be a string. |
33 return a == e || e == null; | 34 return a == e || e == null; |
34 } | 35 } |
35 | 36 |
36 main() { | 37 main() { |
37 Expect.isTrue(foo(JS('', 'void 0'))); | 38 Expect.isTrue(foo(JS('', 'void 0'))); |
38 } | 39 } |
OLD | NEW |