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/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>
221 lines
7.5 KiB
JavaScript
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));
|
|
}
|
|
})();
|