mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-11-01 12:07:34 +09:00
147 lines
4.9 KiB
JavaScript
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);
|
|
}
|