{-# LANGUAGE GADTs      #-}
{-# LANGUAGE RankNTypes #-}

module HaskellWorks.Data.Json.Simd.Index.Simple
  ( makeSimpleJsonIbBps
  , makeSimpleJsonIbBpsUnsafe
  , enabledMakeSimpleJsonIbBps
  ) where

import Control.Monad.ST
import Data.Word
import HaskellWorks.Data.Json.Simd.Internal.Index.Simple

import qualified Control.Monad.ST.Unsafe                      as ST
import qualified Data.ByteString                              as BS
import qualified Data.ByteString.Internal                     as BSI
import qualified Data.ByteString.Lazy                         as LBS
import qualified Data.Vector.Storable.Mutable                 as DVSM
import qualified Foreign.ForeignPtr                           as F
import qualified Foreign.ForeignPtr.Unsafe                    as F
import qualified Foreign.Marshal.Unsafe                       as F
import qualified Foreign.Ptr                                  as F
import qualified HaskellWorks.Data.Json.Simd.Capabilities     as C
import qualified HaskellWorks.Data.Json.Simd.Internal.Foreign as F
import qualified HaskellWorks.Data.Json.Simd.Internal.List    as L
import qualified System.IO.Unsafe                             as IO

{- HLINT ignore "Reduce duplication"  -}
{- HLINT ignore "Redundant do"        -}

makeSimpleJsonIbBps :: LBS.ByteString -> Either String [(BS.ByteString, BS.ByteString)]
makeSimpleJsonIbBps :: ByteString -> Either String [(ByteString, ByteString)]
makeSimpleJsonIbBps ByteString
lbs = if Bool
enabledMakeSimpleJsonIbBps
  then [(ByteString, ByteString)]
-> Either String [(ByteString, ByteString)]
forall a b. b -> Either a b
Right (ByteString -> [(ByteString, ByteString)]
makeSimpleJsonIbBpsUnsafe ByteString
lbs)
  else String -> Either String [(ByteString, ByteString)]
forall a b. a -> Either a b
Left String
"makeSimpleJsonIbBps function is disabled"

makeSimpleJsonIbBpsUnsafe :: LBS.ByteString -> [(BS.ByteString, BS.ByteString)]
makeSimpleJsonIbBpsUnsafe :: ByteString -> [(ByteString, ByteString)]
makeSimpleJsonIbBpsUnsafe ByteString
lbs = ByteString
-> ByteString
-> [ByteString]
-> [ByteString]
-> [(ByteString, ByteString)]
forall a b. a -> b -> [a] -> [b] -> [(a, b)]
L.zipPadded ByteString
BS.empty ByteString
BS.empty [ByteString]
ibs [ByteString]
bps
  where chunks :: [(ByteString, ByteString, ByteString)]
chunks  = ByteString -> [(ByteString, ByteString, ByteString)]
makeIbs ByteString
lbs
        ibs :: [ByteString]
ibs     = ((ByteString, ByteString, ByteString) -> ByteString)
-> [(ByteString, ByteString, ByteString)] -> [ByteString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(ByteString
a, ByteString
_, ByteString
_) -> ByteString
a) [(ByteString, ByteString, ByteString)]
chunks
        bps :: [ByteString]
bps     = [(ByteString, ByteString, ByteString)] -> [ByteString]
ibsToIndexByteStrings [(ByteString, ByteString, ByteString)]
chunks

makeIbs :: LBS.ByteString -> [(BS.ByteString, BS.ByteString, BS.ByteString)]
makeIbs :: ByteString -> [(ByteString, ByteString, ByteString)]
makeIbs ByteString
lbs = IO [(ByteString, ByteString, ByteString)]
-> [(ByteString, ByteString, ByteString)]
forall a. IO a -> a
F.unsafeLocalState (IO [(ByteString, ByteString, ByteString)]
 -> [(ByteString, ByteString, ByteString)])
-> IO [(ByteString, ByteString, ByteString)]
-> [(ByteString, ByteString, ByteString)]
forall a b. (a -> b) -> a -> b
$ do
  WorkBuffers
wb <- Int -> IO WorkBuffers
allocWorkBuffers (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1024 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1204)
  WorkState
ws <- IO WorkState
allocWorkState
  IO [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall a. IO a -> IO a
IO.unsafeInterleaveIO (IO [(ByteString, ByteString, ByteString)]
 -> IO [(ByteString, ByteString, ByteString)])
-> IO [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall a b. (a -> b) -> a -> b
$ WorkBuffers
-> WorkState
-> [ByteString]
-> IO [(ByteString, ByteString, ByteString)]
go WorkBuffers
wb WorkState
ws (ByteString -> [ByteString]
LBS.toChunks ByteString
lbs)
  where go :: WorkBuffers -> WorkState -> [BS.ByteString] -> IO [(BS.ByteString, BS.ByteString, BS.ByteString)]
        go :: WorkBuffers
-> WorkState
-> [ByteString]
-> IO [(ByteString, ByteString, ByteString)]
go WorkBuffers
_  WorkState
_  []       = [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
        go WorkBuffers
wb WorkState
ws (ByteString
bs:[ByteString]
bss) = do
          let resLen :: Int
resLen = ByteString -> Int
BS.length ByteString
bs Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8
          ForeignPtr Word8
resIbFptr  <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
F.mallocForeignPtrBytes Int
resLen
          ForeignPtr Word8
resAFptr   <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
F.mallocForeignPtrBytes Int
resLen
          ForeignPtr Word8
resBFptr   <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
F.mallocForeignPtrBytes Int
resLen
          let resIbPtr :: Ptr UInt8
resIbPtr  = Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr (ForeignPtr Word8 -> Ptr Word8
forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr Word8
resIbFptr)
          let resAPtr :: Ptr UInt8
resAPtr   = Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr (ForeignPtr Word8 -> Ptr Word8
forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr Word8
resAFptr )
          let resBPtr :: Ptr UInt8
resBPtr   = Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr (ForeignPtr Word8 -> Ptr Word8
forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr Word8
resBFptr )
          let (ForeignPtr Word8
bsFptr, Int
bsOff, Int
bsLen) = ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr ByteString
bs
          let bsPtr :: Ptr Any
bsPtr = Ptr Word8 -> Ptr Any
forall a b. Ptr a -> Ptr b
F.castPtr (ForeignPtr Word8 -> Ptr Word8
forall a. ForeignPtr a -> Ptr a
F.unsafeForeignPtrToPtr ForeignPtr Word8
bsFptr)
          UInt64
_ <- Ptr UInt8
-> UInt64
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt64
-> Ptr UInt64
-> Ptr UInt64
-> Ptr UInt64
-> Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> IO UInt64
F.processChunk
            (Ptr Any -> Int -> Ptr UInt8
forall a b. Ptr a -> Int -> Ptr b
F.plusPtr Ptr Any
bsPtr Int
bsOff) -- in_buffer:           Ptr UInt8
            (Int -> UInt64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
bsLen)    -- in_length:           Size
            (WorkBuffers -> Ptr UInt8
workBuffersD WorkBuffers
wb)       -- work_bits_of_d:      Ptr UInt8
            (WorkBuffers -> Ptr UInt8
workBuffersA WorkBuffers
wb)       -- work_bits_of_a:      Ptr UInt8
            (WorkBuffers -> Ptr UInt8
workBuffersZ WorkBuffers
wb)       -- work_bits_of_z:      Ptr UInt8
            (WorkBuffers -> Ptr UInt8
workBuffersQ WorkBuffers
wb)       -- work_bits_of_q:      Ptr UInt8
            (WorkBuffers -> Ptr UInt8
workBuffersB WorkBuffers
wb)       -- work_bits_of_b:      Ptr UInt8
            (WorkBuffers -> Ptr UInt8
workBuffersE WorkBuffers
wb)       -- work_bits_of_e:      Ptr UInt8
            (WorkState -> Ptr UInt64
workStateZ WorkState
ws)         -- last_trailing_ones:  Ptr Size
            (WorkState -> Ptr UInt64
workStateO WorkState
ws)         -- quote_odds_carry:    Ptr Size
            (WorkState -> Ptr UInt64
workStateE WorkState
ws)         -- quote_evens_carry:   Ptr Size
            (WorkState -> Ptr UInt64
workStateM WorkState
ws)         -- quote_mask_carry:    Ptr UInt64
            Ptr UInt8
resIbPtr                -- result_ibs:          Ptr UInt8
            Ptr UInt8
resAPtr                 -- result_a:            Ptr UInt8
            Ptr UInt8
resBPtr                 -- result_z:            Ptr UInt8
          let r :: (ByteString, ByteString, ByteString)
r =
                ( ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr ForeignPtr Word8
resIbFptr Int
0 Int
resLen
                , ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr ForeignPtr Word8
resAFptr  Int
0 Int
resLen
                , ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr ForeignPtr Word8
resBFptr  Int
0 Int
resLen
                )
          [(ByteString, ByteString, ByteString)]
rs <- IO [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall a. IO a -> IO a
IO.unsafeInterleaveIO (IO [(ByteString, ByteString, ByteString)]
 -> IO [(ByteString, ByteString, ByteString)])
-> IO [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall a b. (a -> b) -> a -> b
$ WorkBuffers
-> WorkState
-> [ByteString]
-> IO [(ByteString, ByteString, ByteString)]
go WorkBuffers
wb WorkState
ws [ByteString]
bss
          [(ByteString, ByteString, ByteString)]
-> IO [(ByteString, ByteString, ByteString)]
forall (m :: * -> *) a. Monad m => a -> m a
return ((ByteString, ByteString, ByteString)
r(ByteString, ByteString, ByteString)
-> [(ByteString, ByteString, ByteString)]
-> [(ByteString, ByteString, ByteString)]
forall a. a -> [a] -> [a]
:[(ByteString, ByteString, ByteString)]
rs)

ibsToIndexByteStrings :: ()
  => [(BS.ByteString, BS.ByteString, BS.ByteString)]
  -> [BS.ByteString]
ibsToIndexByteStrings :: [(ByteString, ByteString, ByteString)] -> [ByteString]
ibsToIndexByteStrings [(ByteString, ByteString, ByteString)]
bits = IO [ByteString] -> [ByteString]
forall a. IO a -> a
F.unsafeLocalState (IO [ByteString] -> [ByteString])
-> IO [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ do
  BpState
bpState <- IO BpState
emptyBpState
  IO [ByteString] -> IO [ByteString]
forall a. IO a -> IO a
IO.unsafeInterleaveIO (IO [ByteString] -> IO [ByteString])
-> IO [ByteString] -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ BpState -> [Step] -> IO [ByteString]
go BpState
bpState (((ByteString, ByteString, ByteString) -> Step)
-> [(ByteString, ByteString, ByteString)] -> [Step]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(ByteString
a, ByteString
b, ByteString
c) -> ByteString -> ByteString -> ByteString -> Step
mkIndexStep ByteString
a ByteString
b ByteString
c) [(ByteString, ByteString, ByteString)]
bits)
  where go :: ()
          => BpState
          -> [Step]
          -> IO [BS.ByteString]
        go :: BpState -> [Step] -> IO [ByteString]
go BpState
s (Step
step:[Step]
steps) = do
          let bp :: ByteString
bp = BpState -> Step -> ByteString
stepToByteString BpState
s Step
step
          [ByteString]
bps <- IO [ByteString] -> IO [ByteString]
forall a. IO a -> IO a
IO.unsafeInterleaveIO (IO [ByteString] -> IO [ByteString])
-> IO [ByteString] -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ BpState -> [Step] -> IO [ByteString]
go BpState
s [Step]
steps
          [ByteString] -> IO [ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> IO [ByteString])
-> [ByteString] -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$ ByteString
bpByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
bps
        go BpState
s [] = [ByteString] -> IO [ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return [BpState -> Step -> ByteString
stepToByteString BpState
s Step
indexStepFinal]

mkIndexStep :: BS.ByteString -> BS.ByteString -> BS.ByteString -> Step
mkIndexStep :: ByteString -> ByteString -> ByteString -> Step
mkIndexStep ByteString
is ByteString
as ByteString
zs | Int
isLen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
asLen Bool -> Bool -> Bool
&& Int
asLen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
zsLen = (forall s. BpState -> MVector s Word64 -> ST s Int) -> Int -> Step
Step forall s. BpState -> MVector s Word64 -> ST s Int
go Int
isLen
  where isLen :: Int
isLen = ByteString -> Int
BS.length ByteString
is
        asLen :: Int
asLen = ByteString -> Int
BS.length ByteString
as
        zsLen :: Int
zsLen = ByteString -> Int
BS.length ByteString
zs
        (ForeignPtr Word8
isFptr, Int
_, Int
_) = ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr ByteString
is
        (ForeignPtr Word8
asFptr, Int
_, Int
_) = ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr ByteString
as
        (ForeignPtr Word8
zsFptr, Int
_, Int
_) = ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr ByteString
zs
        go  :: BpState
            -> DVSM.MVector s Word64
            -> ST s Int
        go :: BpState -> MVector s Word64 -> ST s Int
go BpState
bpState MVector s Word64
bpvm = (UInt64 -> Int) -> ST s UInt64 -> ST s Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap UInt64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ST s UInt64 -> ST s Int)
-> (IO UInt64 -> ST s UInt64) -> IO UInt64 -> ST s Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO UInt64 -> ST s UInt64
forall a s. IO a -> ST s a
ST.unsafeIOToST (IO UInt64 -> ST s Int) -> IO UInt64 -> ST s Int
forall a b. (a -> b) -> a -> b
$ do
          let (ForeignPtr Word64
outFptr, Int
_, Int
_) = MVector s Word64 -> (ForeignPtr Word64, Int, Int)
forall a s. Storable a => MVector s a -> (ForeignPtr a, Int, Int)
DVSM.unsafeToForeignPtr MVector s Word64
bpvm

          ForeignPtr Word64 -> (Ptr Word64 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr ForeignPtr Word64
outFptr ((Ptr Word64 -> IO UInt64) -> IO UInt64)
-> (Ptr Word64 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
outPtr ->
            ForeignPtr Word8 -> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr ForeignPtr Word8
isFptr ((Ptr Word8 -> IO UInt64) -> IO UInt64)
-> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
isPtr ->
              ForeignPtr Word8 -> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr ForeignPtr Word8
asFptr ((Ptr Word8 -> IO UInt64) -> IO UInt64)
-> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
asPtr ->
                ForeignPtr Word8 -> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr ForeignPtr Word8
zsFptr ((Ptr Word8 -> IO UInt64) -> IO UInt64)
-> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
zsPtr ->
                  ForeignPtr Word8 -> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr (BpState -> ForeignPtr Word8
bpStateP BpState
bpState) ((Ptr Word8 -> IO UInt64) -> IO UInt64)
-> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bpStatePtr -> do
                    Ptr UInt8
-> Ptr UInt8
-> Ptr UInt8
-> UInt64
-> Ptr ()
-> Ptr UInt8
-> IO UInt64
F.writeBpChunk
                      (Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word8
isPtr)
                      (Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word8
asPtr)
                      (Ptr Word8 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word8
zsPtr)
                      (Int -> UInt64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
is))
                      (Ptr Word8 -> Ptr ()
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word8
bpStatePtr)
                      (Ptr Word64 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word64
outPtr)
mkIndexStep ByteString
_ ByteString
_ ByteString
_ = String -> Step
forall a. HasCallStack => String -> a
error String
"Mismatched input size"

indexStepFinal :: Step
indexStepFinal :: Step
indexStepFinal = (forall s. BpState -> MVector s Word64 -> ST s Int) -> Int -> Step
Step forall s. BpState -> MVector s Word64 -> ST s Int
go Int
2
  where go  :: BpState
            -> DVSM.MVector s Word64
            -> ST s Int
        go :: BpState -> MVector s Word64 -> ST s Int
go BpState
bpState MVector s Word64
bpvm = (UInt64 -> Int) -> ST s UInt64 -> ST s Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap UInt64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ST s UInt64 -> ST s Int)
-> (IO UInt64 -> ST s UInt64) -> IO UInt64 -> ST s Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO UInt64 -> ST s UInt64
forall a s. IO a -> ST s a
ST.unsafeIOToST (IO UInt64 -> ST s Int) -> IO UInt64 -> ST s Int
forall a b. (a -> b) -> a -> b
$ do
          let (ForeignPtr Word64
outFptr, Int
_, Int
_) = MVector s Word64 -> (ForeignPtr Word64, Int, Int)
forall a s. Storable a => MVector s a -> (ForeignPtr a, Int, Int)
DVSM.unsafeToForeignPtr MVector s Word64
bpvm

          ForeignPtr Word64 -> (Ptr Word64 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr ForeignPtr Word64
outFptr ((Ptr Word64 -> IO UInt64) -> IO UInt64)
-> (Ptr Word64 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
outPtr ->
            ForeignPtr Word8 -> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
F.withForeignPtr (BpState -> ForeignPtr Word8
bpStateP BpState
bpState) ((Ptr Word8 -> IO UInt64) -> IO UInt64)
-> (Ptr Word8 -> IO UInt64) -> IO UInt64
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
bpStatePtr -> do
              Ptr () -> Ptr UInt8 -> IO UInt64
F.writeBpChunkFinal (Ptr Word8 -> Ptr ()
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word8
bpStatePtr) (Ptr Word64 -> Ptr UInt8
forall a b. Ptr a -> Ptr b
F.castPtr Ptr Word64
outPtr)

stepToByteString :: BpState -> Step -> BS.ByteString
stepToByteString :: BpState -> Step -> ByteString
stepToByteString BpState
state (Step forall s. BpState -> MVector s Word64 -> ST s Int
step Int
size) = IO ByteString -> ByteString
forall a. IO a -> a
F.unsafeLocalState (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
  let bsSize :: Int
bsSize = Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8
  ForeignPtr Word8
bpFptr <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
BSI.mallocByteString Int
bsSize
  let bpVm :: MVector RealWorld Word64
bpVm = ForeignPtr Word64 -> Int -> Int -> MVector RealWorld Word64
forall a s. Storable a => ForeignPtr a -> Int -> Int -> MVector s a
DVSM.unsafeFromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word64
forall a b. ForeignPtr a -> ForeignPtr b
F.castForeignPtr ForeignPtr Word8
bpFptr) Int
0 Int
size
  Int
w64Size <- ST RealWorld Int -> IO Int
forall a. ST RealWorld a -> IO a
stToIO (ST RealWorld Int -> IO Int) -> ST RealWorld Int -> IO Int
forall a b. (a -> b) -> a -> b
$ BpState -> MVector RealWorld Word64 -> ST RealWorld Int
forall s. BpState -> MVector s Word64 -> ST s Int
step BpState
state MVector RealWorld Word64
bpVm
  ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.PS ForeignPtr Word8
bpFptr Int
0 (Int
w64Size Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8))

enabledMakeSimpleJsonIbBps :: Bool
enabledMakeSimpleJsonIbBps :: Bool
enabledMakeSimpleJsonIbBps = Bool
C.avx_2 Bool -> Bool -> Bool
&& Bool
C.sse_4_2 Bool -> Bool -> Bool
&& Bool
C.bmi_2