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>
565 lines
20 KiB
JavaScript
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));
|
|
})();
|