summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/multi-value/call-js.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/multi-value/call-js.js')
-rw-r--r--js/src/jit-test/tests/wasm/multi-value/call-js.js138
1 files changed, 138 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/multi-value/call-js.js b/js/src/jit-test/tests/wasm/multi-value/call-js.js
new file mode 100644
index 0000000000..7af031e5f0
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/multi-value/call-js.js
@@ -0,0 +1,138 @@
+
+wasmFullPass(`
+ (module
+ (import "env" "f" (func $f (result i32 i32 i32)))
+ (func (export "run") (result i32)
+ (call $f)
+ i32.sub
+ i32.sub))`,
+ 42,
+ { env: { f: () => [52, 10, 0] } });
+
+wasmFullPass(`
+ (module
+ (import "env" "f" (func $f (result i64 i64 i64)))
+ (func (export "run") (result i64)
+ (call $f)
+ i64.sub
+ i64.sub))`,
+ 42n,
+ { env: { f: () => [52n, 10n, 0n] } });
+
+wasmFullPass(`
+ (module
+ (import "env" "f" (func $f (result f32 f32 f32)))
+ (func (export "run") (result i32)
+ (call $f)
+ f32.sub
+ f32.sub
+ i32.trunc_f32_s))`,
+ 42,
+ { env: { f: () => [52.25, 10.5, 0.25] } });
+
+wasmFullPass(`
+ (module
+ (import "env" "f" (func $f (result f64 f64 f64)))
+ (func (export "run") (result i32)
+ (call $f)
+ f64.sub
+ f64.sub
+ i32.trunc_f64_s))`,
+ 42,
+ { env: { f: () => [52.25, 10.5, 0.25] } });
+
+// Multiple values are returned as an iterable; it doesn't have to be an array.
+function expectMultiValuePass(f) {
+ wasmFullPass(`
+ (module
+ (import "env" "f" (func $f (result i32 i32 i32)))
+ (func (export "run") (result i32)
+ (call $f)
+ i32.sub
+ i32.sub))`,
+ 42,
+ { env: { f } });
+}
+function expectMultiValueError(f, type, pattern) {
+ let module = new WebAssembly.Module(wasmTextToBinary(`
+ (module
+ (import "env" "f" (func $f (result i32 i32 i32)))
+ (func (export "run") (result i32)
+ (call $f)
+ i32.sub
+ i32.sub))`));
+
+ let instance = new WebAssembly.Instance(module, { env: { f } } );
+ assertErrorMessage(() => instance.exports.run(), type, pattern);
+}
+
+expectMultiValuePass(() => [52, 10, 0]);
+expectMultiValuePass(() => [32, -10, 0]);
+expectMultiValuePass(() => [52.75, 10, 0.5]); // Values converted to i32 via ToInt32.
+expectMultiValuePass(() => [42, undefined, undefined]);
+expectMultiValuePass(() => (function*() { yield 52; yield 10; yield 0; })());
+expectMultiValuePass(() => (function*() { yield '52'; yield '10'; yield 0; })());
+
+// Multi-value result must be iterable.
+expectMultiValueError(() => 1, TypeError, /iterable/);
+expectMultiValueError(() => 1n, TypeError, /iterable/);
+
+// Check that the iterator's values are collected first, and that the
+// length of the result is correct.
+expectMultiValueError(() => [1], TypeError, /expected 3, got 1/);
+expectMultiValueError(() => [1n], TypeError, /expected 3, got 1/);
+expectMultiValueError(() => [52, 10, 0, 0], TypeError, /expected 3, got 4/);
+expectMultiValueError(() => (function*() { yield 52; yield 10; yield 0; yield 0; })(),
+ TypeError, /expected 3, got 4/);
+
+// Check that side effects from conversions are done in order.
+{
+ let calls = [];
+ function log(x) { calls.push(x); return x; }
+ function logged(x) { return { valueOf: () => log(x) } }
+ expectMultiValuePass(() => [logged(52), logged(10), logged(0)]);
+ assertEq(calls.join(','), '52,10,0');
+}
+
+function expectMultiValueResult(text, expected) {
+ let instance = wasmEvalText(text);
+ assertDeepEq(instance.exports.run(), expected);
+}
+
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result i32 i32 i32)
+ (i32.const 0)
+ (i32.const 52)
+ (i32.const 10)))`, [0, 52, 10]);
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result f32 f32 f32)
+ (f32.const 0.5)
+ (f32.const 52.5)
+ (f32.const 10.5)))`, [0.5, 52.5, 10.5]);
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result f64 f64 f64)
+ (f64.const 0.5)
+ (f64.const 52.5)
+ (f64.const 10.5)))`, [0.5, 52.5, 10.5]);
+
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result i32 i64 i32)
+ (i32.const 0)
+ (i64.const 52)
+ (i32.const 10)))`, [0, 52n, 10]);
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result i64 i32 i64)
+ (i64.const 0)
+ (i32.const 52)
+ (i64.const 10)))`, [0n, 52, 10n]);
+expectMultiValueResult(`
+ (module
+ (func (export "run") (result i64 i64 i64)
+ (i64.const 0)
+ (i64.const 52)
+ (i64.const 10)))`, [0n, 52n, 10n]);