x86-64bit 0.4 → 0.4.1
raw patch · 3 files changed
+18/−7 lines, 3 files
Files
- CHANGELOG.md +4/−0
- CodeGen/X86/FFI.hs +13/−6
- x86-64bit.cabal +1/−1
CHANGELOG.md view
@@ -1,3 +1,7 @@+# Version 0.4.1 + +- fix a bug which caused segmentation fault if a compiled function was called multiple times + # Version 0.4 - rewrite FFI
CodeGen/X86/FFI.hs view
@@ -3,6 +3,7 @@ {-# language BangPatterns #-} {-# language ViewPatterns #-} {-# language FlexibleInstances #-}+{-# language FlexibleContexts #-} {-# language TypeFamilies #-} module CodeGen.X86.FFI where @@ -10,6 +11,7 @@ import Control.Monad import Control.Exception (evaluate)+import Control.DeepSeq import Foreign import Foreign.C.Types import Foreign.ForeignPtr@@ -33,10 +35,15 @@ #endif -class MapResult a => Callable a where dynCCall :: FunPtr a -> a+class (MapResult a, NFData (Result a)) => Callable a where dynCCall :: FunPtr a -> a -callForeignPtr :: Callable a => ForeignPtr a -> a-callForeignPtr p = deeperSeq (unsafePerformIO $ touchForeignPtr p) (dynCCall $ castPtrToFunPtr $ unsafeForeignPtrToPtr p)+{-# NOINLINE callForeignPtr #-}+callForeignPtr :: Callable a => IO (ForeignPtr a) -> a+callForeignPtr p_ = mapResult f (dynCCall $ castPtrToFunPtr $ unsafeForeignPtrToPtr p)+ where+ p = unsafePerformIO p_+ {-# NOINLINE f #-}+ f x = unsafePerformIO $ evaluate (force x) <* touchForeignPtr p class MapResult a => CallableHs a where createHsPtr :: a -> IO (FunPtr a) @@ -80,7 +87,7 @@ {-# NOINLINE compile #-} compile :: Callable a => Code -> a-compile x = callForeignPtr $ unsafePerformIO $ do+compile x = callForeignPtr $ do let (bytes, fromIntegral -> size) = buildTheCode x arr <- c_aligned_malloc (fromIntegral size) PAGE_SIZE _ <- virtualProtect (castPtr arr) (fromIntegral size) flag_PAGE_EXECUTE_READWRITE@@ -91,7 +98,7 @@ {-# NOINLINE compile #-} compile :: Callable a => Code -> a-compile x = callForeignPtr $ unsafePerformIO $ do+compile x = callForeignPtr $ do let (bytes, fromIntegral -> size) = buildTheCode x arr <- memalign PAGE_SIZE size _ <- mprotect arr size 0x7 -- READ, WRITE, EXEC@@ -116,7 +123,7 @@ {-# NOINLINE compile #-} compile :: Callable a => Code -> a-compile x = callForeignPtr $ unsafePerformIO $ do+compile x = callForeignPtr $ do let (bytes, fromIntegral -> size) = buildTheCode x arr <- posixMemAlign PAGE_SIZE size _ <- mprotect arr size 0x7 -- READ, WRITE, EXEC
x86-64bit.cabal view
@@ -1,5 +1,5 @@ name: x86-64bit -version: 0.4 +version: 0.4.1 homepage: https://github.com/divipp/x86-64 synopsis: Runtime code generation for x86 64 bit machine code description: The primary goal of x86-64bit is to provide a lightweight assembler for machine generated 64 bit x86 assembly instructions. See README.md for further details.