Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
8dd6f453
by Cheng Shao at 2026-04-08T04:38:11-04:00
-
371ef200
by Cheng Shao at 2026-04-08T04:38:11-04:00
12 changed files:
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Interpreter.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ObjLink.hs
- libraries/ghci/GHCi/Run.hs
- testsuite/tests/driver/linkwhole/Main.hs
- testsuite/tests/ghci/should_run/T18064.script
- testsuite/tests/rts/KeepCafsMain.hs
- utils/jsffi/dyld.mjs
Changes:
| ... | ... | @@ -37,6 +37,7 @@ import GHC.Prelude |
| 37 | 37 | import GHC.Types.SrcLoc
|
| 38 | 38 | import GHC.Types.Name.Occurrence
|
| 39 | 39 | import Control.DeepSeq
|
| 40 | +import qualified Data.ByteString.Short as SBS
|
|
| 40 | 41 | import Data.IntMap.Strict (IntMap)
|
| 41 | 42 | import qualified Data.IntMap.Strict as IM
|
| 42 | 43 | |
| ... | ... | @@ -235,8 +236,8 @@ getBreakVars = getBreakXXX modBreaks_vars |
| 235 | 236 | getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]
|
| 236 | 237 | getBreakDecls = getBreakXXX modBreaks_decls
|
| 237 | 238 | |
| 238 | --- | Get the decls for this breakpoint
|
|
| 239 | -getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO ((String, String))
|
|
| 239 | +-- | Get the cost centre info for this breakpoint
|
|
| 240 | +getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (SBS.ShortByteString, SBS.ShortByteString)
|
|
| 240 | 241 | getBreakCCS = getBreakXXX modBreaks_ccs
|
| 241 | 242 | |
| 242 | 243 | -- | Internal utility to access a ModBreaks field at a particular breakpoint index
|
| ... | ... | @@ -405,7 +405,7 @@ loadExternalPlugins ps = do |
| 405 | 405 | symbol
|
| 406 | 406 | | null unit = ztmp
|
| 407 | 407 | | otherwise = zEncodeString unit ++ "_" ++ ztmp
|
| 408 | - plugin <- lookupSymbol symbol >>= \case
|
|
| 408 | + plugin <- lookupSymbol (utf8EncodeShortByteString symbol) >>= \case
|
|
| 409 | 409 | Nothing -> pprPanic "loadExternalPlugins"
|
| 410 | 410 | (vcat [ text "Symbol not found"
|
| 411 | 411 | , text " Library path: " <> text path
|
| ... | ... | @@ -23,6 +23,7 @@ module GHC.HsToCore.Breakpoints |
| 23 | 23 | |
| 24 | 24 | import GHC.Prelude
|
| 25 | 25 | import Data.Array
|
| 26 | +import qualified Data.ByteString.Short as SBS
|
|
| 26 | 27 | |
| 27 | 28 | import GHC.HsToCore.Ticks (Tick (..))
|
| 28 | 29 | import GHC.Data.SizedSeq
|
| ... | ... | @@ -31,6 +32,7 @@ import GHC.Types.Name (OccName) |
| 31 | 32 | import GHC.Types.Tickish (BreakTickIndex, BreakpointId(..))
|
| 32 | 33 | import GHC.Unit.Module (Module)
|
| 33 | 34 | import GHC.Utils.Binary
|
| 35 | +import GHC.Utils.Encoding (utf8EncodeShortByteString)
|
|
| 34 | 36 | import GHC.Utils.Outputable
|
| 35 | 37 | import Data.List (intersperse)
|
| 36 | 38 | import Data.Coerce
|
| ... | ... | @@ -59,7 +61,7 @@ data ModBreaks |
| 59 | 61 | , modBreaks_decls :: !(Array BreakTickIndex [String])
|
| 60 | 62 | -- ^ An array giving the names of the declarations enclosing each breakpoint.
|
| 61 | 63 | -- See Note [Field modBreaks_decls]
|
| 62 | - , modBreaks_ccs :: !(Array BreakTickIndex (String, String))
|
|
| 64 | + , modBreaks_ccs :: !(Array BreakTickIndex (SBS.ShortByteString, SBS.ShortByteString))
|
|
| 63 | 65 | -- ^ Array pointing to cost centre info for each breakpoint;
|
| 64 | 66 | -- actual 'CostCentre' allocation is done at link-time.
|
| 65 | 67 | , modBreaks_module :: !Module
|
| ... | ... | @@ -89,8 +91,8 @@ mkModBreaks interpreterProfiled modl extendedMixEntries |
| 89 | 91 | | interpreterProfiled =
|
| 90 | 92 | listArray
|
| 91 | 93 | (0, count - 1)
|
| 92 | - [ ( concat $ intersperse "." $ tick_path t,
|
|
| 93 | - renderWithContext defaultSDocContext $ ppr $ tick_loc t
|
|
| 94 | + [ ( utf8EncodeShortByteString $ concat $ intersperse "." $ tick_path t,
|
|
| 95 | + utf8EncodeShortByteString $ renderWithContext defaultSDocContext $ ppr $ tick_loc t
|
|
| 94 | 96 | )
|
| 95 | 97 | | t <- entries
|
| 96 | 98 | ]
|
| ... | ... | @@ -1846,7 +1846,7 @@ allocateCCS interp ce mbss |
| 1846 | 1846 | ccs <- {- one ccs ptr per tick index -}
|
| 1847 | 1847 | mkCostCentres
|
| 1848 | 1848 | interp
|
| 1849 | - (moduleNameString $ moduleName modBreaks_module)
|
|
| 1849 | + (moduleNameFS $ moduleName modBreaks_module)
|
|
| 1850 | 1850 | (elems modBreaks_ccs)
|
| 1851 | 1851 | return $ M.fromList $
|
| 1852 | 1852 | zipWith (\el ix -> (BreakpointId modBreaks_module ix, el)) ccs [0..]
|
| ... | ... | @@ -107,6 +107,7 @@ import Control.Monad.IO.Class |
| 107 | 107 | import Control.Monad.Catch as MC (mask)
|
| 108 | 108 | import Data.Binary
|
| 109 | 109 | import Data.ByteString (ByteString)
|
| 110 | +import qualified Data.ByteString.Short as SBS
|
|
| 110 | 111 | import Foreign hiding (void)
|
| 111 | 112 | import qualified GHC.Exts.Heap as Heap
|
| 112 | 113 | import GHC.Stack.CCS (CostCentre,CostCentreStack)
|
| ... | ... | @@ -352,9 +353,15 @@ evalStringToIOString interp fhv str = |
| 352 | 353 | mallocData :: Interp -> ByteString -> IO (RemotePtr ())
|
| 353 | 354 | mallocData interp bs = interpCmd interp (MallocData bs)
|
| 354 | 355 | |
| 355 | -mkCostCentres :: Interp -> String -> [(String,String)] -> IO [RemotePtr CostCentre]
|
|
| 356 | -mkCostCentres interp mod ccs =
|
|
| 357 | - interpCmd interp (MkCostCentres mod ccs)
|
|
| 356 | +mkCostCentres :: Interp -> FastString -> [(SBS.ShortByteString, SBS.ShortByteString)] -> IO [RemotePtr CostCentre]
|
|
| 357 | +mkCostCentres interp mod ccs = do
|
|
| 358 | + rp <- modifyMVar (interpStringCache interp) $ \fs_env ->
|
|
| 359 | + case lookupFsEnv fs_env mod of
|
|
| 360 | + Just rp -> pure (fs_env, rp)
|
|
| 361 | + Nothing -> do
|
|
| 362 | + rp <- fmap head $ interpCmd interp $ MallocStrings [bytesFS mod]
|
|
| 363 | + pure (extendFsEnv fs_env mod rp, rp)
|
|
| 364 | + interpCmd interp $ MkCostCentres rp ccs
|
|
| 358 | 365 | |
| 359 | 366 | -- | Create a set of BCOs that may be mutually recursive.
|
| 360 | 367 | createBCOs :: Interp -> [ResolvedBCO] -> IO [HValueRef]
|
| ... | ... | @@ -413,7 +420,7 @@ evalBreakpointToId :: EvalBreakpoint -> InternalBreakpointId |
| 413 | 420 | evalBreakpointToId eval_break =
|
| 414 | 421 | let
|
| 415 | 422 | mkUnitId u = fsToUnit $ mkFastStringShortByteString u
|
| 416 | - toModule u n = mkModule (mkUnitId u) (mkModuleName n)
|
|
| 423 | + toModule u n = mkModule (mkUnitId u) (mkModuleNameFS (mkFastStringShortByteString n))
|
|
| 417 | 424 | in
|
| 418 | 425 | InternalBreakpointId
|
| 419 | 426 | { ibi_info_mod = toModule (eb_info_mod_unit eval_break) (eb_info_mod eval_break)
|
| ... | ... | @@ -465,27 +472,27 @@ lookupSymbol :: Interp -> InterpSymbol s -> IO (Maybe (Ptr ())) |
| 465 | 472 | lookupSymbol interp str = withSymbolCache interp str $
|
| 466 | 473 | case interpInstance interp of
|
| 467 | 474 | #if defined(HAVE_INTERNAL_INTERPRETER)
|
| 468 | - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS (interpSymbolToCLabel str)))
|
|
| 475 | + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 469 | 476 | #endif
|
| 470 | 477 | ExternalInterp ext -> case ext of
|
| 471 | 478 | ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do
|
| 472 | 479 | uninterruptibleMask_ $
|
| 473 | - sendMessage inst (LookupSymbol (unpackFS (interpSymbolToCLabel str)))
|
|
| 480 | + sendMessage inst (LookupSymbol (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 474 | 481 | ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str)
|
| 475 | 482 | ExtWasm i -> withWasmInterp i $ \inst -> fmap fromRemotePtr <$> do
|
| 476 | 483 | uninterruptibleMask_ $
|
| 477 | - sendMessage inst (LookupSymbol (unpackFS (interpSymbolToCLabel str)))
|
|
| 484 | + sendMessage inst (LookupSymbol (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 478 | 485 | |
| 479 | 486 | lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> InterpSymbol s -> IO (Maybe (Ptr ()))
|
| 480 | 487 | lookupSymbolInDLL interp dll str = withSymbolCache interp str $
|
| 481 | 488 | case interpInstance interp of
|
| 482 | 489 | #if defined(HAVE_INTERNAL_INTERPRETER)
|
| 483 | - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS (interpSymbolToCLabel str)))
|
|
| 490 | + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 484 | 491 | #endif
|
| 485 | 492 | ExternalInterp ext -> case ext of
|
| 486 | 493 | ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do
|
| 487 | 494 | uninterruptibleMask_ $
|
| 488 | - sendMessage inst (LookupSymbolInDLL dll (unpackFS (interpSymbolToCLabel str)))
|
|
| 495 | + sendMessage inst (LookupSymbolInDLL dll (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 489 | 496 | ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str)
|
| 490 | 497 | -- wasm dyld doesn't track which symbol comes from which .so
|
| 491 | 498 | ExtWasm {} -> lookupSymbol interp str
|
| ... | ... | @@ -519,7 +526,7 @@ interpSymbolToCLabel s = eliminateInterpSymbol s interpretedInterpSymbol $ \is - |
| 519 | 526 | |
| 520 | 527 | lookupClosure :: Interp -> InterpSymbol s -> IO (Maybe HValueRef)
|
| 521 | 528 | lookupClosure interp str =
|
| 522 | - interpCmd interp (LookupClosure (unpackFS (interpSymbolToCLabel str)))
|
|
| 529 | + interpCmd interp (LookupClosure (fastStringToShortByteString (interpSymbolToCLabel str)))
|
|
| 523 | 530 | |
| 524 | 531 | -- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache'
|
| 525 | 532 | -- which maps symbols to the address where they are loaded.
|
| ... | ... | @@ -86,9 +86,9 @@ data Message a where |
| 86 | 86 | |
| 87 | 87 | -- These all invoke the corresponding functions in the RTS Linker API.
|
| 88 | 88 | InitLinker :: Message ()
|
| 89 | - LookupSymbol :: String -> Message (Maybe (RemotePtr ()))
|
|
| 90 | - LookupSymbolInDLL :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ()))
|
|
| 91 | - LookupClosure :: String -> Message (Maybe HValueRef)
|
|
| 89 | + LookupSymbol :: !BS.ShortByteString -> Message (Maybe (RemotePtr ()))
|
|
| 90 | + LookupSymbolInDLL :: !(RemotePtr LoadedDLL) -> !BS.ShortByteString -> Message (Maybe (RemotePtr ()))
|
|
| 91 | + LookupClosure :: !BS.ShortByteString -> Message (Maybe HValueRef)
|
|
| 92 | 92 | LoadDLLs :: [String] -> Message (Either String [RemotePtr LoadedDLL])
|
| 93 | 93 | LoadArchive :: String -> Message () -- error?
|
| 94 | 94 | LoadObj :: String -> Message () -- error?
|
| ... | ... | @@ -162,8 +162,8 @@ data Message a where |
| 162 | 162 | |
| 163 | 163 | -- | Create a set of CostCentres with the same module name
|
| 164 | 164 | MkCostCentres
|
| 165 | - :: String -- module, RemotePtr so it can be shared
|
|
| 166 | - -> [(String,String)] -- (name, SrcSpan)
|
|
| 165 | + :: !(RemotePtr ()) -- ModuleName
|
|
| 166 | + -> ![(BS.ShortByteString, BS.ShortByteString)] -- (name, SrcSpan)
|
|
| 167 | 167 | -> Message [RemotePtr CostCentre]
|
| 168 | 168 | |
| 169 | 169 | -- | Show a 'CostCentreStack' as a @[String]@
|
| ... | ... | @@ -430,7 +430,7 @@ data EvalStatus_ a b |
| 430 | 430 | instance Binary a => Binary (EvalStatus_ a b)
|
| 431 | 431 | |
| 432 | 432 | data EvalBreakpoint = EvalBreakpoint
|
| 433 | - { eb_info_mod :: String -- ^ Breakpoint info module
|
|
| 433 | + { eb_info_mod :: !BS.ShortByteString -- ^ Breakpoint info module
|
|
| 434 | 434 | , eb_info_mod_unit :: BS.ShortByteString -- ^ Breakpoint tick module unit id
|
| 435 | 435 | , eb_info_index :: Int -- ^ Breakpoint info index
|
| 436 | 436 | }
|
| ... | ... | @@ -31,6 +31,8 @@ import GHCi.RemoteTypes |
| 31 | 31 | import GHCi.Message (LoadedDLL)
|
| 32 | 32 | import Control.Exception (throwIO, ErrorCall(..))
|
| 33 | 33 | import Control.Monad ( when )
|
| 34 | +import qualified Data.ByteString.Short as BS
|
|
| 35 | +import Data.Char (ord)
|
|
| 34 | 36 | import Data.Foldable
|
| 35 | 37 | import Foreign.C
|
| 36 | 38 | import Foreign.Marshal.Alloc ( alloca, free )
|
| ... | ... | @@ -104,15 +106,15 @@ unloadObj f = throwIO $ ErrorCall $ "unloadObj: unsupported on wasm for " <> f |
| 104 | 106 | purgeObj :: String -> IO ()
|
| 105 | 107 | purgeObj f = throwIO $ ErrorCall $ "purgeObj: unsupported on wasm for " <> f
|
| 106 | 108 | |
| 107 | -lookupSymbol :: String -> IO (Maybe (Ptr a))
|
|
| 108 | -lookupSymbol sym = do
|
|
| 109 | - r <- js_lookupSymbol $ toJSString sym
|
|
| 109 | +lookupSymbol :: BS.ShortByteString -> IO (Maybe (Ptr a))
|
|
| 110 | +lookupSymbol sym@(BS.SBS ba#) = do
|
|
| 111 | + r <- js_lookupSymbolPtr ba# (BS.length sym)
|
|
| 110 | 112 | evaluate $ if r == nullPtr then Nothing else Just r
|
| 111 | 113 | |
| 112 | -foreign import javascript unsafe "__ghc_wasm_jsffi_dyld.lookupSymbol($1)"
|
|
| 113 | - js_lookupSymbol :: JSString -> IO (Ptr a)
|
|
| 114 | +foreign import javascript unsafe "__ghc_wasm_jsffi_dyld.lookupSymbolPtr($1,$2)"
|
|
| 115 | + js_lookupSymbolPtr :: ByteArray# -> Int -> IO (Ptr a)
|
|
| 114 | 116 | |
| 115 | -lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a))
|
|
| 117 | +lookupSymbolInDLL :: Ptr LoadedDLL -> BS.ShortByteString -> IO (Maybe (Ptr a))
|
|
| 116 | 118 | lookupSymbolInDLL _ _ = pure Nothing
|
| 117 | 119 | |
| 118 | 120 | resolveObjs :: IO Bool
|
| ... | ... | @@ -149,27 +151,27 @@ initObjLinker :: ShouldRetainCAFs -> IO () |
| 149 | 151 | initObjLinker RetainCAFs = c_initLinker_ 1
|
| 150 | 152 | initObjLinker _ = c_initLinker_ 0
|
| 151 | 153 | |
| 152 | -lookupSymbol :: String -> IO (Maybe (Ptr a))
|
|
| 154 | +lookupSymbol :: BS.ShortByteString -> IO (Maybe (Ptr a))
|
|
| 153 | 155 | lookupSymbol str_in = do
|
| 154 | 156 | let str = prefixUnderscore str_in
|
| 155 | - withCAString str $ \c_str -> do
|
|
| 157 | + BS.useAsCString str $ \c_str -> do
|
|
| 156 | 158 | addr <- c_lookupSymbol c_str
|
| 157 | 159 | if addr == nullPtr
|
| 158 | 160 | then return Nothing
|
| 159 | 161 | else return (Just addr)
|
| 160 | 162 | |
| 161 | -lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a))
|
|
| 163 | +lookupSymbolInDLL :: Ptr LoadedDLL -> BS.ShortByteString -> IO (Maybe (Ptr a))
|
|
| 162 | 164 | lookupSymbolInDLL dll str_in = do
|
| 163 | 165 | let str = prefixUnderscore str_in
|
| 164 | - withCAString str $ \c_str -> do
|
|
| 166 | + BS.useAsCString str $ \c_str -> do
|
|
| 165 | 167 | addr <- c_lookupSymbolInNativeObj dll c_str
|
| 166 | 168 | if addr == nullPtr
|
| 167 | 169 | then return Nothing
|
| 168 | 170 | else return (Just addr)
|
| 169 | 171 | |
| 170 | -prefixUnderscore :: String -> String
|
|
| 172 | +prefixUnderscore :: BS.ShortByteString -> BS.ShortByteString
|
|
| 171 | 173 | prefixUnderscore
|
| 172 | - | cLeadingUnderscore = ('_':)
|
|
| 174 | + | cLeadingUnderscore = BS.cons (fromIntegral (ord '_'))
|
|
| 173 | 175 | | otherwise = id
|
| 174 | 176 | |
| 175 | 177 | -- | loadDLL loads a dynamic library using the OS's native linker
|
| ... | ... | @@ -298,7 +300,7 @@ isWindowsHost = False |
| 298 | 300 | |
| 299 | 301 | #endif
|
| 300 | 302 | |
| 301 | -lookupClosure :: String -> IO (Maybe HValueRef)
|
|
| 303 | +lookupClosure :: BS.ShortByteString -> IO (Maybe HValueRef)
|
|
| 302 | 304 | lookupClosure str = do
|
| 303 | 305 | m <- lookupSymbol str
|
| 304 | 306 | case m of
|
| ... | ... | @@ -34,7 +34,7 @@ import Control.DeepSeq |
| 34 | 34 | import Control.Exception
|
| 35 | 35 | import Control.Monad
|
| 36 | 36 | import Data.ByteString (ByteString)
|
| 37 | -import qualified Data.ByteString.Short as BS
|
|
| 37 | +import qualified Data.ByteString.Short.Internal as BS
|
|
| 38 | 38 | import qualified Data.ByteString.Unsafe as B
|
| 39 | 39 | import GHC.Exts
|
| 40 | 40 | import qualified GHC.Exts.Heap as Heap
|
| ... | ... | @@ -135,12 +135,12 @@ foreign import javascript "((ptr,off) => globalThis.h$loadJS(h$decodeUtf8z(ptr,o |
| 135 | 135 | |
| 136 | 136 | foreign import javascript "((ptr,off) => globalThis.h$lookupClosure(h$decodeUtf8z(ptr,off)))" lookupJSClosure# :: CString -> State# RealWorld -> (# State# RealWorld, Int# #)
|
| 137 | 137 | |
| 138 | -lookupJSClosure' :: String -> IO Int
|
|
| 139 | -lookupJSClosure' str = withCString str $ \cstr -> IO (\s ->
|
|
| 138 | +lookupJSClosure' :: BS.ShortByteString -> IO Int
|
|
| 139 | +lookupJSClosure' str = BS.useAsCString str $ \cstr -> IO (\s ->
|
|
| 140 | 140 | case lookupJSClosure# cstr s of
|
| 141 | 141 | (# s', r #) -> (# s', I# r #))
|
| 142 | 142 | |
| 143 | -lookupJSClosure :: String -> IO (Maybe HValueRef)
|
|
| 143 | +lookupJSClosure :: BS.ShortByteString -> IO (Maybe HValueRef)
|
|
| 144 | 144 | lookupJSClosure str = lookupJSClosure' str >>= \case
|
| 145 | 145 | 0 -> pure Nothing
|
| 146 | 146 | r -> pure (Just (RemoteRef (RemotePtr (fromIntegral r))))
|
| ... | ... | @@ -359,7 +359,7 @@ withBreakAction opts breakMVar statusMVar mtid act |
| 359 | 359 | if is_exception
|
| 360 | 360 | then pure Nothing
|
| 361 | 361 | else do
|
| 362 | - info_mod <- peekCString (Ptr info_mod#)
|
|
| 362 | + info_mod <- BS.packCString (Ptr info_mod#)
|
|
| 363 | 363 | info_mod_uid <- BS.packCString (Ptr info_mod_uid#)
|
| 364 | 364 | pure (Just (EvalBreakpoint info_mod info_mod_uid (I# infox#)))
|
| 365 | 365 | putMVar statusMVar $ EvalBreak apStack_r breakpoint resume_r ccs
|
| ... | ... | @@ -434,17 +434,24 @@ mkString0 bs = B.unsafeUseAsCStringLen bs $ \(cstr,len) -> do |
| 434 | 434 | pokeElemOff (ptr :: Ptr CChar) len 0
|
| 435 | 435 | return (castRemotePtr (toRemotePtr ptr))
|
| 436 | 436 | |
| 437 | -mkCostCentres :: String -> [(String,String)] -> IO [RemotePtr CostCentre]
|
|
| 437 | +mkCostCentres :: RemotePtr () -> [(BS.ShortByteString, BS.ShortByteString)] -> IO [RemotePtr CostCentre]
|
|
| 438 | 438 | #if defined(PROFILING)
|
| 439 | 439 | mkCostCentres mod ccs = do
|
| 440 | - c_module <- newCString mod
|
|
| 440 | + let c_module = fromRemotePtr $ castRemotePtr mod
|
|
| 441 | 441 | mapM (mk_one c_module) ccs
|
| 442 | 442 | where
|
| 443 | 443 | mk_one c_module (decl_path,srcspan) = do
|
| 444 | - c_name <- newCString decl_path
|
|
| 445 | - c_srcspan <- newCString srcspan
|
|
| 444 | + c_name <- newCStringFromSBS decl_path
|
|
| 445 | + c_srcspan <- newCStringFromSBS srcspan
|
|
| 446 | 446 | toRemotePtr <$> c_mkCostCentre c_name c_module c_srcspan
|
| 447 | 447 | |
| 448 | + newCStringFromSBS sbs = do
|
|
| 449 | + let len = BS.length sbs
|
|
| 450 | + buf <- mallocBytes $ len + 1
|
|
| 451 | + BS.copyToPtr sbs 0 buf (fromIntegral len)
|
|
| 452 | + pokeByteOff buf len (0 :: Word8)
|
|
| 453 | + pure buf
|
|
| 454 | + |
|
| 448 | 455 | foreign import ccall unsafe "mkCostCentre"
|
| 449 | 456 | c_mkCostCentre :: Ptr CChar -> Ptr CChar -> Ptr CChar -> IO (Ptr CostCentre)
|
| 450 | 457 | #else
|
| 1 | +{-# LANGUAGE OverloadedStrings #-}
|
|
| 1 | 2 | {-# LANGUAGE RecordWildCards #-}
|
| 2 | 3 | |
| 3 | 4 | module Main (main) where
|
| 4 | 5 | |
| 5 | 6 | import Control.Exception
|
| 6 | 7 | import Control.Monad
|
| 8 | +import Data.ByteString.Short (ShortByteString)
|
|
| 7 | 9 | |
| 8 | 10 | import Foreign
|
| 9 | 11 | |
| ... | ... | @@ -15,7 +17,7 @@ import GHCi.ObjLink |
| 15 | 17 | |
| 16 | 18 | rotateSO
|
| 17 | 19 | :: (FunPtr (IO (StablePtr a)) -> (IO (StablePtr a)))
|
| 18 | - -> String
|
|
| 20 | + -> ShortByteString
|
|
| 19 | 21 | -> (Maybe FilePath, FilePath)
|
| 20 | 22 | -> IO a
|
| 21 | 23 | rotateSO dynamicCall symName (old, newDLL) = do
|
| 1 | +:set -XOverloadedStrings
|
|
| 1 | 2 | import GHCi.ObjLink
|
| 2 | 3 | lookupClosure "blah" |
| 1 | +{-# LANGUAGE OverloadedStrings #-}
|
|
| 2 | + |
|
| 1 | 3 | module Main (main) where
|
| 2 | 4 | |
| 3 | 5 | import Foreign
|
| ... | ... | @@ -1334,6 +1334,13 @@ class DyLD { |
| 1334 | 1334 | }
|
| 1335 | 1335 | return 0;
|
| 1336 | 1336 | }
|
| 1337 | + |
|
| 1338 | + lookupSymbolPtr(symPtr, symLen) {
|
|
| 1339 | + const sym = new TextDecoder("utf-8", { fatal: true }).decode(
|
|
| 1340 | + new Uint8Array(this.#memory.buffer, symPtr, symLen)
|
|
| 1341 | + );
|
|
| 1342 | + return this.lookupSymbol(sym);
|
|
| 1343 | + }
|
|
| 1337 | 1344 | }
|
| 1338 | 1345 | |
| 1339 | 1346 | // The main entry point of dyld that may be run on node/browser, and
|