on master help sign in
Fusion-related size calculations: detect overflows
a80bdadBryan O'Sullivan
Data/Text/Fusion/Size.hs+23−8
@@ -68,11 +68,17 @@ instance Num Size where
68 fromInteger = f where f = Exact . fromInteger
68 fromInteger = f where f = Exact . fromInteger
69 {-# INLINE f #-}
69 {-# INLINE f #-}
70
70
71+add :: Int -> Int -> Int
72+add m n | mn > 0 = mn
73+ | otherwise = overflowError
74+ where mn = m + n
75+{-# INLINE add #-}
76+
71addSize :: Size -> Size -> Size
77addSize :: Size -> Size -> Size
72−addSize (Exact m) (Exact n) = Exact (m+n)
78+addSize (Exact m) (Exact n) = Exact (add m n)
73−addSize (Exact m) (Max n) = Max (m+n)
79+addSize (Exact m) (Max n) = Max (add m n)
74−addSize (Max m) (Exact n) = Max (m+n)
80+addSize (Max m) (Exact n) = Max (add m n)
75−addSize (Max m) (Max n) = Max (m+n)
81+addSize (Max m) (Max n) = Max (add m n)
76addSize _ _ = Unknown
82addSize _ _ = Unknown
77{-# INLINE addSize #-}
83{-# INLINE addSize #-}
78
84
@@ -85,11 +91,17 @@ subtractSize a@(Max _) Unknown = a
85subtractSize _ _ = Unknown
91subtractSize _ _ = Unknown
86{-# INLINE subtractSize #-}
92{-# INLINE subtractSize #-}
87
93
94+mul :: Int -> Int -> Int
95+mul m n
96+ | m <= maxBound `div` n = m * n
97+ | otherwise = overflowError
98+{-# INLINE mul #-}
99+
88mulSize :: Size -> Size -> Size
100mulSize :: Size -> Size -> Size
89−mulSize (Exact m) (Exact n) = Exact (m*n)
101+mulSize (Exact m) (Exact n) = Exact (mul m n)
90−mulSize (Exact m) (Max n) = Max (m*n)
102+mulSize (Exact m) (Max n) = Max (mul m n)
91−mulSize (Max m) (Exact n) = Max (m*n)
103+mulSize (Max m) (Exact n) = Max (mul m n)
92−mulSize (Max m) (Max n) = Max (m*n)
104+mulSize (Max m) (Max n) = Max (mul m n)
93mulSize _ _ = Unknown
105mulSize _ _ = Unknown
94{-# INLINE mulSize #-}
106{-# INLINE mulSize #-}
95
107
@@ -129,3 +141,6 @@ isEmpty (Exact n) = n <= 0
129isEmpty (Max n) = n <= 0
141isEmpty (Max n) = n <= 0
130isEmpty _ = False
142isEmpty _ = False
131{-# INLINE isEmpty #-}
143{-# INLINE isEmpty #-}
144+
145+overflowError :: Int
146+overflowError = error "Data.Text.Fusion.Size: size overflow"