blob: c4b21f748dea854c293c71cab719290727ad4619 [file] [edit]
// Copyright (c) 2026, 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.
// Regression test for https://github.com/dart-lang/sdk/issues/64099.
//
// When a bool local declared outside a loop is combined with a
// non-short-circuiting binary operator (|, &, ^) whose other operand contains
// an await, dart2wasm was emitting invalid wasm where a bool (i32) was left
// on the stack across an async suspension.
import 'package:expect/expect.dart';
Future<bool> f(int i) async => i.isEven;
Future<bool> testForOrAssign(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v |= await f(i);
}
return v;
}
Future<bool> testWhileOrAssign(int n) async {
bool v = false;
int i = 0;
while (i < n) {
v |= await f(i);
i++;
}
return v;
}
Future<bool> testAndAssign(int n) async {
bool v = true;
for (int i = 0; i < n; i++) {
v &= await f(i);
}
return v;
}
Future<bool> testXorAssign(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v ^= await f(i);
}
return v;
}
Future<bool> testBinaryOrLeft(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v = v | await f(i);
}
return v;
}
Future<bool> testBinaryOrRight(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v = await f(i) | v;
}
return v;
}
Future<bool> testBinaryAndLeft(int n) async {
bool v = true;
for (int i = 0; i < n; i++) {
v = v & await f(i);
}
return v;
}
Future<bool> testBinaryAndRight(int n) async {
bool v = true;
for (int i = 0; i < n; i++) {
v = await f(i) & v;
}
return v;
}
Future<bool> testBinaryXorLeft(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v = v ^ await f(i);
}
return v;
}
Future<bool> testBinaryXorRight(int n) async {
bool v = false;
for (int i = 0; i < n; i++) {
v = await f(i) ^ v;
}
return v;
}
Future<int> testConditionalReuse(bool cond) async {
return cond
? (await Future.value(42)).abs()
: (await Future.value("hello")).length;
}
void main() async {
Expect.isTrue(await testForOrAssign(4));
Expect.isFalse(await testForOrAssign(0));
Expect.isTrue(await testWhileOrAssign(4));
Expect.isFalse(await testWhileOrAssign(0));
Expect.isFalse(await testAndAssign(4));
Expect.isTrue(await testAndAssign(1));
Expect.isFalse(await testAndAssign(2));
Expect.isFalse(await testXorAssign(4));
Expect.isTrue(await testXorAssign(1));
Expect.isTrue(await testBinaryOrLeft(4));
Expect.isTrue(await testBinaryOrRight(4));
Expect.isFalse(await testBinaryAndLeft(4));
Expect.isFalse(await testBinaryAndRight(4));
Expect.isTrue(await testBinaryXorLeft(1));
Expect.isTrue(await testBinaryXorRight(1));
Expect.equals(42, await testConditionalReuse(true));
Expect.equals(5, await testConditionalReuse(false));
}