blob: ab9f64c8c0408c188f1f54ea73f8bdad7278ba98 [file] [log] [blame]
//@ runWebAssemblySuite("--useWebAssemblyReferences=true")
'use strict';
let console = { log: print }
let hostrefs = {};
let hostsym = Symbol("hostref");
function hostref(s) {
if (! (s in hostrefs)) hostrefs[s] = {[hostsym]: s};
return hostrefs[s];
}
function is_hostref(x) {
return (x !== null && hostsym in x) ? 1 : 0;
}
function is_funcref(x) {
return typeof x === "function" ? 1 : 0;
}
function eq_ref(x, y) {
return x === y ? 1 : 0;
}
let spectest = {
hostref: hostref,
is_hostref: is_hostref,
is_funcref: is_funcref,
eq_ref: eq_ref,
print: console.log.bind(console),
print_i32: console.log.bind(console),
print_i32_f32: console.log.bind(console),
print_f64_f64: console.log.bind(console),
print_f32: console.log.bind(console),
print_f64: console.log.bind(console),
global_i32: 666,
global_f32: 666,
global_f64: 666,
table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}),
memory: new WebAssembly.Memory({initial: 1, maximum: 2})
};
let handler = {
get(target, prop) {
return (prop in target) ? target[prop] : {};
}
};
let registry = new Proxy({spectest}, handler);
function register(name, instance) {
registry[name] = instance.exports;
}
function module(bytes, valid = true) {
let buffer = new ArrayBuffer(bytes.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
view[i] = bytes.charCodeAt(i);
}
let validated;
try {
validated = WebAssembly.validate(buffer);
} catch (e) {
throw new Error("Wasm validate throws");
}
if (validated !== valid) {
throw new Error("Wasm validate failure" + (valid ? "" : " expected"));
}
return new WebAssembly.Module(buffer);
}
function instance(bytes, imports = registry) {
return new WebAssembly.Instance(module(bytes), imports);
}
function call(instance, name, args) {
return instance.exports[name](...args);
}
function get(instance, name) {
let v = instance.exports[name];
return (v instanceof WebAssembly.Global) ? v.value : v;
}
function exports(instance) {
return {module: instance.exports, spectest: spectest};
}
function run(action) {
action();
}
function assert_malformed(bytes) {
try { module(bytes, false) } catch (e) {
if (e instanceof WebAssembly.CompileError) return;
}
throw new Error("Wasm decoding failure expected");
}
function assert_invalid(bytes) {
try { module(bytes, false) } catch (e) {
if (e instanceof WebAssembly.CompileError) return;
}
throw new Error("Wasm validation failure expected");
}
function assert_unlinkable(bytes) {
let mod = module(bytes);
try { new WebAssembly.Instance(mod, registry) } catch (e) {
if (e instanceof WebAssembly.LinkError) return;
}
throw new Error("Wasm linking failure expected");
}
function assert_uninstantiable(bytes) {
let mod = module(bytes);
try { new WebAssembly.Instance(mod, registry) } catch (e) {
if (e instanceof WebAssembly.RuntimeError) return;
}
throw new Error("Wasm trap expected");
}
function assert_trap(action) {
try { action() } catch (e) {
if (e instanceof WebAssembly.RuntimeError) return;
}
throw new Error("Wasm trap expected");
}
let StackOverflow;
try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor }
function assert_exhaustion(action) {
try { action() } catch (e) {
if (e instanceof StackOverflow) return;
}
throw new Error("Wasm resource exhaustion expected");
}
function assert_return(action, expected) {
let actual = action();
if (!Object.is(actual, expected)) {
throw new Error("Wasm return value " + expected + " expected, got " + actual);
};
}
function assert_return_canonical_nan(action) {
let actual = action();
// Note that JS can't reliably distinguish different NaN values,
// so there's no good way to test that it's a canonical NaN.
if (!Number.isNaN(actual)) {
throw new Error("Wasm return value NaN expected, got " + actual);
};
}
function assert_return_arithmetic_nan(action) {
// Note that JS can't reliably distinguish different NaN values,
// so there's no good way to test for specific bitpatterns here.
let actual = action();
if (!Number.isNaN(actual)) {
throw new Error("Wasm return value NaN expected, got " + actual);
};
}
function assert_return_ref(action) {
let actual = action();
if (actual === null || typeof actual !== "object" && typeof actual !== "function") {
throw new Error("Wasm reference return value expected, got " + actual);
};
}
function assert_return_func(action) {
let actual = action();
if (typeof actual !== "function") {
throw new Error("Wasm function return value expected, got " + actual);
};
}
// ref_is_null.wast:1
let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x05\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x00\x00\x60\x01\x6f\x00\x60\x01\x7f\x01\x7f\x03\x88\x80\x80\x80\x00\x07\x00\x01\x02\x03\x02\x04\x04\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x02\x70\x00\x02\x07\xc1\x80\x80\x80\x00\x06\x06\x61\x6e\x79\x72\x65\x66\x00\x00\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x01\x04\x69\x6e\x69\x74\x00\x03\x06\x64\x65\x69\x6e\x69\x74\x00\x04\x0b\x61\x6e\x79\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x05\x0c\x66\x75\x6e\x63\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x06\x09\x88\x80\x80\x80\x00\x01\x02\x01\x41\x01\x0b\x01\x02\x0a\xd4\x80\x80\x80\x00\x07\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\xd0\x26\x00\x41\x01\xd0\x26\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x00\x10\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x01\x10\x01\x0b");
// ref_is_null.wast:29
assert_return(() => call($1, "anyref", [null]), 1);
// ref_is_null.wast:30
assert_return(() => call($1, "funcref", [null]), 1);
// ref_is_null.wast:32
assert_return(() => call($1, "anyref", [hostref(1)]), 0);
// ref_is_null.wast:34
run(() => call($1, "init", [hostref(0)]));
// ref_is_null.wast:36
assert_return(() => call($1, "anyref-elem", [0]), 1);
// ref_is_null.wast:37
assert_return(() => call($1, "funcref-elem", [0]), 1);
// ref_is_null.wast:39
assert_return(() => call($1, "anyref-elem", [1]), 0);
// ref_is_null.wast:40
assert_return(() => call($1, "funcref-elem", [1]), 0);
// ref_is_null.wast:42
run(() => call($1, "deinit", []));
// ref_is_null.wast:44
assert_return(() => call($1, "anyref-elem", [0]), 1);
// ref_is_null.wast:45
assert_return(() => call($1, "funcref-elem", [0]), 1);
// ref_is_null.wast:47
assert_return(() => call($1, "anyref-elem", [1]), 1);
// ref_is_null.wast:48
assert_return(() => call($1, "funcref-elem", [1]), 1);