[Git][ghc/ghc][master] 2 commits: wasm: fix setImmediate() implementation for Cloudflare Workers

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Tue Nov 12 06:27:39 UTC 2024



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00
wasm: fix setImmediate() implementation for Cloudflare Workers

This patch fixes setImmediate() implementation for Cloudflare Workers
in the wasm backend's js prelude script. Cloudflare Workers doesn't
support the MessageChannel API, and we use a setTimeout() based
fallback implementation in this case.

- - - - -
bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00
wasm: fix FinalizationRegistry logic for Cloudflare Workers

This patch fixes FinalizationRegistry related logic for Cloudflare
Workers in wasm backend js post linker. Cloudflare Workers doesn't
support FinalizationRegistry, in this case we use a dummy
implementation that doesn't do anything.

- - - - -


2 changed files:

- utils/jsffi/post-link.mjs
- utils/jsffi/prelude.mjs


Changes:

=====================================
utils/jsffi/post-link.mjs
=====================================
@@ -62,7 +62,7 @@ export async function postLink(mod) {
   // Keep this in sync with dyld.mjs!
   src = `${src}\nexport default (__exports) => {`;
   src = `${src}\nconst __ghc_wasm_jsffi_jsval_manager = new JSValManager();`;
-  src = `${src}\nconst __ghc_wasm_jsffi_finalization_registry = new FinalizationRegistry(sp => __exports.rts_freeStablePtr(sp));`;
+  src = `${src}\nconst __ghc_wasm_jsffi_finalization_registry = globalThis.FinalizationRegistry ? new FinalizationRegistry(sp => __exports.rts_freeStablePtr(sp)) : { register: () => {}, unregister: () => true };`;
   src = `${src}\nreturn {`;
   src = `${src}\nnewJSVal: (v) => __ghc_wasm_jsffi_jsval_manager.newJSVal(v),`;
   src = `${src}\ngetJSVal: (k) => __ghc_wasm_jsffi_jsval_manager.getJSVal(k),`;


=====================================
utils/jsffi/prelude.mjs
=====================================
@@ -51,6 +51,10 @@ export class JSValManager {
 
 // The actual setImmediate() to be used. This is a ESM module top
 // level binding and doesn't pollute the globalThis namespace.
+//
+// To benchmark different setImmediate() implementations in the
+// browser, use https://github.com/jphpsf/setImmediate-shim-demo as a
+// starting point.
 const setImmediate = await (async () => {
   // node, bun, or other scripts might have set this up in the browser
   if (globalThis.setImmediate) {
@@ -67,30 +71,35 @@ const setImmediate = await (async () => {
     return (cb, ...args) => scheduler.postTask(() => cb(...args));
   }
 
-  // A simple & fast setImmediate() implementation for browsers. It's
-  // not a drop-in replacement for node.js setImmediate() because:
-  // 1. There's no clearImmediate(), and setImmediate() doesn't return
-  //    anything
-  // 2. There's no guarantee that callbacks scheduled by setImmediate()
-  //    are executed in the same order (in fact it's the opposite lol),
-  //    but you are never supposed to rely on this assumption anyway
-  class SetImmediate {
-    #fs = [];
-    #mc = new MessageChannel();
+  // Cloudflare workers doesn't support MessageChannel
+  if (globalThis.MessageChannel) {
+    // A simple & fast setImmediate() implementation for browsers. It's
+    // not a drop-in replacement for node.js setImmediate() because:
+    // 1. There's no clearImmediate(), and setImmediate() doesn't return
+    //    anything
+    // 2. There's no guarantee that callbacks scheduled by setImmediate()
+    //    are executed in the same order (in fact it's the opposite lol),
+    //    but you are never supposed to rely on this assumption anyway
+    class SetImmediate {
+      #fs = [];
+      #mc = new MessageChannel();
 
-    constructor() {
-      this.#mc.port1.addEventListener("message", () => {
-        this.#fs.pop()();
-      });
-      this.#mc.port1.start();
-    }
+      constructor() {
+        this.#mc.port1.addEventListener("message", () => {
+          this.#fs.pop()();
+        });
+        this.#mc.port1.start();
+      }
 
-    setImmediate(cb, ...args) {
-      this.#fs.push(() => cb(...args));
-      this.#mc.port2.postMessage(undefined);
+      setImmediate(cb, ...args) {
+        this.#fs.push(() => cb(...args));
+        this.#mc.port2.postMessage(undefined);
+      }
     }
+
+    const sm = new SetImmediate();
+    return (cb, ...args) => sm.setImmediate(cb, ...args);
   }
 
-  const sm = new SetImmediate();
-  return (cb, ...args) => sm.setImmediate(cb, ...args);
+  return (cb, ...args) => setTimeout(cb, 0, ...args);
 })();



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ad9ac63abed33aa48d4df40142d2809bdfd1ff0...bea8ea4cabcd51d098a361bd27d78884effa5d00

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ad9ac63abed33aa48d4df40142d2809bdfd1ff0...bea8ea4cabcd51d098a361bd27d78884effa5d00
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20241112/5d984ecb/attachment-0001.html>


More information about the ghc-commits mailing list