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)
278 lines
8.3 KiB
JavaScript
278 lines
8.3 KiB
JavaScript
import Builder from '../Builder.js'
|
|
import * as assert from '../assert.js'
|
|
|
|
{
|
|
function makeInstance() {
|
|
const tableDescription = {initial: 1, element: "anyfunc"};
|
|
const builder = new Builder()
|
|
.Type()
|
|
.Func([], "void")
|
|
.End()
|
|
.Import()
|
|
.Table("imp", "table", tableDescription)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params:["i32"], ret:"void"})
|
|
.GetLocal(0) // parameter to call
|
|
.GetLocal(0) // call index
|
|
.CallIndirect(0, 0) // calling function of type [] => 'void'
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
const table = new WebAssembly.Table(tableDescription);
|
|
return {instance: new WebAssembly.Instance(module, {imp: {table}}), table};
|
|
}
|
|
|
|
function makeInstance2(f) {
|
|
const builder = new Builder()
|
|
.Type()
|
|
.End()
|
|
.Import()
|
|
.Function("imp", "f", {params:[], ret:"void"})
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params: [], ret: "void" })
|
|
.Call(0)
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
return new WebAssembly.Instance(module, {imp: {f}});
|
|
}
|
|
|
|
const {instance: i1, table: t1} = makeInstance();
|
|
const foo = i1.exports.foo;
|
|
|
|
let called = false;
|
|
let shouldThrow = false;
|
|
const i2 = makeInstance2(function() {
|
|
called = true;
|
|
if (shouldThrow)
|
|
throw new Error("Threw");
|
|
});
|
|
|
|
t1.set(0, i2.exports.foo);
|
|
for (let i = 0; i < 1000; ++i) {
|
|
foo(0);
|
|
assert.eq(called, true);
|
|
called = false;
|
|
}
|
|
shouldThrow = true;
|
|
for (let i = 0; i < 1000; ++i) {
|
|
assert.throws(() => foo(0), Error, "Threw");
|
|
assert.eq(called, true);
|
|
called = false;
|
|
}
|
|
}
|
|
|
|
{
|
|
function makeInstance() {
|
|
const tableDescription = {initial: 1, element: "anyfunc"};
|
|
const builder = new Builder()
|
|
.Type()
|
|
.Func(["i32"], "void")
|
|
.End()
|
|
.Import()
|
|
.Table("imp", "table", tableDescription)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params:["i32", "i32"], ret:"void"})
|
|
.GetLocal(1) // parameter to call
|
|
.GetLocal(0) // call index
|
|
.CallIndirect(0, 0) // calling function of type ['i32'] => 'void'
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
const table = new WebAssembly.Table(tableDescription);
|
|
return {instance: new WebAssembly.Instance(module, {imp: {table}}), table};
|
|
}
|
|
|
|
function makeInstance2(memory, f) {
|
|
const builder = new Builder()
|
|
.Type()
|
|
.End()
|
|
.Import()
|
|
.Function("imp", "f", {params:['i32', 'i32'], ret:"void"})
|
|
.Memory("imp", "memory", memoryDescription)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params: ["i32"], ret: "void" })
|
|
.GetLocal(0)
|
|
.GetLocal(0)
|
|
.I32Load(2, 0)
|
|
.Call(0)
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
return new WebAssembly.Instance(module, {imp: {f, memory}});
|
|
}
|
|
|
|
const {instance: i1, table: t1} = makeInstance();
|
|
const foo = (memOffset) => i1.exports.foo(0, memOffset);
|
|
|
|
const memoryDescription = {initial:1};
|
|
const mem = new WebAssembly.Memory(memoryDescription);
|
|
let called = false;
|
|
|
|
const pageSize = 64 * 1024;
|
|
let buf = new Uint32Array(mem.buffer);
|
|
const i2 = makeInstance2(mem, function(i, value) {
|
|
assert.eq(i & 3, 0);
|
|
assert.eq(buf[i/4], value);
|
|
called = true;
|
|
});
|
|
t1.set(0, i2.exports.foo);
|
|
|
|
for (let i = 0; i < pageSize/4; ++i) {
|
|
buf[i] = i+1;
|
|
}
|
|
|
|
for (let i = 0; i < pageSize/4; ++i) {
|
|
foo(i*4);
|
|
assert.eq(called, true);
|
|
called = false;
|
|
}
|
|
|
|
for (let i = pageSize/4; i < 2*pageSize/4; ++i) {
|
|
assert.throws(() => foo(i*4), WebAssembly.RuntimeError, "Out of bounds memory access");
|
|
assert.eq(called, false);
|
|
}
|
|
}
|
|
|
|
{
|
|
function makeInstance() {
|
|
const tableDescription = {initial: 1, element: "anyfunc"};
|
|
const builder = new Builder()
|
|
.Type()
|
|
.Func(["i32"], "void")
|
|
.End()
|
|
.Import()
|
|
.Table("imp", "table", tableDescription)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params:["i32", "i32"], ret:"void"})
|
|
.GetLocal(1) // parameter to call
|
|
.GetLocal(0) // call index
|
|
.CallIndirect(0, 0) // calling function of type ['i32'] => 'void'
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
const table = new WebAssembly.Table(tableDescription);
|
|
return {instance: new WebAssembly.Instance(module, {imp: {table}}), table};
|
|
}
|
|
|
|
function makeInstance2(memory, f) {
|
|
const builder = new Builder()
|
|
.Type()
|
|
.End()
|
|
.Import()
|
|
.Function("imp", "f", {params:['i32', 'i32'], ret:"void"})
|
|
.Memory("imp", "memory", memoryDescription)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Code()
|
|
.Function("foo", {params: ["i32"], ret: "void" })
|
|
.GetLocal(0)
|
|
.GetLocal(0)
|
|
.I32Load(2, 0)
|
|
.Call(0)
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
|
|
|
|
const bin = builder.WebAssembly().get();
|
|
const module = new WebAssembly.Module(bin);
|
|
return new WebAssembly.Instance(module, {imp: {f, memory}});
|
|
}
|
|
|
|
function exportImport(f) {
|
|
let builder = (new Builder())
|
|
.Type().End()
|
|
.Import()
|
|
.Function("imp", "f", {params: ['i32'], ret:"void"})
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("func", {module: "imp", field: "f"})
|
|
.End()
|
|
.Code().End();
|
|
return (new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), {imp: {f}})).exports.func;
|
|
}
|
|
|
|
const {instance: i1, table: t1} = makeInstance();
|
|
const foo = (memOffset) => i1.exports.foo(0, memOffset);
|
|
|
|
const memoryDescription = {initial:1};
|
|
const mem = new WebAssembly.Memory(memoryDescription);
|
|
let called = false;
|
|
|
|
const pageSize = 64 * 1024;
|
|
let buf = new Uint32Array(mem.buffer);
|
|
const i2 = makeInstance2(mem, function(i, value) {
|
|
assert.eq(i & 3, 0);
|
|
assert.eq(buf[i/4], value);
|
|
called = true;
|
|
});
|
|
|
|
const exportedImport = exportImport(function(offset) {
|
|
i2.exports.foo(offset);
|
|
});
|
|
t1.set(0, exportedImport);
|
|
|
|
for (let i = 0; i < pageSize/4; ++i) {
|
|
buf[i] = i+1;
|
|
}
|
|
|
|
for (let i = 0; i < pageSize/4; ++i) {
|
|
foo(i*4);
|
|
assert.eq(called, true);
|
|
called = false;
|
|
}
|
|
|
|
for (let i = pageSize/4; i < 2*pageSize/4; ++i) {
|
|
assert.throws(() => foo(i*4), WebAssembly.RuntimeError, "Out of bounds memory access");
|
|
assert.eq(called, false);
|
|
}
|
|
}
|