| 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 |