blob: bf9682859d3185343aca077f6e8094bb81eb072c [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.
import 'package:expect/expect.dart';
import 'package:wasm_builder/wasm_builder.dart';
void main() {
testNoEffectTryTable();
testOneOutputTryTable();
testFunctionTryTable();
}
void testNoEffectTryTable() {
final moduleBuilder = ModuleBuilder('test', null);
final tagType = moduleBuilder.types.defineFunction(const [], const []);
final definedTag = moduleBuilder.tags.define(tagType);
final importedTag = moduleBuilder.tags.import('env', 'jsTag', tagType);
final fnType = moduleBuilder.types.defineFunction(const [], const []);
final fn = moduleBuilder.functions.define(fnType, 'testNoEffect');
final b = fn.body;
final catchAllRefLabel = b.block(const [], const [
RefType.exn(nullable: true),
]);
final catchAllLabel = b.block();
final catchRefLabel = b.block(const [], const [RefType.exn(nullable: true)]);
final catchLabel = b.block();
b.try_table([
Catch(definedTag, catchLabel),
CatchRef(importedTag, catchRefLabel),
CatchAll(catchAllLabel),
CatchAllRef(catchAllRefLabel),
]);
b.nop();
b.end(); // end try_table
b.return_();
b.end(); // end catchLabel
b.return_();
b.end(); // end catchRefLabel
b.drop();
b.return_();
b.end(); // end catchAllLabel
b.return_();
b.end(); // end catchAllRefLabel
b.drop();
b.end(); // end function
fn.build();
final module = moduleBuilder.build();
final wat = module.printAsWat();
Expect.isTrue(wat.contains('(tag \$env.jsTag (import "env" "jsTag"))'));
Expect.isTrue(wat.contains('(tag \$tag0)'));
Expect.isTrue(
wat.contains(
'try_table \$label4 (catch \$tag0 \$label3) (catch_ref \$env.jsTag \$label2) '
'(catch_all \$label1) (catch_all_ref \$label0)',
),
'Actual WAT:\n$wat',
);
// Verify round-trip serialize/deserialize preserves WAT output.
final serializer = Serializer();
module.serialize(serializer);
final deserialized = Module.deserialize(Deserializer(serializer.data));
Expect.equals(wat, deserialized.printAsWat());
}
void testOneOutputTryTable() {
final moduleBuilder = ModuleBuilder('test', null);
final tagType = moduleBuilder.types.defineFunction(const [
NumType.i32,
], const []);
final tag = moduleBuilder.tags.define(tagType);
final fnType = moduleBuilder.types.defineFunction(const [], const [
NumType.i32,
]);
final fn = moduleBuilder.functions.define(fnType, 'testOneOutput');
final b = fn.body;
final catchLabel = b.block(const [], const [NumType.i32]);
b.try_table([Catch(tag, catchLabel)], const [], const [NumType.i32]);
b.i32_const(42);
b.end(); // end try_table
b.end(); // end catchLabel
b.end(); // end function
fn.build();
final module = moduleBuilder.build();
final wat = module.printAsWat();
Expect.isTrue(
wat.contains('try_table \$label1 (result i32) (catch \$tag0 \$label0)'),
'Actual WAT:\n$wat',
);
final serializer = Serializer();
module.serialize(serializer);
final deserialized = Module.deserialize(Deserializer(serializer.data));
Expect.equals(wat, deserialized.printAsWat());
}
void testFunctionTryTable() {
final moduleBuilder = ModuleBuilder('test', null);
final tagType = moduleBuilder.types.defineFunction(const [], const []);
moduleBuilder.tags.define(tagType);
final fnType = moduleBuilder.types.defineFunction(
const [NumType.i32],
const [NumType.i32, NumType.i64],
);
final fn = moduleBuilder.functions.define(fnType, 'testFunctionType');
final b = fn.body;
final catchLabel = b.block();
b.local_get(b.locals[0]);
b.try_table([CatchAll(catchLabel)], const [NumType.i32], const [
NumType.i32,
NumType.i64,
]);
b.i64_const(100);
b.end(); // end try_table
b.return_();
b.end(); // end catchLabel
b.i32_const(0);
b.i64_const(0);
b.end(); // end function
fn.build();
final module = moduleBuilder.build();
final wat = module.printAsWat();
Expect.isTrue(
wat.contains(
'try_table \$label1 (param i32) (result i32) (result i64) (catch_all \$label0)',
),
'Actual WAT:\n$wat',
);
final serializer = Serializer();
module.serialize(serializer);
final deserialized = Module.deserialize(Deserializer(serializer.data));
Expect.equals(wat, deserialized.printAsWat());
}