blob: b3b401f108fe81382fff402f05b425a3936a4d23 [file] [log] [blame]
import { instantiate } from "../wabt-wrapper.js";
import * as assert from "../assert.js";
const maxArities = 64;
async function paramForwarder(numParams, paramType, value, imports) {
let body = "";
let inlineCheck = "";
for (let i = 0; i < numParams; ++i) {
body += `(get_local ${i + 1}) (call 0)\n`;
inlineCheck += `(i32.lt_u (i32.const ${i + 1}) (get_local 0)) (if
(then (br_if 0 (${paramType}.ne (get_local ${i + 1}) (${paramType}.const ${value}))))
(else (br_if 0 (${paramType}.eq (get_local ${i + 1}) (get_local ${i + 1}))))
)
`;
}
let wat = `
(module
(func (import "env" "check") (param ${paramType}))
(func (export "func") (param i32 ${Array(numParams).fill(paramType).join(" ")})
(block
${body}
${inlineCheck}
return
)
unreachable
)
)
`;
return await instantiate(wat, imports);
}
async function test () {
for (let wasmArity = 20; wasmArity < maxArities; ++wasmArity) {
let callerArity;
let numChecked = 0;
const check = value => {
assert.isNumber(value);
if (callerArity <= wasmArity) {
if (numChecked < callerArity)
assert.eq(value, 64);
else
assert.eq(value, NaN);
} else {
if (numChecked < wasmArity)
assert.eq(value, 64);
else
asseert.eq(value, NaN);
}
++numChecked;
}
const instance = await paramForwarder(wasmArity, "f64", 64, {env: {check}});
for (callerArity = 0; callerArity < maxArities; ++callerArity) {
const params = Array(callerArity + 1).fill(64);
params[0] = callerArity;
instance.exports.func(...params);
numChecked = 0;
}
}
}
assert.asyncTest(test());