blob: 52b02a198f9bc32773672a76f2312a13576ead88 [file] [log] [blame]
// Copyright (c) 2012, 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.
import "package:expect/expect.dart";
var myString;
String ifBailout(test) {
if (test) {
// Share the same variable for the type inference.
var o = myString;
// Make sure the type inference wants an array.
if (false) o[1] = 2;
return '${o[0]} bailout';
}
return '${myString[0]} no bailout';
}
String ifElseBailout(test) {
if (test) {
// Share the same variable for the type inference.
var o = myString;
// Make sure the type inference wants an array.
if (false) o[1] = 2;
return '${o[0]} if bailout';
} else {
// Share the same variable for the type inference.
var o = myString;
// Make sure the type inference wants an array.
if (false) o[1] = 2;
return '${o[0]} else bailout';
}
}
String forBailout() {
var n = myString.length;
var res = '';
for (int i = 0; i < n; i++) {
var o = myString;
if (false) o[1] = 2;
res += o[i];
}
return res;
}
String forInBailout() {
var n = myString.length;
var res = '';
for (int i in myString.codeUnits) {
var o = myString;
if (false) o[1] = 2;
res += new String.fromCharCodes([i]);
}
return res;
}
String innerForBailout() {
var n = myString.length;
var res = '';
for (int i = 0; i < 2; i++) {
for (int j = 0; j < n; j++) {
var o = myString;
if (false) o[1] = 2;
res += o[j];
}
}
return res;
}
String whileBailout() {
var n = myString.length;
var res = '';
var i = 0;
while (i < n) {
var o = myString;
if (false) o[1] = 2;
res += o[i];
i++;
}
return res;
}
String doWhileBailout() {
var n = myString.length;
var res = '';
var i = 0;
do {
var o = myString;
if (false) o[1] = 2;
res += o[i];
i++;
} while (i < n);
return res;
}
void phiBailout() {
var prev = -1;
bool inside = false;
for (int i = 0; i < 2; i++) {
var o = myString;
// prev will be a phi converted to a local, and if we're not
// careful, the bailout target may not have the right value for
// it.
if (prev != -1) {
inside = true;
if (false) o[0] = 1;
print(o[0]);
Expect.equals(0, prev);
}
prev = i;
}
Expect.isTrue(inside);
}
int fibonacci(int n) {
int a = 0, b = 1, i = 0;
// i, a, b will become phis, and then locals. The i++ creates a
// load/store sequence that we must be careful with.
while (i++ < n) {
a = a + b;
b = a - b;
var o = myString;
if (false) o[0] = 2;
print(o[0]);
}
return a;
}
void ifPhiBailout1(int bailout) {
var a = 0;
var c = 0;
if (a == 0) c = a++;
else c = a--;
if (bailout == 1) {
var o = myString;
if (false) o[0] = 2;
print(o[0]);
}
Expect.equals(1, a);
Expect.equals(0, c);
if (a == 0) c = a++;
else c = a--;
if (bailout == 2) {
var o = myString;
if (false) o[0] = 2;
print(o[0]);
}
Expect.equals(0, a);
Expect.equals(1, c);
}
void ifPhiBailout2(int bailout) {
var a = 0;
var c = 0;
if (a == 0) {
c = a;
a = a + 1;
} else {
c = a;
a = a - 1;
}
if (bailout == 1) {
var o = myString;
if (false) o[0] = 2;
print(o[0]);
}
Expect.equals(1, a);
Expect.equals(0, c);
if (a == 0) {
c = a;
a = a + 1;
} else {
c = a;
a = a - 1;
}
if (bailout == 2) {
var o = myString;
if (false) o[0] = 2;
print(o[0]);
}
Expect.equals(0, a);
Expect.equals(1, c);
}
main() {
myString = '1';
Expect.equals('1 no bailout', ifBailout(false));
Expect.equals('1 bailout', ifBailout(true));
Expect.equals('1 else bailout', ifElseBailout(false));
Expect.equals('1 if bailout', ifElseBailout(true));
myString = '1234';
Expect.equals('1234', forBailout());
Expect.equals('1234', forInBailout());
Expect.equals('12341234', innerForBailout());
Expect.equals('1234', whileBailout());
Expect.equals('1234', doWhileBailout());
Expect.equals(102334155, fibonacci(40));
phiBailout();
ifPhiBailout1(1);
ifPhiBailout1(2);
ifPhiBailout2(1);
ifPhiBailout2(2);
}