5b127a9796
This is primarily to aid in testing the Wasm out of bounds trap handler. We keep track of how many faults have been recovered by the Wasm trap handler. This count is exposed to JavaScript through a testing-only runtime function. This allows tests to verify whether the trap handler is actually running. Bug: v8:5277 Change-Id: Ie8037a36d84eb08166c6e40c7225d912683d5786 Reviewed-on: https://chromium-review.googlesource.com/665968 Commit-Queue: Eric Holk <eholk@chromium.org> Reviewed-by: Mircea Trofin <mtrofin@chromium.org> Cr-Commit-Position: refs/heads/master@{#48076}
175 lines
4.9 KiB
JavaScript
175 lines
4.9 KiB
JavaScript
// Copyright 2015 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: --expose-wasm --expose-gc --stress-compaction --allow-natives-syntax
|
|
|
|
load("test/mjsunit/wasm/wasm-constants.js");
|
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
var kMemSize = 65536;
|
|
|
|
function genModule(memory) {
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
builder.addImportedMemory("", "memory", 1);
|
|
builder.exportMemoryAs("memory");
|
|
builder.addFunction("main", kSig_i_i)
|
|
.addBody([
|
|
// main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
|
|
// TODO(titzer): this manual bytecode has a copy of test-run-wasm.cc
|
|
/**/ kExprLoop, kWasmStmt, // --
|
|
/* */ kExprGetLocal, 0, // --
|
|
/* */ kExprIf, kWasmStmt, // --
|
|
/* */ kExprGetLocal, 0, // --
|
|
/* */ kExprI32LoadMem, 0, 0, // --
|
|
/* */ kExprIf, kWasmStmt, // --
|
|
/* */ kExprI32Const, 127, // --
|
|
/* */ kExprReturn, // --
|
|
/* */ kExprEnd, // --
|
|
/* */ kExprGetLocal, 0, // --
|
|
/* */ kExprI32Const, 4, // --
|
|
/* */ kExprI32Sub, // --
|
|
/* */ kExprSetLocal, 0, // --
|
|
/* */ kExprBr, 1, // --
|
|
/* */ kExprEnd, // --
|
|
/* */ kExprEnd, // --
|
|
/**/ kExprI32Const, 0 // --
|
|
])
|
|
.exportFunc();
|
|
var module = builder.instantiate({"": {memory:memory}});
|
|
assertTrue(module.exports.memory instanceof WebAssembly.Memory);
|
|
if (memory != null) assertEquals(memory.buffer, module.exports.memory.buffer);
|
|
return module;
|
|
}
|
|
|
|
function testPokeMemory() {
|
|
print("testPokeMemory");
|
|
var module = genModule(new WebAssembly.Memory({initial: 1}));
|
|
var buffer = module.exports.memory.buffer;
|
|
var main = module.exports.main;
|
|
assertEquals(kMemSize, buffer.byteLength);
|
|
|
|
var array = new Int8Array(buffer);
|
|
assertEquals(kMemSize, array.length);
|
|
|
|
for (var i = 0; i < kMemSize; i++) {
|
|
assertEquals(0, array[i]);
|
|
}
|
|
|
|
for (var i = 0; i < 10; i++) {
|
|
assertEquals(0, main(kMemSize - 4));
|
|
|
|
array[kMemSize/2 + i] = 1;
|
|
assertEquals(0, main(kMemSize/2 - 4));
|
|
assertEquals(-1, main(kMemSize - 4));
|
|
|
|
array[kMemSize/2 + i] = 0;
|
|
assertEquals(0, main(kMemSize - 4));
|
|
}
|
|
}
|
|
|
|
testPokeMemory();
|
|
|
|
function genAndGetMain(buffer) {
|
|
return genModule(buffer).exports.main; // to prevent intermediates living
|
|
}
|
|
|
|
function testSurvivalAcrossGc() {
|
|
var checker = genAndGetMain(new WebAssembly.Memory({initial: 1}));
|
|
for (var i = 0; i < 3; i++) {
|
|
print("gc run ", i);
|
|
assertEquals(0, checker(kMemSize - 4));
|
|
gc();
|
|
}
|
|
}
|
|
|
|
testSurvivalAcrossGc();
|
|
testSurvivalAcrossGc();
|
|
testSurvivalAcrossGc();
|
|
testSurvivalAcrossGc();
|
|
|
|
|
|
function testPokeOuterMemory() {
|
|
print("testPokeOuterMemory");
|
|
var buffer = new WebAssembly.Memory({initial: kMemSize / kPageSize});
|
|
var module = genModule(buffer);
|
|
var main = module.exports.main;
|
|
assertEquals(kMemSize, buffer.buffer.byteLength);
|
|
|
|
var array = new Int8Array(buffer.buffer);
|
|
assertEquals(kMemSize, array.length);
|
|
|
|
for (var i = 0; i < kMemSize; i++) {
|
|
assertEquals(0, array[i]);
|
|
}
|
|
|
|
for (var i = 0; i < 10; i++) {
|
|
assertEquals(0, main(kMemSize - 4));
|
|
|
|
array[kMemSize/2 + i] = 1;
|
|
assertEquals(0, main(kMemSize/2 - 4));
|
|
assertEquals(-1, main(kMemSize - 4));
|
|
|
|
array[kMemSize/2 + i] = 0;
|
|
assertEquals(0, main(kMemSize - 4));
|
|
}
|
|
}
|
|
|
|
testPokeOuterMemory();
|
|
|
|
function testOuterMemorySurvivalAcrossGc() {
|
|
var buffer = new WebAssembly.Memory({initial: kMemSize / kPageSize});
|
|
var checker = genAndGetMain(buffer);
|
|
for (var i = 0; i < 3; i++) {
|
|
print("gc run ", i);
|
|
assertEquals(0, checker(kMemSize - 4));
|
|
gc();
|
|
}
|
|
}
|
|
|
|
testOuterMemorySurvivalAcrossGc();
|
|
testOuterMemorySurvivalAcrossGc();
|
|
testOuterMemorySurvivalAcrossGc();
|
|
testOuterMemorySurvivalAcrossGc();
|
|
|
|
|
|
function testOOBThrows() {
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
builder.addMemory(1, 1, true);
|
|
builder.addFunction("geti", kSig_i_ii)
|
|
.addBody([
|
|
kExprGetLocal, 0,
|
|
kExprGetLocal, 1,
|
|
kExprI32LoadMem, 0, 0,
|
|
kExprI32StoreMem, 0, 0,
|
|
kExprGetLocal, 1,
|
|
kExprI32LoadMem, 0, 0,
|
|
])
|
|
.exportFunc();
|
|
|
|
var module = builder.instantiate();
|
|
var offset;
|
|
|
|
function read() { return module.exports.geti(0, offset); }
|
|
function write() { return module.exports.geti(offset, 0); }
|
|
|
|
for (offset = 0; offset < 65533; offset++) {
|
|
assertEquals(0, read());
|
|
assertEquals(0, write());
|
|
}
|
|
|
|
|
|
for (offset = 65534; offset < 66536; offset++) {
|
|
const trap_count = %GetWasmRecoveredTrapCount();
|
|
assertTraps(kTrapMemOutOfBounds, read);
|
|
assertTraps(kTrapMemOutOfBounds, write);
|
|
if (%IsWasmTrapHandlerEnabled()) {
|
|
assertEquals(trap_count + 2, %GetWasmRecoveredTrapCount());
|
|
}
|
|
}
|
|
}
|
|
|
|
testOOBThrows();
|