[Git][ghc/ghc][wip/js-staging] 2 commits: Refactor Expr
Sylvain Henry (@hsyl20)
gitlab at gitlab.haskell.org
Sat Sep 24 08:08:09 UTC 2022
Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC
Commits:
a5c074c8 by Sylvain Henry at 2022-09-24T10:11:14+02:00
Refactor Expr
- - - - -
fc880b1b by Sylvain Henry at 2022-09-24T10:11:14+02:00
Object: reduce pinned allocation. And don't forget to hClose invalid objects
- - - - -
3 changed files:
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/Utils/Binary.hs
Changes:
=====================================
compiler/GHC/StgToJS/Expr.hs
=====================================
@@ -74,6 +74,7 @@ import qualified Data.Map as M
import Control.Monad
import Control.Arrow ((&&&))
+-- | Evaluate an expression in the given expression context (continuation)
genExpr :: HasDebugCallStack => ExprCtx -> CgStgExpr -> G (JStat, ExprResult)
genExpr ctx stg = case stg of
StgApp f args -> genApp ctx f args
@@ -287,17 +288,32 @@ genBody :: HasDebugCallStack
-> CgStgExpr
-> G JStat
genBody ctx i startReg args e = do
- la <- loadArgs startReg args
+ -- load arguments into local variables
+ la <- do
+ args' <- concatMapM genIdArgI args
+ return (declAssignAll args' (fmap toJExpr [startReg..]))
+
+ -- assert that arguments have valid runtime reps
lav <- verifyRuntimeReps args
- let ids :: [TypedExpr]
- ids = -- take (resultSize args $ idType i) jsRegsFromR1
- reverse . fst $
- foldl' (\(rs, vs) (rep, size) ->
- let (vs0, vs1) = splitAt size vs
- in (TypedExpr rep vs0:rs,vs1))
- ([], jsRegsFromR1)
- (resultSize args $ idType i)
- (e, _r) <- genExpr (ctx { ctxTarget = ids }) e
+
+ -- compute PrimReps and their number of slots required to return the result of
+ -- i applied to args.
+ let res_vars = resultSize args (idType i)
+
+ -- compute typed expressions for each slot and assign registers
+ let go_var regs = \case
+ [] -> []
+ ((rep,size):rs) ->
+ let !(regs0,regs1) = splitAt size regs
+ !ts = go_var regs1 rs
+ in TypedExpr rep regs0 : ts
+
+ let tgt = go_var jsRegsFromR1 res_vars
+ let !ctx' = ctx { ctxTarget = tgt }
+
+ -- generate code for the expression
+ (e, _r) <- genExpr ctx' e
+
return $ la <> lav <> e <> returnStack
-- find the result type after applying the function to the arguments
@@ -339,11 +355,6 @@ resultSize [] t
where
t' = unwrapType t
-loadArgs :: HasDebugCallStack => StgReg -> [Id] -> G JStat
-loadArgs start args = do
- args' <- concatMapM genIdArgI args
- return (declAssignAll args' (fmap toJExpr [start..]))
-
verifyRuntimeReps :: HasDebugCallStack => [Id] -> G JStat
verifyRuntimeReps xs = do
runtime_assert <- csRuntimeAssert <$> getSettings
=====================================
compiler/GHC/StgToJS/Object.hs
=====================================
@@ -72,6 +72,9 @@ import Data.Map (Map)
import qualified Data.Map as M
import Data.Word
import Data.Char
+import Foreign.Storable
+import Foreign.Marshal.Array
+import System.IO
import GHC.Settings.Constants (hiVersion)
@@ -235,20 +238,28 @@ putObject bh mod_name deps os = do
-- | Test if the object file is a JS object
isJsObjectFile :: FilePath -> IO Bool
-isJsObjectFile fp =
- readBinMemN (length magic) fp >>= \case
- Nothing -> pure False
- Just bh -> getCheckMagic bh
+isJsObjectFile fp = do
+ let !n = length magic
+ withBinaryFile fp ReadMode $ \hdl -> do
+ allocaArray n $ \ptr -> do
+ n' <- hGetBuf hdl ptr n
+ if (n' /= n)
+ then pure False
+ else checkMagic (peekElemOff ptr)
+
+-- | Check magic
+checkMagic :: (Int -> IO Word8) -> IO Bool
+checkMagic get_byte = do
+ let go_magic !i = \case
+ [] -> pure True
+ (e:es) -> get_byte i >>= \case
+ c | fromIntegral (ord e) == c -> go_magic (i+1) es
+ | otherwise -> pure False
+ go_magic 0 magic
-- | Parse object magic
getCheckMagic :: BinHandle -> IO Bool
-getCheckMagic bh = do
- let go_magic = \case
- [] -> pure True
- (e:es) -> getByte bh >>= \case
- c | fromIntegral (ord e) == c -> go_magic es
- | otherwise -> pure False
- go_magic magic
+getCheckMagic bh = checkMagic (const (getByte bh))
-- | Parse object header
getObjectHeader :: BinHandle -> IO (Either String ModuleName)
=====================================
compiler/GHC/Utils/Binary.hs
=====================================
@@ -289,19 +289,19 @@ writeBinMem (BinMem _ ix_r _ arr_r) fn = do
readBinMem :: FilePath -> IO BinHandle
readBinMem filename = do
- h <- openBinaryFile filename ReadMode
- filesize' <- hFileSize h
- let filesize = fromIntegral filesize'
- readBinMem_ filesize h
+ withBinaryFile filename ReadMode $ \h -> do
+ filesize' <- hFileSize h
+ let filesize = fromIntegral filesize'
+ readBinMem_ filesize h
readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle)
readBinMemN size filename = do
- h <- openBinaryFile filename ReadMode
- filesize' <- hFileSize h
- let filesize = fromIntegral filesize'
- if filesize < size
- then pure Nothing
- else Just <$> readBinMem_ size h
+ withBinaryFile filename ReadMode $ \h -> do
+ filesize' <- hFileSize h
+ let filesize = fromIntegral filesize'
+ if filesize < size
+ then pure Nothing
+ else Just <$> readBinMem_ size h
readBinMem_ :: Int -> Handle -> IO BinHandle
readBinMem_ filesize h = do
@@ -309,7 +309,6 @@ readBinMem_ filesize h = do
count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize
when (count /= filesize) $
error ("Binary.readBinMem: only read " ++ show count ++ " bytes")
- hClose h
arr_r <- newIORef arr
ix_r <- newFastMutInt 0
sz_r <- newFastMutInt filesize
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2304e401ff2ed1241355b64e8e1ac91b6b6d7ce...fc880b1bed25ff401820d269821dd3d7eaafd358
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2304e401ff2ed1241355b64e8e1ac91b6b6d7ce...fc880b1bed25ff401820d269821dd3d7eaafd358
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220924/773e360f/attachment-0001.html>
More information about the ghc-commits
mailing list