Cheng Shao pushed to branch wip/batch-loaddll at Glasgow Haskell Compiler / GHC

Commits:

19 changed files:

Changes:

  • compiler/GHC/ByteCode/Asm.hs
    ... ... @@ -843,16 +843,18 @@ assembleI platform i = case i of
    843 843
     
    
    844 844
       BRK_FUN ibi@(InternalBreakpointId info_mod infox) -> do
    
    845 845
         p1 <- ptr $ BCOPtrBreakArray info_mod
    
    846
    -    let -- cast that checks that round-tripping through Word16 doesn't change the value
    
    847
    -        toW16 x = let r = fromIntegral x :: Word16
    
    848
    -                  in if fromIntegral r == x
    
    846
    +    let -- cast that checks that round-tripping through Word32 doesn't change the value
    
    847
    +        infoW32 = let r = fromIntegral infox :: Word32
    
    848
    +                   in if fromIntegral r == infox
    
    849 849
                         then r
    
    850
    -                    else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)
    
    850
    +                    else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr infox)
    
    851
    +        ix_hi = fromIntegral (infoW32 `shiftR` 16)
    
    852
    +        ix_lo = fromIntegral (infoW32 .&. 0xffff)
    
    851 853
         info_addr        <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName info_mod
    
    852 854
         info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS     $ moduleUnitId info_mod
    
    853 855
         np               <- lit1 $ BCONPtrCostCentre ibi
    
    854 856
         emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr
    
    855
    -                      , SmallOp (toW16 infox), Op np ]
    
    857
    +                      , SmallOp ix_hi, SmallOp ix_lo, Op np ]
    
    856 858
     
    
    857 859
       BRK_ALTS active -> emit_ bci_BRK_ALTS [SmallOp (if active then 1 else 0)]
    
    858 860
     
    

  • compiler/GHC/Driver/Plugins.hs
    ... ... @@ -421,7 +421,7 @@ loadExternalPlugins ps = do
    421 421
     loadExternalPluginLib :: FilePath -> IO ()
    
    422 422
     loadExternalPluginLib path = do
    
    423 423
       -- load library
    
    424
    -  loadDLL path >>= \case
    
    424
    +  loadDLLs [path] >>= \case
    
    425 425
         Left errmsg -> pprPanic "loadExternalPluginLib"
    
    426 426
                          (vcat [ text "Can't load plugin library"
    
    427 427
                                , text "  Library path: " <> text path
    

  • compiler/GHC/Linker/Loader.hs
    1 1
     {-# LANGUAGE CPP #-}
    
    2 2
     {-# LANGUAGE RecordWildCards #-}
    
    3 3
     {-# LANGUAGE LambdaCase #-}
    
    4
    +{-# LANGUAGE ViewPatterns #-}
    
    4 5
     
    
    5 6
     --
    
    6 7
     --  (c) The University of Glasgow 2002-2006
    
    ... ... @@ -534,7 +535,7 @@ preloadLib interp hsc_env lib_paths framework_paths pls lib_spec = do
    534 535
           return pls
    
    535 536
     
    
    536 537
         DLL dll_unadorned -> do
    
    537
    -      maybe_errstr <- loadDLL interp (platformSOName platform dll_unadorned)
    
    538
    +      maybe_errstr <- loadDLLs interp [platformSOName platform dll_unadorned]
    
    538 539
           case maybe_errstr of
    
    539 540
              Right _ -> maybePutStrLn logger "done"
    
    540 541
              Left mm | platformOS platform /= OSDarwin ->
    
    ... ... @@ -544,14 +545,14 @@ preloadLib interp hsc_env lib_paths framework_paths pls lib_spec = do
    544 545
                -- since (apparently) some things install that way - see
    
    545 546
                -- ticket #8770.
    
    546 547
                let libfile = ("lib" ++ dll_unadorned) <.> "so"
    
    547
    -           err2 <- loadDLL interp libfile
    
    548
    +           err2 <- loadDLLs interp [libfile]
    
    548 549
                case err2 of
    
    549 550
                  Right _ -> maybePutStrLn logger "done"
    
    550 551
                  Left _  -> preloadFailed mm lib_paths lib_spec
    
    551 552
           return pls
    
    552 553
     
    
    553 554
         DLLPath dll_path -> do
    
    554
    -      do maybe_errstr <- loadDLL interp dll_path
    
    555
    +      do maybe_errstr <- loadDLLs interp [dll_path]
    
    555 556
              case maybe_errstr of
    
    556 557
                 Right _ -> maybePutStrLn logger "done"
    
    557 558
                 Left mm -> preloadFailed mm lib_paths lib_spec
    
    ... ... @@ -891,7 +892,7 @@ dynLoadObjs interp hsc_env pls@LoaderState{..} objs = do
    891 892
     
    
    892 893
         -- if we got this far, extend the lifetime of the library file
    
    893 894
         changeTempFilesLifetime tmpfs TFL_GhcSession [soFile]
    
    894
    -    m <- loadDLL interp soFile
    
    895
    +    m <- loadDLLs interp [soFile]
    
    895 896
         case m of
    
    896 897
           Right _ -> return $! pls { temp_sos = (libPath, libName) : temp_sos }
    
    897 898
           Left err -> linkFail msg (text err)
    
    ... ... @@ -1128,33 +1129,57 @@ loadPackages interp hsc_env new_pkgs = do
    1128 1129
     
    
    1129 1130
     loadPackages' :: Interp -> HscEnv -> [UnitId] -> LoaderState -> IO LoaderState
    
    1130 1131
     loadPackages' interp hsc_env new_pks pls = do
    
    1131
    -    pkgs' <- link (pkgs_loaded pls) new_pks
    
    1132
    -    return $! pls { pkgs_loaded = pkgs'
    
    1132
    +  (reverse -> pkgs_info_list, pkgs_almost_loaded) <-
    
    1133
    +    downsweep
    
    1134
    +      ([], pkgs_loaded pls)
    
    1135
    +      new_pks
    
    1136
    +  let link_one pkgs new_pkg_info = do
    
    1137
    +        (hs_cls, extra_cls, loaded_dlls) <-
    
    1138
    +          loadPackage
    
    1139
    +            interp
    
    1140
    +            hsc_env
    
    1141
    +            new_pkg_info
    
    1142
    +        evaluate $
    
    1143
    +          adjustUDFM
    
    1144
    +            ( \old_pkg_info ->
    
    1145
    +                old_pkg_info
    
    1146
    +                  { loaded_pkg_hs_objs = hs_cls,
    
    1147
    +                    loaded_pkg_non_hs_objs = extra_cls,
    
    1148
    +                    loaded_pkg_hs_dlls = loaded_dlls
    
    1133 1149
                       }
    
    1150
    +            )
    
    1151
    +            pkgs
    
    1152
    +            (Packages.unitId new_pkg_info)
    
    1153
    +  pkgs_loaded' <- foldlM link_one pkgs_almost_loaded pkgs_info_list
    
    1154
    +  evaluate $ pls {pkgs_loaded = pkgs_loaded'}
    
    1134 1155
       where
    
    1135
    -     link :: PkgsLoaded -> [UnitId] -> IO PkgsLoaded
    
    1136
    -     link pkgs new_pkgs =
    
    1137
    -         foldM link_one pkgs new_pkgs
    
    1138
    -
    
    1139
    -     link_one pkgs new_pkg
    
    1140
    -        | new_pkg `elemUDFM` pkgs   -- Already linked
    
    1141
    -        = return pkgs
    
    1142
    -
    
    1143
    -        | Just pkg_cfg <- lookupUnitId (hsc_units hsc_env) new_pkg
    
    1144
    -        = do { let deps = unitDepends pkg_cfg
    
    1145
    -               -- Link dependents first
    
    1146
    -             ; pkgs' <- link pkgs deps
    
    1147
    -                -- Now link the package itself
    
    1148
    -             ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg
    
    1149
    -             ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg
    
    1150
    -                                                   | dep_pkg <- deps
    
    1151
    -                                                   , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg)
    
    1152
    -                                                   ]
    
    1153
    -             ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) }
    
    1154
    -
    
    1155
    -        | otherwise
    
    1156
    -        = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))
    
    1157
    -
    
    1156
    +    downsweep = foldlM downsweep_one
    
    1157
    +
    
    1158
    +    downsweep_one (pkgs_info_list, pkgs) new_pkg
    
    1159
    +      | new_pkg `elemUDFM` pkgs = pure (pkgs_info_list, pkgs)
    
    1160
    +      | Just new_pkg_info <- lookupUnitId (hsc_units hsc_env) new_pkg = do
    
    1161
    +          let new_pkg_deps = unitDepends new_pkg_info
    
    1162
    +          (pkgs_info_list', pkgs') <- downsweep (pkgs_info_list, pkgs) new_pkg_deps
    
    1163
    +          let new_pkg_trans_deps =
    
    1164
    +                unionManyUniqDSets
    
    1165
    +                  [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg
    
    1166
    +                  | dep_pkg <- new_pkg_deps,
    
    1167
    +                    loaded_pkg_info <- maybeToList $ pkgs' `lookupUDFM` dep_pkg
    
    1168
    +                  ]
    
    1169
    +          pure
    
    1170
    +            ( new_pkg_info : pkgs_info_list',
    
    1171
    +              addToUDFM pkgs' new_pkg $
    
    1172
    +                LoadedPkgInfo
    
    1173
    +                  { loaded_pkg_uid = new_pkg,
    
    1174
    +                    loaded_pkg_hs_objs = [],
    
    1175
    +                    loaded_pkg_non_hs_objs = [],
    
    1176
    +                    loaded_pkg_hs_dlls = [],
    
    1177
    +                    loaded_pkg_trans_deps = new_pkg_trans_deps
    
    1178
    +                  }
    
    1179
    +            )
    
    1180
    +      | otherwise =
    
    1181
    +          throwGhcExceptionIO
    
    1182
    +            (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))
    
    1158 1183
     
    
    1159 1184
     loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL])
    
    1160 1185
     loadPackage interp hsc_env pkg
    
    ... ... @@ -1221,11 +1246,11 @@ loadPackage interp hsc_env pkg
    1221 1246
             loadFrameworks interp platform pkg
    
    1222 1247
             -- See Note [Crash early load_dyn and locateLib]
    
    1223 1248
             -- Crash early if can't load any of `known_dlls`
    
    1224
    -        mapM_ (load_dyn interp hsc_env True) known_extra_dlls
    
    1225
    -        loaded_dlls <- mapMaybeM (load_dyn interp hsc_env True) known_hs_dlls
    
    1249
    +        _ <- load_dyn interp hsc_env True known_extra_dlls
    
    1250
    +        loaded_dlls <- load_dyn interp hsc_env True known_hs_dlls
    
    1226 1251
             -- For remaining `dlls` crash early only when there is surely
    
    1227 1252
             -- no package's DLL around ... (not is_dyn)
    
    1228
    -        mapM_ (load_dyn interp hsc_env (not is_dyn) . platformSOName platform) dlls
    
    1253
    +        _ <- load_dyn interp hsc_env (not is_dyn) $ map (platformSOName platform) dlls
    
    1229 1254
     #else
    
    1230 1255
             let loaded_dlls = []
    
    1231 1256
     #endif
    
    ... ... @@ -1299,12 +1324,12 @@ restriction very easily.
    1299 1324
     -- we have already searched the filesystem; the strings passed to load_dyn
    
    1300 1325
     -- can be passed directly to loadDLL.  They are either fully-qualified
    
    1301 1326
     -- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so").  In the latter case,
    
    1302
    --- loadDLL is going to search the system paths to find the library.
    
    1303
    -load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO (Maybe (RemotePtr LoadedDLL))
    
    1304
    -load_dyn interp hsc_env crash_early dll = do
    
    1305
    -  r <- loadDLL interp dll
    
    1327
    +-- loadDLLs is going to search the system paths to find the library.
    
    1328
    +load_dyn :: Interp -> HscEnv -> Bool -> [FilePath] -> IO [RemotePtr LoadedDLL]
    
    1329
    +load_dyn interp hsc_env crash_early dlls = do
    
    1330
    +  r <- loadDLLs interp dlls
    
    1306 1331
       case r of
    
    1307
    -    Right loaded_dll -> pure (Just loaded_dll)
    
    1332
    +    Right loaded_dlls -> pure loaded_dlls
    
    1308 1333
         Left err ->
    
    1309 1334
           if crash_early
    
    1310 1335
             then cmdLineErrorIO err
    
    ... ... @@ -1313,7 +1338,7 @@ load_dyn interp hsc_env crash_early dll = do
    1313 1338
                 $ reportDiagnostic logger
    
    1314 1339
                     neverQualify diag_opts
    
    1315 1340
                       noSrcSpan (WarningWithFlag Opt_WarnMissedExtraSharedLib) $ withPprStyle defaultUserStyle (note err)
    
    1316
    -          pure Nothing
    
    1341
    +          pure []
    
    1317 1342
       where
    
    1318 1343
         diag_opts = initDiagOpts (hsc_dflags hsc_env)
    
    1319 1344
         logger = hsc_logger hsc_env
    
    ... ... @@ -1369,7 +1394,7 @@ locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib0
    1369 1394
         --   then  look in library-dirs and inplace GCC for a static library (libfoo.a)
    
    1370 1395
         --   then  try "gcc --print-file-name" to search gcc's search path
    
    1371 1396
         --       for a dynamic library (#5289)
    
    1372
    -    --   otherwise, assume loadDLL can find it
    
    1397
    +    --   otherwise, assume loadDLLs can find it
    
    1373 1398
         --
    
    1374 1399
         --   The logic is a bit complicated, but the rationale behind it is that
    
    1375 1400
         --   loading a shared library for us is O(1) while loading an archive is
    

  • compiler/GHC/Linker/MacOS.hs
    ... ... @@ -162,7 +162,7 @@ loadFramework interp extraPaths rootname
    162 162
          -- sorry for the hardcoded paths, I hope they won't change anytime soon:
    
    163 163
          defaultFrameworkPaths = ["/Library/Frameworks", "/System/Library/Frameworks"]
    
    164 164
     
    
    165
    -     -- Try to call loadDLL for each candidate path.
    
    165
    +     -- Try to call loadDLLs for each candidate path.
    
    166 166
          --
    
    167 167
          -- See Note [macOS Big Sur dynamic libraries]
    
    168 168
          findLoadDLL [] errs =
    
    ... ... @@ -170,7 +170,7 @@ loadFramework interp extraPaths rootname
    170 170
            -- has no built-in paths for frameworks: give up
    
    171 171
            return $ Just errs
    
    172 172
          findLoadDLL (p:ps) errs =
    
    173
    -       do { dll <- loadDLL interp (p </> fwk_file)
    
    173
    +       do { dll <- loadDLLs interp [p </> fwk_file]
    
    174 174
               ; case dll of
    
    175 175
                   Right _  -> return Nothing
    
    176 176
                   Left err -> findLoadDLL ps ((p ++ ": " ++ err):errs)
    

  • compiler/GHC/Linker/Types.hs
    ... ... @@ -494,7 +494,7 @@ data LibrarySpec
    494 494
        | DLL String         -- "Unadorned" name of a .DLL/.so
    
    495 495
                             --  e.g.    On unix     "qt"  denotes "libqt.so"
    
    496 496
                             --          On Windows  "burble"  denotes "burble.DLL" or "libburble.dll"
    
    497
    -                        --  loadDLL is platform-specific and adds the lib/.so/.DLL
    
    497
    +                        --  loadDLLs is platform-specific and adds the lib/.so/.DLL
    
    498 498
                             --  suffixes platform-dependently
    
    499 499
     
    
    500 500
        | DLLPath FilePath   -- Absolute or relative pathname to a dynamic library
    

  • compiler/GHC/Runtime/Interpreter.hs
    ... ... @@ -38,7 +38,7 @@ module GHC.Runtime.Interpreter
    38 38
       , lookupSymbol
    
    39 39
       , lookupSymbolInDLL
    
    40 40
       , lookupClosure
    
    41
    -  , loadDLL
    
    41
    +  , loadDLLs
    
    42 42
       , loadArchive
    
    43 43
       , loadObj
    
    44 44
       , unloadObj
    
    ... ... @@ -559,13 +559,13 @@ withSymbolCache interp str determine_addr = do
    559 559
     purgeLookupSymbolCache :: Interp -> IO ()
    
    560 560
     purgeLookupSymbolCache interp = purgeInterpSymbolCache (interpSymbolCache interp)
    
    561 561
     
    
    562
    --- | loadDLL loads a dynamic library using the OS's native linker
    
    562
    +-- | 'loadDLLs' loads dynamic libraries using the OS's native linker
    
    563 563
     -- (i.e. dlopen() on Unix, LoadLibrary() on Windows).  It takes either
    
    564
    --- an absolute pathname to the file, or a relative filename
    
    565
    --- (e.g. "libfoo.so" or "foo.dll").  In the latter case, loadDLL
    
    566
    --- searches the standard locations for the appropriate library.
    
    567
    -loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL))
    
    564
    +-- absolute pathnames to the files, or relative filenames
    
    565
    +-- (e.g. "libfoo.so" or "foo.dll").  In the latter case, 'loadDLLs'
    
    566
    +-- searches the standard locations for the appropriate libraries.
    
    567
    +loadDLLs :: Interp -> [String] -> IO (Either String [RemotePtr LoadedDLL])
    
    568
    +loadDLLs interp strs = interpCmd interp (LoadDLLs strs)
    
    568 569
     
    
    569 570
     loadArchive :: Interp -> String -> IO ()
    
    570 571
     loadArchive interp path = do
    
    ... ... @@ -761,4 +761,3 @@ readIModModBreaks hug mod = imodBreaks_modBreaks . expectJust <$> readIModBreaks
    761 761
     fromEvalResult :: EvalResult a -> IO a
    
    762 762
     fromEvalResult (EvalException e) = throwIO (fromSerializableException e)
    
    763 763
     fromEvalResult (EvalSuccess a) = return a
    764
    -

  • libraries/base/changelog.md
    1 1
     # Changelog for [`base` package](http://hackage.haskell.org/package/base)
    
    2 2
     
    
    3 3
     ## 4.23.0.0 *TBA*
    
    4
    +  * Remove deprecated, unstable heap representation details from `GHC.Exts` ([CLC proposal #212](https://github.com/haskell/core-libraries-committee/issues/212))
    
    4 5
       * Add `Data.List.NonEmpty.mapMaybe`. ([CLC proposal #337](https://github.com/haskell/core-libraries-committee/issues/337))
    
    5 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))
    
    6 7
       * Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
    

  • libraries/base/src/GHC/Exts.hs
    ... ... @@ -26,12 +26,6 @@ module GHC.Exts
    26 26
          -- **  Legacy interface for arrays of arrays
    
    27 27
          module GHC.Internal.ArrayArray,
    
    28 28
          -- *  Primitive operations
    
    29
    -     {-# DEPRECATED ["The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14", "These symbols should be imported from ghc-internal instead if needed."] #-}
    
    30
    -     Prim.BCO,
    
    31
    -     {-# DEPRECATED ["The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14", "These symbols should be imported from ghc-internal instead if needed."] #-}
    
    32
    -     Prim.mkApUpd0#,
    
    33
    -     {-# DEPRECATED ["The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14", "These symbols should be imported from ghc-internal instead if needed."] #-}
    
    34
    -     Prim.newBCO#,
    
    35 29
          module GHC.Prim,
    
    36 30
          module GHC.Prim.Ext,
    
    37 31
          -- **  Running 'RealWorld' state thread
    
    ... ... @@ -130,9 +124,6 @@ import GHC.Prim hiding
    130 124
       , whereFrom#
    
    131 125
       , isByteArrayWeaklyPinned#, isMutableByteArrayWeaklyPinned#
    
    132 126
     
    
    133
    -  -- deprecated
    
    134
    -  , BCO, mkApUpd0#, newBCO#
    
    135
    -
    
    136 127
       -- Don't re-export vector FMA instructions
    
    137 128
       , fmaddFloatX4#
    
    138 129
       , fmsubFloatX4#
    
    ... ... @@ -255,8 +246,6 @@ import GHC.Prim hiding
    255 246
       , minWord8X32#
    
    256 247
       , minWord8X64#
    
    257 248
       )
    
    258
    -import qualified GHC.Prim as Prim
    
    259
    -  ( BCO, mkApUpd0#, newBCO# )
    
    260 249
     
    
    261 250
     import GHC.Prim.Ext
    
    262 251
     
    

  • libraries/ghci/GHCi/CreateBCO.hs
    ... ... @@ -6,10 +6,6 @@
    6 6
     {-# LANGUAGE UnboxedTuples #-}
    
    7 7
     {-# LANGUAGE RecordWildCards #-}
    
    8 8
     {-# LANGUAGE CPP #-}
    
    9
    -{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
    
    10
    --- TODO We want to import GHC.Internal.Base (BCO, mkApUpd0#, newBCO#) instead
    
    11
    --- of from GHC.Exts when we can require of the bootstrap compiler to have
    
    12
    --- ghc-internal.
    
    13 9
     
    
    14 10
     --
    
    15 11
     --  (c) The University of Glasgow 2002-2006
    
    ... ... @@ -30,7 +26,8 @@ import Data.Array.Base
    30 26
     import Foreign hiding (newArray)
    
    31 27
     import Unsafe.Coerce (unsafeCoerce)
    
    32 28
     import GHC.Arr          ( Array(..) )
    
    33
    -import GHC.Exts
    
    29
    +import GHC.Exts   hiding ( BCO, mkApUpd0#, newBCO# )
    
    30
    +import GHC.Internal.Base ( BCO, mkApUpd0#, newBCO# )
    
    34 31
     import GHC.IO
    
    35 32
     import Control.Exception ( ErrorCall(..) )
    
    36 33
     
    

  • libraries/ghci/GHCi/Message.hs
    ... ... @@ -84,7 +84,7 @@ data Message a where
    84 84
       LookupSymbol :: String -> Message (Maybe (RemotePtr ()))
    
    85 85
       LookupSymbolInDLL :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ()))
    
    86 86
       LookupClosure :: String -> Message (Maybe HValueRef)
    
    87
    -  LoadDLL :: String -> Message (Either String (RemotePtr LoadedDLL))
    
    87
    +  LoadDLLs :: [String] -> Message (Either String [RemotePtr LoadedDLL])
    
    88 88
       LoadArchive :: String -> Message () -- error?
    
    89 89
       LoadObj :: String -> Message () -- error?
    
    90 90
       UnloadObj :: String -> Message () -- error?
    
    ... ... @@ -441,7 +441,7 @@ data BreakModule
    441 441
     -- that type isn't available here.
    
    442 442
     data BreakUnitId
    
    443 443
     
    
    444
    --- | A dummy type that tags pointers returned by 'LoadDLL'.
    
    444
    +-- | A dummy type that tags pointers returned by 'LoadDLLs'.
    
    445 445
     data LoadedDLL
    
    446 446
     
    
    447 447
     -- SomeException can't be serialized because it contains dynamic
    
    ... ... @@ -555,7 +555,7 @@ getMessage = do
    555 555
           1  -> Msg <$> return InitLinker
    
    556 556
           2  -> Msg <$> LookupSymbol <$> get
    
    557 557
           3  -> Msg <$> LookupClosure <$> get
    
    558
    -      4  -> Msg <$> LoadDLL <$> get
    
    558
    +      4  -> Msg <$> LoadDLLs <$> get
    
    559 559
           5  -> Msg <$> LoadArchive <$> get
    
    560 560
           6  -> Msg <$> LoadObj <$> get
    
    561 561
           7  -> Msg <$> UnloadObj <$> get
    
    ... ... @@ -601,7 +601,7 @@ putMessage m = case m of
    601 601
       InitLinker                  -> putWord8 1
    
    602 602
       LookupSymbol str            -> putWord8 2  >> put str
    
    603 603
       LookupClosure str           -> putWord8 3  >> put str
    
    604
    -  LoadDLL str                 -> putWord8 4  >> put str
    
    604
    +  LoadDLLs strs               -> putWord8 4  >> put strs
    
    605 605
       LoadArchive str             -> putWord8 5  >> put str
    
    606 606
       LoadObj str                 -> putWord8 6  >> put str
    
    607 607
       UnloadObj str               -> putWord8 7  >> put str
    

  • libraries/ghci/GHCi/ObjLink.hs
    ... ... @@ -12,7 +12,7 @@
    12 12
     -- dynamic linker.
    
    13 13
     module GHCi.ObjLink
    
    14 14
       ( initObjLinker, ShouldRetainCAFs(..)
    
    15
    -  , loadDLL
    
    15
    +  , loadDLLs
    
    16 16
       , loadArchive
    
    17 17
       , loadObj
    
    18 18
       , unloadObj
    
    ... ... @@ -43,6 +43,10 @@ import Control.Exception (catch, evaluate)
    43 43
     import GHC.Wasm.Prim
    
    44 44
     #endif
    
    45 45
     
    
    46
    +#if defined(wasm32_HOST_ARCH)
    
    47
    +import Data.List (intercalate)
    
    48
    +#endif
    
    49
    +
    
    46 50
     -- ---------------------------------------------------------------------------
    
    47 51
     -- RTS Linker Interface
    
    48 52
     -- ---------------------------------------------------------------------------
    
    ... ... @@ -67,20 +71,25 @@ data ShouldRetainCAFs
    67 71
     initObjLinker :: ShouldRetainCAFs -> IO ()
    
    68 72
     initObjLinker _ = pure ()
    
    69 73
     
    
    70
    -loadDLL :: String -> IO (Either String (Ptr LoadedDLL))
    
    71
    -loadDLL f =
    
    74
    +-- Batch load multiple DLLs at once via dyld to enable a single
    
    75
    +-- dependency resolution and more parallel compilation. We pass a
    
    76
    +-- NUL-delimited JSString to avoid array marshalling on wasm.
    
    77
    +loadDLLs :: [String] -> IO (Either String [Ptr LoadedDLL])
    
    78
    +loadDLLs fs =
    
    72 79
       m `catch` \(err :: JSException) ->
    
    73
    -    pure $ Left $ "loadDLL failed for " <> f <> ": " <> show err
    
    80
    +    pure $ Left $ "loadDLLs failed: " <> show err
    
    74 81
       where
    
    82
    +    packed :: JSString
    
    83
    +    packed = toJSString (intercalate ['\0'] fs)
    
    75 84
         m = do
    
    76
    -      evaluate =<< js_loadDLL (toJSString f)
    
    77
    -      pure $ Right nullPtr
    
    85
    +      evaluate =<< js_loadDLLs packed
    
    86
    +      pure $ Right (replicate (length fs) nullPtr)
    
    78 87
     
    
    79 88
     -- See Note [Variable passing in JSFFI] for where
    
    80 89
     -- __ghc_wasm_jsffi_dyld comes from
    
    81 90
     
    
    82
    -foreign import javascript safe "__ghc_wasm_jsffi_dyld.loadDLL($1)"
    
    83
    -  js_loadDLL :: JSString -> IO ()
    
    91
    +foreign import javascript safe "__ghc_wasm_jsffi_dyld.loadDLLs($1)"
    
    92
    +  js_loadDLLs :: JSString -> IO ()
    
    84 93
     
    
    85 94
     loadArchive :: String -> IO ()
    
    86 95
     loadArchive f = throwIO $ ErrorCall $ "loadArchive: unsupported on wasm for " <> f
    
    ... ... @@ -241,6 +250,16 @@ resolveObjs = do
    241 250
        r <- c_resolveObjs
    
    242 251
        return (r /= 0)
    
    243 252
     
    
    253
    +loadDLLs :: [String] -> IO (Either String [Ptr LoadedDLL])
    
    254
    +loadDLLs = go []
    
    255
    +  where
    
    256
    +    go acc [] = pure (Right (reverse acc))
    
    257
    +    go acc (p:ps) = do
    
    258
    +      r <- loadDLL p
    
    259
    +      case r of
    
    260
    +        Left err -> pure (Left err)
    
    261
    +        Right h  -> go (h:acc) ps
    
    262
    +
    
    244 263
     -- ---------------------------------------------------------------------------
    
    245 264
     -- Foreign declarations to RTS entry points which does the real work;
    
    246 265
     -- ---------------------------------------------------------------------------
    

  • libraries/ghci/GHCi/Run.hs
    ... ... @@ -57,7 +57,7 @@ run m = case m of
    57 57
     #if defined(javascript_HOST_ARCH)
    
    58 58
       LoadObj p                   -> withCString p loadJS
    
    59 59
       InitLinker                  -> notSupportedJS m
    
    60
    -  LoadDLL {}                  -> notSupportedJS m
    
    60
    +  LoadDLLs {}                 -> notSupportedJS m
    
    61 61
       LoadArchive {}              -> notSupportedJS m
    
    62 62
       UnloadObj {}                -> notSupportedJS m
    
    63 63
       AddLibrarySearchPath {}     -> notSupportedJS m
    
    ... ... @@ -69,7 +69,7 @@ run m = case m of
    69 69
       LookupClosure str           -> lookupJSClosure str
    
    70 70
     #else
    
    71 71
       InitLinker -> initObjLinker RetainCAFs
    
    72
    -  LoadDLL str -> fmap toRemotePtr <$> loadDLL str
    
    72
    +  LoadDLLs strs -> fmap (map toRemotePtr) <$> loadDLLs strs
    
    73 73
       LoadArchive str -> loadArchive str
    
    74 74
       LoadObj str -> loadObj str
    
    75 75
       UnloadObj str -> unloadObj str
    

  • libraries/ghci/GHCi/TH.hs
    1 1
     {-# LANGUAGE ScopedTypeVariables, StandaloneDeriving, DeriveGeneric,
    
    2 2
         TupleSections, RecordWildCards, InstanceSigs, CPP #-}
    
    3 3
     {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
    
    4
    -{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
    
    5
    --- TODO We want to import GHC.Internal.Desugar instead of GHC.Desugar when we
    
    6
    --- can require of the bootstrap compiler to have ghc-internal.
    
    7 4
     
    
    8 5
     -- |
    
    9 6
     -- Running TH splices
    
    ... ... @@ -112,7 +109,7 @@ import Data.IORef
    112 109
     import Data.Map (Map)
    
    113 110
     import qualified Data.Map as M
    
    114 111
     import Data.Maybe
    
    115
    -import GHC.Desugar (AnnotationWrapper(..))
    
    112
    +import GHC.Internal.Desugar (AnnotationWrapper(..))
    
    116 113
     import qualified GHC.Boot.TH.Syntax as TH
    
    117 114
     import Unsafe.Coerce
    
    118 115
     
    

  • libraries/ghci/ghci.cabal.in
    ... ... @@ -86,11 +86,7 @@ library
    86 86
             rts,
    
    87 87
             array            == 0.5.*,
    
    88 88
             base             >= 4.8 && < 4.23,
    
    89
    -        -- ghc-internal     == @ProjectVersionForLib@.*
    
    90
    -        -- TODO: Use GHC.Internal.Desugar and GHC.Internal.Base from
    
    91
    -        -- ghc-internal instead of ignoring the deprecation warning in GHCi.TH
    
    92
    -        -- and GHCi.CreateBCO when we require ghc-internal of the bootstrap
    
    93
    -        -- compiler
    
    89
    +        ghc-internal     >= 9.1001.0 && <=@ProjectVersionForLib@.0,
    
    94 90
             ghc-prim         >= 0.5.0 && < 0.14,
    
    95 91
             binary           == 0.8.*,
    
    96 92
             bytestring       >= 0.10 && < 0.13,
    

  • rts/Disassembler.c
    ... ... @@ -89,7 +89,7 @@ disInstr ( StgBCO *bco, int pc )
    89 89
              p1           = BCO_GET_LARGE_ARG;
    
    90 90
              info_mod     = BCO_GET_LARGE_ARG;
    
    91 91
              info_unit_id = BCO_GET_LARGE_ARG;
    
    92
    -         info_wix     = BCO_NEXT;
    
    92
    +         info_wix     = BCO_READ_NEXT_32;
    
    93 93
              np           = BCO_GET_LARGE_ARG;
    
    94 94
              debugBelch ("BRK_FUN " );  printPtr( ptrs[p1] );
    
    95 95
              debugBelch("%" FMT_Word, literals[info_mod] );
    

  • rts/Interpreter.c
    ... ... @@ -720,7 +720,7 @@ interpretBCO (Capability* cap)
    720 720
                 arg1_brk_array      = BCO_GET_LARGE_ARG;
    
    721 721
                 /* info_mod_name = */ BCO_GET_LARGE_ARG;
    
    722 722
                 /* info_mod_id   = */ BCO_GET_LARGE_ARG;
    
    723
    -            arg4_info_index     = BCO_NEXT;
    
    723
    +            arg4_info_index     = BCO_READ_NEXT_32;
    
    724 724
     
    
    725 725
                 StgPtr* ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
    
    726 726
                 StgArrBytes* breakPoints = (StgArrBytes *) BCO_PTR(arg1_brk_array);
    
    ... ... @@ -1542,7 +1542,7 @@ run_BCO:
    1542 1542
                 arg1_brk_array      = BCO_GET_LARGE_ARG;
    
    1543 1543
                 arg2_info_mod_name  = BCO_GET_LARGE_ARG;
    
    1544 1544
                 arg3_info_mod_id    = BCO_GET_LARGE_ARG;
    
    1545
    -            arg4_info_index     = BCO_NEXT;
    
    1545
    +            arg4_info_index     = BCO_READ_NEXT_32;
    
    1546 1546
     #if defined(PROFILING)
    
    1547 1547
                 arg5_cc             = BCO_GET_LARGE_ARG;
    
    1548 1548
     #else
    

  • testsuite/tests/module/T21752.stderr deleted
    1
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    2
    -    In the use of ‘newBCO#’ (imported from GHC.Exts):
    
    3
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    4
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    5
    -
    
    6
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    7
    -    In the use of ‘newBCO#’ (imported from GHC.Exts):
    
    8
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    9
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    10
    -
    
    11
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    12
    -    In the use of ‘mkApUpd0#’ (imported from GHC.Exts):
    
    13
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    14
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    15
    -
    
    16
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    17
    -    In the use of ‘mkApUpd0#’ (imported from GHC.Exts):
    
    18
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    19
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    20
    -
    
    21
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    22
    -    In the use of type constructor or class ‘BCO’
    
    23
    -    (imported from GHC.Exts):
    
    24
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    25
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    26
    -
    
    27
    -T21752A.hs:4:5: warning: [GHC-68441] [-Wdeprecations (in -Wextended-warnings)]
    
    28
    -    In the use of type constructor or class ‘BCO’
    
    29
    -    (imported from GHC.Exts):
    
    30
    -    Deprecated: "The BCO, mkApUpd0#, and newBCO# re-exports from GHC.Exts have been deprecated and will be removed in 9.14
    
    31
    -                 These symbols should be imported from ghc-internal instead if needed."
    
    32
    -

  • testsuite/tests/rts/linker/T2615.hs
    ... ... @@ -4,7 +4,7 @@ library_name = "libfoo_script_T2615.so" -- this is really a linker script
    4 4
     
    
    5 5
     main = do
    
    6 6
       initObjLinker RetainCAFs
    
    7
    -  result <- loadDLL library_name
    
    7
    +  result <- loadDLLs [library_name]
    
    8 8
       case result of
    
    9 9
         Right _ -> putStrLn (library_name ++ " loaded successfully")
    
    10 10
         Left x  -> putStrLn ("error: " ++ x)

  • utils/jsffi/dyld.mjs
    ... ... @@ -9,7 +9,7 @@
    9 9
     //    iserv (GHCi.Server.defaultServer). This part only runs in
    
    10 10
     //    nodejs.
    
    11 11
     // 2. Dynamic linker: provide RTS linker interfaces like
    
    12
    -//    loadDLL/lookupSymbol etc which are imported by wasm iserv. This
    
    12
    +//    loadDLLs/lookupSymbol etc which are imported by wasm iserv. This
    
    13 13
     //    part can run in browsers as well.
    
    14 14
     //
    
    15 15
     // When GHC starts external interpreter for the wasm target, it starts
    
    ... ... @@ -50,7 +50,7 @@
    50 50
     //
    
    51 51
     // *** What works right now and what doesn't work yet?
    
    52 52
     //
    
    53
    -// loadDLL & bytecode interpreter work. Template Haskell & ghci work.
    
    53
    +// loadDLLs & bytecode interpreter work. Template Haskell & ghci work.
    
    54 54
     // Profiled dynamic code works. Compiled code and bytecode can all be
    
    55 55
     // loaded, though the side effects are constrained to what's supported
    
    56 56
     // by wasi preview1: we map the full host filesystem into wasm cause
    
    ... ... @@ -801,17 +801,17 @@ class DyLD {
    801 801
         return this.#rpc.findSystemLibrary(f);
    
    802 802
       }
    
    803 803
     
    
    804
    -  // When we do loadDLL, we first perform "downsweep" which return a
    
    804
    +  // When we do loadDLLs, we first perform "downsweep" which return a
    
    805 805
       // toposorted array of dependencies up to itself, then sequentially
    
    806 806
       // load the downsweep result.
    
    807 807
       //
    
    808 808
       // The rationale of a separate downsweep phase, instead of a simple
    
    809
    -  // recursive loadDLL function is: V8 delegates async
    
    809
    +  // recursive loadDLLs function is: V8 delegates async
    
    810 810
       // WebAssembly.compile to a background worker thread pool. To
    
    811 811
       // maintain consistent internal linker state, we *must* load each so
    
    812 812
       // file sequentially, but it's okay to kick off compilation asap,
    
    813 813
       // store the Promise in downsweep result and await for the actual
    
    814
    -  // WebAssembly.Module in loadDLL logic. This way we can harness some
    
    814
    +  // WebAssembly.Module in loadDLLs logic. This way we can harness some
    
    815 815
       // background parallelism.
    
    816 816
       async #downsweep(p) {
    
    817 817
         const toks = p.split("/");
    
    ... ... @@ -852,8 +852,26 @@ class DyLD {
    852 852
         return acc;
    
    853 853
       }
    
    854 854
     
    
    855
    -  // The real stuff
    
    856
    -  async loadDLL(p) {
    
    855
    +  // Batch load multiple DLLs in one go.
    
    856
    +  // Accepts a NUL-delimited string of paths to avoid array marshalling.
    
    857
    +  // Each path can be absolute or a soname; dependency resolution is
    
    858
    +  // performed across the full set to enable maximal parallel compile
    
    859
    +  // while maintaining sequential instantiation order.
    
    860
    +  async loadDLLs(packed) {
    
    861
    +    // Normalize input to an array of strings. When called from Haskell
    
    862
    +    // we pass a single JSString containing NUL-separated paths.
    
    863
    +    const paths = (typeof packed === "string"
    
    864
    +      ? (packed.length === 0 ? [] : packed.split("\0"))
    
    865
    +      : [packed] // tolerate an accidental single path object
    
    866
    +    ).filter((s) => s.length > 0);
    
    867
    +
    
    868
    +    // Compute a single downsweep plan for the whole batch.
    
    869
    +    // Note: #downsweep mutates #loadedSos to break cycles and dedup.
    
    870
    +    const plan = [];
    
    871
    +    for (const p of paths) {
    
    872
    +      plan.push(...(await this.#downsweep(p)));
    
    873
    +    }
    
    874
    +
    
    857 875
         for (const {
    
    858 876
           memSize,
    
    859 877
           memP2Align,
    
    ... ... @@ -861,7 +879,7 @@ class DyLD {
    861 879
           tableP2Align,
    
    862 880
           modp,
    
    863 881
           soname,
    
    864
    -    } of await this.#downsweep(p)) {
    
    882
    +    } of plan) {
    
    865 883
           const import_obj = {
    
    866 884
             wasi_snapshot_preview1: this.#wasi.wasiImport,
    
    867 885
             env: {
    
    ... ... @@ -1138,7 +1156,7 @@ export async function main({ rpc, libdir, ghciSoPath, args }) {
    1138 1156
           rpc,
    
    1139 1157
         });
    
    1140 1158
         await dyld.addLibrarySearchPath(libdir);
    
    1141
    -    await dyld.loadDLL(ghciSoPath);
    
    1159
    +    await dyld.loadDLLs(ghciSoPath);
    
    1142 1160
     
    
    1143 1161
         const reader = rpc.readStream.getReader();
    
    1144 1162
         const writer = rpc.writeStream.getWriter();