| 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 "native_testing.dart"; | 21 import "package:expect/expect.dart"; |
| 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 |