@@ -683,14 +683,13 @@ eval env !denv !activeThreads !stk !k r (Match i br) = do
683
683
n <- peekOffN stk i
684
684
eval env denv activeThreads stk k r $ selectBranch n br
685
685
eval 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
689
688
eval env ! denv ! activeThreads ! stk ! k r (NMatch _mr i br) = do
690
689
n <- peekOffN stk i
691
690
eval env denv activeThreads stk k r $ selectBranch n br
692
691
eval 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
694
693
if t == TT. pureEffectTag
695
694
then eval env denv activeThreads stk k r pu
696
695
else case ANF. unpackTags t of
@@ -1000,46 +999,41 @@ buildData !stk !r !t (VArgV i) = do
1000
999
l = fsize stk - i
1001
1000
{-# INLINE buildData #-}
1002
1001
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
+
1003
1012
-- Dumps a data type closure to the stack without writing its tag.
1004
1013
-- Instead, the tag is returned for direct case analysis.
1005
1014
dumpDataNoTag ::
1006
1015
Maybe Reference ->
1007
1016
Stack ->
1008
- Val ->
1009
- IO ( PackedTag , Stack )
1017
+ Closure ->
1018
+ IO Stack
1010
1019
dumpDataNoTag ! mr ! stk = \ case
1011
1020
-- Normally we want to avoid dumping unboxed values since it's unnecessary, but sometimes we don't know the type of
1012
1021
-- 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
1014
1024
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
1043
1037
{-# INLINE dumpDataNoTag #-}
1044
1038
1045
1039
-- Note: although the representation allows it, it is impossible
@@ -1995,6 +1989,94 @@ selectBranch t (TestW df cs) = lookupWithDefault df t cs
1995
1989
selectBranch _ (TestT {}) = error " impossible"
1996
1990
{-# INLINE selectBranch #-}
1997
1991
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
+
1998
2080
-- Splits off a portion of the continuation up to a given prompt.
1999
2081
--
2000
2082
-- The main procedure walks along the 'code' stack `k`, keeping track of how
0 commit comments