blob: e4e286d88f2332cdea815920ba67377fe091ea34 [file] [log] [blame]
import * as assert from '../assert.js';
import Builder from '../Builder.js';
const numRandomIterations = 128;
// Generate wasm export functions of arity [0, max), using each valid
// WebAssembly type as parameters. Make sure this number is high enough to force
// non-register calls.
const maxArities = 64;
// Calls a "check" function for each parameter received.
const paramExporter = (params, returnedParam, imports) => {
const ret = params.length ? params[returnedParam] : "void";
let builder = (new Builder())
.Type().End()
.Import()
.Function("imp", "checki32", { params: ["i32"] })
.Function("imp", "checkf32", { params: ["f32"] })
.Function("imp", "checkf64", { params: ["f64"] })
.End()
.Function().End()
.Export()
.Function("func")
.End()
.Code()
.Function("func", { params: params, ret: ret });
for (let i = 0; i < params.length; ++i) {
builder = builder.GetLocal(i);
switch (params[i]) {
case "i32": builder = builder.Call(0); break;
case "f32": builder = builder.Call(1); break;
case "f64": builder = builder.Call(2); break;
default: throw new Error(`Unexpected type`);
}
}
if (ret !== "void")
builder = builder.GetLocal(returnedParam);
builder = builder.Return().End().End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
return new WebAssembly.Instance(module, { imp: imports });
};
var buffer = new ArrayBuffer(8);
var viewi16 = new Int16Array(buffer);
var viewi32 = new Int32Array(buffer);
var viewf32 = new Float32Array(buffer);
var viewf64 = new Float64Array(buffer);
const random16 = () => (Math.random() * (1 + 0xffff)) | 0;
const setBuffer = () => {
for (let i = 0; i < 4; ++i)
viewi16[i] = random16();
};
const types = [
{ type: "i32", generate: () => { setBuffer(); return viewi32[0]; } },
// i64 isn't supported.
{ type: "f32", generate: () => { setBuffer(); return viewf32[0]; } },
{ type: "f64", generate: () => { setBuffer(); return viewf64[0]; } },
];
for (let iteration = 0; iteration < numRandomIterations; ++iteration) {
const arity = (Math.random() * (maxArities + 1)) | 0;
let params = [];
let args = [];
for (let a = 0; a < arity; ++a) {
const type =( Math.random() * types.length) | 0;
params.push(types[type].type);
args.push(types[type].generate());
}
let numChecked = 0;
const imports = {
checki32: v => assert.eq(v, args[numChecked++]),
checkf32: v => assert.eq(v, args[numChecked++]),
checkf64: v => assert.eq(v, args[numChecked++]),
};
const returnedParam = (Math.random() * params.length) | 0;
const instance = paramExporter(params, returnedParam, imports);
const result = instance.exports.func(...args);
assert.eq(result, args.length ? args[returnedParam] : undefined);
}