node/deps/v8/test/mjsunit/wasm/exceptions-gc.js
Michaël Zasso 09a8440b45
deps: update V8 to 12.2.281.27
PR-URL: https://github.com/nodejs/node/pull/51362
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2024-03-31 15:36:07 +02:00

221 lines
7.5 KiB
JavaScript

// Copyright 2023 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: --allow-natives-syntax
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
// Test throwing/catching the reference type value.
(function TestThrowCatchRefParam() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i);
let struct = builder.addStruct([makeField(kWasmI32, true)]);
builder.addFunction("doubler", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 0, kExprI32Add])
.exportFunc();
builder.addFunction("struct_producer",
makeSig([kWasmI32], [wasmRefType(struct)]))
.addBody([kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct])
.exportFunc();
for (let [name, code] of
[["extern", kWasmExternRef],
["sig", sig],
["struct", struct]]) {
let type = wasmRefNullType(code);
let except = builder.addTag(makeSig([type], []));
builder.addFunction("throw_catch_param_" + name, makeSig([type],[type]))
.addBody([
kExprTry, kWasmRefNull, code & kLeb128Mask,
kExprLocalGet, 0,
kExprThrow, except,
kExprCatch, except,
// fall-through
kExprEnd,
]).exportFunc();
}
let instance = builder.instantiate();
let wasm = instance.exports;
let o = new Object();
assertEquals(o, wasm.throw_catch_param_extern(o));
assertEquals(1, wasm.throw_catch_param_extern(1));
assertEquals(2.3, wasm.throw_catch_param_extern(2.3));
assertEquals("str", wasm.throw_catch_param_extern("str"));
let struct_obj = wasm.struct_producer(42);
assertEquals(struct_obj, wasm.throw_catch_param_struct(struct_obj));
let doubler_obj = wasm.doubler;
assertEquals(doubler_obj, wasm.throw_catch_param_sig(doubler_obj));
assertEquals(20, wasm.throw_catch_param_sig(doubler_obj)(10));
})();
// Test the encoding of a thrown exception with a null-ref value.
(function TestThrowRefNull() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)]);
let except = builder.addTag(makeSig([wasmRefNullType(struct)], []));
builder.addFunction("throw_null", kSig_v_v)
.addBody([kExprRefNull, kNullRefCode, kExprThrow, except])
.exportFunc();
let instance = builder.instantiate();
assertWasmThrows(instance, except, [null],
() => instance.exports.throw_null());
})();
(function TestJSToWasm() {
print(arguments.callee.name);
let producer = (function() {
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI64, true)]);
let array = builder.addArray(wasmRefNullType(struct), true);
let sig = builder.addType(kSig_i_ii);
let struct_builder =
builder.addFunction("struct_builder",
makeSig([kWasmI64], [wasmRefType(struct)]))
.addBody([kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct])
.exportFunc();
let array_builder =
builder.addFunction("array_builder",
makeSig([kWasmI32], [wasmRefType(array)]))
.addBody([kExprLocalGet, 0, kGCPrefix, kExprArrayNewDefault, array])
.exportFunc();
let adder = builder.addFunction("adder", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
.exportFunc();
return builder.instantiate().exports;
})();
let struct_obj = producer.struct_builder(42n);
let array_obj = producer.array_builder(10);
let function_obj = producer.adder;
let external_obj = {};
let tag = new WebAssembly.Tag({
parameters: ["externref", "anyfunc", "anyref", "eqref", "i31ref",
"structref", "arrayref"]});
let values_mistyped = [external_obj, 123, function_obj, struct_obj, -33,
struct_obj, array_obj];
assertThrows(() => new WebAssembly.Exception(tag, values_mistyped), TypeError,
/.* must be null \(if nullable\) or a Wasm function object/);
let values = [external_obj, function_obj, 123, struct_obj, -33,
struct_obj, array_obj];
let exn = new WebAssembly.Exception(tag, values);
// Make sure we roundtrip corretly through wasm using
// the Exception constructor/getArg.
for (i = 0 ; i < values.length; i++) {
assertEquals(exn.getArg(tag, i), values[i]);
}
let t = () => { throw exn; }
// Make sure objects in a JS exception object are correctly encoded as wasm
// objects.
let consumer = (function () {
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI64, true)]);
builder.addArray(wasmRefNullType(struct), true);
let sig = builder.addType(kSig_i_ii);
let tag_sig = builder.addType(makeSig([
kWasmExternRef, kWasmFuncRef, kWasmAnyRef, kWasmEqRef, kWasmI31Ref,
kWasmStructRef, kWasmArrayRef], []));
let throwing = builder.addImport("m", "t", kSig_i_v);
let tag_index = builder.addImportedTag("m", "tag", tag_sig);
builder.addFunction("catching", kSig_i_v)
.addLocals(kWasmExternRef, 1)
.addLocals(kWasmFuncRef, 1)
.addLocals(kWasmAnyRef, 1)
.addLocals(kWasmEqRef, 1)
.addLocals(kWasmI31Ref, 1)
.addLocals(kWasmStructRef, 1)
.addLocals(kWasmArrayRef, 1)
.addBody([
kExprTry, kWasmI32,
kExprCallFunction, throwing,
kExprCatch, tag_index,
kExprLocalSet, 6,
kExprLocalSet, 5,
kExprLocalSet, 4,
kExprLocalSet, 3,
kExprLocalSet, 2,
kExprLocalSet, 1,
kExprLocalSet, 0,
// adder(10, 20)
kExprI32Const, 10, kExprI32Const, 20,
kExprLocalGet, 1, kGCPrefix, kExprRefCast, sig, kExprCallRef, sig,
// 123
kExprLocalGet, 2, kGCPrefix, kExprRefCast, kI31RefCode,
kGCPrefix, kExprI31GetS,
// (i32) struct(42l).get_0
kExprLocalGet, 3, kGCPrefix, kExprRefCast, struct,
kGCPrefix, kExprStructGet, struct, 0, kExprI32ConvertI64,
// -33
kExprLocalGet, 4, kGCPrefix, kExprI31GetS,
// (i32) struct(42l).get_0
kExprLocalGet, 5, kGCPrefix, kExprRefCast, struct,
kGCPrefix, kExprStructGet, struct, 0, kExprI32ConvertI64,
// array.length
kExprLocalGet, 6, kGCPrefix, kExprArrayLen,
// Now add them all up.
kExprI32Add, kExprI32Add, kExprI32Add, kExprI32Add, kExprI32Add,
kExprEnd])
.exportFunc()
return builder.instantiate({m: {t: t, tag: tag}}).exports
})();
assertEquals(30 + 123 + 42 + (-33) + 42 + 10, consumer.catching());
})();
(function TestWasmToJS() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_ii);
let adder = builder.addFunction("adder", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
.exportFunc();
let tag = builder.addTag(makeSig([kWasmFuncRef, kWasmFuncRef], []));
builder.addExportOfKind("tag", kExternalTag, tag);
builder.addFunction("thrower", kSig_v_v)
.addBody([kExprRefNull, kFuncRefCode, kExprRefFunc, adder.index,
kExprThrow, tag])
.exportFunc();
let wasm = builder.instantiate().exports;
// Make sure objects thrown from Wasm and retrieved with getArg are correctly
// decoded as JS objects.
try { wasm.thrower() }
catch (e) {
assertEquals(null, e.getArg(wasm.tag, 0));
assertEquals(99, e.getArg(wasm.tag, 1)(44, 55));
}
})();