Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 51f470a0 by soulomoon at 2025-09-27T20:32:57-04:00 Remove hptAllInstances usage during upsweep Previously, during the upsweep phase when checking safe imports, we were loading the module interface with runTcInteractive, which in turn calls hptAllInstances. This accesses non-below modules from the home package table. Change the implementation of checkSafeImports to use initTcWithGbl and loadSysInterface to load the module interface, since we already have TcGblEnv at hand. This eliminates the unnecessary use of runTcInteractive and hptAllInstances during the upsweep phase. - - - - - 4307f32b by Ben Gamari at 2025-09-27T20:32:58-04:00 base: Update changelog to reflect timing of IOPort# removal This change will make 9.14 afterall. - - - - - 9419d402 by Cheng Shao at 2025-09-27T20:32:58-04:00 rts: fix wasm JSFFI initialization constructor code This commit fixes wasm JSFFI initialization constructor code so that the constructor is self-contained and avoids invoking a fake __main_argc_argv function. The previous approach of reusing __main_void logic in wasi-libc saves a tiny bit of code, at the expense of link-time trouble whenever GHC links a wasm module without -no-hs-main, in which case the driver-generated main function would clash with the definition here, resulting in a linker error. It's simply better to avoid messing with the main function, and it would additionally allow linking wasm32-wasi command modules that does make use of synchronous JSFFI. - - - - - dd8382a4 by Cheng Shao at 2025-09-27T20:32:59-04:00 rts: provide stub implementations of ExecPage functions for wasm This patch provides stub implementations of ExecPage functions for wasm. They are never actually invoked at runtime for any non-TNTC platform, yet they can cause link-time errors of missing symbols when the GHCi.InfoTable module gets linked into the final wasm module (e.g. a GHC API program). - - - - - 4 changed files: - compiler/GHC/Driver/Main.hs - libraries/base/changelog.md - rts/ExecPage.c - rts/wasm/JSFFI.c Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -165,7 +165,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface, loadSysInterface ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -1765,7 +1765,7 @@ hscCheckSafe' m l = do -- so we need to call 'getModuleInterface' to load from disk case iface of Just _ -> return iface - Nothing -> snd `fmap` (liftIO $ getModuleInterface hsc_env m) + Nothing -> liftIO $ initIfaceLoad hsc_env (Just <$> loadSysInterface (text "checkSafeImports") m) -- | Check the list of packages are trusted. ===================================== libraries/base/changelog.md ===================================== @@ -6,7 +6,6 @@ * Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338)) * Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356)) * Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332)) - * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213)) * Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351)) * Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350)) * Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339)) @@ -37,7 +36,7 @@ * `GHC.TypeNats.Internal` * `GHC.ExecutionStack.Internal`. * Deprecate `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329) - + * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213)) * Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)). * Fix the rewrite rule for `scanl'` not being strict in the first element of the output list ([#26143](https://gitlab.haskell.org/ghc/ghc/-/issues/26143)). ===================================== rts/ExecPage.c ===================================== @@ -10,15 +10,23 @@ #include "linker/MMap.h" ExecPage *allocateExecPage(void) { +#if defined(wasm32_HOST_ARCH) + return NULL; +#else ExecPage *page = (ExecPage *) mmapAnon(getPageSize()); return page; +#endif } void freezeExecPage(ExecPage *page) { +#if !defined(wasm32_HOST_ARCH) mprotectForLinker(page, getPageSize(), MEM_READ_EXECUTE); flushExec(getPageSize(), page); +#endif } void freeExecPage(ExecPage *page) { +#if !defined(wasm32_HOST_ARCH) munmapForLinker(page, getPageSize(), "freeExecPage"); +#endif } ===================================== rts/wasm/JSFFI.c ===================================== @@ -5,6 +5,8 @@ #include "Threads.h" #include "sm/Sanity.h" +#include <sysexits.h> + #if defined(__wasm_reference_types__) extern HsBool rts_JSFFI_flag; @@ -12,21 +14,8 @@ extern HsStablePtr rts_threadDelay_impl; extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure; extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure; -int __main_void(void); - -int __main_argc_argv(int, char*[]); - -int __main_argc_argv(int argc, char *argv[]) { - RtsConfig __conf = defaultRtsConfig; - __conf.rts_opts_enabled = RtsOptsAll; - __conf.rts_hs_main = false; - hs_init_ghc(&argc, &argv, __conf); - // See Note [threadDelay on wasm] for details. - rts_JSFFI_flag = HS_BOOL_TRUE; - getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure); - rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure); - return 0; -} +__attribute__((__weak__)) +int __main_argc_argv(int argc, char *argv[]); // Note [JSFFI initialization] // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -66,11 +55,69 @@ int __main_argc_argv(int argc, char *argv[]) { // by the GHC codegen, and priority 102 to the initialization logic // here to ensure hs_init_ghc() sees everything it needs to see. __attribute__((constructor(102))) static void __ghc_wasm_jsffi_init(void) { - // See - // https://gitlab.haskell.org/ghc/wasi-libc/-/blob/master/libc-bottom-half/sour... - // for its definition. It initializes some libc state, then calls - // __main_argc_argv defined above. - __main_void(); + // If linking static code without -no-hs-main, then the driver + // emitted main() is in charge of its own RTS initialization, so + // skip. +#if !defined(__PIC__) + if (__main_argc_argv) { + return; + } +#endif + + // Code below is mirrored from + // https://gitlab.haskell.org/haskell-wasm/wasi-libc/-/blob/master/libc-bottom-..., + // fetches argc/argv using wasi api + __wasi_errno_t err; + + // Get the sizes of the arrays we'll have to create to copy in the args. + size_t argv_buf_size; + size_t argc; + err = __wasi_args_sizes_get(&argc, &argv_buf_size); + if (err != __WASI_ERRNO_SUCCESS) { + _Exit(EX_OSERR); + } + + // Add 1 for the NULL pointer to mark the end, and check for overflow. + size_t num_ptrs = argc + 1; + if (num_ptrs == 0) { + _Exit(EX_SOFTWARE); + } + + // Allocate memory for storing the argument chars. + char *argv_buf = malloc(argv_buf_size); + if (argv_buf == NULL) { + _Exit(EX_SOFTWARE); + } + + // Allocate memory for the array of pointers. This uses `calloc` both to + // handle overflow and to initialize the NULL pointer at the end. + char **argv = calloc(num_ptrs, sizeof(char *)); + if (argv == NULL) { + free(argv_buf); + _Exit(EX_SOFTWARE); + } + + // Fill the argument chars, and the argv array with pointers into those chars. + // TODO: Remove the casts on `argv_ptrs` and `argv_buf` once the witx is + // updated with char8 support. + err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf); + if (err != __WASI_ERRNO_SUCCESS) { + free(argv_buf); + free(argv); + _Exit(EX_OSERR); + } + + // Now that we have argc/argv, proceed to initialize the GHC RTS + RtsConfig __conf = defaultRtsConfig; + __conf.rts_opts_enabled = RtsOptsAll; + __conf.rts_hs_main = false; + hs_init_ghc((int *)&argc, &argv, __conf); + // See Note [threadDelay on wasm] for details. + rts_JSFFI_flag = HS_BOOL_TRUE; + getStablePtr(( + StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure); + rts_threadDelay_impl = getStablePtr(( + StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure); } typedef __externref_t HsJSVal; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/402053d5c6f24ab5e4bce06819a1aba... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/402053d5c6f24ab5e4bce06819a1aba... You're receiving this email because of your account on gitlab.haskell.org.