Dactyloidae/js/src/jit-test/lib/wasm.js

147 lines
4.9 KiB
JavaScript

if (!wasmIsSupported())
quit();
load(libdir + "asserts.js");
function wasmEvalText(str, imports) {
let binary = wasmTextToBinary(str);
let valid = WebAssembly.validate(binary);
let m;
try {
m = new WebAssembly.Module(binary);
assertEq(valid, true);
} catch(e) {
assertEq(valid, false);
throw e;
}
return new WebAssembly.Instance(m, imports);
}
function wasmValidateText(str) {
assertEq(WebAssembly.validate(wasmTextToBinary(str)), true);
}
function wasmFailValidateText(str, pattern) {
let binary = wasmTextToBinary(str);
assertEq(WebAssembly.validate(binary), false);
assertErrorMessage(() => new WebAssembly.Module(binary), WebAssembly.CompileError, pattern);
}
function mismatchError(actual, expect) {
var str = `type mismatch: expression has type ${actual} but expected ${expect}`;
return RegExp(str);
}
function jsify(wasmVal) {
if (wasmVal === 'nan')
return NaN;
if (wasmVal === 'infinity')
return Infinity;
if (wasmVal === '-infinity')
return Infinity;
if (wasmVal === '-0')
return -0;
return wasmVal;
}
// Assert that the expected value is equal to the int64 value, as passed by
// Baldr: {low: int32, high: int32}.
// - if the expected value is in the int32 range, it can be just a number.
// - otherwise, an object with the properties "high" and "low".
function assertEqI64(observed, expect) {
assertEq(typeof observed, 'object', "observed must be an i64 object");
assertEq(typeof expect === 'object' || typeof expect === 'number', true,
"expect must be an i64 object or number");
let {low, high} = observed;
if (typeof expect === 'number') {
assertEq(expect, expect | 0, "in int32 range");
assertEq(low, expect | 0, "low 32 bits don't match");
assertEq(high, expect < 0 ? -1 : 0, "high 32 bits don't match"); // sign extension
} else {
assertEq(typeof expect.low, 'number');
assertEq(typeof expect.high, 'number');
assertEq(low, expect.low | 0, "low 32 bits don't match");
assertEq(high, expect.high | 0, "high 32 bits don't match");
}
}
// Asserts in Baldr test mode that NaN payloads match.
function assertEqNaN(x, y) {
if (typeof x === 'number') {
assertEq(Number.isNaN(x), Number.isNaN(y));
return;
}
assertEq(typeof x === 'object' &&
typeof x.nan_low === 'number',
true,
"assertEqNaN args must have shape {nan_high, nan_low}");
assertEq(typeof y === 'object' &&
typeof y.nan_low === 'number',
true,
"assertEqNaN args must have shape {nan_high, nan_low}");
assertEq(typeof x.nan_high,
typeof y.nan_high,
"both args must have nan_high, or none");
assertEq(x.nan_high, y.nan_high, "assertEqNaN nan_high don't match");
if (typeof x.nan_low !== 'undefined')
assertEq(x.nan_low, y.nan_low, "assertEqNaN nan_low don't match");
}
function createI64(val) {
let ret;
if (typeof val === 'number') {
assertEq(val, val|0, "number input to createI64 must be an int32");
ret = {
low: val,
high: val < 0 ? -1 : 0 // sign extension
};
} else {
assertEq(typeof val, 'string');
assertEq(val.slice(0, 2), "0x");
val = val.slice(2).padStart(16, '0');
ret = {
low: parseInt(val.slice(8, 16), 16),
high: parseInt(val.slice(0, 8), 16)
};
}
return ret;
}
function _wasmFullPassInternal(assertValueFunc, text, expected, maybeImports, ...args) {
let binary = wasmTextToBinary(text);
assertEq(WebAssembly.validate(binary), true, "Must validate.");
let module = new WebAssembly.Module(binary);
let instance = new WebAssembly.Instance(module, maybeImports);
assertEq(typeof instance.exports.run, 'function', "A 'run' function must be exported.");
assertValueFunc(instance.exports.run(...args), expected, "Initial module must return the expected result.");
let retext = wasmBinaryToText(binary);
let rebinary = wasmTextToBinary(retext);
assertEq(WebAssembly.validate(rebinary), true, "Recreated binary must validate.");
let remodule = new WebAssembly.Module(rebinary);
let reinstance = new WebAssembly.Instance(remodule, maybeImports);
assertValueFunc(reinstance.exports.run(...args), expected, "Reformed module must return the expected result");
}
// Fully test a module:
// - ensure it validates.
// - ensure it compiles and produces the expected result.
// - ensure textToBinary(binaryToText(binary)) = binary
// Preconditions:
// - the binary module must export a function called "run".
function wasmFullPass(text, expected, maybeImports, ...args) {
_wasmFullPassInternal(assertEq, text, expected, maybeImports, ...args);
}
function wasmFullPassI64(text, expected, maybeImports, ...args) {
_wasmFullPassInternal(assertEqI64, text, expected, maybeImports, ...args);
}