From bd0a8b7e7537499f7dc703f78ac96f34e4c40554 Mon Sep 17 00:00:00 2001 From: Cheng Shao <terrorjack@type.dance> Date: Wed, 13 Nov 2024 13:43:42 +0000 Subject: [PATCH] wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. --- libraries/ghci/GHCi/ObjLink.hs | 8 ++++---- testsuite/tests/th/wasm/all.T | 2 +- utils/jsffi/dyld.mjs | 23 ++++++++++++++++------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libraries/ghci/GHCi/ObjLink.hs b/libraries/ghci/GHCi/ObjLink.hs index a7232f1ccbe..1875918a921 100644 --- a/libraries/ghci/GHCi/ObjLink.hs +++ b/libraries/ghci/GHCi/ObjLink.hs @@ -76,7 +76,7 @@ loadDLL f = evaluate =<< js_loadDLL (toJSString f) pure $ Right nullPtr -foreign import javascript safe "__exports.__dyld.loadDLL($1)" +foreign import javascript safe "__ghc_wasm_jsffi_dyld.loadDLL($1)" js_loadDLL :: JSString -> IO () loadArchive :: String -> IO () @@ -96,7 +96,7 @@ lookupSymbol sym = do r <- js_lookupSymbol $ toJSString sym evaluate $ if r == nullPtr then Nothing else Just r -foreign import javascript unsafe "__exports.__dyld.lookupSymbol($1)" +foreign import javascript unsafe "__ghc_wasm_jsffi_dyld.lookupSymbol($1)" js_lookupSymbol :: JSString -> IO (Ptr a) lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) @@ -114,7 +114,7 @@ addLibrarySearchPath p = do evaluate =<< js_addLibrarySearchPath (toJSString p) pure nullPtr -foreign import javascript safe "__exports.__dyld.addLibrarySearchPath($1)" +foreign import javascript safe "__ghc_wasm_jsffi_dyld.addLibrarySearchPath($1)" js_addLibrarySearchPath :: JSString -> IO () removeLibrarySearchPath :: Ptr () -> IO Bool @@ -128,7 +128,7 @@ findSystemLibrary f = m `catch` \(_ :: JSException) -> pure Nothing p <- evaluate $ fromJSString p' pure $ Just p -foreign import javascript safe "__exports.__dyld.findSystemLibrary($1)" +foreign import javascript safe "__ghc_wasm_jsffi_dyld.findSystemLibrary($1)" js_findSystemLibrary :: JSString -> IO JSString #else diff --git a/testsuite/tests/th/wasm/all.T b/testsuite/tests/th/wasm/all.T index 9bc4793eaa0..c02fa5ff366 100644 --- a/testsuite/tests/th/wasm/all.T +++ b/testsuite/tests/th/wasm/all.T @@ -2,4 +2,4 @@ setTestOpts([ unless(arch('wasm32'), skip) ]) -test('T25473', [expect_broken(25473)], multimod_compile, ['T25473B', '-v0']) +test('T25473', [], multimod_compile, ['T25473B', '-v0']) diff --git a/utils/jsffi/dyld.mjs b/utils/jsffi/dyld.mjs index 95a93a907d3..0756a525134 100755 --- a/utils/jsffi/dyld.mjs +++ b/utils/jsffi/dyld.mjs @@ -293,9 +293,13 @@ class DyLD { #loadedSos = new Set(); // Mapping from export names to export funcs. It's also passed as - // __exports in JSFFI code, hence the "memory" special field. __dyld - // is used by ghci to call into here. - exportFuncs = { memory: this.#memory, __dyld: this }; + // __exports in JSFFI code, hence the "memory" special field. + exportFuncs = { memory: this.#memory }; + + // The FinalizationRegistry used by JSFFI. + #finalizationRegistry = new FinalizationRegistry((sp) => + this.exportFuncs.rts_freeStablePtr(sp) + ); // The GOT.func table. #gotFunc = {}; @@ -623,17 +627,22 @@ class DyLD { const mod = await modp; - // Fulfill the ghc_wasm_jsffi imports + // Fulfill the ghc_wasm_jsffi imports. Use new Function() + // instead of eval() to prevent bindings in this local scope to + // be accessed by JSFFI code snippets. Object.assign( import_obj.ghc_wasm_jsffi, new Function( - "return (__exports) => ({".concat( + "__exports", + "__ghc_wasm_jsffi_dyld", + "__ghc_wasm_jsffi_finalization_registry", + "return {".concat( ...parseSections(mod).map( (rec) => `${rec[0]}: ${parseRecord(rec)}, ` ), - "});" + "};" ) - )()(this.exportFuncs) + )(this.exportFuncs, this, this.#finalizationRegistry) ); // Fulfill the rest of the imports -- GitLab