Support ghc 9.2 and 9.0

Bump upper bound on base. This continues to support GHC 8.10.7.

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
This commit is contained in:
Andrew Martin 2022-04-08 10:43:40 -04:00 committed by GitHub
parent da17c6ab85
commit dde5a9b07d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 26 deletions

View file

@ -5,6 +5,10 @@ Note: Prior to version 0.3.4.0, this library was named
`small-bytearray-builder` is now just a compatibility shim `small-bytearray-builder` is now just a compatibility shim
to ease the migration process. to ease the migration process.
## 0.3.11.0 -- 2022-??-??
* Support GHC 9.2
## 0.3.10.0 -- 2022-03-01 ## 0.3.10.0 -- 2022-03-01
* Add upper bound on base since this does not build with GHC 9.2. * Add upper bound on base since this does not build with GHC 9.2.

View file

@ -43,10 +43,12 @@ library
Data.Bytes.Builder.Bounded Data.Bytes.Builder.Bounded
Data.Bytes.Builder.Bounded.Class Data.Bytes.Builder.Bounded.Class
Data.Bytes.Builder.Bounded.Unsafe Data.Bytes.Builder.Bounded.Unsafe
other-modules:
Compat
reexported-modules: reexported-modules:
Data.Bytes.Chunks Data.Bytes.Chunks
build-depends: build-depends:
, base >=4.12.0.0 && <4.16 , base >=4.12.0.0 && <4.17
, byteslice >=0.2.6 && <0.3 , byteslice >=0.2.6 && <0.3
, bytestring >=0.10.8.2 && <0.12 , bytestring >=0.10.8.2 && <0.12
, haskell-src-meta >=0.8 , haskell-src-meta >=0.8
@ -59,6 +61,11 @@ library
, text-short >=0.1.3 && <0.2 , text-short >=0.1.3 && <0.2
, wide-word >=0.1.0.9 && <0.2 , wide-word >=0.1.0.9 && <0.2
, zigzag , zigzag
if impl(ghc >= 9.2)
hs-source-dirs: src-9.2
else
if impl(ghc >= 8.10)
hs-source-dirs: src-9.0
if flag(checked) if flag(checked)
build-depends: primitive-checked >= 0.7 && <0.8 build-depends: primitive-checked >= 0.7 && <0.8
else else

53
src-9.0/Compat.hs Normal file
View file

@ -0,0 +1,53 @@
{-# language MagicHash #-}
-- This is actually used with both GHC 8.10 and with GHC 9.0.
-- The name of the directory is a little misleading.
module Compat
( int8ToInt#
, int16ToInt#
, int32ToInt#
, wordToWord8#
, wordToWord16#
, wordToWord32#
, word8ToWord#
, word16ToWord#
, word32ToWord#
) where
import GHC.Exts (Int#,Word#)
int8ToInt# :: Int# -> Int#
{-# inline int8ToInt# #-}
int8ToInt# x = x
int16ToInt# :: Int# -> Int#
{-# inline int16ToInt# #-}
int16ToInt# x = x
int32ToInt# :: Int# -> Int#
{-# inline int32ToInt# #-}
int32ToInt# x = x
wordToWord8# :: Word# -> Word#
{-# inline wordToWord8# #-}
wordToWord8# x = x
wordToWord16# :: Word# -> Word#
{-# inline wordToWord16# #-}
wordToWord16# x = x
wordToWord32# :: Word# -> Word#
{-# inline wordToWord32# #-}
wordToWord32# x = x
word8ToWord# :: Word# -> Word#
{-# inline word8ToWord# #-}
word8ToWord# x = x
word16ToWord# :: Word# -> Word#
{-# inline word16ToWord# #-}
word16ToWord# x = x
word32ToWord# :: Word# -> Word#
{-# inline word32ToWord# #-}
word32ToWord# x = x

15
src-9.2/Compat.hs Normal file
View file

@ -0,0 +1,15 @@
{-# language MagicHash #-}
module Compat
( int8ToInt#
, int16ToInt#
, int32ToInt#
, wordToWord8#
, wordToWord16#
, wordToWord32#
, word8ToWord#
, word16ToWord#
, word32ToWord#
) where
import GHC.Exts

View file

@ -172,6 +172,8 @@ import GHC.ST (ST(ST))
import GHC.Word (Word(W#),Word8(W8#)) import GHC.Word (Word(W#),Word8(W8#))
import Numeric.Natural (Natural) import Numeric.Natural (Natural)
import qualified Compat as C
import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Nat as Nat
import qualified Arithmetic.Types as Arithmetic import qualified Arithmetic.Types as Arithmetic
import qualified Data.Bytes as Bytes import qualified Data.Bytes as Bytes
@ -1277,7 +1279,7 @@ approxDiv10 !n = unsafeShiftR (0x1999999A * n) 32
-- (# sX, bufX, 0#, lenX, Mutable buf0 off0 cs0 #) -- (# sX, bufX, 0#, lenX, Mutable buf0 off0 cs0 #)
unsafeWordToWord8 :: Word -> Word8 unsafeWordToWord8 :: Word -> Word8
unsafeWordToWord8 (W# w) = W8# w unsafeWordToWord8 (W# w) = W8# (C.wordToWord8# w)
-- | This function and the documentation for it are copied from -- | This function and the documentation for it are copied from
-- Takano Akio's fast-builder library. -- Takano Akio's fast-builder library.

View file

@ -123,6 +123,8 @@ import GHC.TypeLits (type (+))
import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#)) import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#))
import Data.Bytes.Types (Bytes(Bytes)) import Data.Bytes.Types (Bytes(Bytes))
import qualified Compat as C
import qualified Arithmetic.Lte as Lte import qualified Arithmetic.Lte as Lte
import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Nat as Nat
import qualified Arithmetic.Types as Arithmetic import qualified Arithmetic.Types as Arithmetic
@ -230,12 +232,12 @@ word64Dec (W64# w) = wordCommonDec# w
-- | Requires up to 10 bytes. Encodes an unsigned 32-bit integer as decimal. -- | Requires up to 10 bytes. Encodes an unsigned 32-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
word32Dec :: Word32 -> Builder 10 word32Dec :: Word32 -> Builder 10
word32Dec (W32# w) = wordCommonDec# w word32Dec (W32# w) = wordCommonDec# (C.word32ToWord# w)
-- | Requires up to 5 bytes. Encodes an unsigned 16-bit integer as decimal. -- | Requires up to 5 bytes. Encodes an unsigned 16-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
word16Dec :: Word16 -> Builder 5 word16Dec :: Word16 -> Builder 5
word16Dec (W16# w) = wordCommonDec# w word16Dec (W16# w) = wordCommonDec# (C.word16ToWord# w)
-- | Requires up to 3 bytes. Encodes an unsigned 8-bit integer as decimal. -- | Requires up to 3 bytes. Encodes an unsigned 8-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
@ -247,7 +249,7 @@ word8Dec (W8# w) =
-- However, I (Andrew Martin) am concerned that although lookup -- However, I (Andrew Martin) am concerned that although lookup
-- table perform very well in microbenchmarks, they can thrash -- table perform very well in microbenchmarks, they can thrash
-- L1 cache in real applications. -- L1 cache in real applications.
word8Dec# w word8Dec# (C.word8ToWord# w)
-- | Requires up to 19 bytes. Encodes an unsigned machine-sized integer -- | Requires up to 19 bytes. Encodes an unsigned machine-sized integer
-- as decimal. This encoding never starts with a zero unless the argument -- as decimal. This encoding never starts with a zero unless the argument
@ -267,21 +269,21 @@ int64Dec (I64# w) = intCommonDec# w
-- Negative numbers are preceded by a minus sign. Positive numbers -- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything. -- are not preceded by anything.
int32Dec :: Int32 -> Builder 11 int32Dec :: Int32 -> Builder 11
int32Dec (I32# w) = intCommonDec# w int32Dec (I32# w) = intCommonDec# (C.int32ToInt# w)
-- | Requires up to 6 bytes. Encodes a signed 16-bit integer as decimal. -- | Requires up to 6 bytes. Encodes a signed 16-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers -- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything. -- are not preceded by anything.
int16Dec :: Int16 -> Builder 6 int16Dec :: Int16 -> Builder 6
int16Dec (I16# w) = intCommonDec# w int16Dec (I16# w) = intCommonDec# (C.int16ToInt# w)
-- | Requires up to 4 bytes. Encodes a signed 8-bit integer as decimal. -- | Requires up to 4 bytes. Encodes a signed 8-bit integer as decimal.
-- This encoding never starts with a zero unless the argument was zero. -- This encoding never starts with a zero unless the argument was zero.
-- Negative numbers are preceded by a minus sign. Positive numbers -- Negative numbers are preceded by a minus sign. Positive numbers
-- are not preceded by anything. -- are not preceded by anything.
int8Dec :: Int8 -> Builder 4 int8Dec :: Int8 -> Builder 4
int8Dec (I8# w) = intCommonDec# w int8Dec (I8# w) = intCommonDec# (C.int8ToInt# w)
-- | Requires up to 20 bytes. Encodes a signed machine-sized integer -- | Requires up to 20 bytes. Encodes a signed machine-sized integer
-- as decimal. This encoding never starts with a zero unless the -- as decimal. This encoding never starts with a zero unless the
@ -441,13 +443,13 @@ word48PaddedLowerHex (W64# w) = word48PaddedLowerHex# w
-- hexadecimal, zero-padding the encoding to 8 digits. This uses -- hexadecimal, zero-padding the encoding to 8 digits. This uses
-- uppercase for the alphabetical digits. -- uppercase for the alphabetical digits.
word32PaddedUpperHex :: Word32 -> Builder 8 word32PaddedUpperHex :: Word32 -> Builder 8
word32PaddedUpperHex (W32# w) = word32PaddedUpperHex# w word32PaddedUpperHex (W32# w) = word32PaddedUpperHex# (C.word32ToWord# w)
-- | Requires exactly 8 bytes. Encodes a 32-bit unsigned integer as -- | Requires exactly 8 bytes. Encodes a 32-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 8 digits. This uses -- hexadecimal, zero-padding the encoding to 8 digits. This uses
-- lowercase for the alphabetical digits. -- lowercase for the alphabetical digits.
word32PaddedLowerHex :: Word32 -> Builder 8 word32PaddedLowerHex :: Word32 -> Builder 8
word32PaddedLowerHex (W32# w) = word32PaddedLowerHex# w word32PaddedLowerHex (W32# w) = word32PaddedLowerHex# (C.word32ToWord# w)
-- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as -- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 4 digits. This uses -- hexadecimal, zero-padding the encoding to 4 digits. This uses
@ -456,7 +458,7 @@ word32PaddedLowerHex (W32# w) = word32PaddedLowerHex# w
-- >>> word16PaddedUpperHex 0xab0 -- >>> word16PaddedUpperHex 0xab0
-- 0AB0 -- 0AB0
word16PaddedUpperHex :: Word16 -> Builder 4 word16PaddedUpperHex :: Word16 -> Builder 4
word16PaddedUpperHex (W16# w) = word16PaddedUpperHex# w word16PaddedUpperHex (W16# w) = word16PaddedUpperHex# (C.word16ToWord# w)
-- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as -- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 4 digits. This uses -- hexadecimal, zero-padding the encoding to 4 digits. This uses
@ -465,7 +467,7 @@ word16PaddedUpperHex (W16# w) = word16PaddedUpperHex# w
-- >>> word16PaddedLowerHex 0xab0 -- >>> word16PaddedLowerHex 0xab0
-- 0ab0 -- 0ab0
word16PaddedLowerHex :: Word16 -> Builder 4 word16PaddedLowerHex :: Word16 -> Builder 4
word16PaddedLowerHex (W16# w) = word16PaddedLowerHex# w word16PaddedLowerHex (W16# w) = word16PaddedLowerHex# (C.word16ToWord# w)
-- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as -- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. Letters are presented -- hexadecimal. No leading zeroes are displayed. Letters are presented
@ -474,7 +476,7 @@ word16PaddedLowerHex (W16# w) = word16PaddedLowerHex# w
-- >>> word16LowerHex 0xab0 -- >>> word16LowerHex 0xab0
-- ab0 -- ab0
word16LowerHex :: Word16 -> Builder 4 word16LowerHex :: Word16 -> Builder 4
word16LowerHex (W16# w) = word16LowerHex# w word16LowerHex (W16# w) = word16LowerHex# (C.word16ToWord# w)
-- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as -- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. Letters are presented -- hexadecimal. No leading zeroes are displayed. Letters are presented
@ -483,25 +485,25 @@ word16LowerHex (W16# w) = word16LowerHex# w
-- >>> word16UpperHex 0xab0 -- >>> word16UpperHex 0xab0
-- AB0 -- AB0
word16UpperHex :: Word16 -> Builder 4 word16UpperHex :: Word16 -> Builder 4
word16UpperHex (W16# w) = word16UpperHex# w word16UpperHex (W16# w) = word16UpperHex# (C.word16ToWord# w)
-- | Requires at most 2 bytes. Encodes a 8-bit unsigned integer as -- | Requires at most 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal. No leading zeroes are displayed. If the number is zero, -- hexadecimal. No leading zeroes are displayed. If the number is zero,
-- a single zero digit is used. -- a single zero digit is used.
word8LowerHex :: Word8 -> Builder 2 word8LowerHex :: Word8 -> Builder 2
word8LowerHex (W8# w) = word8LowerHex# w word8LowerHex (W8# w) = word8LowerHex# (C.word8ToWord# w)
-- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as -- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 2 digits. This uses -- hexadecimal, zero-padding the encoding to 2 digits. This uses
-- uppercase for the alphabetical digits. -- uppercase for the alphabetical digits.
word8PaddedUpperHex :: Word8 -> Builder 2 word8PaddedUpperHex :: Word8 -> Builder 2
word8PaddedUpperHex (W8# w) = word8PaddedUpperHex# w word8PaddedUpperHex (W8# w) = word8PaddedUpperHex# (C.word8ToWord# w)
-- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as -- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as
-- hexadecimal, zero-padding the encoding to 2 digits. This uses -- hexadecimal, zero-padding the encoding to 2 digits. This uses
-- lowercase for the alphabetical digits. -- lowercase for the alphabetical digits.
word8PaddedLowerHex :: Word8 -> Builder 2 word8PaddedLowerHex :: Word8 -> Builder 2
word8PaddedLowerHex (W8# w) = word8PaddedLowerHex# w word8PaddedLowerHex (W8# w) = word8PaddedLowerHex# (C.word8ToWord# w)
-- TODO: Is it actually worth unrolling this loop. I suspect that it -- TODO: Is it actually worth unrolling this loop. I suspect that it
-- might not be. Benchmark this. -- might not be. Benchmark this.
@ -853,7 +855,7 @@ wordLEB128 (W# w) = lebCommon (W# w)
-- | Encode a 32-bit word with LEB-128. -- | Encode a 32-bit word with LEB-128.
word32LEB128 :: Word32 -> Builder 5 word32LEB128 :: Word32 -> Builder 5
word32LEB128 (W32# w) = lebCommon (W# w) word32LEB128 (W32# w) = lebCommon (W# (C.word32ToWord# w))
-- | Encode a 64-bit word with LEB-128. -- | Encode a 64-bit word with LEB-128.
word64LEB128 :: Word64 -> Builder 10 word64LEB128 :: Word64 -> Builder 10
@ -933,19 +935,19 @@ int64BE :: Int64 -> Builder 8
int64BE (I64# i) = word64BE (W64# (int2Word# i)) int64BE (I64# i) = word64BE (W64# (int2Word# i))
int32BE :: Int32 -> Builder 4 int32BE :: Int32 -> Builder 4
int32BE (I32# i) = word32BE (W32# (int2Word# i)) int32BE (I32# i) = word32BE (W32# (C.wordToWord32# (int2Word# (C.int32ToInt# i))))
int16BE :: Int16 -> Builder 2 int16BE :: Int16 -> Builder 2
int16BE (I16# i) = word16BE (W16# (int2Word# i)) int16BE (I16# i) = word16BE (W16# (C.wordToWord16# (int2Word# (C.int16ToInt# i))))
int64LE :: Int64 -> Builder 8 int64LE :: Int64 -> Builder 8
int64LE (I64# i) = word64LE (W64# (int2Word# i)) int64LE (I64# i) = word64LE (W64# (int2Word# i))
int32LE :: Int32 -> Builder 4 int32LE :: Int32 -> Builder 4
int32LE (I32# i) = word32LE (W32# (int2Word# i)) int32LE (I32# i) = word32LE (W32# (C.wordToWord32# (int2Word# (C.int32ToInt# i))))
int16LE :: Int16 -> Builder 2 int16LE :: Int16 -> Builder 2
int16LE (I16# i) = word16LE (W16# (int2Word# i)) int16LE (I16# i) = word16LE (W16# (C.wordToWord16# (int2Word# (C.int16ToInt# i))))
word128LE :: Word128 -> Builder 16 word128LE :: Word128 -> Builder 16
word128LE (Word128 hi lo) = append (word64LE lo) (word64LE hi) word128LE (Word128 hi lo) = append (word64LE lo) (word64LE hi)
@ -1072,7 +1074,7 @@ approxDiv10 :: Word -> Word
approxDiv10 !n = unsafeShiftR (0x1999999A * n) 32 approxDiv10 !n = unsafeShiftR (0x1999999A * n) 32
unsafeWordToWord8 :: Word -> Word8 unsafeWordToWord8 :: Word -> Word8
unsafeWordToWord8 (W# w) = W8# w unsafeWordToWord8 (W# w) = W8# (C.wordToWord8# w)
foreign import ccall unsafe "bytebuild_paste_double" c_paste_double :: foreign import ccall unsafe "bytebuild_paste_double" c_paste_double ::
MutableByteArray# s -> Int# -> Double# -> IO Int MutableByteArray# s -> Int# -> Double# -> IO Int

View file

@ -47,6 +47,8 @@ import GHC.Exts (RealWorld,IsString,Int#,State#)
import GHC.ST (ST(ST)) import GHC.ST (ST(ST))
import GHC.IO (stToIO) import GHC.IO (stToIO)
import qualified Compat as C
import qualified Data.Bytes.Builder.Bounded as Bounded import qualified Data.Bytes.Builder.Bounded as Bounded
import qualified Data.Bytes.Builder.Bounded.Unsafe as UnsafeBounded import qualified Data.Bytes.Builder.Bounded.Unsafe as UnsafeBounded
import qualified Data.Primitive as PM import qualified Data.Primitive as PM
@ -246,16 +248,16 @@ goString (c : cs) buf0 off0 len0 cs0 s0 = case len0 ># 3# of
goCString :: Addr# -> MutableByteArray# s -> Int# -> Int# -> Commits s goCString :: Addr# -> MutableByteArray# s -> Int# -> Int# -> Commits s
-> State# s -> (# State# s, MutableByteArray# s, Int#, Int#, Commits s #) -> State# s -> (# State# s, MutableByteArray# s, Int#, Int#, Commits s #)
goCString addr buf0 off0 len0 cs0 s0 = case Exts.indexWord8OffAddr# addr 0# of goCString addr buf0 off0 len0 cs0 s0 = case C.word8ToWord# (Exts.indexWord8OffAddr# addr 0#) of
0## -> (# s0, buf0, off0, len0, cs0 #) 0## -> (# s0, buf0, off0, len0, cs0 #)
w -> case len0 of w -> case len0 of
0# -> case Exts.newByteArray# 4080# s0 of 0# -> case Exts.newByteArray# 4080# s0 of
(# s1, buf1 #) -> case Exts.writeWord8Array# buf1 0# w s1 of (# s1, buf1 #) -> case Exts.writeWord8Array# buf1 0# (C.wordToWord8# w) s1 of
s2 -> goCString s2 -> goCString
(Exts.plusAddr# addr 1# ) buf1 1# (4080# -# 1# ) (Exts.plusAddr# addr 1# ) buf1 1# (4080# -# 1# )
(Mutable buf0 off0 cs0) (Mutable buf0 off0 cs0)
s2 s2
_ -> case Exts.writeWord8Array# buf0 off0 w s0 of _ -> case Exts.writeWord8Array# buf0 off0 (C.wordToWord8# w) s0 of
s1 -> goCString (Exts.plusAddr# addr 1# ) buf0 (off0 +# 1# ) (len0 -# 1# ) cs0 s1 s1 -> goCString (Exts.plusAddr# addr 1# ) buf0 (off0 +# 1# ) (len0 -# 1# ) cs0 s1
fromEffect :: fromEffect ::