diff --git a/libraries/ghci/GHCi/ObjLink.hs b/libraries/ghci/GHCi/ObjLink.hs index a7232f1ccbe8b0e6d1192bdff4cebf7a3a90eaf3..1875918a9210ea5ac126a810fe7266eb5e37ecc6 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 9bc4793eaa08b33c6390dc3dbd0d94800a106d7b..c02fa5ff366bafb5aa07c3831fff15c6ca21b7b8 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 2f67a8e89e1b565086cc3ce017ecb20d154f4473..3c1c2106557af837d978f495343e2fe1e7acf8e3 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