From 43d48b449a46e805e3baeafbafa62b6cd6f761c9 Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Thu, 2 May 2024 09:47:43 +0000
Subject: [PATCH] wasm: use scheduler.postTask() for context switch when
 available

This patch makes use of scheduler.postTask() for JSFFI context switch
when it's available. It's a more principled approach than our
MessageChannel based setImmediate() implementation, and it's available
in latest version of Chromium based browsers.
---
 utils/jsffi/prelude.js | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/utils/jsffi/prelude.js b/utils/jsffi/prelude.js
index a8a3afd0c2f8..e54a29279013 100644
--- a/utils/jsffi/prelude.js
+++ b/utils/jsffi/prelude.js
@@ -75,17 +75,21 @@ class SetImmediate {
 
 // The actual setImmediate() to be used. This is a ESM module top
 // level binding and doesn't pollute the globalThis namespace.
-let setImmediate;
-if (globalThis.setImmediate) {
-  // node.js, bun
-  setImmediate = globalThis.setImmediate;
-} else {
+const setImmediate = await (async () => {
+  // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler
+  if (globalThis.scheduler) {
+    return (cb, ...args) => scheduler.postTask(() => cb(...args));
+  }
+  // node, bun, or other scripts might have set this up in the browser
+  if (globalThis.setImmediate) {
+    return globalThis.setImmediate;
+  }
   try {
     // deno
-    setImmediate = (await import("node:timers")).setImmediate;
+    return (await import("node:timers")).setImmediate;
   } catch {
     // browsers
     const sm = new SetImmediate();
-    setImmediate = (cb, ...args) => sm.setImmediate(cb, ...args);
+    return (cb, ...args) => sm.setImmediate(cb, ...args);
   }
-}
+})();
-- 
GitLab