Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup: use internal ByteArray pointers to reduce copying #6

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/Extism.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ module Extism (
import Foreign.ForeignPtr
import Foreign.C.String
import Foreign.Ptr
import GHC.Ptr
import Foreign.Marshal.Array
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.StablePtr
import Foreign.Concurrent
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.ByteString.Internal (c2w, w2c)
import Data.ByteString.Internal (c2w, w2c, unsafePackLenAddress)
import Data.ByteString.Unsafe (unsafeUseAsCString)
import qualified Text.JSON (encode, decode, toJSObject, showJSON, Result(..))
import qualified Extism.JSON (JSON(..))
Expand Down Expand Up @@ -143,18 +144,20 @@ functionExists (Plugin plugin) name =
b <- withCString name (extism_plugin_function_exists plugin')
if b == 1 then return True else return False)

-- Used to convert a value into linear memory
class ToBytes a where
toBytes :: a -> B.ByteString

-- Used to read a value from linear memory
class FromPointer a where
fromPointer :: CString -> Int -> IO (Result a)

instance ToBytes B.ByteString where
toBytes x = x

instance FromPointer B.ByteString where
fromPointer ptr len = do
x <- B.packCStringLen (castPtr ptr, fromIntegral len)
fromPointer (Ptr ptr) len = do
x <- unsafePackLenAddress (fromIntegral len) ptr
return $ Right x

instance ToBytes [Char] where
Expand All @@ -167,6 +170,7 @@ instance FromPointer [Char] where
Left e -> return $ Left e
Right bs -> return $ Right $ fromByteString bs

-- Wraps a `JSON` value for input/output
newtype JSONValue x = JSONValue x

instance Extism.JSON.JSON a => ToBytes (JSONValue a) where
Expand Down
13 changes: 5 additions & 8 deletions src/Extism/HostFunction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ import Foreign.C.String
import Foreign.StablePtr
import Foreign.Concurrent
import Foreign.Marshal.Array
import qualified Data.ByteString.Internal as BS (c2w)
import GHC.Ptr
import qualified Data.ByteString.Internal as BS (c2w, unsafePackLenAddress)
import Data.IORef

-- | Access the plugin that is currently executing from inside a host function
Expand Down Expand Up @@ -76,19 +77,15 @@ memoryOffset (CurrentPlugin plugin _ _ _) (MemoryHandle offs) = do
-- | Access the data associated with a handle as a 'ByteString'
memoryBytes :: CurrentPlugin -> MemoryHandle -> IO B.ByteString
memoryBytes plugin offs = do
ptr <- memoryOffset plugin offs
Ptr ptr <- memoryOffset plugin offs
len <- memoryLength plugin offs
arr <- peekArray (fromIntegral len) ptr
return $ B.pack arr
BS.unsafePackLenAddress (fromIntegral len) ptr


-- | Access the data associated with a handle as a 'String'
memoryString :: CurrentPlugin -> MemoryHandle -> IO String
memoryString plugin offs = do
ptr <- memoryOffset plugin offs
len <- memoryLength plugin offs
arr <- peekArray (fromIntegral len) ptr
return $ fromByteString $ B.pack arr
fromByteString <$> memoryBytes plugin offs

-- | Access the data associated with a handle and convert it into a Haskell type
memoryGet :: FromPointer a => CurrentPlugin -> MemoryHandle -> IO (Result a)
Expand Down
Loading