mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 17:35:26 +00:00

PR-URL: https://github.com/nodejs/node/pull/54077 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
300 lines
9.1 KiB
JavaScript
300 lines
9.1 KiB
JavaScript
// Copyright 2024 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --experimental-wasm-exnref --no-experimental-wasm-inlining
|
|
|
|
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
let getExnRef = function() {
|
|
let tag = new WebAssembly.Tag({parameters: []});
|
|
return new WebAssembly.Exception(tag, []);
|
|
}
|
|
|
|
// Helper module to produce an exnref or convert a JS value to an exnref.
|
|
let helper = (function () {
|
|
let builder = new WasmModuleBuilder();
|
|
let tag_index = builder.addTag(kSig_v_v);
|
|
let throw_index = builder.addImport('m', 'import', kSig_v_r);
|
|
builder.addFunction('get_exnref', makeSig([], [kWasmExnRef]))
|
|
.addBody([
|
|
kExprTryTable, kWasmVoid, 1,
|
|
kCatchAllRef, 0,
|
|
kExprThrow, tag_index,
|
|
kExprEnd,
|
|
kExprUnreachable,
|
|
]).exportFunc();
|
|
builder.addFunction('to_exnref', makeSig([kWasmExternRef], [kWasmExnRef]))
|
|
.addBody([
|
|
kExprTryTable, kWasmVoid, 1,
|
|
kCatchAllRef, 0,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, throw_index,
|
|
kExprEnd,
|
|
kExprUnreachable,
|
|
]).exportFunc();
|
|
function throw_js(r) { throw r; }
|
|
let instance = builder.instantiate({m: {import: throw_js}});
|
|
return instance;
|
|
})();
|
|
|
|
(function RefTestExnRef() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let get_exnref = builder.addImport('m', 'get_exnref', makeSig([], [kWasmExnRef]));
|
|
builder.addFunction('testExnRef',
|
|
makeSig([], [kWasmI32, kWasmI32, kWasmI32, kWasmI32]))
|
|
.addLocals(kWasmExnRef, 1)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprRefTest, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprRefTest, kNullExnRefCode,
|
|
kExprCallFunction, get_exnref,
|
|
kGCPrefix, kExprRefTest, kExnRefCode,
|
|
kExprCallFunction, get_exnref,
|
|
kGCPrefix, kExprRefTest, kNullExnRefCode,
|
|
]).exportFunc();
|
|
|
|
builder.addFunction('testNullExnRef',
|
|
makeSig([], [kWasmI32, kWasmI32, kWasmI32, kWasmI32]))
|
|
.addLocals(kWasmExnRef, 1)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprRefTestNull, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kGCPrefix, kExprRefTestNull, kNullExnRefCode,
|
|
kExprCallFunction, get_exnref,
|
|
kGCPrefix, kExprRefTestNull, kExnRefCode,
|
|
kExprCallFunction, get_exnref,
|
|
kGCPrefix, kExprRefTestNull, kNullExnRefCode,
|
|
]).exportFunc();
|
|
|
|
|
|
let instance = builder.instantiate({m: {get_exnref: helper.exports.get_exnref}});
|
|
let wasm = instance.exports;
|
|
assertEquals([0, 0, 1, 0], wasm.testExnRef());
|
|
assertEquals([1, 1, 1, 0], wasm.testNullExnRef());
|
|
})();
|
|
|
|
(function RefCastExnRef() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
let to_exnref = builder.addImport('m', 'to_exnref', makeSig([kWasmExternRef], [kWasmExnRef]));
|
|
|
|
builder.addFunction('castToExnRef',
|
|
makeSig([kWasmExternRef], []))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
kGCPrefix, kExprRefCast, kExnRefCode,
|
|
kExprThrowRef])
|
|
.exportFunc();
|
|
builder.addFunction('castToNullExnRef',
|
|
makeSig([kWasmExternRef], []))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
kGCPrefix, kExprRefCast, kNullExnRefCode,
|
|
kExprDrop])
|
|
.exportFunc();
|
|
builder.addFunction('castNullToExnRef',
|
|
makeSig([kWasmExternRef], []))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
kGCPrefix, kExprRefCastNull, kExnRefCode,
|
|
kExprThrowRef])
|
|
.exportFunc();
|
|
builder.addFunction('castNullToNullExnRef',
|
|
makeSig([kWasmExternRef], []))
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
kGCPrefix, kExprRefCastNull, kNullExnRefCode,
|
|
kGCPrefix, kExprRefCastNull, kExnRefCode,
|
|
kExprThrowRef])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({m: {to_exnref: helper.exports.to_exnref}});
|
|
let wasm = instance.exports;
|
|
|
|
let exnRef = getExnRef();
|
|
assertTraps(kTrapIllegalCast, () => wasm.castToExnRef(null));
|
|
assertThrowsEquals(() => wasm.castToExnRef(exnRef), exnRef);
|
|
assertTraps(kTrapIllegalCast, () => wasm.castToNullExnRef(null));
|
|
assertTraps(kTrapIllegalCast, () => wasm.castToNullExnRef(exnRef));
|
|
|
|
assertThrows(() => wasm.castNullToExnRef(null), Error, /rethrowing null value/);
|
|
assertThrowsEquals(() => wasm.castNullToExnRef(exnRef), exnRef);
|
|
assertThrows(() => wasm.castNullToNullExnRef(null), Error, /rethrowing null value/);
|
|
assertTraps(kTrapIllegalCast, () => wasm.castNullToNullExnRef(exnRef));
|
|
})();
|
|
|
|
(function BrOnCastExnRef() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
let to_exnref = builder.addImport('m', 'to_exnref', makeSig([kWasmExternRef], [kWasmExnRef]));
|
|
|
|
builder.addFunction('castToExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRef, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCast(
|
|
0, wasmRefNullType(kWasmExnRef), wasmRefType(kWasmExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
builder.addFunction('castToNullExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRef, kNullExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCast(
|
|
0, wasmRefNullType(kWasmExnRef), wasmRefType(kWasmNullExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction('castNullToExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRefNull, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCast(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
builder.addFunction('castNullToNullExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRefNull, kNullExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCast(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmNullExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction('castFailToExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRefNull, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCastFail(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefType(kWasmExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
builder.addFunction('castFailToNullExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRefNull, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCastFail(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefType(kWasmNullExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction('castFailNullToExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRef, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCastFail(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
builder.addFunction('castFailNullToNullExnRef',
|
|
makeSig([kWasmExternRef], [kWasmI32]))
|
|
.addBody([
|
|
kExprBlock, kWasmRef, kExnRefCode,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, to_exnref,
|
|
...wasmBrOnCastFail(0,
|
|
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmNullExnRef)),
|
|
kExprI32Const, 0,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprReturn,
|
|
])
|
|
.exportFunc();
|
|
|
|
let instance = builder.instantiate({m: {to_exnref: helper.exports.to_exnref}});
|
|
let wasm = instance.exports;
|
|
let exnRef = getExnRef();
|
|
|
|
assertEquals(0, wasm.castToExnRef(null));
|
|
assertEquals(1, wasm.castToExnRef(exnRef));
|
|
|
|
assertEquals(0, wasm.castToNullExnRef(null));
|
|
assertEquals(0, wasm.castToNullExnRef(exnRef));
|
|
|
|
assertEquals(1, wasm.castNullToExnRef(null));
|
|
assertEquals(1, wasm.castNullToExnRef(exnRef));
|
|
|
|
assertEquals(1, wasm.castNullToNullExnRef(null));
|
|
assertEquals(0, wasm.castNullToNullExnRef(exnRef));
|
|
|
|
assertEquals(1, wasm.castFailToExnRef(null));
|
|
assertEquals(0, wasm.castFailToExnRef(exnRef));
|
|
|
|
assertEquals(1, wasm.castFailToNullExnRef(null));
|
|
assertEquals(1, wasm.castFailToNullExnRef(exnRef));
|
|
|
|
assertEquals(0, wasm.castFailNullToExnRef(null));
|
|
assertEquals(0, wasm.castFailNullToExnRef(exnRef));
|
|
|
|
assertEquals(0, wasm.castFailNullToNullExnRef(null));
|
|
assertEquals(1, wasm.castFailNullToNullExnRef(exnRef));
|
|
})();
|