on master help sign in
Fix code generation for top level tail call definitions
bf63cb8Evan Czaplicki
src/Generate/JavaScript.hs+14−1
@@ -150,7 +150,7 @@ addGlobalHelp mode graph global state =
150
150
151 Opt.DefineTailFunc argNames body deps ->
151 Opt.DefineTailFunc argNames body deps ->
152 addStmt (addDeps deps state) (
152 addStmt (addDeps deps state) (
153− var global (Expr.generateFunction (map Name.fromLocal argNames) (Expr.generate mode body))
153+ generateTailDef mode global argNames body
154 )
154 )
155
155
156 Opt.Ctor name index arity ->
156 Opt.Ctor name index arity ->
@@ -214,6 +214,19 @@ var (Opt.Global home name) code =
214
214
215
215
216
216
217+-- GENERATE TAIL DEFS
218+
219+
220+generateTailDef :: Name.Mode -> Opt.Global -> [N.Name] -> Opt.Expr -> JS.Stmt
221+generateTailDef mode (Opt.Global home name) argNames body =
222+ let
223+ definition =
224+ Expr.generateTailDef mode name argNames body
225+ in
226+ JS.Var [ (Name.fromGlobal home name, Just definition) ]
227+
228+
229+
217-- GENERATE CYCLES
230-- GENERATE CYCLES
218
231
219
232
src/Generate/JavaScript/Expression.hs+11−10
@@ -2,7 +2,7 @@
2module Generate.JavaScript.Expression
2module Generate.JavaScript.Expression
3 ( generate
3 ( generate
4 , generateCtor
4 , generateCtor
5− , generateFunction
5+ , generateTailDef
6 , generateMain
6 , generateMain
7 , Code
7 , Code
8 , codeToExpr
8 , codeToExpr
@@ -714,15 +714,16 @@ generateDef mode def =
714 JS.Var [ (Name.fromLocal name, Just (generateJsExpr mode body)) ]
714 JS.Var [ (Name.fromLocal name, Just (generateJsExpr mode body)) ]
715
715
716 Opt.TailDef name argNames body ->
716 Opt.TailDef name argNames body ->
717− let
717+ JS.Var [ (Name.fromLocal name, Just (generateTailDef mode name argNames body)) ]
718− function =
718+
719+
720+generateTailDef :: Mode -> N.Name -> [N.Name] -> Opt.Expr -> JS.Expr
721+generateTailDef mode name argNames body =
719− JS.Function Nothing (map Name.fromLocal argNames)
722+ JS.Function Nothing (map Name.fromLocal argNames)
720− [ JS.Labelled (Name.fromLocal name) $
723+ [ JS.Labelled (Name.fromLocal name) $
721− JS.While (JS.Bool True) $
724+ JS.While (JS.Bool True) $
722− codeToStmt $ generate mode body
725+ codeToStmt $ generate mode body
723− ]
726+ ]
724− in
725− JS.Var [ (Name.fromLocal name, Just function) ]
726
727
727
728
728
729
src/Optimize/Expression.hs+23−2
@@ -408,8 +408,29 @@ hasTailCall expression =
408 Opt.Let _ body ->
408 Opt.Let _ body ->
409 hasTailCall body
409 hasTailCall body
410
410
411− Opt.Case _ _ _ branches ->
411+ Opt.Destruct _ body ->
412+ hasTailCall body
413+
414+ Opt.Case _ _ decider jumps ->
412− any (hasTailCall . snd) branches
415+ decidecHasTailCall decider || any (hasTailCall . snd) jumps
413
416
414 _ ->
417 _ ->
415 False
418 False
419+
420+
421+decidecHasTailCall :: Opt.Decider Opt.Choice -> Bool
422+decidecHasTailCall decider =
423+ case decider of
424+ Opt.Leaf choice ->
425+ case choice of
426+ Opt.Inline expr ->
427+ hasTailCall expr
428+
429+ Opt.Jump _ ->
430+ False
431+
432+ Opt.Chain _ success failure ->
433+ decidecHasTailCall success || decidecHasTailCall failure
434+
435+ Opt.FanOut _ tests fallback ->
436+ decidecHasTailCall fallback || any (decidecHasTailCall . snd) tests