mirror of
https://github.com/tc39/test262.git
synced 2025-05-03 22:40:28 +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)
152 lines
4.9 KiB
JavaScript
152 lines
4.9 KiB
JavaScript
import Builder from '../Builder.js';
|
|
import * as assert from '../assert.js';
|
|
|
|
|
|
function exportImport(type) {
|
|
let builder = (new Builder())
|
|
.Type().End()
|
|
.Import()
|
|
.Function("imp", "f", type)
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("func", {module: "imp", field: "f"})
|
|
.End()
|
|
.Code().End();
|
|
return new WebAssembly.Module(builder.WebAssembly().get());
|
|
}
|
|
|
|
{
|
|
let type = { params: ["i32"], ret: "i32" };
|
|
let module = exportImport(type);
|
|
let called = false;
|
|
let foo = (i) => {
|
|
called = true;
|
|
return i + 42;
|
|
};
|
|
let instance = new WebAssembly.Instance(module, {imp: {f: foo}});
|
|
assert.truthy(instance.exports.func !== foo);
|
|
for (let i = 0; i < 100; i++) {
|
|
let r1 = instance.exports.func(i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
let r2 = foo(i);
|
|
called = false;
|
|
assert.eq(r1, r2);
|
|
}
|
|
|
|
{
|
|
let builder = (new Builder())
|
|
.Type().End()
|
|
.Import()
|
|
.Function("imp", "f", {params: []})
|
|
.End()
|
|
.Function().End()
|
|
.Code().End();
|
|
let module = new WebAssembly.Module(builder.WebAssembly().get());
|
|
// This should not type check.
|
|
assert.throws(() => new WebAssembly.Instance(module, {imp: {f: instance.exports.func}}), WebAssembly.LinkError, "imported function imp:f signature doesn't match the provided WebAssembly function's signature");
|
|
}
|
|
|
|
{
|
|
assert.truthy(typeof instance.exports.func === "function", "is_function bytecode should handle wrapper function.");
|
|
let value = typeof instance.exports.func;
|
|
assert.eq(value, "function", "the result of typeof should be 'function'");
|
|
}
|
|
}
|
|
|
|
{
|
|
const tableDescription = {element: "anyfunc", initial: 2};
|
|
function makeInstance(type, imp) {
|
|
const builder = new Builder()
|
|
.Type()
|
|
.Func(["i32"], "i32")
|
|
.Func(["i32", "i32"], "i32")
|
|
.End()
|
|
.Import()
|
|
.Table("imp", "table", tableDescription)
|
|
.Function("imp", "f1", {params: ["i32"], ret:"i32"})
|
|
.Function("imp", "f2", {params: ["i32", "i32"], ret:"i32"})
|
|
.End()
|
|
.Function().End()
|
|
.Export()
|
|
.Function("foo")
|
|
.End()
|
|
.Element()
|
|
.Element({offset: 0, functionIndices: [0, 1]})
|
|
.End()
|
|
.Code()
|
|
.Function("foo", 1)
|
|
.GetLocal(1) // parameter to call
|
|
.GetLocal(0) // call index
|
|
.CallIndirect(0, 0) // calling function of type ['i32'] => 'i32'
|
|
.Return()
|
|
.End()
|
|
.End();
|
|
let module = new WebAssembly.Module(builder.WebAssembly().get());
|
|
return new WebAssembly.Instance(module, imp);
|
|
}
|
|
|
|
function Bar(){};
|
|
noInline(Bar);
|
|
let called = false;
|
|
let foo = (i) => {
|
|
called = true;
|
|
new Bar;
|
|
return i*42;
|
|
}
|
|
let table = new WebAssembly.Table(tableDescription);
|
|
let inst = makeInstance({params:['i32'], ret:"i32"}, {imp: {f1: foo, f2:foo, table}});
|
|
for (let i = 0; i < 1000; i++) {
|
|
let r1 = inst.exports.foo(0, i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
let r2 = foo(i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
assert.eq(r1, r2);
|
|
}
|
|
for (let i = 0; i < 1000; i++) {
|
|
assert.throws(() => inst.exports.foo(1, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match");
|
|
assert.truthy(!called);
|
|
}
|
|
for (let i = 0; i < 1000; i++) {
|
|
let r1 = table.get(0)(i);
|
|
table.set(0, table.get(0)); // just make sure setting a wrapper function works.
|
|
assert.truthy(called);
|
|
called = false;
|
|
let r2 = table.get(1)(i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
assert.eq(r1, r2);
|
|
}
|
|
|
|
{
|
|
let nextInst = makeInstance({params:['i32'], ret:"i32"}, {imp: {f1: table.get(0), f2:inst.exports.foo, table}});
|
|
for (let i = 0; i < 1000; i++) {
|
|
let r1 = nextInst.exports.foo(0, i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
let r2 = foo(i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
assert.eq(r1, r2);
|
|
}
|
|
|
|
for (let i = 0; i < 1000; i++) {
|
|
assert.throws(() => nextInst.exports.foo(1, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match");
|
|
assert.truthy(!called);
|
|
}
|
|
|
|
for (let i = 0; i < 1000; i++) {
|
|
let r1 = table.get(1)(0, i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
let r2 = foo(i);
|
|
assert.truthy(called);
|
|
called = false;
|
|
assert.eq(r1, r2);
|
|
}
|
|
}
|
|
}
|