node/deps/v8/test/mjsunit/wasm/stack-switching-params.js
Michaël Zasso f1e0b83e7b
deps: update V8 to 14.6.202.33
PR-URL: https://github.com/nodejs/node/pull/61898
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-04-24 18:01:28 +02:00

243 lines
8.3 KiB
JavaScript

// Copyright 2025 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-wasmfx --expose-gc
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let builder = new WasmModuleBuilder();
let sig_v_v = builder.addType(kSig_v_v);
let sig_i_i = builder.addType(kSig_i_i);
let cont_v_v = builder.addCont(sig_v_v);
let cont_i_i = builder.addCont(sig_i_i);
let tag_i_i = builder.addTag(kSig_i_i);
let block_sig = builder.addType(
makeSig([], [kWasmI32, wasmRefType(cont_i_i)]));
let g_cont_i_i = builder.addGlobal(wasmRefNullType(cont_i_i), true, false);
let ilfdsr = [kWasmI32, kWasmI64, kWasmF32, kWasmF64, kWasmS128,
kWasmExternRef];
let sig_ilfdsr_ilfdsr = builder.addType(makeSig(ilfdsr, ilfdsr));
let cont_ilfdsr_ilfdsr = builder.addCont(sig_ilfdsr_ilfdsr);
let tag_ilfdsr_ilfdsr = builder.addTag(makeSig(ilfdsr, ilfdsr));
let block_sig_ilfdsr = builder.addType(
makeSig([], ilfdsr.concat([wasmRefType(cont_ilfdsr_ilfdsr)])));
let sig_r_r = builder.addType(kSig_r_r);
let cont_r_r = builder.addCont(sig_r_r);
// Use the memory and a global to pass and receive values to and from the
// initial func ref of a stack, until the stack entry wrapper supports
// params/returns:
builder.addMemory(1, 1);
builder.exportMemoryAs('mem');
let g_ref_in = builder.addGlobal(kWasmExternRef, true).exportAs('g_ref_in');
let g_ref_param = builder.addGlobal(kWasmExternRef, true)
.exportAs('g_ref_param');
let g_ref_tag_param = builder.addGlobal(kWasmExternRef, true)
.exportAs('g_ref_tag_param');
let g_ref_tag_return = builder.addGlobal(kWasmExternRef, true).exportAs('g_ref_tag_return');
let g_ref_cont_return = builder.addGlobal(kWasmExternRef, true).exportAs('g_ref_cont_return');
let suspend_tag0 = builder.addFunction("suspend_tag0", kSig_i_i)
.addBody([
kExprLocalGet, 0,
kExprI32Const, 1,
kExprI32Add,
kExprSuspend, tag_i_i,
kExprI32Const, 1,
kExprI32Add
]).exportFunc();
builder.addFunction("test_i32", kSig_i_i)
.addBody([
kExprBlock, block_sig,
kExprLocalGet, 0,
kExprRefFunc, suspend_tag0.index,
kExprContNew, cont_i_i,
kExprResume, cont_i_i, 1, kOnSuspend, tag_i_i, 0,
kExprUnreachable,
kExprEnd,
kExprGlobalSet, g_cont_i_i.index,
kExprI32Const, 1, kExprI32Add,
kExprGlobalGet, g_cont_i_i.index,
kExprResume, cont_i_i, 0,
kExprI32Const, 1,
kExprI32Add,
]).exportFunc();
let suspend_tag_ilfdsr_ilfdsr =
builder.addFunction("suspend_tag_ilfdsr_ilfdsr", sig_ilfdsr_ilfdsr)
.addBody([
// Save received params to memory/global.
...wasmI32Const(40), kExprLocalGet, 0, kExprI32StoreMem, 0, 0,
...wasmI32Const(40), kExprLocalGet, 1, kExprI64StoreMem, 0, 4,
...wasmI32Const(40), kExprLocalGet, 2, kExprF32StoreMem, 0, 12,
...wasmI32Const(40), kExprLocalGet, 3, kExprF64StoreMem, 0, 16,
...wasmI32Const(40), kExprLocalGet, 4,
kSimdPrefix, kExprS128StoreMem, 0, 24,
kExprLocalGet, 5, kExprGlobalSet, g_ref_param.index,
// Forward params to the suspend tag.
kExprLocalGet, 0,
kExprLocalGet, 1,
kExprLocalGet, 2,
kExprLocalGet, 3,
kExprLocalGet, 4,
kExprLocalGet, 5,
kExprSuspend, tag_ilfdsr_ilfdsr,
// Receive tag returns.
kExprGlobalSet, g_ref_tag_return.index,
kExprLocalSet, 4,
kExprLocalSet, 3,
kExprLocalSet, 2,
kExprLocalSet, 1,
kExprLocalSet, 0,
// Save tag returns to memory/global.
...wasmI32Const(120), kExprLocalGet, 0, kExprI32StoreMem, 0, 0,
...wasmI32Const(120), kExprLocalGet, 1, kExprI64StoreMem, 0, 4,
...wasmI32Const(120), kExprLocalGet, 2, kExprF32StoreMem, 0, 12,
...wasmI32Const(120), kExprLocalGet, 3, kExprF64StoreMem, 0, 16,
...wasmI32Const(120), kExprLocalGet, 4,
kSimdPrefix, kExprS128StoreMem, 0, 24,
// Finally, return the values.
kExprLocalGet, 0,
kExprLocalGet, 1,
kExprLocalGet, 2,
kExprLocalGet, 3,
kExprLocalGet, 4,
kExprGlobalGet, g_ref_tag_return.index,
]).exportFunc();
let test_ilfdsr = builder.addFunction("test_ilfdsr", kSig_v_v)
.addLocals(kWasmI32, 1)
.addLocals(kWasmI64, 1)
.addLocals(kWasmF32, 1)
.addLocals(kWasmF64, 1)
.addLocals(kWasmS128, 1)
.addLocals(wasmRefType(cont_ilfdsr_ilfdsr), 1)
.addBody([
// Initial resume/suspend:
kExprBlock, block_sig_ilfdsr,
kExprI32Const, 0, kExprI32LoadMem, 0, 0,
kExprI32Const, 0, kExprI64LoadMem, 0, 4,
kExprI32Const, 0, kExprF32LoadMem, 0, 12,
kExprI32Const, 0, kExprF64LoadMem, 0, 16,
kExprI32Const, 0, kSimdPrefix, kExprS128LoadMem, 0, 24,
kExprGlobalGet, g_ref_in.index,
kExprRefFunc, suspend_tag_ilfdsr_ilfdsr.index,
kExprContNew, cont_ilfdsr_ilfdsr,
kExprResume, cont_ilfdsr_ilfdsr, 1, kOnSuspend, tag_ilfdsr_ilfdsr, 0,
kExprUnreachable,
kExprEnd,
// Receive cont and tag params.
kExprLocalSet, 5,
kExprGlobalSet, g_ref_tag_param.index,
kExprLocalSet, 4,
kExprLocalSet, 3,
kExprLocalSet, 2,
kExprLocalSet, 1,
kExprLocalSet, 0,
// Save tag params to memory/global.
...wasmI32Const(80), kExprLocalGet, 0, kExprI32StoreMem, 0, 0,
...wasmI32Const(80), kExprLocalGet, 1, kExprI64StoreMem, 0, 4,
...wasmI32Const(80), kExprLocalGet, 2, kExprF32StoreMem, 0, 12,
...wasmI32Const(80), kExprLocalGet, 3, kExprF64StoreMem, 0, 16,
...wasmI32Const(80), kExprLocalGet, 4,
kSimdPrefix, kExprS128StoreMem, 0, 24,
// Resume with the same params.
kExprLocalGet, 0,
kExprLocalGet, 1,
kExprLocalGet, 2,
kExprLocalGet, 3,
kExprLocalGet, 4,
kExprGlobalGet, g_ref_tag_param.index,
kExprLocalGet, 5,
kExprResume, cont_ilfdsr_ilfdsr, 0,
// Receive return values.
kExprGlobalSet, g_ref_cont_return.index,
kExprLocalSet, 4,
kExprLocalSet, 3,
kExprLocalSet, 2,
kExprLocalSet, 1,
kExprLocalSet, 0,
// Save return values to memory/global.
...wasmI32Const(160), kExprLocalGet, 0, kExprI32StoreMem, 0, 0,
...wasmI32Const(160), kExprLocalGet, 1, kExprI64StoreMem, 0, 4,
...wasmI32Const(160), kExprLocalGet, 2, kExprF32StoreMem, 0, 12,
...wasmI32Const(160), kExprLocalGet, 3, kExprF64StoreMem, 0, 16,
...wasmI32Const(160), kExprLocalGet, 4,
kSimdPrefix, kExprS128StoreMem, 0, 24,
]).exportFunc();
let identity_ref = builder.addFunction("identity_ref", kSig_r_r)
.addBody([
kExprLocalGet, 0,
]).exportFunc();
block_sig = builder.addType(makeSig([], [wasmRefType(cont_r_r)]));
builder.addFunction("test_return_ref", kSig_r_r)
.addBody([
kExprLocalGet, 0,
kExprRefFunc, identity_ref.index,
kExprContNew, cont_r_r,
kExprResume, cont_r_r, 0,
]).exportFunc();
let instance = builder.instantiate();
(function TestI32() {
print(arguments.callee.name);
// Param is incremented 4 times, once after each stack switch: start, suspend,
// resume, return.
assertEquals(5, instance.exports.test_i32(1));
})();
(function TestManyTypes() {
print(arguments.callee.name);
instance.exports.g_ref_in.value = {};
let mem = new Uint8Array(instance.exports.mem.buffer);
for (let i = 0; i < 40; ++i) {
mem[i] = i;
}
instance.exports.test_ilfdsr();
// Check initial params:
for (let i = 0; i < 40; ++i) {
assertEquals(i, mem[40 + i]);
}
assertSame(instance.exports.g_ref_in.value,
instance.exports.g_ref_param.value);
// Check tag params:
for (let i = 0; i < 40; ++i) {
assertEquals(i, mem[80 + i]);
}
assertSame(instance.exports.g_ref_in.value,
instance.exports.g_ref_tag_param.value);
// Check tag returns:
for (let i = 0; i < 40; ++i) {
assertEquals(i, mem[120 + i]);
}
assertSame(instance.exports.g_ref_in.value,
instance.exports.g_ref_tag_return.value);
// Check cont returns:
for (let i = 0; i < 40; ++i) {
assertEquals(i, mem[160 + i]);
}
assertSame(instance.exports.g_ref_in.value,
instance.exports.g_ref_cont_return.value);
})();
(function TestReturnRef() {
let ref = {};
assertEquals(ref, instance.exports.test_return_ref(ref));
})();