mirror of
https://github.com/tc39/test262.git
synced 2025-05-04 15:00:42 +02:00
* [javascriptcore-test262-automation] changes from git@github.com:WebKit/webkit.git at sha 949e26452cfa153a7f4afe593da97e2fe9e1b706 on Tue Jul 03 2018 14:35:15 GMT-0400 (Eastern Daylight Time)
84 lines
3.0 KiB
JavaScript
84 lines
3.0 KiB
JavaScript
import * as assert from '../assert.js';
|
|
import Builder from '../Builder.js';
|
|
|
|
const memoryInfo = { initial: 2 };
|
|
const tableInfo = { element: "anyfunc", initial: 8 };
|
|
|
|
async function StartTrapsAsync() {
|
|
const builder = (new Builder())
|
|
.Type().End()
|
|
.Import()
|
|
.Memory("imp", "memory", memoryInfo)
|
|
.Table("imp", "table", tableInfo)
|
|
.Function("imp", "func", { params: ["i32"] })
|
|
.End()
|
|
.Function().End()
|
|
.Start("startMeUp").End()
|
|
.Element()
|
|
.Element({ offset: 4, functionIndices: [0, 1] })
|
|
.End()
|
|
.Code()
|
|
.Function("startMeUp", { params: [] })
|
|
.I32Const(0).I32Load(2, 0).I32Const(0xfeedface).I32Store(2, 0)
|
|
.I32Const(4).I32Load(2, 0).I32Const(0xc0fec0fe).I32Store(2, 0) // This will trap.
|
|
// This is unreachable:
|
|
.I32Const(42).Call(0) // Calls func(42).
|
|
.End()
|
|
.End()
|
|
.Data()
|
|
.Segment([0xef, 0xbe, 0xad, 0xde]).Offset(1024).End()
|
|
.End();
|
|
|
|
const memory = new WebAssembly.Memory(memoryInfo);
|
|
const buffer = new Uint32Array(memory.buffer);
|
|
|
|
const table = new WebAssembly.Table(tableInfo);
|
|
|
|
// The instance will use these as addresses for stores.
|
|
buffer[0] = 128;
|
|
buffer[1] = 0xc0defefe; // This is out of bounds.
|
|
|
|
// This function shouldn't get called because the trap occurs before the call.
|
|
let value = 0;
|
|
const func = v => value = v;
|
|
|
|
const module = new WebAssembly.Module(builder.WebAssembly().get());
|
|
const imp = { imp: { memory, table, func } };
|
|
|
|
const promise = WebAssembly.instantiate(module, imp);
|
|
await assert.throwsAsync(promise, WebAssembly.RuntimeError, `Out of bounds memory access`);
|
|
|
|
assert.eq(value, 0);
|
|
|
|
for (let i = 0; i < buffer.length; ++i) {
|
|
switch (i) {
|
|
case 0: assert.eq(buffer[i], 128); break; // Initial ArrayBuffer store.
|
|
case 1: assert.eq(buffer[i], 0xc0defefe); break; // Initial ArrayBuffer store.
|
|
case 32: assert.eq(buffer[i], 0xfeedface); break; // First store from start function.
|
|
case 256: assert.eq(buffer[i], 0xdeadbeef); break; // Data segment.
|
|
default: assert.eq(buffer[i], 0); break; // The rest.
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < table.length; ++i) {
|
|
switch (i) {
|
|
case 4: assert.isFunction(table.get(i)); break;
|
|
case 5: assert.isFunction(table.get(i)); break;
|
|
default: assert.eq(table.get(i), null); break;
|
|
}
|
|
}
|
|
|
|
// Call the imported `func`.
|
|
table.get(4)(0xf00f);
|
|
assert.eq(value, 0xf00f);
|
|
value = 0;
|
|
|
|
// Call the start function again on the instance. The instance is otherwise inaccessible!
|
|
buffer[32] = 0; // Reset the location which will be set by the first store.
|
|
assert.throws(() => table.get(5)(), WebAssembly.RuntimeError, `Out of bounds memory access`);
|
|
assert.eq(buffer[32], 0xfeedface); // The first store should still succeed.
|
|
assert.eq(value, 0);
|
|
}
|
|
|
|
assert.asyncTest(StartTrapsAsync());
|