Skip to content

Commit 0682f1a

Browse files
authored
Bug fix for #1064 and #843 (#1321)
* Bug fix for #1064 and #843 Removes broken fix for #843 in Emit.hs, thus fixing #1064. And then this commit focuses on fixing the memory management side of things, so that we don't add deleters for symbols in the left-hand-side of match case expressions if we are matching on a ref (e.g. using match-ref). * Add sumtype memory tests
1 parent 499a03e commit 0682f1a

File tree

3 files changed

+58
-15
lines changed

3 files changed

+58
-15
lines changed

src/Emit.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
445445
when isNotVoid $
446446
appendToSrc (addIndent indent' ++ retVar ++ " = " ++ caseExprRetVal ++ ";\n")
447447
let Just caseLhsInfo' = caseLhsInfo
448-
when
449-
(matchMode == MatchValue)
450-
(delete indent' caseLhsInfo')
448+
delete indent' caseLhsInfo'
451449
appendToSrc (addIndent indent ++ "}\n")
452450
in do
453451
exprVar <- visit indent expr

src/Memory.hs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ manageMemory typeEnv globalEnv root =
337337
-- 2. Variables deleted in at least one case has to be deleted in all, so make a union U of all such vars
338338
-- but remove the ones that were not present before the 'match'
339339
-- 3. In each case - take the intersection of U and the vars deleted in that case and add this result to its deleters
340-
matchExpr@(XObj (Match _) _ _) : expr : cases ->
340+
matchExpr@(XObj (Match matchMode) _ _) : expr : cases ->
341341
do
342342
visitedExpr <- visit expr
343343
case visitedExpr of
@@ -346,7 +346,7 @@ manageMemory typeEnv globalEnv root =
346346
do
347347
_ <- unmanage typeEnv globalEnv okVisitedExpr
348348
MemState preDeleters deps lifetimes <- get
349-
vistedCasesAndDeps <- mapM visitMatchCase (pairwise cases)
349+
vistedCasesAndDeps <- mapM (visitMatchCase matchMode) (pairwise cases)
350350
case sequence vistedCasesAndDeps of
351351
Left e -> pure (Left e)
352352
Right okCasesAndDeps ->
@@ -415,32 +415,32 @@ manageMemory typeEnv globalEnv root =
415415
Right (XObj (Lst (okF : okArgs)) i t)
416416
[] -> pure (Right xobj)
417417
visitList _ = error "Must visit list."
418-
visitMatchCase :: (XObj, XObj) -> State MemState (Either TypeError ((Set.Set Deleter, (XObj, XObj)), Set.Set Ty))
419-
visitMatchCase (lhs@XObj {}, rhs@XObj {}) =
418+
visitMatchCase :: MatchMode -> (XObj, XObj) -> State MemState (Either TypeError ((Set.Set Deleter, (XObj, XObj)), Set.Set Ty))
419+
visitMatchCase matchMode (lhs@XObj {}, rhs@XObj {}) =
420420
do
421421
MemState preDeleters _ _ <- get
422-
_ <- visitCaseLhs lhs
422+
_ <- visitCaseLhs matchMode lhs
423423
visitedRhs <- visit rhs
424424
_ <- unmanage typeEnv globalEnv rhs
425425
MemState postDeleters postDeps postLifetimes <- get
426426
put (MemState preDeleters postDeps postLifetimes) -- Restore managed variables, TODO: Use a "local" state monad instead?
427427
pure $ do
428428
okVisitedRhs <- visitedRhs
429429
pure ((postDeleters, (lhs, okVisitedRhs)), postDeps)
430-
visitCaseLhs :: XObj -> State MemState (Either TypeError [()])
431-
visitCaseLhs (XObj (Lst vars) _ _) =
430+
visitCaseLhs :: MatchMode -> XObj -> State MemState (Either TypeError [()])
431+
visitCaseLhs matchMode (XObj (Lst vars) _ _) =
432432
do
433-
result <- mapM visitCaseLhs vars
433+
result <- mapM (visitCaseLhs matchMode) vars
434434
let result' = sequence result
435435
pure (fmap concat result')
436-
visitCaseLhs xobj@(XObj (Sym (SymPath _ name) _) _ _)
437-
| isVarName name = do
436+
visitCaseLhs matchMode xobj@(XObj (Sym (SymPath _ name) _) _ _)
437+
| (matchMode == MatchValue) && isVarName name = do
438438
manage typeEnv globalEnv xobj
439439
pure (Right [])
440440
| otherwise = pure (Right [])
441-
visitCaseLhs (XObj Ref _ _) =
441+
visitCaseLhs _ (XObj Ref _ _) =
442442
pure (Right [])
443-
visitCaseLhs x =
443+
visitCaseLhs _ x =
444444
error ("Unhandled: " ++ show x)
445445
visitLetBinding :: (XObj, XObj) -> State MemState (Either TypeError (XObj, XObj))
446446
visitLetBinding (name, expr) =

test/memory.carp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,46 @@
444444
(match m
445445
_ 1)))))
446446

447+
(deftype Example
448+
One
449+
(Two [String]))
450+
451+
(defn sumtype-8 []
452+
(let-do [ex [(Example.Two @"OKOK")]]
453+
(match-ref (Array.unsafe-nth &ex 0)
454+
(Example.Two s) (println* s)
455+
_ ())))
456+
457+
(deftype Sum One Two)
458+
459+
(defn sumtype-9 []
460+
(let [state @"Ok" sumt &(Sum.One)]
461+
(match-ref sumt
462+
Sum.One (println* &@&state)
463+
Sum.Two ())))
464+
465+
(defn sumtype-10 []
466+
(let [state 0]
467+
(match-ref &(Sum.One)
468+
Sum.One (println* ((fn [] @&state)))
469+
Sum.Two ())))
470+
471+
(deftype ExampleA
472+
One
473+
(Two [(Array String)]))
474+
475+
(defn sumtype-11 []
476+
(match-ref &(Just (ExampleA.Two [@"OKOK"]))
477+
(Just s) ()
478+
_ ())
479+
)
480+
481+
(defn sumtype-12 []
482+
(match (Just (ExampleA.Two [@"OKOK"]))
483+
(Just s) ()
484+
_ ())
485+
)
486+
447487
(deftest test
448488
(assert-no-leak test scope-1 "scope-1 does not leak")
449489
(assert-no-leak test scope-2 "scope-2 does not leak")
@@ -513,4 +553,9 @@
513553
(assert-no-leak test sumtype-5 "sumtype-5 does not leak")
514554
(assert-no-leak test sumtype-6 "sumtype-6 does not leak")
515555
(assert-no-leak test sumtype-7 "sumtype-7 does not leak")
556+
(assert-no-leak test sumtype-8 "sumtype-8 does not leak")
557+
(assert-no-leak test sumtype-9 "sumtype-9 does not leak")
558+
(assert-no-leak test sumtype-10 "sumtype-10 does not leak")
559+
(assert-no-leak test sumtype-11 "sumtype-11 does not leak")
560+
(assert-no-leak test sumtype-12 "sumtype-12 does not leak")
516561
)

0 commit comments

Comments
 (0)