@@ -683,14 +683,13 @@ eval env !denv !activeThreads !stk !k r (Match i br) = do
683683 n <- peekOffN stk i
684684 eval env denv activeThreads stk k r $ selectBranch n br
685685eval env ! denv ! activeThreads ! stk ! k r (DMatch mr i br) = do
686- (t, stk) <- dumpDataNoTag mr stk =<< peekOff stk i
687- eval env denv activeThreads stk k r $
688- selectBranch (maskTags t) br
686+ (nx, stk) <- dataBranch mr stk br =<< bpeekOff stk i
687+ eval env denv activeThreads stk k r nx
689688eval env ! denv ! activeThreads ! stk ! k r (NMatch _mr i br) = do
690689 n <- peekOffN stk i
691690 eval env denv activeThreads stk k r $ selectBranch n br
692691eval env ! denv ! activeThreads ! stk ! k r (RMatch i pu br) = do
693- (t, stk) <- dumpDataNoTag Nothing stk =<< peekOff stk i
692+ (t, stk) <- dumpDataValNoTag stk =<< peekOff stk i
694693 if t == TT. pureEffectTag
695694 then eval env denv activeThreads stk k r pu
696695 else case ANF. unpackTags t of
@@ -1000,46 +999,41 @@ buildData !stk !r !t (VArgV i) = do
1000999 l = fsize stk - i
10011000{-# INLINE buildData #-}
10021001
1002+ dumpDataValNoTag ::
1003+ Stack ->
1004+ Val ->
1005+ IO (PackedTag , Stack )
1006+ dumpDataValNoTag stk (BoxedVal c) =
1007+ (closureTag c,) <$> dumpDataNoTag Nothing stk c
1008+ dumpDataValNoTag _ v =
1009+ die $ " dumpDataValNoTag: unboxed val: " ++ show v
1010+ {-# inline dumpDataValNoTag #-}
1011+
10031012-- Dumps a data type closure to the stack without writing its tag.
10041013-- Instead, the tag is returned for direct case analysis.
10051014dumpDataNoTag ::
10061015 Maybe Reference ->
10071016 Stack ->
1008- Val ->
1009- IO ( PackedTag , Stack )
1017+ Closure ->
1018+ IO Stack
10101019dumpDataNoTag ! mr ! stk = \ case
10111020 -- Normally we want to avoid dumping unboxed values since it's unnecessary, but sometimes we don't know the type of
10121021 -- the incoming value and end up dumping unboxed values, so we just push them back to the stack as-is. e.g. in type-casts/coercions
1013- val@ (UnboxedVal _ t) -> do
1022+ Enum _ _ -> pure stk
1023+ Data1 _ _ x -> do
10141024 stk <- bump stk
1015- poke stk val
1016- pure (unboxedPackedTag t, stk)
1017- BoxedVal clos -> case clos of
1018- (Enum _ t) -> pure (t, stk)
1019- (Data1 _ t x) -> do
1020- stk <- bump stk
1021- poke stk x
1022- pure (t, stk)
1023- (Data2 _ t x y) -> do
1024- stk <- bumpn stk 2
1025- pokeOff stk 1 y
1026- poke stk x
1027- pure (t, stk)
1028- (DataG _ t seg) -> do
1029- stk <- dumpSeg stk seg S
1030- pure (t, stk)
1031- clo ->
1032- die $
1033- " dumpDataNoTag: bad closure: "
1034- ++ show clo
1035- ++ maybe " " (\ r -> " \n expected type: " ++ show r) mr
1036- where
1037- unboxedPackedTag :: UnboxedTypeTag -> PackedTag
1038- unboxedPackedTag = \ case
1039- CharTag -> TT. charTag
1040- FloatTag -> TT. floatTag
1041- IntTag -> TT. intTag
1042- NatTag -> TT. natTag
1025+ poke stk x
1026+ pure stk
1027+ Data2 _ _ x y -> do
1028+ stk <- bumpn stk 2
1029+ pokeOff stk 1 y
1030+ stk <$ poke stk x
1031+ DataG _ _ seg -> dumpSeg stk seg S
1032+ clo ->
1033+ die $
1034+ " dumpDataNoTag: bad closure: "
1035+ ++ show clo
1036+ ++ maybe " " (\ r -> " \n expected type: " ++ show r) mr
10431037{-# INLINE dumpDataNoTag #-}
10441038
10451039-- Note: although the representation allows it, it is impossible
@@ -1995,6 +1989,94 @@ selectBranch t (TestW df cs) = lookupWithDefault df t cs
19951989selectBranch _ (TestT {}) = error " impossible"
19961990{-# INLINE selectBranch #-}
19971991
1992+ -- Combined branch selection and field dumping function for data types.
1993+ -- Fields should only be dumped on _matches_, not default cases, because
1994+ -- default cases potentially cover many constructors which could result
1995+ -- in a variable number of values being put on the stack. Default cases
1996+ -- uniformly expect _no_ values to be added to the stack.
1997+ dataBranch
1998+ :: Maybe Reference -> Stack -> MBranch -> Closure -> IO (MSection , Stack )
1999+ dataBranch mrf stk (Test1 u cu df) = \ case
2000+ Enum _ t
2001+ | maskTags t == u -> pure (cu, stk)
2002+ | otherwise -> pure (df, stk)
2003+ Data1 _ t x
2004+ | maskTags t == u -> do
2005+ stk <- bump stk
2006+ (cu, stk) <$ poke stk x
2007+ | otherwise -> pure (df, stk)
2008+ Data2 _ t x y
2009+ | maskTags t == u -> do
2010+ stk <- bumpn stk 2
2011+ pokeOff stk 1 y
2012+ (cu, stk) <$ poke stk x
2013+ | otherwise -> pure (df, stk)
2014+ DataG _ t seg
2015+ | maskTags t == u -> (cu,) <$> dumpSeg stk seg S
2016+ | otherwise -> pure (df, stk)
2017+ clo -> dataBranchClosureError mrf clo
2018+ dataBranch mrf stk (Test2 u cu v cv df) = \ case
2019+ Enum _ t
2020+ | maskTags t == u -> pure (cu, stk)
2021+ | maskTags t == v -> pure (cv, stk)
2022+ | otherwise -> pure (df, stk)
2023+ Data1 _ t x
2024+ | maskTags t == u -> do
2025+ stk <- bump stk
2026+ (cu, stk) <$ poke stk x
2027+ | maskTags t == v -> do
2028+ stk <- bump stk
2029+ (cv, stk) <$ poke stk x
2030+ | otherwise -> pure (df, stk)
2031+ Data2 _ t x y
2032+ | maskTags t == u -> do
2033+ stk <- bumpn stk 2
2034+ pokeOff stk 1 y
2035+ (cu, stk) <$ poke stk x
2036+ | maskTags t == v -> do
2037+ stk <- bumpn stk 2
2038+ pokeOff stk 1 y
2039+ (cv, stk) <$ poke stk x
2040+ | otherwise -> pure (df, stk)
2041+ DataG _ t seg
2042+ | maskTags t == u -> (cu,) <$> dumpSeg stk seg S
2043+ | maskTags t == v -> (cv,) <$> dumpSeg stk seg S
2044+ | otherwise -> pure (df, stk)
2045+ clo -> dataBranchClosureError mrf clo
2046+ dataBranch mrf stk (TestW df bs) = \ case
2047+ Enum _ t
2048+ | Just ca <- EC. lookup (maskTags t) bs -> pure (ca, stk)
2049+ | otherwise -> pure (df, stk)
2050+ Data1 _ t x
2051+ | Just ca <- EC. lookup (maskTags t) bs -> do
2052+ stk <- bump stk
2053+ (ca, stk) <$ poke stk x
2054+ | otherwise -> pure (df, stk)
2055+ Data2 _ t x y
2056+ | Just ca <- EC. lookup (maskTags t) bs -> do
2057+ stk <- bumpn stk 2
2058+ pokeOff stk 1 y
2059+ (ca, stk) <$ poke stk x
2060+ | otherwise -> pure (df, stk)
2061+ DataG _ t seg
2062+ | Just ca <- EC. lookup (maskTags t) bs ->
2063+ (ca,) <$> dumpSeg stk seg S
2064+ | otherwise -> pure (df, stk)
2065+ clo -> dataBranchClosureError mrf clo
2066+ dataBranch _ _ br = \ _ ->
2067+ dataBranchBranchError br
2068+ {-# inline dataBranch #-}
2069+
2070+ dataBranchClosureError :: Maybe Reference -> Closure -> IO a
2071+ dataBranchClosureError mrf clo =
2072+ die $ " dataBranch: bad closure: "
2073+ ++ show clo
2074+ ++ maybe " " (\ r -> " \n expected type: " ++ show r) mrf
2075+
2076+ dataBranchBranchError :: MBranch -> IO a
2077+ dataBranchBranchError br =
2078+ die $ " dataBranch: unexpected branch: " ++ show br
2079+
19982080-- Splits off a portion of the continuation up to a given prompt.
19992081--
20002082-- The main procedure walks along the 'code' stack `k`, keeping track of how
0 commit comments