@@ -13,7 +13,7 @@ import Control.Arrow ((&&&))
1313import Control.Monad (forM, liftM, replicateM, void)
1414import Control.Monad.Supply.Class
1515
16−import Data.List ((\\), delete, intersect)
16+import Data.List ((\\), delete, intersect, nub)
1717import qualified Data.Foldable as F
1818import qualified Data.Map as M
1919import Data.Maybe (fromMaybe, isNothing, mapMaybe)
@@ -157,20 +157,35 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
157157 pure $
158158 let retainedName = identToCpp ident
159159 retained = AST.Var Nothing $ retainedName
160− -- unretained = AST.Var Nothing $ retainedName <> unretainedSuffix
161− -- alias = AST.Var Nothing . -- Note: prevents optimizer from eliminating this
162− -- prettyPrintCpp1 $
163− -- AST.VariableIntroduction Nothing retainedName (Just unretained)
160+ unretainedName = retainedName <> unretainedSuffix
161+ unretained = AST.Var Nothing $ unretainedName
162+ boxed = AST.Var Nothing . -- Note: prevents optimizer from eliminating this
163+ prettyPrintCpp1 $
164+ AST.VariableIntroduction
165+ Nothing
166+ retainedName
167+ (Just unretained)
168+ alias = AST.Var Nothing $ "auto& " <> retainedName <> " = " <> unretainedName
164169 in
165170 case cpp of
166171 AST.Function _ name args (AST.Block Nothing cpps) ->
167172 AST.Assignment Nothing
168− (retained)
173+ retained
169174 (AST.Function Nothing
170175 name
171176 args
172− (AST.Block Nothing cpps))
173− _ -> AST.Assignment Nothing retained cpp
177+ (AST.Block Nothing (boxed : cpps)))
178+ _ ->
179+ AST.Assignment Nothing
180+ retained
181+ (AST.App Nothing
182+ (AST.Function Nothing
183+ Nothing
184+ []
185+ (AST.Block Nothing ([ alias
186+ , AST.Return Nothing cpp
187+ ])))
188+ [])
174189 nonRecToCpp _ (ss, _, _, _) ident val = do
175190 cpp <- valueToCpp val
176191 pure $ AST.VariableIntroduction Nothing (identToCpp ident) (Just cpp)
@@ -241,6 +256,13 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
241256 valueToCpp (Let _ ds val) = do
242257 let recurs = concatMap getNames $ filter isRec ds
243258 recurDs = (\v -> AST.Var Nothing $ "boxed_r " <> identToCpp v) <$> recurs
259+ recurDsWeak = (\v -> AST.Var
260+ Nothing
261+ ("boxed_weak_r " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
262+ ) <$> recurs
263+ mutualRecurWarning = if any isMutRec $ filter isRec ds
264+ then [AST.Var Nothing "#pragma message(\"Mutually recursive lets will cause retain cycles (memory leaks)\") //"]
265+ else []
244266 ds' <- concat <$> mapM (bindToCpp LetDecl) ds
245267 ret <- valueToCpp val
246268 return $
@@ -248,12 +270,15 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
248270 (AST.Function Nothing
249271 Nothing
250272 []
251− (AST.Block Nothing (recurDs ++ ds' ++ [AST.Return Nothing ret])))
273+ (AST.Block Nothing (recurDs ++ recurDsWeak ++ mutualRecurWarning ++ ds' ++ [AST.Return Nothing ret])))
252274 []
253275 where
254276 isRec :: Bind Ann -> Bool
255277 isRec (Rec _) = True
256− isRec _ = False
278+ isRec _ = False
279+ isMutRec :: Bind Ann -> Bool
280+ isMutRec b | (length . nub $ getNames b) > 1 = True
281+ | otherwise = False
257282 valueToCpp (Constructor (_, _, _, Just IsNewtype) _ (ProperName ctor) _) = error "IsNewtype"
258283 valueToCpp (Constructor _ _ (ProperName ctor) fields) =
259284 let body = AST.ObjectLiteral Nothing $ (mkString ctor, AST.BooleanLiteral Nothing True) :