Michaël Zasso 918fe04351
deps: update V8 to 13.6.233.8
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:06:53 +02:00

565 lines
20 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-shared --no-wasm-inlining-call-indirect
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
(function SharedGlobal() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let callee_sig = builder.addType(kSig_v_v, kNoSuperType, true, true);
let sig = builder.addType(kSig_i_i, kNoSuperType, true, true);
let global = builder.addGlobal(kWasmI32, true, true, [kExprI32Const, 0]);
let side_effect = builder.addFunction("side_effect", callee_sig).addBody([]);
builder.addFunction("roundtrip", sig)
.addBody([kExprLocalGet, 0, kExprGlobalSet, global.index,
// Adding intermediate side-effect to prevent load elimination.
kExprCallFunction, side_effect.index,
kExprGlobalGet, global.index])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(10, wasm.roundtrip(10));
})();
(function SharedGlobalAbstractType() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, false);
let struct = builder.addStruct(
[makeField(kWasmI32, true)], kNoSuperType, false, true);
let global = builder.addGlobal(
wasmRefNullType(kWasmAnyRef).shared(), true, true,
[kExprRefNull, kWasmSharedTypeForm, kAnyRefCode]);
let side_effect = builder.addFunction("side_effect", kSig_v_v).addBody([]);
builder.addFunction("roundtrip", sig)
.addBody([kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct,
kExprGlobalSet, global.index,
// Adding intermediate side-effect to prevent load elimination.
kExprCallFunction, side_effect.index,
kExprGlobalGet, global.index,
kGCPrefix, kExprRefCast, struct,
kGCPrefix, kExprStructGet, struct, 0])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(10, wasm.roundtrip(10));
})();
(function SharedGlobalInNonSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, false);
let global = builder.addGlobal(kWasmI32, true, true, [kExprI32Const, 0]);
builder.addFunction("roundtrip", sig)
.addBody([kExprLocalGet, 0, kExprGlobalSet, global.index,
kExprGlobalGet, global.index])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(10, wasm.roundtrip(10));
})();
(function SharedGlobalInNonSharedFunctionExported() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, false);
let global = builder.addGlobal(kWasmI32, true, true, [kExprI32Const, 0])
.exportAs("g");
builder.addFunction("roundtrip", sig)
.addBody([kExprLocalGet, 0, kExprGlobalSet, global.index,
kExprGlobalGet, global.index])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(10, wasm.roundtrip(10));
assertEquals(10, wasm.g.value);
wasm.g.value = 20;
assertEquals(20, wasm.g.value);
})();
(function InvalidGlobalInSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_v_i, kNoSuperType, true, true);
let global = builder.addGlobal(kWasmI32, true, false, [kExprI32Const, 0]);
builder.addFunction("setter", sig)
.addBody([kExprLocalGet, 0, kExprGlobalSet, global.index]);
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/Cannot access non-shared global 0 in a shared function/);
})();
(function InvalidGlobalInSharedConstantExpression() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let global_non_shared =
builder.addGlobal(kWasmI32, true, false, [kExprI32Const, 0]);
builder.addGlobal(
kWasmI32, true, true, [kExprGlobalGet, global_non_shared.index]);
assertThrows(
() => builder.instantiate(), WebAssembly.CompileError,
/Cannot access non-shared global 0 in a shared constant expression/);
})();
(function InvalidImportedGlobal() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i);
builder.addImportedGlobal("m", "g", wasmRefType(sig), true, true);
assertThrows(
() => builder.instantiate(), WebAssembly.CompileError,
/shared imported global must have shared type/);
})();
(function SharedTypes() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, true);
let struct =
builder.addStruct([makeField(kWasmI32, true)], kNoSuperType, false, true);
builder.addFunction("main", sig)
.addLocals(wasmRefType(struct), 1)
.addBody([
kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct,
kExprLocalSet, 1,
kExprLocalGet, 1, kGCPrefix, kExprStructGet, struct, 0])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(42, wasm.main(42));
})();
(function InvalidLocal() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, true);
let struct =
builder.addStruct([makeField(kWasmI32, true)], kNoSuperType, false, false);
builder.addFunction("main", sig)
.addLocals(wasmRefType(struct), 1)
.addBody([kExprLocalGet, 0])
.exportFunc();
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/local must have shared type/)
})();
(function InvalidStack() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_v, kNoSuperType, true, true);
let struct =
builder.addStruct([makeField(kWasmI32, true)], kNoSuperType, false, false);
builder.addFunction("main", sig)
.addBody([
kExprI32Const, 42, kGCPrefix, kExprStructNew, struct,
kGCPrefix, kExprStructGet, struct, 0])
.exportFunc();
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/struct.new does not have a shared type/);
})();
(function InvalidFuncRefInConstantExpression() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i);
let adder = builder.addFunction("adder", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
let global = builder.addGlobal(wasmRefType(sig), true, true,
[kExprRefFunc, adder.index]);
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/Shared global 0 must have shared type, actual type \(ref 0\)/);
})();
(function DataSegmentInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_v_v, kNoSuperType, false, true);
let data = builder.addPassiveDataSegment([1, 2, 3], true);
builder.addFunction("drop", sig)
.addBody([kNumericPrefix, kExprDataDrop, data])
.exportFunc();
builder.instantiate().exports.drop();
})();
(function InvalidDataSegmentInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_v_v, kNoSuperType, false, true);
let data = builder.addPassiveDataSegment([1, 2, 3], false);
builder.addFunction("drop", sig)
.addBody([kNumericPrefix, kExprDataDrop, data])
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/cannot refer to non-shared segment/);
})();
(function ElementSegmentInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_v_v, kNoSuperType, false, true);
let func = builder.addFunction("void", sig).addBody([]);
let elem = builder.addPassiveElementSegment(
[[kExprRefFunc, func.index]], wasmRefType(0), true);
builder.addFunction("drop", sig)
.addBody([kNumericPrefix, kExprElemDrop, elem])
builder.instantiate();
})();
(function InvalidElementSegmentInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_v_v, kNoSuperType, false, true);
let elem = builder.addPassiveElementSegment(
[[kExprRefNull, kNullFuncRefCode]], kWasmFuncRef, false);
builder.addFunction("drop", sig)
.addBody([kNumericPrefix, kExprElemDrop, elem])
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/cannot reference non-shared element segment/);
})();
(function TableInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)], kNoSuperType,
true, true);
let sig = builder.addType(makeSig([kWasmI32], [wasmRefNullType(struct)]),
kNoSuperType, false, true);
let table = builder.addTable(wasmRefNullType(struct), 10, undefined,
[kExprRefNull, struct], true);
builder.addFunction("get", sig)
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
.exportFunc();
let instance = builder.instantiate();
assertEquals(null, instance.exports.get(0));
})();
(function TableInNonSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)], kNoSuperType,
true, true);
let sig = builder.addType(makeSig([kWasmI32], [wasmRefNullType(struct)]),
kNoSuperType, false, false);
let table = builder.addTable(wasmRefNullType(struct), 10, undefined,
[kExprRefNull, struct], true)
.exportAs("t");
builder.addFunction("get", sig)
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
.exportFunc();
builder.addFunction("allocate", sig)
.addBody([kGCPrefix, kExprStructNewDefault, struct])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(null, wasm.get(0));
let o = wasm.allocate();
wasm.t.set(1, o);
assertEquals(o, wasm.t.get(1));
})();
(function FunctionTableInNonSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let table = builder.addTable(
wasmRefNullType(kWasmFuncRef).shared(), 10, undefined,
[kExprRefNull, kWasmSharedTypeForm, kFuncRefCode], true);
let sig = builder.addType(kSig_i_ii, kNoSuperType, true, true);
let add = builder.addFunction("add", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]);
let mul = builder.addFunction("mul", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Mul]);
builder.addActiveElementSegment(
table.index, [kExprI32Const, 0],
[[kExprRefFunc, add.index], [kExprRefFunc, mul.index]],
wasmRefNullType(kWasmFuncRef).shared(), true);
let passive = builder.addPassiveElementSegment(
[[kExprRefFunc, add.index], [kExprRefFunc, mul.index]],
wasmRefNullType(kWasmFuncRef).shared(), true);
builder.addFunction("call", kSig_i_iii)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
kExprCallIndirect, sig, table.index])
.exportFunc();
builder.addFunction("call_through_get", kSig_i_iii)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kExprLocalGet, 2, kExprTableGet, table.index,
kGCPrefix, kExprRefCast, sig,
kExprCallRef, sig])
.exportFunc()
builder.addFunction("set", kSig_v_v)
.addBody([
kExprI32Const, 0, kExprRefFunc, mul.index, kExprTableSet, table.index])
.exportFunc();
builder.addFunction("grow", kSig_v_v)
.addBody([kExprRefNull, kWasmSharedTypeForm, kFuncRefCode,
kExprI32Const, 42, kNumericPrefix, kExprTableGrow, table.index,
kExprDrop])
.exportFunc();
builder.addFunction("fill", kSig_v_v)
.addBody([kExprI32Const, 10, kExprRefFunc, add.index, kExprI32Const, 42,
kNumericPrefix, kExprTableFill, table.index])
.exportFunc();
builder.addFunction("init", kSig_v_v)
.addBody([kExprI32Const, 20, kExprI32Const, 0, kExprI32Const, 2,
kNumericPrefix, kExprTableInit, passive, table.index])
.exportFunc();
builder.addFunction("copy", kSig_v_v)
.addBody([kExprI32Const, 30, kExprI32Const, 20, kExprI32Const, 2,
kNumericPrefix, kExprTableCopy, table.index, table.index])
.exportFunc();
builder.addFunction("size", kSig_i_v)
.addBody([kNumericPrefix, kExprTableSize, table.index])
.exportFunc();
let wasm = builder.instantiate().exports;
assertEquals(30, wasm.call(10, 20, 0));
assertEquals(200, wasm.call(10, 20, 1));
assertEquals(30, wasm.call_through_get(10, 20, 0));
assertEquals(200, wasm.call_through_get(10, 20, 1));
wasm.set();
assertEquals(200, wasm.call(10, 20, 0));
wasm.grow();
assertTraps(kTrapFuncSigMismatch, () => wasm.call(10, 20, 42));
wasm.fill();
assertEquals(30, wasm.call(10, 20, 42));
wasm.init();
assertEquals(200, wasm.call(10, 20, 21));
wasm.copy();
assertEquals(30, wasm.call(10, 20, 30));
assertEquals(200, wasm.call(10, 20, 31));
assertEquals(52, wasm.size());
})();
(function InvalidTableInFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)], kNoSuperType,
true, true);
let sig = builder.addType(makeSig([kWasmI32], [wasmRefNullType(struct)]),
kNoSuperType, false, true);
let table = builder.addTable(wasmRefNullType(struct), 10, undefined,
[kExprRefNull, struct], false);
builder.addFunction("get", sig)
.addBody([kExprLocalGet, 0, kExprTableGet, table.index])
.exportFunc();
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/cannot reference non-shared table/);
})();
(function InvalidTableInitializer() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_shared = builder.addType(kSig_v_v, kNoSuperType, false, true);
let sig = builder.addType(kSig_v_v, kNoSuperType, false, false);
builder.addTable(wasmRefNullType(sig_shared), 10, undefined,
[kExprRefNull, sig], true);
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/type error in constant expression\[0\] \(expected \(ref null 0\), got \(ref null 1\)\)/);
})();
(function CallNonShared() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_i, kNoSuperType, true, true);
let callee = builder.addFunction("callee", kSig_v_v).addBody([]);
builder.addFunction("caller", sig)
.addBody([kExprCallFunction, callee.index])
.exportFunc();
assertThrows(() => builder.instantiate(), WebAssembly.CompileError,
/cannot call non-shared function/);
})();
(function CallIndirectSharedImported() {
print(arguments.callee.name);
let exported_function = (function() {
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_ii, kNoSuperType, true, true);
let global = builder.addGlobal(kWasmI32, true, true, wasmI32Const(42));
builder.addFunction("f", sig)
.addBody([kExprGlobalGet, global.index, kExprLocalGet, 0,
kExprLocalGet, 1, kExprI32Add, kExprI32Add])
.exportFunc();
return builder.instantiate().exports.f;
})();
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_ii, kNoSuperType, true, true);
let table = builder.addTable(wasmRefNullType(sig), 10, undefined, undefined,
true);
let imp0 = builder.addImport("m", "imp0", sig);
let imp1 = builder.addImport("m", "imp1", sig);
builder.addActiveElementSegment(
table.index, wasmI32Const(0), [[kExprRefFunc, imp0], [kExprRefFunc, imp1]],
wasmRefNullType(sig), true);
let call = builder.addFunction("call", kSig_i_iii)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
kExprCallIndirect, sig, table.index])
.exportFunc();
let wasm = builder.instantiate(
{m : {imp0 : (x, y) => x * y, imp1: exported_function}}).exports;
assertEquals(200, wasm.call(10, 20, 0));
assertEquals(42 + 10 + 20, wasm.call(10, 20, 1));
})();
(function CallIndirectSharedImportedWrongNonSharedType() {
print(arguments.callee.name);
let exported_function = (function() {
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_ii, kNoSuperType, true, false);
builder.addFunction("f", sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add])
.exportFunc();
return builder.instantiate().exports.f;
})();
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_ii, kNoSuperType, true, true);
builder.addImport("m", "imp", sig);
assertThrows(
() => builder.instantiate({m : {imp : exported_function}}),
WebAssembly.LinkError,
/imported function does not match the expected type/);
})();
(function SharedRefFuncInNonSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let callee_sig = builder.addType(kSig_i_ii, kNoSuperType, true, true);
let add = builder.addFunction("add", callee_sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]);
let mul = builder.addFunction("mul", callee_sig)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Mul]);
builder.addDeclarativeElementSegment(
[[kExprRefFunc, add.index], [kExprRefFunc, mul.index]],
wasmRefNullType(callee_sig), true);
let caller = builder.addFunction("caller", kSig_i_iii)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kExprLocalGet, 2,
kExprIf, kWasmRef, callee_sig,
kExprRefFunc, add.index,
kExprElse,
kExprRefFunc, mul.index,
kExprEnd,
kExprCallRef, callee_sig])
.exportFunc()
let wasm = builder.instantiate().exports;
// The first two calls have to call into the builtin.
assertEquals(30, wasm.caller(10, 20, 1));
assertEquals(200, wasm.caller(10, 20, 0));
assertEquals(30, wasm.caller(10, 20, 1));
assertEquals(200, wasm.caller(10, 20, 0));
})();
(function SharedArrayNewAndInitInNonSharedFunction() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let struct_type = builder.addStruct(
[makeField(kWasmI32, true)], kNoSuperType, true, true);
let array_type =
builder.addArray(wasmRefType(struct_type), true, kNoSuperType, true,
true);
let segment = builder.addPassiveElementSegment(
[[kExprI32Const, 0, kGCPrefix, kExprStructNew, struct_type],
[kExprI32Const, 1, kGCPrefix, kExprStructNew, struct_type],
[kExprI32Const, 2, kGCPrefix, kExprStructNew, struct_type],
[kExprI32Const, 3, kGCPrefix, kExprStructNew, struct_type]],
wasmRefType(struct_type), true);
builder.addFunction("new_segment", makeSig([], [wasmRefType(array_type)]))
.addBody([kExprI32Const, 0, kExprI32Const, 4,
kGCPrefix, kExprArrayNewElem, array_type, segment])
.exportFunc();
builder.addFunction("get", makeSig([wasmRefNullType(array_type), kWasmI32],
[kWasmI32]))
.addBody([kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprArrayGet, array_type,
kGCPrefix, kExprStructGet, struct_type, 0])
.exportFunc();
builder.addFunction("init_segment",
makeSig([wasmRefNullType(array_type)], []))
.addBody([kExprLocalGet, 0, kExprI32Const, 2, kExprI32Const, 0,
kExprI32Const, 2,
kGCPrefix, kExprArrayInitElem, array_type, segment])
.exportFunc();
let wasm = builder.instantiate().exports;
let array = wasm.new_segment();
assertEquals(0, wasm.get(array, 0));
assertEquals(1, wasm.get(array, 1));
assertEquals(2, wasm.get(array, 2));
assertEquals(3, wasm.get(array, 3));
wasm.init_segment(array);
assertEquals(0, wasm.get(array, 0));
assertEquals(1, wasm.get(array, 1));
assertEquals(0, wasm.get(array, 2));
assertEquals(1, wasm.get(array, 3));
})();