From cca68421831d0b5aadb82a649921188e343094e0 Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Wed, 5 Mar 2025 23:59:18 +0000
Subject: [PATCH] wasm: do not use wasm type reflection in dyld

The wasm dynamic linker used to depend on v8's experimental wasm type
reflection support to generate stub functions when treating GOT.func
items that aren't exported by any loaded library yet. However, as we
work towards wasm ghci browser mode (#25399), we need to ensure the
wasm dyld logic is portable across browsers. So this commit removes
the usage of wasm type reflection in wasm dyld, and it shall only be
added many months later when this feature is widely available in
browsers.
---
 utils/jsffi/dyld.mjs | 34 +++++++++-------------------------
 1 file changed, 9 insertions(+), 25 deletions(-)

diff --git a/utils/jsffi/dyld.mjs b/utils/jsffi/dyld.mjs
index db9c8b382d6..30c0d4dea56 100755
--- a/utils/jsffi/dyld.mjs
+++ b/utils/jsffi/dyld.mjs
@@ -1,4 +1,4 @@
-#!/usr/bin/env -S node --disable-warning=ExperimentalWarning --experimental-wasm-type-reflection --max-old-space-size=65536 --no-turbo-fast-api-calls --wasm-lazy-validation
+#!/usr/bin/env -S node --disable-warning=ExperimentalWarning --max-old-space-size=65536 --no-turbo-fast-api-calls --wasm-lazy-validation
 
 // Note [The Wasm Dynamic Linker]
 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -693,30 +693,15 @@ class DyLD {
             continue;
           }
 
-          // For lazy GOT.func entries we can do better than poison:
-          // insert a stub in the table, so we at least get an error
-          // message that includes the missing function's name, not a
-          // mysterious table trap. The function type is Cmm function
-          // type as a best effort guess, if there's a type mismatch
-          // then call_indirect would trap.
-          //
-          // Also set a __poison field since we can't compare value
-          // against DyLD.#poison.
+          // Can't find this function, so poison it like GOT.mem.
+          // TODO: when wasm type reflection is widely available in
+          // browsers, use the WebAssembly.Function constructor to
+          // dynamically create a stub function that does better error
+          // reporting
           this.#gotFunc[name] = new WebAssembly.Global(
             { value: "i32", mutable: true },
-            this.#table.grow(
-              1,
-              new WebAssembly.Function(
-                { parameters: [], results: ["i32"] },
-                () => {
-                  throw new WebAssembly.RuntimeError(
-                    `non-existent function ${name}`
-                  );
-                }
-              )
-            )
+            DyLD.#poison
           );
-          this.#gotFunc[name].__poison = true;
           continue;
         }
 
@@ -754,8 +739,7 @@ class DyLD {
           if (this.#gotFunc[k]) {
             // ghc-prim/ghc-internal may export functions imported by
             // rts
-            assert(this.#gotFunc[k].__poison);
-            delete this.#gotFunc[k].__poison;
+            assert(this.#gotFunc[k].value === DyLD.#poison);
             this.#table.set(this.#gotFunc[k].value, v);
           }
           continue;
@@ -830,7 +814,7 @@ class DyLD {
     if (this.#gotMem[sym] && this.#gotMem[sym].value !== DyLD.#poison) {
       return this.#gotMem[sym].value;
     }
-    if (this.#gotFunc[sym] && !this.#gotFunc[sym].__poison) {
+    if (this.#gotFunc[sym] && this.#gotFunc[sym].value !== DyLD.#poison) {
       return this.#gotFunc[sym].value;
     }
     // Not in GOT.func yet, create the entry on demand
-- 
GitLab