@@ -13,7 +13,7 @@ import Control.Arrow ((&&&))
13import Control.Monad (forM, liftM, replicateM, void)
13import Control.Monad (forM, liftM, replicateM, void)
14import Control.Monad.Supply.Class
14import Control.Monad.Supply.Class
16−import Data.List ((\\), delete, intersect)
16+import Data.List ((\\), delete, intersect, nub)
17import qualified Data.Foldable as F
17import qualified Data.Foldable as F
18import qualified Data.Map as M
18import qualified Data.Map as M
19import Data.Maybe (fromMaybe, isNothing, mapMaybe)
19import Data.Maybe (fromMaybe, isNothing, mapMaybe)
@@ -157,20 +157,35 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
158 let retainedName = identToCpp ident
158 let retainedName = identToCpp ident
159 retained = AST.Var Nothing $ retainedName
159 retained = AST.Var Nothing $ retainedName
160− -- unretained = AST.Var Nothing $ retainedName <> unretainedSuffix
160+ unretainedName = retainedName <> unretainedSuffix
161+ unretained = AST.Var Nothing $ unretainedName
161− -- alias = AST.Var Nothing . -- Note: prevents optimizer from eliminating this
162+ boxed = AST.Var Nothing . -- Note: prevents optimizer from eliminating this
162− -- prettyPrintCpp1 $
163+ prettyPrintCpp1 $
163− -- AST.VariableIntroduction Nothing retainedName (Just unretained)
164+ AST.VariableIntroduction
168+ alias = AST.Var Nothing $ "auto& " <> retainedName <> " = " <> unretainedName
165 case cpp of
170 case cpp of
166 AST.Function _ name args (AST.Block Nothing cpps) ->
171 AST.Function _ name args (AST.Block Nothing cpps) ->
167 AST.Assignment Nothing
172 AST.Assignment Nothing
168− (retained)
173+ retained
169 (AST.Function Nothing
174 (AST.Function Nothing
172− (AST.Block Nothing cpps))
177+ (AST.Block Nothing (boxed : cpps)))
173− _ -> AST.Assignment Nothing retained cpp
179+ AST.Assignment Nothing
182+ (AST.Function Nothing
185+ (AST.Block Nothing ([ alias
186+ , AST.Return Nothing cpp
174 nonRecToCpp _ (ss, _, _, _) ident val = do
189 nonRecToCpp _ (ss, _, _, _) ident val = do
175 cpp <- valueToCpp val
190 cpp <- valueToCpp val
176 pure $ AST.VariableIntroduction Nothing (identToCpp ident) (Just cpp)
191 pure $ AST.VariableIntroduction Nothing (identToCpp ident) (Just cpp)
@@ -241,6 +256,13 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
241 valueToCpp (Let _ ds val) = do
256 valueToCpp (Let _ ds val) = do
242 let recurs = concatMap getNames $ filter isRec ds
257 let recurs = concatMap getNames $ filter isRec ds
243 recurDs = (\v -> AST.Var Nothing $ "boxed_r " <> identToCpp v) <$> recurs
258 recurDs = (\v -> AST.Var Nothing $ "boxed_r " <> identToCpp v) <$> recurs
259+ recurDsWeak = (\v -> AST.Var
261+ ("boxed_weak_r " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
263+ mutualRecurWarning = if any isMutRec $ filter isRec ds
264+ then [AST.Var Nothing "#pragma message(\"Mutually recursive lets will cause retain cycles (memory leaks)\") //"]
244 ds' <- concat <$> mapM (bindToCpp LetDecl) ds
266 ds' <- concat <$> mapM (bindToCpp LetDecl) ds
245 ret <- valueToCpp val
267 ret <- valueToCpp val
@@ -248,12 +270,15 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
248 (AST.Function Nothing
270 (AST.Function Nothing
251− (AST.Block Nothing (recurDs ++ ds' ++ [AST.Return Nothing ret])))
273+ (AST.Block Nothing (recurDs ++ recurDsWeak ++ mutualRecurWarning ++ ds' ++ [AST.Return Nothing ret])))
254 isRec :: Bind Ann -> Bool
276 isRec :: Bind Ann -> Bool
255 isRec (Rec _) = True
277 isRec (Rec _) = True
256− isRec _ = False
278+ isRec _ = False
279+ isMutRec :: Bind Ann -> Bool
280+ isMutRec b | (length . nub $ getNames b) > 1 = True
257 valueToCpp (Constructor (_, _, _, Just IsNewtype) _ (ProperName ctor) _) = error "IsNewtype"
282 valueToCpp (Constructor (_, _, _, Just IsNewtype) _ (ProperName ctor) _) = error "IsNewtype"
258 valueToCpp (Constructor _ _ (ProperName ctor) fields) =
283 valueToCpp (Constructor _ _ (ProperName ctor) fields) =
259 let body = AST.ObjectLiteral Nothing $ (mkString ctor, AST.BooleanLiteral Nothing True) :
284 let body = AST.ObjectLiteral Nothing $ (mkString ctor, AST.BooleanLiteral Nothing True) :