Skip to content

Commit 5f3f532

Browse files
authored
Merge pull request #5423 from unisonweb/cp/fix-segfault
Fix interpreter segfault
2 parents 8e29b0a + e28a16f commit 5f3f532

File tree

8 files changed

+98
-50
lines changed

8 files changed

+98
-50
lines changed

unison-runtime/src/Unison/Runtime/ANF.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ import Data.Bits (shiftL, shiftR, (.&.), (.|.))
9797
import Data.Functor.Compose (Compose (..))
9898
import Data.List hiding (and, or)
9999
import Data.Map qualified as Map
100-
import Data.Primitive qualified as PA
101100
import Data.Set qualified as Set
102101
import Data.Text qualified as Data.Text
103102
import GHC.Stack (CallStack, callStack)
@@ -112,6 +111,7 @@ import Unison.Pattern qualified as P
112111
import Unison.Prelude
113112
import Unison.Reference (Id, Reference, Reference' (Builtin, DerivedId))
114113
import Unison.Referent (Referent, pattern Con, pattern Ref)
114+
import Unison.Runtime.Array qualified as PA
115115
import Unison.Symbol (Symbol)
116116
import Unison.Term hiding (List, Ref, Text, float, fresh, resolve)
117117
import Unison.Type qualified as Ty

unison-runtime/src/Unison/Runtime/Array.hs

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -141,44 +141,67 @@ checkIBArray name a f arr i
141141
checkIMBArray
142142
:: CheckCtx
143143
=> Prim a
144+
=> PrimMonad m
144145
=> String
145146
-> a
146-
-> (MutableByteArray s -> Int -> r)
147-
-> MutableByteArray s -> Int -> r
148-
checkIMBArray name a f arr i
149-
| i < 0 || sizeofMutableByteArray arr `quot` sizeOf a <= i
150-
= error $ name ++ " unsafe check out of bounds: " ++ show i
151-
| otherwise = f arr i
147+
-> (MutableByteArray (PrimState m) -> Int -> m r)
148+
-> MutableByteArray (PrimState m) -> Int -> m r
149+
checkIMBArray name a f arr i = do
150+
sz <- getSizeofMutableByteArray arr
151+
if (i < 0 || sz `quot` sizeOf a <= i)
152+
then error $ name ++ " unsafe check out of bounds: " ++ show i
153+
else f arr i
152154
{-# inline checkIMBArray #-}
153155

156+
-- check write mutable byte array
157+
checkWMBArray
158+
:: CheckCtx
159+
=> Prim a
160+
=> PrimMonad m
161+
=> String
162+
-> (MutableByteArray (PrimState m) -> Int -> a -> m r)
163+
-> MutableByteArray (PrimState m) -> Int -> a -> m r
164+
checkWMBArray name f arr i a = do
165+
sz <- getSizeofMutableByteArray arr
166+
if (i < 0 || sz `quot` sizeOf a <= i)
167+
then error $ name ++ " unsafe check out of bounds: " ++ show i
168+
else f arr i a
169+
{-# inline checkWMBArray #-}
170+
171+
154172
-- check copy byte array
155173
checkCBArray
156174
:: CheckCtx
175+
=> PrimMonad m
157176
=> String
158-
-> (MBA s -> Int -> BA -> Int -> Int -> r)
159-
-> MBA s -> Int -> BA -> Int -> Int -> r
160-
checkCBArray name f dst d src s l
161-
| d < 0
162-
|| s < 0
163-
|| sizeofMutableByteArray dst < d + l
164-
|| sizeofByteArray src < s + l
165-
= error $ name ++ " unsafe check out of bounds: " ++ show (d, s, l)
166-
| otherwise = f dst d src s l
177+
-> (MBA (PrimState m) -> Int -> BA -> Int -> Int -> m r)
178+
-> MBA (PrimState m) -> Int -> BA -> Int -> Int -> m r
179+
checkCBArray name f dst d src s l = do
180+
szd <- getSizeofMutableByteArray dst
181+
if (d < 0
182+
|| s < 0
183+
|| szd < d + l
184+
|| sizeofByteArray src < s + l
185+
) then error $ name ++ " unsafe check out of bounds: " ++ show (d, s, l)
186+
else f dst d src s l
167187
{-# inline checkCBArray #-}
168188

169189
-- check copy mutable byte array
170190
checkCMBArray
171191
:: CheckCtx
192+
=> PrimMonad m
172193
=> String
173-
-> (MBA s -> Int -> MBA s -> Int -> Int -> r)
174-
-> MBA s -> Int -> MBA s -> Int -> Int -> r
175-
checkCMBArray name f dst d src s l
176-
| d < 0
177-
|| s < 0
178-
|| sizeofMutableByteArray dst < d + l
179-
|| sizeofMutableByteArray src < s + l
180-
= error $ name ++ " unsafe check out of bounds: " ++ show (d, s, l)
181-
| otherwise = f dst d src s l
194+
-> (MBA (PrimState m) -> Int -> MBA (PrimState m) -> Int -> Int -> m r)
195+
-> MBA (PrimState m) -> Int -> MBA (PrimState m) -> Int -> Int -> m r
196+
checkCMBArray name f dst d src s l = do
197+
szd <- getSizeofMutableByteArray dst
198+
szs <- getSizeofMutableByteArray src
199+
if ( d < 0
200+
|| s < 0
201+
|| szd < d + l
202+
|| szs < s + l
203+
) then error $ name ++ " unsafe check out of bounds: " ++ show (d, s, l)
204+
else f dst d src s l
182205
{-# inline checkCMBArray #-}
183206

184207
-- check index prim array
@@ -197,35 +220,57 @@ checkIPArray name f arr i
197220
-- check index mutable prim array
198221
checkIMPArray
199222
:: CheckCtx
223+
=> PrimMonad m
200224
=> Prim a
201225
=> String
202-
-> (MutablePrimArray s a -> Int -> r)
203-
-> MutablePrimArray s a -> Int -> r
204-
checkIMPArray name f arr i
205-
| i < 0 || sizeofMutablePrimArray arr <= i
206-
= error $ name ++ " unsafe check out of bounds: " ++ show i
207-
| otherwise = f arr i
226+
-> (MutablePrimArray (PrimState m) a -> Int -> m r)
227+
-> MutablePrimArray (PrimState m) a -> Int -> m r
228+
checkIMPArray name f arr i = do
229+
asz <- getSizeofMutablePrimArray arr
230+
if (i < 0 || asz <= i)
231+
then error $ name ++ " unsafe check out of bounds: " ++ show i
232+
else f arr i
208233
{-# inline checkIMPArray #-}
209234

235+
-- check write mutable prim array
236+
checkWMPArray
237+
:: CheckCtx
238+
=> PrimMonad m
239+
=> Prim a
240+
=> String
241+
-> (MutablePrimArray (PrimState m) a -> Int -> a -> m r)
242+
-> MutablePrimArray (PrimState m) a -> Int -> a -> m r
243+
checkWMPArray name f arr i a = do
244+
asz <- getSizeofMutablePrimArray arr
245+
if (i < 0 || asz <= i)
246+
then error $ name ++ " unsafe check out of bounds: " ++ show i
247+
else f arr i a
248+
{-# inline checkWMPArray #-}
249+
250+
210251
#else
211252
type CheckCtx :: Constraint
212253
type CheckCtx = ()
213254

214-
checkIMArray, checkIMPArray, checkIPArray :: String -> r -> r
255+
checkIMArray, checkIMPArray, checkWMPArray, checkIPArray :: String -> r -> r
215256
checkCArray, checkCMArray, checkRMArray :: String -> r -> r
216257
checkIMArray _ = id
217258
checkIMPArray _ = id
259+
checkWMPArray _ = id
218260
checkCArray _ = id
219261
checkCMArray _ = id
220262
checkRMArray _ = id
221263
checkIPArray _ = id
222264

223-
checkIBArray, checkIMBArray :: String -> a -> r -> r
265+
checkIBArray, checkIMBArray:: String -> a -> r -> r
224266
checkCBArray, checkCMBArray :: String -> r -> r
225267
checkIBArray _ _ = id
226268
checkIMBArray _ _ = id
227269
checkCBArray _ = id
228270
checkCMBArray _ = id
271+
272+
checkWMBArray :: String -> r -> r
273+
checkWMBArray _ = id
229274
#endif
230275

231276
readArray ::
@@ -301,7 +346,7 @@ writeByteArray ::
301346
Int ->
302347
a ->
303348
m ()
304-
writeByteArray = checkIMBArray @a "writeByteArray" undefined PA.writeByteArray
349+
writeByteArray = checkWMBArray "writeByteArray" PA.writeByteArray
305350
{-# INLINE writeByteArray #-}
306351

307352
indexByteArray ::
@@ -368,7 +413,7 @@ writePrimArray ::
368413
Int ->
369414
a ->
370415
m ()
371-
writePrimArray = checkIMPArray "writePrimArray" PA.writePrimArray
416+
writePrimArray = checkWMPArray "writePrimArray" PA.writePrimArray
372417
{-# INLINE writePrimArray #-}
373418

374419
indexPrimArray ::

unison-runtime/src/Unison/Runtime/Foreign.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import Control.Concurrent (MVar, ThreadId)
2323
import Control.Concurrent.STM (TVar)
2424
import Crypto.Hash qualified as Hash
2525
import Data.IORef (IORef)
26-
import Data.Primitive (ByteArray, MutableArray, MutableByteArray)
2726
import Data.Tagged (Tagged (..))
2827
import Data.X509 qualified as X509
2928
import Network.Socket (Socket)
@@ -35,6 +34,7 @@ import System.Process (ProcessHandle)
3534
import Unison.Reference (Reference)
3635
import Unison.Referent (Referent)
3736
import Unison.Runtime.ANF (Code, Value)
37+
import Unison.Runtime.Array
3838
import Unison.Type qualified as Ty
3939
import Unison.Util.Bytes (Bytes)
4040
import Unison.Util.Text (Text)
@@ -256,6 +256,7 @@ instance BuiltinForeign FilePath where foreignRef = Tagged Ty.filePathRef
256256
instance BuiltinForeign TLS.Context where foreignRef = Tagged Ty.tlsRef
257257

258258
instance BuiltinForeign Code where foreignRef = Tagged Ty.codeRef
259+
259260
instance BuiltinForeign Value where foreignRef = Tagged Ty.valueRef
260261

261262
instance BuiltinForeign TimeSpec where foreignRef = Tagged Ty.timeSpecRef

unison-runtime/src/Unison/Runtime/Foreign/Function.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import Data.Atomics (Ticket)
2020
import Data.Char qualified as Char
2121
import Data.Foldable (toList)
2222
import Data.IORef (IORef)
23-
import Data.Primitive.Array as PA
24-
import Data.Primitive.ByteArray as PA
2523
import Data.Sequence qualified as Sq
2624
import Data.Time.Clock.POSIX (POSIXTime)
2725
import Data.Word (Word16, Word32, Word64, Word8)
@@ -32,6 +30,7 @@ import System.IO (BufferMode (..), Handle, IOMode, SeekMode)
3230
import Unison.Builtin.Decls qualified as Ty
3331
import Unison.Reference (Reference)
3432
import Unison.Runtime.ANF (Code, Value, internalBug)
33+
import Unison.Runtime.Array qualified as PA
3534
import Unison.Runtime.Exception
3635
import Unison.Runtime.Foreign
3736
import Unison.Runtime.MCode

unison-runtime/src/Unison/Runtime/MCode.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ import Data.Bits (shiftL, shiftR, (.|.))
5757
import Data.Coerce
5858
import Data.Functor ((<&>))
5959
import Data.Map.Strict qualified as M
60-
import Data.Primitive.ByteArray
61-
import Data.Primitive.PrimArray
62-
import Data.Primitive.PrimArray qualified as PA
6360
import Data.Void (Void, absurd)
6461
import Data.Word (Word16, Word64)
6562
import GHC.Stack (HasCallStack)
@@ -91,6 +88,8 @@ import Unison.Runtime.ANF
9188
pattern TVar,
9289
)
9390
import Unison.Runtime.ANF qualified as ANF
91+
import Unison.Runtime.Array
92+
import Unison.Runtime.Array qualified as PA
9493
import Unison.Runtime.Builtin.Types (builtinTypeNumbering)
9594
import Unison.Util.EnumContainers as EC
9695
import Unison.Util.Text (Text)

unison-runtime/src/Unison/Runtime/MCode/Serialize.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import Data.Bytes.Get
1414
import Data.Bytes.Put
1515
import Data.Bytes.Serial
1616
import Data.Bytes.VarInt
17-
import Data.Primitive.PrimArray
1817
import Data.Void (Void)
1918
import Data.Word (Word64)
2019
import GHC.Exts (IsList (..))
20+
import Unison.Runtime.Array (PrimArray)
2121
import Unison.Runtime.MCode hiding (MatchT)
2222
import Unison.Runtime.Serialize
2323
import Unison.Util.Text qualified as Util.Text

unison-runtime/src/Unison/Runtime/Serialize.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import Data.Bytes.VarInt
1414
import Data.Foldable (traverse_)
1515
import Data.Int (Int64)
1616
import Data.Map.Strict as Map (Map, fromList, toList)
17-
import Data.Primitive qualified as PA
1817
import Data.Text (Text)
1918
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
2019
import Data.Vector.Primitive qualified as BA
@@ -26,6 +25,7 @@ import Unison.Hash (Hash)
2625
import Unison.Hash qualified as Hash
2726
import Unison.Reference (Id' (..), Reference, Reference' (Builtin, DerivedId), pattern Derived)
2827
import Unison.Referent (Referent, pattern Con, pattern Ref)
28+
import Unison.Runtime.Array qualified as PA
2929
import Unison.Runtime.Exception
3030
import Unison.Runtime.MCode
3131
( BPrim1 (..),

unison-runtime/src/Unison/Runtime/Stack.hs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ module Unison.Runtime.Stack
9696
where
9797

9898
import Control.Monad.Primitive
99+
import Data.Primitive (sizeOf)
99100
import Data.Word
100101
import GHC.Exts as L (IsList (..))
101102
import Unison.Prelude
@@ -246,7 +247,7 @@ splitData = \case
246247
ints :: ByteArray -> [Int]
247248
ints ba = fmap (indexByteArray ba) [n - 1, n - 2 .. 0]
248249
where
249-
n = sizeofByteArray ba `div` 8
250+
n = sizeofByteArray ba `div` intSize
250251

251252
-- | Converts a list of integers representing an unboxed segment back into the
252253
-- appropriate segment. Segments are stored backwards in the runtime, so this
@@ -348,11 +349,14 @@ type UA = MutableByteArray (PrimState IO)
348349

349350
type BA = MutableArray (PrimState IO) Closure
350351

352+
intSize :: Int
353+
intSize = sizeOf (0 :: Int)
354+
351355
words :: Int -> Int
352-
words n = n `div` 8
356+
words n = n `div` intSize
353357

354358
bytes :: Int -> Int
355-
bytes n = n * 8
359+
bytes n = n * intSize
356360

357361
type Arrs = (UA, BA)
358362

@@ -666,7 +670,7 @@ augSeg mode (Stack ap fp sp ustk bstk) (useg, bseg) margs = do
666670
cop <- newByteArray $ ssz + upsz + asz
667671
copyByteArray cop soff useg 0 ssz
668672
copyMutableByteArray cop 0 ustk (bytes $ ap + 1) upsz
669-
for_ margs $ uargOnto ustk sp cop (words poff + upsz - 1)
673+
for_ margs $ uargOnto ustk sp cop (words poff + bpsz - 1)
670674
unsafeFreezeByteArray cop
671675
where
672676
ssz = sizeofByteArray useg
@@ -675,9 +679,9 @@ augSeg mode (Stack ap fp sp ustk bstk) (useg, bseg) margs = do
675679
| otherwise = (0, upsz + asz)
676680
upsz = bytes bpsz
677681
asz = case margs of
678-
Nothing -> 0
679-
Just (Arg1 _) -> 8
680-
Just (Arg2 _ _) -> 16
682+
Nothing -> bytes 0
683+
Just (Arg1 _) -> bytes 1
684+
Just (Arg2 _ _) -> bytes 2
681685
Just (ArgN v) -> bytes $ sizeofPrimArray v
682686
Just (ArgR _ l) -> bytes l
683687
boxedSeg = do

0 commit comments

Comments
 (0)