import Builder from '../Builder.js' import * as assert from '../assert.js' const count = 10; const pages = 6; const memoryDescription = {initial:1}; const pageSize = 64 * 1024; function createWasmInstance(memory) { const builder = new Builder() .Type().End() .Import() .Memory("imp", "memory", memoryDescription) .End() .Function().End() .Export() .Function("current") .Function("get") .Function("grow") .End() .Code() .Function("current", { params: [], ret: "i32" }) .CurrentMemory(0) .Return() .End() .Function("get", { params: ["i32"], ret: "i32" }) .GetLocal(0) .I32Load(2, 0) .Return() .End() .Function("grow", { params: ["i32"], ret: "i32" }) .GetLocal(0) .GrowMemory(0) .Return() .End() .End(); const bin = builder.WebAssembly().get(); const module = new WebAssembly.Module(bin); return new WebAssembly.Instance(module, {imp: {memory}}); } function doFillMemory(mem, length) { const buf = new Uint32Array(mem.buffer); for (let i = 0; i < length; ++i) { buf[i * 4] = i + 1; } } function doCheckTrap(instances, mem, numPages, length) { const buf = new Uint32Array(mem.buffer); for (let instance of instances) { const foo = instance.exports.get; for (let i = 0; i < length; i++) { assert.eq(foo(i * 4), buf[i]); } assert.throws(() => foo(numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); } } function doCheckNoTrap(instances, mem, numPages, length) { const buf = new Uint32Array(mem.buffer); for (let instance of instances) { const foo = instance.exports.get; for (let i = 0; i < length; i++) { assert.eq(foo(i * 4), buf[i]); } assert.eq(foo(numPages * pageSize + 1), 0); } } function doMemoryGrow(instances) { const instance = instances[0]; // Take first instance and grow shared memory instance.exports.grow(1); } function doCheck(mem, instances, numPages) { const length = mem.buffer.byteLength / 4; doFillMemory(mem, length); doCheckTrap(instances, mem, numPages, length); doMemoryGrow(instances); doCheckNoTrap(instances, mem, numPages, length); } function checkWasmInstancesWithSharedMemory() { const mem = new WebAssembly.Memory(memoryDescription); const instances = []; for (let i = 0; i < count; i++) { instances.push(createWasmInstance(mem)); } for(let i = 1; i < pages; i++) { doCheck(mem, instances, i); } let instance; for (let i = 0; i < count; i++) { instance = instances.shift(); } fullGC(); const survivedInstances = [ instance ]; // Should survive only one instance after full GC doCheck(mem, survivedInstances, pages); // Recheck only for survie instances } checkWasmInstancesWithSharedMemory();