@@ -254,15 +254,29 @@ jsSubst var new (JSReturn ret) =
254254
255255jsSubst _ _ js = js
256256
257−inlineAble :: JS -> Bool
258−inlineAble (JSNew con [tag, args]) = True
259−inlineAble (JSApp (JSRaw "__IDRRT__tailcall") _) = False
260−inlineAble JSNull = True
261−inlineAble (JSString _) = True
262−inlineAble (JSType _) = True
263−inlineAble (JSNum _) = True
264−inlineAble (JSApp (JSRaw "__IDRRT__bigInt") _) = True
265−inlineAble _ = False
257+inlineAble :: Bool -> JS -> JS -> Bool
258+inlineAble _ (JSNew con [tag, args]) _ = True
259+inlineAble _ JSNull _ = True
260+inlineAble _ (JSString _) _ = True
261+inlineAble _ (JSType _) _ = True
262+inlineAble _ (JSNum _) _ = True
263+inlineAble _ (JSApp (JSRaw "__IDRRT__bigInt") _) _ = True
264+inlineAble insideTC (JSApp (JSRaw "__IDRRT__tailcall") _) into =
265+ not insideTC && not (doesTailcall into)
266+ where
267+ doesTailcall :: JS -> Bool
268+ doesTailcall (JSApp (JSRaw "__IDRRT__tailcall") _) = True
269+ doesTailcall (JSApp (JSRaw _) args) = any id (map doesTailcall args)
270+ doesTailcall (JSApp f args) = doesTailcall f || any id (map doesTailcall args)
271+ doesTailcall (JSReturn ret) = doesTailcall ret
272+ doesTailcall (JSFunction [_] body) = doesTailcall body
273+ doesTailcall (JSNew _ [tag, args]) = doesTailcall args
274+ doesTailcall (JSNew _ [JSFunction [] body]) = doesTailcall body
275+ doesTailcall (JSArray vals) = any id (map doesTailcall vals)
276+ doesTailcall (JSVar _) = False
277+ doesTailcall _ = True
278+
279+inlineAble _ _ _ = False
266280
267281optimizeJS :: JS -> JS
268282optimizeJS (JSApp (JSFunction [] (JSSeq ret)) []) =
@@ -271,12 +285,12 @@ optimizeJS (JSApp (JSFunction [] (JSSeq ret)) []) =
271285optimizeJS (JSApp (JSFunction [arg] (JSReturn ret)) [val])
272286 | JSNew con [tag, vals] <- ret
273287 , opt <- optimizeJS val
274− , inlineAble opt =
288+ , inlineAble False opt vals =
275289 JSNew con [tag, jsSubst arg opt vals]
276290
277291 | JSNew con [JSFunction [] (JSReturn (JSApp fun vars))] <- ret
278292 , opt <- optimizeJS val
279− , inlineAble opt =
293+ , all id $ map (inlineAble False opt) vars =
280294 JSNew con [JSFunction [] (
281295 JSReturn $ JSApp fun (map (jsSubst arg opt) vars)
282296 )]
@@ -285,17 +299,18 @@ optimizeJS (JSApp (JSFunction [arg] (JSReturn ret)) [val])
285299 JSReturn (JSApp fun args)
286300 )] <- ret
287301 , opt <- optimizeJS val
288− , inlineAble opt =
302+ , all id $ map (inlineAble True opt) args =
289303 JSApp (JSRaw "__IDRRT__tailcall") [JSFunction [] (
290304 JSReturn $ JSApp fun (map (jsSubst arg opt) args)
291305 )]
292306
293307 | JSApp (JSFunction [x] (JSReturn body)) [y] <- ret
294− , opt <- optimizeJS val
295− , inlineAble opt =
308+ , opt <- optimizeJS val
309+ , optBody <- optimizeJS body
310+ , inlineAble False opt optBody =
296311 optimizeJS (
297312 JSApp (JSFunction [x] $
298− JSReturn $ jsSubst arg opt (optimizeJS body)
313+ JSReturn $ jsSubst arg opt optBody
299314 ) [y]
300315 )
301316