on master help sign in
Fusion-related size calculations: detect overflows

--HG-- extra : convert_revision : ebbb521a5eeaa1ab3bdec3175628c2fe3dfd2929

commita80bdade84d187b69f696792296dc885ca5e3b3d authorBryan O'Sullivan <bos@serpentine.com> dateSun 10 Oct 2010, 03:28 (16 years ago) parentb5e4b98
1 file changed+23−8
Data/Text/Fusion/Size.hs+23−8
Data/Text/Fusion/Size.hs+23−8
@@ -68,11 +68,17 @@ instance Num Size where
6868 fromInteger = f where f = Exact . fromInteger
6969 {-# INLINE f #-}
7070
71+add :: Int -> Int -> Int
72+add m n | mn > 0 = mn
73+ | otherwise = overflowError
74+ where mn = m + n
75+{-# INLINE add #-}
76+
7177addSize :: Size -> Size -> Size
72−addSize (Exact m) (Exact n) = Exact (m+n)
73−addSize (Exact m) (Max n) = Max (m+n)
74−addSize (Max m) (Exact n) = Max (m+n)
75−addSize (Max m) (Max n) = Max (m+n)
78+addSize (Exact m) (Exact n) = Exact (add m n)
79+addSize (Exact m) (Max n) = Max (add m n)
80+addSize (Max m) (Exact n) = Max (add m n)
81+addSize (Max m) (Max n) = Max (add m n)
7682addSize _ _ = Unknown
7783{-# INLINE addSize #-}
7884
@@ -85,11 +91,17 @@ subtractSize a@(Max _) Unknown = a
8591subtractSize _ _ = Unknown
8692{-# INLINE subtractSize #-}
8793
94+mul :: Int -> Int -> Int
95+mul m n
96+ | m <= maxBound `div` n = m * n
97+ | otherwise = overflowError
98+{-# INLINE mul #-}
99+
88100mulSize :: Size -> Size -> Size
89−mulSize (Exact m) (Exact n) = Exact (m*n)
90−mulSize (Exact m) (Max n) = Max (m*n)
91−mulSize (Max m) (Exact n) = Max (m*n)
92−mulSize (Max m) (Max n) = Max (m*n)
101+mulSize (Exact m) (Exact n) = Exact (mul m n)
102+mulSize (Exact m) (Max n) = Max (mul m n)
103+mulSize (Max m) (Exact n) = Max (mul m n)
104+mulSize (Max m) (Max n) = Max (mul m n)
93105mulSize _ _ = Unknown
94106{-# INLINE mulSize #-}
95107
@@ -129,3 +141,6 @@ isEmpty (Exact n) = n <= 0
129141isEmpty (Max n) = n <= 0
130142isEmpty _ = False
131143{-# INLINE isEmpty #-}
144+
145+overflowError :: Int
146+overflowError = error "Data.Text.Fusion.Size: size overflow"