Commit 2d2d95c6 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm][memory64] Add first mjsunit test

This CL prepares the WasmModuleBuilder for memory64 and adds a first
mjsunit test which executes a few memory loads and stores, some of them
trapping.

R=manoskouk@chromium.org

Bug: v8:10949
Change-Id: Ia77c32ff0ee774665cd4bd0997c3609f6f17b80f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2589974
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72077}
parent 32dfefac
// Copyright 2021 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-memory64
load('test/mjsunit/wasm/wasm-module-builder.js');
// We use standard JavaScript doubles to represent bytes and offsets. They offer
// enough precision (53 bits) for every allowed memory size.
function BasicMemory64Tests(num_pages) {
const num_bytes = num_pages * kPageSize;
print(`Testing ${num_bytes} bytes (${num_pages} pages)`);
let builder = new WasmModuleBuilder();
builder.addMemory64(num_pages, num_pages, true);
builder.addFunction('load', makeSig([kWasmF64], [kWasmI32]))
.addBody([
kExprLocalGet, 0, // local.get 0
kExprI64UConvertF64, // i64.uconvert_sat.f64
kExprI32LoadMem, 0, 0, // i32.load_mem align=1 offset=0
])
.exportFunc();
builder.addFunction('store', makeSig([kWasmF64, kWasmI32], []))
.addBody([
kExprLocalGet, 0, // local.get 0
kExprI64UConvertF64, // i64.uconvert_sat.f64
kExprLocalGet, 1, // local.get 1
kExprI32StoreMem, 0, 0, // i32.store_mem align=1 offset=0
])
.exportFunc();
let module = builder.instantiate();
let memory = module.exports.memory;
let load = module.exports.load;
let store = module.exports.store;
let array = new Int8Array(memory.buffer);
assertEquals(num_bytes, array.length);
assertEquals(0, load(num_bytes - 4));
assertThrows(() => load(num_bytes - 3));
store(num_bytes - 4, 0x12345678);
assertEquals(0x12345678, load(num_bytes - 4));
let kStoreOffset = 27;
store(kStoreOffset, 11);
assertEquals(11, load(kStoreOffset));
// Now check 100 random positions. All except for kStoreOffset should be zero.
for (let i = 0; i < 100; ++i) {
let position = Math.floor(Math.random() * num_bytes);
if (position == kStoreOffset) continue;
assertEquals(0, array[position]);
}
}
(function TestSmallMemory() {
print(arguments.callee.name);
BasicMemory64Tests(4);
})();
(function Test3GBMemory() {
print(arguments.callee.name);
let num_pages = 3 * 1024 * 1024 * 1024 / kPageSize;
// This test can fail if 3GB of memory cannot be allocated.
try {
BasicMemory64Tests(num_pages);
} catch (e) {
assertInstanceof(e, RangeError);
assertMatches(/Out of memory/, e.message);
}
})();
// TODO(clemensb): Allow for memories >4GB and enable this test.
//(function Test5GBMemory() {
// print(arguments.callee.name);
// let num_pages = 5 * 1024 * 1024 * 1024 / kPageSize;
// BasicMemory64Tests(num_pages);
//})();
......@@ -76,10 +76,12 @@ let kWasmFunctionTypeForm = 0x60;
let kWasmStructTypeForm = 0x5f;
let kWasmArrayTypeForm = 0x5e;
let kLimitsNoMaximum = 0
let kLimitsHasMaximum = 1;
let kLimitsSharedNoMaximum = 2;
let kLimitsSharedHasMaximum = 3;
let kLimitsNoMaximum = 0x00;
let kLimitsWithMaximum = 0x01;
let kLimitsSharedNoMaximum = 0x02;
let kLimitsSharedWithMaximum = 0x03;
let kLimitsMemory64NoMaximum = 0x04;
let kLimitsMemory64WithMaximum = 0x05;
// Segment flags
let kActiveNoIndex = 0;
......@@ -1024,7 +1026,24 @@ class WasmModuleBuilder {
}
addMemory(min, max, exported, shared) {
this.memory = {min: min, max: max, exported: exported, shared: shared};
this.memory = {
min: min,
max: max,
exported: exported,
shared: shared || false,
is_memory64: false
};
return this;
}
addMemory64(min, max, exported) {
this.memory = {
min: min,
max: max,
exported: exported,
shared: false,
is_memory64: true
};
return this;
}
......@@ -1363,12 +1382,22 @@ class WasmModuleBuilder {
binary.emit_section(kMemorySectionCode, section => {
section.emit_u8(1); // one memory entry
const has_max = wasm.memory.max !== undefined;
const is_shared = wasm.memory.shared !== undefined;
section.emit_u8(is_shared
? (has_max ? kLimitsSharedHasMaximum : kLimitsSharedNoMaximum)
: (has_max ? kLimitsHasMaximum : kLimitsNoMaximum));
if (wasm.memory.is_memory64) {
assertFalse(
wasm.memory.shared, 'sharing memory64 is not supported (yet)');
section.emit_u8(
has_max ? kLimitsMemory64WithMaximum : kLimitsMemory64NoMaximum);
section.emit_u64v(wasm.memory.min);
if (has_max) section.emit_u64v(wasm.memory.max);
} else {
section.emit_u8(
wasm.memory.shared ?
(has_max ? kLimitsSharedWithMaximum :
kLimitsSharedNoMaximum) :
(has_max ? kLimitsWithMaximum : kLimitsNoMaximum));
section.emit_u32v(wasm.memory.min);
if (has_max) section.emit_u32v(wasm.memory.max);
}
});
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment