Skip to content

Commit d38b45f

Browse files
committed
Drop assumption that passed bytes are pinned
Apply a fix that in case of unpinned bytes passed in hPutBuffer we first create a pinned ByteArray and copy bytes there
1 parent b5854bb commit d38b45f

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

mempack-scls/mempack-1.0/Data/MemPack/Extra.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import Data.ByteString.Lazy qualified as BSL
3838
import Data.MemPack
3939
import Data.MemPack.Buffer
4040
import Data.MemPack.Error
41+
import Data.Primitive.ByteArray
4142
import Data.Primitive.Ptr
4243
import Data.String (IsString)
4344
import Data.Text qualified as T
@@ -240,12 +241,19 @@ hPutBuffer handle u =
240241
buffer
241242
u
242243
( \bytes -> do
243-
withForeignPtr (pinnedByteArrayToForeignPtr bytes) $ \ptr -> do
244+
pinnedBytes <- pinIfNeeded (ByteArray bytes)
245+
withForeignPtr (byteArrayAsForeignPtr pinnedBytes) $ \ptr -> do
244246
hPutBuf handle ptr len
245247
)
246-
(\addr -> hPutBuf handle (Ptr addr) len) -- Write Ptr#
248+
(\addr -> hPutBuf handle (Ptr addr) len)
247249
where
248250
len = bufferByteCount u
251+
pinIfNeeded bytes
252+
| isByteArrayPinned bytes = return bytes
253+
| otherwise = do
254+
dest <- newPinnedByteArray len
255+
copyByteArray dest 0 bytes 0 len
256+
unsafeFreezeByteArray dest
249257

250258
runDecode :: (IsString e) => Fail e a -> Either e a
251259
runDecode f = runFailLast f

mempack-scls/mempack-2.0/Data/MemPack/Extra.hs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Data.ByteString.Lazy qualified as BSL
3939
import Data.MemPack
4040
import Data.MemPack.Buffer
4141
import Data.MemPack.Error
42+
import Data.Primitive.ByteArray
4243
import Data.Primitive.Ptr
4344
import Data.Text qualified as T
4445
import Data.Typeable
@@ -245,12 +246,20 @@ hPutBuffer handle u =
245246
buffer
246247
u
247248
( \bytes off -> do
248-
withForeignPtr (pinnedByteArrayToForeignPtr bytes) $ \ptr -> do
249-
hPutBuf handle (ptr `plusPtr` (I# off)) (len - (I# off))
249+
(pinnedBytes, offset) <- pinIfNeeded (ByteArray bytes) (I# off)
250+
withForeignPtr (byteArrayAsForeignPtr pinnedBytes) $ \ptr -> do
251+
hPutBuf handle (ptr `plusPtr` offset) (len - offset)
250252
)
251-
(\addr -> hPutBuf handle (Ptr addr) len) -- Write Ptr#
253+
(\addr -> hPutBuf handle (Ptr addr) len)
252254
where
253255
len = bufferByteCount u
256+
pinIfNeeded bytes off
257+
| isByteArrayPinned bytes = return (bytes, off)
258+
| otherwise = do
259+
let l = len - off
260+
dest <- newPinnedByteArray l
261+
copyByteArray dest 0 bytes off l
262+
(,0) <$> unsafeFreezeByteArray dest
254263

255264
runDecode :: (IsString e) => (forall s. FailT e (ST s) a) -> Either e a
256265
runDecode f = runST (runFailLastT f)

0 commit comments

Comments
 (0)