mirror of
https://github.com/nodejs/node.git
synced 2025-05-20 17:41:40 +00:00

PR-URL: https://github.com/nodejs/node/pull/49639 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
137 lines
5.0 KiB
JavaScript
137 lines
5.0 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: --experimental-wasm-multi-memory --experimental-wasm-memory64
|
|
|
|
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
function assertMemoryEquals(expected, memory) {
|
|
assertInstanceof(memory, WebAssembly.Memory);
|
|
assertInstanceof(expected, Uint8Array);
|
|
const buf = new Uint8Array(memory.buffer);
|
|
// For better output, check the first 50 bytes separately first.
|
|
assertEquals(expected.slice(0, 50), buf.slice(0, 50));
|
|
// Now also check the full memory content.
|
|
assertEquals(expected, buf);
|
|
}
|
|
|
|
(function testBasicMultiMemory() {
|
|
print(arguments.callee.name);
|
|
// Test two memories: One 32-bit and one 64-bit, in both orders.
|
|
for (let mem64_idx of [0, 1]) {
|
|
const builder = new WasmModuleBuilder();
|
|
const mem32_idx = 1 - mem64_idx;
|
|
|
|
const mem32_pages = 1;
|
|
const mem32_size = mem32_pages * kPageSize;
|
|
const mem64_pages = 3;
|
|
const mem64_size = mem64_pages * kPageSize;
|
|
if (mem32_idx == 0) {
|
|
builder.addMemory(mem32_pages, mem32_pages);
|
|
builder.addMemory64(mem64_pages, mem64_pages);
|
|
} else {
|
|
builder.addMemory64(mem64_pages, mem64_pages);
|
|
builder.addMemory(mem32_pages, mem32_pages);
|
|
}
|
|
builder.exportMemoryAs('mem32', mem32_idx);
|
|
builder.exportMemoryAs('mem64', mem64_idx);
|
|
|
|
builder.addFunction('load32', kSig_i_i)
|
|
.addBody([kExprLocalGet, 0, kExprI32LoadMem, 0x40, mem32_idx, 0])
|
|
.exportFunc();
|
|
builder.addFunction('load64', kSig_i_l)
|
|
.addBody([kExprLocalGet, 0, kExprI32LoadMem, 0x40, mem64_idx, 0])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
const mem32_offset = 48;
|
|
const mem64_offset = 16;
|
|
const value = 13;
|
|
const view32 = new DataView(instance.exports.mem32.buffer);
|
|
const view64 = new DataView(instance.exports.mem64.buffer);
|
|
view32.setInt32(mem32_offset, value, true);
|
|
view64.setInt32(mem64_offset, value, true);
|
|
|
|
const {load32, load64} = instance.exports;
|
|
|
|
assertEquals(value, load32(mem32_offset));
|
|
assertEquals(0, load32(mem64_offset));
|
|
assertEquals(0, load64(BigInt(mem32_offset)));
|
|
assertEquals(value, load64(BigInt(mem64_offset)));
|
|
|
|
assertEquals(0, load32(mem32_size - 4));
|
|
assertEquals(0, load64(BigInt(mem64_size - 4)));
|
|
assertTraps(kTrapMemOutOfBounds, () => load32(mem32_size - 3));
|
|
assertTraps(kTrapMemOutOfBounds, () => load64(BigInt(mem64_size - 3)));
|
|
}
|
|
})();
|
|
|
|
(function testMultiMemoryInit() {
|
|
print(arguments.callee.name);
|
|
// Test two memories: One 32-bit and one 64-bit, in both orders.
|
|
for (let mem64_idx of [0, 1]) {
|
|
const builder = new WasmModuleBuilder();
|
|
const mem32_idx = 1 - mem64_idx;
|
|
|
|
const mem32_pages = 1;
|
|
const mem32_size = mem32_pages * kPageSize;
|
|
const mem64_pages = 3;
|
|
const mem64_size = mem64_pages * kPageSize;
|
|
if (mem32_idx == 0) {
|
|
builder.addMemory(mem32_pages, mem32_pages);
|
|
builder.addMemory64(mem64_pages, mem64_pages);
|
|
} else {
|
|
builder.addMemory64(mem64_pages, mem64_pages);
|
|
builder.addMemory(mem32_pages, mem32_pages);
|
|
}
|
|
builder.exportMemoryAs('mem32', mem32_idx);
|
|
builder.exportMemoryAs('mem64', mem64_idx);
|
|
|
|
const data = [1, 2, 3, 4, 5];
|
|
const seg_id = builder.addPassiveDataSegment(data);
|
|
|
|
builder.addFunction('init32', kSig_v_iii)
|
|
.addBody([
|
|
kExprLocalGet, 0, // dst
|
|
kExprLocalGet, 1, // offset
|
|
kExprLocalGet, 2, // size
|
|
kNumericPrefix, kExprMemoryInit, seg_id, mem32_idx
|
|
])
|
|
.exportFunc();
|
|
builder.addFunction('init64', kSig_v_lii)
|
|
.addBody([
|
|
kExprLocalGet, 0, // dst
|
|
kExprLocalGet, 1, // offset
|
|
kExprLocalGet, 2, // size
|
|
kNumericPrefix, kExprMemoryInit, seg_id, mem64_idx
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
const {init32, init64} = instance.exports;
|
|
const expected_mem32 = new Uint8Array(mem32_size);
|
|
const expected_mem64 = new Uint8Array(mem64_size);
|
|
|
|
assertMemoryEquals(expected_mem32, instance.exports.mem32);
|
|
assertMemoryEquals(expected_mem64, instance.exports.mem64);
|
|
|
|
init32(7, 1, 3); // dst, (data) offset, size
|
|
expected_mem32.set(data.slice(1, 4), 7);
|
|
assertMemoryEquals(expected_mem32, instance.exports.mem32);
|
|
assertMemoryEquals(expected_mem64, instance.exports.mem64);
|
|
|
|
init64(11n, 3, 2); // dst, (data) offset, size
|
|
expected_mem64.set(data.slice(3, 5), 11);
|
|
assertMemoryEquals(expected_mem32, instance.exports.mem32);
|
|
assertMemoryEquals(expected_mem64, instance.exports.mem64);
|
|
|
|
// Test bounds checks.
|
|
init32(mem32_size - 1, 0, 1); // dst, (data) offset, size
|
|
assertTraps(kTrapMemOutOfBounds, () => init32(mem32_size - 1, 0, 2));
|
|
init64(BigInt(mem64_size - 1), 0, 1); // dst, (data) offset, size
|
|
assertTraps(
|
|
kTrapMemOutOfBounds, () => init64(BigInt(mem64_size - 1), 0, 2));
|
|
}
|
|
})();
|