summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/js-promise-integration/basic.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/js-promise-integration/basic.js')
-rw-r--r--js/src/jit-test/tests/wasm/js-promise-integration/basic.js147
1 files changed, 147 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/js-promise-integration/basic.js b/js/src/jit-test/tests/wasm/js-promise-integration/basic.js
new file mode 100644
index 0000000000..8603886b07
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/js-promise-integration/basic.js
@@ -0,0 +1,147 @@
+// Example from the proposal.
+
+var compute_delta = async (i) => Promise.resolve(i / 100 || 1);
+
+var suspending_compute_delta = new WebAssembly.Function(
+ { parameters: ['externref', 'i32'], results: ['f64'] },
+ compute_delta,
+ { suspending: "first" }
+);
+
+var ins = wasmEvalText(`(module
+ (import "js" "init_state" (func $init_state (result f64)))
+ (import "js" "compute_delta"
+ (func $compute_delta_import (param externref) (param i32) (result f64)))
+
+ (global $suspender (mut externref) (ref.null extern))
+ (global $state (mut f64) (f64.const nan))
+ (func $init (global.set $state (call $init_state)))
+ (start $init)
+
+ (func $compute_delta (param i32) (result f64)
+ (local $suspender_copy externref)
+ (;return (f64.const 0.3);)
+ (;unreachable;)
+ (global.get $suspender)
+ (local.tee $suspender_copy)
+ (local.get 0)
+ (call $compute_delta_import)
+ (local.get $suspender_copy)
+ (global.set $suspender)
+ (return)
+ )
+ (func $get_state (export "get_state") (result f64) (global.get $state))
+ (func $update_state (param i32) (result f64)
+ (global.set $state (f64.add
+ (global.get $state) (call $compute_delta (local.get 0))))
+ (global.get $state)
+ )
+
+ (func (export "update_state_export")
+ (param $suspender externref) (param i32) (result f64)
+ (local.get $suspender)
+ (global.set $suspender)
+ (local.get 1)
+ (call $update_state)
+ (return)
+ )
+)`, {
+ js: {
+ init_state() { return 0; },
+ compute_delta: suspending_compute_delta,
+ },
+});
+
+var update_state = new WebAssembly.Function(
+ { parameters: ['i32'], results: ['externref'] },
+ ins.exports.update_state_export,
+ { promising: "first" }
+);
+
+var res = update_state(4);
+var tasks = res.then((r) => {
+ print(r);
+ assertEq(ins.exports.get_state(), .04);
+});
+
+assertEq(ins.exports.get_state(), 0);
+
+// Also test with exceptions/traps.
+
+async function test(c) {
+ var compute_delta = (i) => Promise.resolve(i/100 || 1);
+ if (c == 1) compute_delta = async (i) => {throw "ff"};
+ if (c == 2) compute_delta = () => {throw "ff";}
+
+ var suspending_compute_delta = new WebAssembly.Function(
+ {parameters:['externref', 'i32'], results:['f64']},
+ compute_delta,
+ {suspending:"first"}
+ );
+
+ var ins = wasmEvalText(`(module
+ (import "js" "init_state" (func $init_state (result f64)))
+ (import "js" "compute_delta"
+ (func $compute_delta_import (param externref) (param i32) (result f64)))
+
+ (global $suspender (mut externref) (ref.null extern))
+ (global $state (mut f64) (f64.const nan))
+ (func $init (global.set $state (call $init_state)))
+ (start $init)
+
+ (func $compute_delta (param i32) (result f64)
+ (local $suspender_copy externref)
+ (;return (f64.const 0.3);)
+ ${c == 3 ? "(unreachable)" : ""}
+ (global.get $suspender)
+ (local.tee $suspender_copy)
+ (local.get 0)
+ (call $compute_delta_import)
+ ${c == 4 ? "(unreachable)" : ""}
+ (local.get $suspender_copy)
+ (global.set $suspender)
+ (return)
+ )
+ (func $get_state (export "get_state") (result f64) (global.get $state))
+ (func $update_state (param i32) (result f64)
+ (global.set $state (f64.add
+ (global.get $state) (call $compute_delta (local.get 0))))
+ (global.get $state)
+ )
+
+ (func (export "update_state_export")
+ (param $suspender externref) (param i32) (result f64)
+ (local.get $suspender)
+ (global.set $suspender)
+ (local.get 1)
+ (call $update_state)
+ (return)
+ )
+ )`, {
+ js: {
+ init_state() { return 0; },
+ compute_delta: suspending_compute_delta,
+ },
+ });
+
+ var update_state = new WebAssembly.Function(
+ {parameters:['i32'], results:['externref']},
+ ins.exports.update_state_export,
+ {promising : "first"}
+ );
+
+ var res = update_state(4);
+ var p = res.then((r) => {
+ assertEq(c, 0);
+ assertEq(ins.exports.get_state(), .04);
+ }).catch(_ => {
+ assertEq(c > 0, true);
+ });
+
+ assertEq(ins.exports.get_state(), 0);
+ await p;
+}
+
+for (let c = 0; c < 5; c++) {
+ tasks = tasks.then(() => test(c));
+}