{-# LANGUAGE OverloadedStrings #-}
module GHC.StgToJS.Stack
( resetSlots
, isolateSlots
, setSlots
, getSlots
, addSlots
, dropSlots
, addUnknownSlots
, push
, push'
, adjSpN
, adjSpN'
, adjSp'
, adjSp
, pushNN
, pushNN'
, pushN'
, pushN
, pushOptimized'
, pushOptimized
, pushLneFrame
, popN
, popSkip
, popSkipI
, loadSkip
, updateThunk
, updateThunk'
, bhStats
)
where
import GHC.Prelude
import GHC.JS.Syntax
import GHC.JS.Make
import GHC.StgToJS.Types
import GHC.StgToJS.Monad
import GHC.StgToJS.Ids
import GHC.StgToJS.ExprCtx
import GHC.StgToJS.Heap
import GHC.StgToJS.Regs
import GHC.Types.Id
import GHC.Utils.Misc
import GHC.Data.FastString
import qualified Data.Bits as Bits
import qualified Data.List as L
import qualified Control.Monad.Trans.State.Strict as State
import Data.Array
import Data.Monoid
import Control.Monad
resetSlots :: G a -> G a
resetSlots :: forall a. G a -> G a
resetSlots G a
m = do
[StackSlot]
s <- G [StackSlot]
getSlots
Int
d <- G Int
getStackDepth
[StackSlot] -> G ()
setSlots []
a
a <- G a
m
[StackSlot] -> G ()
setSlots [StackSlot]
s
Int -> G ()
setStackDepth Int
d
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
isolateSlots :: G a -> G a
isolateSlots :: forall a. G a -> G a
isolateSlots G a
m = do
[StackSlot]
s <- G [StackSlot]
getSlots
Int
d <- G Int
getStackDepth
a
a <- G a
m
[StackSlot] -> G ()
setSlots [StackSlot]
s
Int -> G ()
setStackDepth Int
d
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
setStackDepth :: Int -> G ()
setStackDepth :: Int -> G ()
setStackDepth Int
d = (GenGroupState -> GenGroupState) -> G ()
modifyGroup (\GenGroupState
s -> GenGroupState
s { ggsStackDepth :: Int
ggsStackDepth = Int
d})
getStackDepth :: G Int
getStackDepth :: G Int
getStackDepth = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
State.gets (GenGroupState -> Int
ggsStackDepth forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenState -> GenGroupState
gsGroup)
modifyStackDepth :: (Int -> Int) -> G ()
modifyStackDepth :: (Int -> Int) -> G ()
modifyStackDepth Int -> Int
f = (GenGroupState -> GenGroupState) -> G ()
modifyGroup (\GenGroupState
s -> GenGroupState
s { ggsStackDepth :: Int
ggsStackDepth = Int -> Int
f (GenGroupState -> Int
ggsStackDepth GenGroupState
s) })
setSlots :: [StackSlot] -> G ()
setSlots :: [StackSlot] -> G ()
setSlots [StackSlot]
xs = (GenGroupState -> GenGroupState) -> G ()
modifyGroup (\GenGroupState
g -> GenGroupState
g { ggsStack :: [StackSlot]
ggsStack = [StackSlot]
xs})
getSlots :: G [StackSlot]
getSlots :: G [StackSlot]
getSlots = forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
State.gets (GenGroupState -> [StackSlot]
ggsStack forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenState -> GenGroupState
gsGroup)
modifySlots :: ([StackSlot] -> [StackSlot]) -> G ()
modifySlots :: ([StackSlot] -> [StackSlot]) -> G ()
modifySlots [StackSlot] -> [StackSlot]
f = (GenGroupState -> GenGroupState) -> G ()
modifyGroup (\GenGroupState
g -> GenGroupState
g { ggsStack :: [StackSlot]
ggsStack = [StackSlot] -> [StackSlot]
f (GenGroupState -> [StackSlot]
ggsStack GenGroupState
g)})
addUnknownSlots :: Int -> G ()
addUnknownSlots :: Int -> G ()
addUnknownSlots Int
n = [StackSlot] -> G ()
addSlots (forall a. Int -> a -> [a]
replicate Int
n StackSlot
SlotUnknown)
addSlots :: [StackSlot] -> G ()
addSlots :: [StackSlot] -> G ()
addSlots [StackSlot]
xs = do
[StackSlot]
s <- G [StackSlot]
getSlots
[StackSlot] -> G ()
setSlots ([StackSlot]
xs forall a. [a] -> [a] -> [a]
++ [StackSlot]
s)
dropSlots :: Int -> G ()
dropSlots :: Int -> G ()
dropSlots Int
n = ([StackSlot] -> [StackSlot]) -> G ()
modifySlots (forall a. Int -> [a] -> [a]
drop Int
n)
push :: [JExpr] -> G JStat
push :: [JExpr] -> G JStat
push [JExpr]
xs = do
Int -> G ()
dropSlots (forall (t :: * -> *) a. Foldable t => t a -> Int
length [JExpr]
xs)
(Int -> Int) -> G ()
modifyStackDepth (forall a. Num a => a -> a -> a
+ (forall (t :: * -> *) a. Foldable t => t a -> Int
length [JExpr]
xs))
forall a b c. (a -> b -> c) -> b -> a -> c
flip StgToJSConfig -> [JExpr] -> JStat
push' [JExpr]
xs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> G StgToJSConfig
getSettings
push' :: StgToJSConfig -> [JExpr] -> JStat
push' :: StgToJSConfig -> [JExpr] -> JStat
push' StgToJSConfig
_ [] = forall a. Monoid a => a
mempty
push' StgToJSConfig
cs [JExpr]
xs
| StgToJSConfig -> Bool
csInlinePush StgToJSConfig
cs Bool -> Bool -> Bool
|| Int
l forall a. Ord a => a -> a -> Bool
> Int
32 Bool -> Bool -> Bool
|| Int
l forall a. Ord a => a -> a -> Bool
< Int
2 = Int -> JStat
adjSp' Int
l forall a. Semigroup a => a -> a -> a
<> forall a. Monoid a => [a] -> a
mconcat [JStat]
items
| Bool
otherwise = JExpr -> [JExpr] -> JStat
ApplStat (forall a. ToJExpr a => a -> JExpr
toJExpr forall a b. (a -> b) -> a -> b
$ Array Int Ident
pushN forall i e. Ix i => Array i e -> i -> e
! Int
l) [JExpr]
xs
where
items :: [JStat]
items = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> JExpr -> JStat
f [(Int
1::Int)..] [JExpr]
xs
offset :: Int -> JExpr
offset Int
i | Int
i forall a. Eq a => a -> a -> Bool
== Int
l = JExpr
sp
| Bool
otherwise = JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
SubOp JExpr
sp (forall a. ToJExpr a => a -> JExpr
toJExpr (Int
l forall a. Num a => a -> a -> a
- Int
i))
l :: Int
l = forall (t :: * -> *) a. Foldable t => t a -> Int
length [JExpr]
xs
f :: Int -> JExpr -> JStat
f Int
i JExpr
e = JExpr -> JExpr -> JStat
AssignStat ((JExpr -> JExpr -> JExpr
IdxExpr JExpr
stack) (forall a. ToJExpr a => a -> JExpr
toJExpr (Int -> JExpr
offset Int
i))) (forall a. ToJExpr a => a -> JExpr
toJExpr JExpr
e)
adjSp' :: Int -> JStat
adjSp' :: Int -> JStat
adjSp' Int
0 = forall a. Monoid a => a
mempty
adjSp' Int
n = JExpr
sp JExpr -> JExpr -> JStat
|= JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
AddOp JExpr
sp (forall a. ToJExpr a => a -> JExpr
toJExpr Int
n)
adjSpN' :: Int -> JStat
adjSpN' :: Int -> JStat
adjSpN' Int
0 = forall a. Monoid a => a
mempty
adjSpN' Int
n = JExpr
sp JExpr -> JExpr -> JStat
|= JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
SubOp JExpr
sp (forall a. ToJExpr a => a -> JExpr
toJExpr Int
n)
adjSp :: Int -> G JStat
adjSp :: Int -> G JStat
adjSp Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
adjSp Int
n = do
(Int -> Int) -> G ()
modifyStackDepth (forall a. Num a => a -> a -> a
+Int
n)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> JStat
adjSp' Int
n)
adjSpN :: Int -> G JStat
adjSpN :: Int -> G JStat
adjSpN Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
adjSpN Int
n = do
(Int -> Int) -> G ()
modifyStackDepth (\Int
x -> Int
x forall a. Num a => a -> a -> a
- Int
n)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> JStat
adjSpN' Int
n)
pushN :: Array Int Ident
pushN :: Array Int Ident
pushN = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
1,Int
32) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (FastString -> Ident
TxtI forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FastString
mkFastString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"h$p"forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show) [(Int
1::Int)..Int
32]
pushN' :: Array Int JExpr
pushN' :: Array Int JExpr
pushN' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (JVal -> JExpr
ValExpr forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> JVal
JVar) Array Int Ident
pushN
pushNN :: Array Integer Ident
pushNN :: Array Integer Ident
pushNN = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Integer
1,Integer
255) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (FastString -> Ident
TxtI forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FastString
mkFastString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"h$pp"forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show) [(Int
1::Int)..Int
255]
pushNN' :: Array Integer JExpr
pushNN' :: Array Integer JExpr
pushNN' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (JVal -> JExpr
ValExpr forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> JVal
JVar) Array Integer Ident
pushNN
pushOptimized' :: [(Id,Int)] -> G JStat
pushOptimized' :: [(Id, Int)] -> G JStat
pushOptimized' [(Id, Int)]
xs = do
[StackSlot]
slots <- G [StackSlot]
getSlots
[(JExpr, Bool)] -> G JStat
pushOptimized forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (Id, Int) -> StackSlot -> StateT GenState IO (JExpr, Bool)
f [(Id, Int)]
xs ([StackSlot]
slotsforall a. [a] -> [a] -> [a]
++forall a. a -> [a]
repeat StackSlot
SlotUnknown))
where
f :: (Id, Int) -> StackSlot -> StateT GenState IO (JExpr, Bool)
f (Id
i1,Int
n1) StackSlot
xs2 = do
[JExpr]
xs <- Id -> G [JExpr]
varsForId Id
i1
let !id_n1 :: JExpr
id_n1 = [JExpr]
xs forall a. [a] -> Int -> a
!! (Int
n1forall a. Num a => a -> a -> a
-Int
1)
case StackSlot
xs2 of
SlotId Id
i2 Int
n2 -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (JExpr
id_n1,Id
i1forall a. Eq a => a -> a -> Bool
==Id
i2Bool -> Bool -> Bool
&&Int
n1forall a. Eq a => a -> a -> Bool
==Int
n2)
StackSlot
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (JExpr
id_n1,Bool
False)
pushOptimized :: [(JExpr,Bool)]
-> G JStat
pushOptimized :: [(JExpr, Bool)] -> G JStat
pushOptimized [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
pushOptimized [(JExpr, Bool)]
xs = do
Int -> G ()
dropSlots Int
l
(Int -> Int) -> G ()
modifyStackDepth (forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length [(JExpr, Bool)]
xs)
Bool -> JStat
go forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgToJSConfig -> Bool
csInlinePush forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> G StgToJSConfig
getSettings
where
go :: Bool -> JStat
go Bool
True = JStat
inlinePush
go Bool
_
| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall a b. (a, b) -> b
snd [(JExpr, Bool)]
xs = Int -> JStat
adjSp' Int
l
| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
notforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> b
snd) [(JExpr, Bool)]
xs Bool -> Bool -> Bool
&& Int
l forall a. Ord a => a -> a -> Bool
<= Int
32 =
JExpr -> [JExpr] -> JStat
ApplStat (Array Int JExpr
pushN' forall i e. Ix i => Array i e -> i -> e
! Int
l) (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(JExpr, Bool)]
xs)
| Int
l forall a. Ord a => a -> a -> Bool
<= Int
8 Bool -> Bool -> Bool
&& Bool -> Bool
not (forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last [(JExpr, Bool)]
xs) =
JExpr -> [JExpr] -> JStat
ApplStat (Array Integer JExpr
pushNN' forall i e. Ix i => Array i e -> i -> e
! Integer
sig) [ JExpr
e | (JExpr
e,Bool
False) <- [(JExpr, Bool)]
xs ]
| Bool
otherwise = JStat
inlinePush
l :: Int
l = forall (t :: * -> *) a. Foldable t => t a -> Int
length [(JExpr, Bool)]
xs
sig :: Integer
sig :: Integer
sig = forall a. (a -> a -> a) -> [a] -> a
L.foldl1' forall a. Bits a => a -> a -> a
(Bits..|.) forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(JExpr
_e,Bool
b) Int
i -> if Bool -> Bool
not Bool
b then forall a. Bits a => Int -> a
Bits.bit Int
i else Integer
0) [(JExpr, Bool)]
xs [Int
0..]
inlinePush :: JStat
inlinePush = Int -> JStat
adjSp' Int
l forall a. Semigroup a => a -> a -> a
<> forall a. Monoid a => [a] -> a
mconcat (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> (JExpr, Bool) -> JStat
pushSlot [Int
1..] [(JExpr, Bool)]
xs)
pushSlot :: Int -> (JExpr, Bool) -> JStat
pushSlot Int
i (JExpr
ex, Bool
False) = JExpr -> JExpr -> JExpr
IdxExpr JExpr
stack (Int -> JExpr
offset Int
i) JExpr -> JExpr -> JStat
|= JExpr
ex
pushSlot Int
_ (JExpr, Bool)
_ = forall a. Monoid a => a
mempty
offset :: Int -> JExpr
offset Int
i | Int
i forall a. Eq a => a -> a -> Bool
== Int
l = JExpr
sp
| Bool
otherwise = JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
SubOp JExpr
sp (forall a. ToJExpr a => a -> JExpr
toJExpr (Int
l forall a. Num a => a -> a -> a
- Int
i))
pushLneFrame :: HasDebugCallStack => Int -> ExprCtx -> G JStat
pushLneFrame :: HasDebugCallStack => Int -> ExprCtx -> G JStat
pushLneFrame Int
size ExprCtx
ctx =
let ctx' :: ExprCtx
ctx' = ExprCtx -> Int -> ExprCtx
ctxLneShrinkStack ExprCtx
ctx Int
size
in [(Id, Int)] -> G JStat
pushOptimized' (ExprCtx -> [(Id, Int)]
ctxLneFrameVars ExprCtx
ctx')
popSkip :: Int
-> [JExpr]
-> JStat
popSkip :: Int -> [JExpr] -> JStat
popSkip Int
0 [] = forall a. Monoid a => a
mempty
popSkip Int
n [] = Int -> JStat
adjSpN' Int
n
popSkip Int
n [JExpr]
tgt = Int -> [JExpr] -> JStat
loadSkip Int
n [JExpr]
tgt forall a. Semigroup a => a -> a -> a
<> Int -> JStat
adjSpN' (forall (t :: * -> *) a. Foldable t => t a -> Int
length [JExpr]
tgt forall a. Num a => a -> a -> a
+ Int
n)
loadSkip :: Int -> [JExpr] -> JStat
loadSkip :: Int -> [JExpr] -> JStat
loadSkip = JExpr -> Int -> [JExpr] -> JStat
loadSkipFrom JExpr
sp
where
loadSkipFrom :: JExpr -> Int -> [JExpr] -> JStat
loadSkipFrom :: JExpr -> Int -> [JExpr] -> JStat
loadSkipFrom JExpr
fr Int
n [JExpr]
xs = forall a. Monoid a => [a] -> a
mconcat [JStat]
items
where
items :: [JStat]
items = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> JExpr -> JStat
f [(Int
0::Int)..] (forall a. [a] -> [a]
reverse [JExpr]
xs)
offset :: Int -> JExpr
offset Int
0 = JExpr
fr
offset Int
n = JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
SubOp JExpr
fr (forall a. ToJExpr a => a -> JExpr
toJExpr Int
n)
f :: Int -> JExpr -> JStat
f Int
i JExpr
ex = JExpr
ex JExpr -> JExpr -> JStat
|= JExpr -> JExpr -> JExpr
IdxExpr JExpr
stack (forall a. ToJExpr a => a -> JExpr
toJExpr (Int -> JExpr
offset (Int
iforall a. Num a => a -> a -> a
+Int
n)))
popSkipI :: Int -> [(Ident,StackSlot)] -> G JStat
popSkipI :: Int -> [(Ident, StackSlot)] -> G JStat
popSkipI Int
0 [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
popSkipI Int
n [] = Int -> G JStat
popN Int
n
popSkipI Int
n [(Ident, StackSlot)]
xs = do
Int -> G ()
addUnknownSlots Int
n
[StackSlot] -> G ()
addSlots (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Ident, StackSlot)]
xs)
JStat
a <- Int -> G JStat
adjSpN (forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Ident, StackSlot)]
xs forall a. Num a => a -> a -> a
+ Int
n)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> [Ident] -> JStat
loadSkipI Int
n (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(Ident, StackSlot)]
xs) forall a. Semigroup a => a -> a -> a
<> JStat
a)
loadSkipI :: Int -> [Ident] -> JStat
loadSkipI :: Int -> [Ident] -> JStat
loadSkipI = JExpr -> Int -> [Ident] -> JStat
loadSkipIFrom JExpr
sp
where loadSkipIFrom :: JExpr -> Int -> [Ident] -> JStat
loadSkipIFrom :: JExpr -> Int -> [Ident] -> JStat
loadSkipIFrom JExpr
fr Int
n [Ident]
xs = forall a. Monoid a => [a] -> a
mconcat [JStat]
items
where
items :: [JStat]
items = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Ident -> JStat
f [(Int
0::Int)..] (forall a. [a] -> [a]
reverse [Ident]
xs)
offset :: Int -> JExpr
offset Int
0 = JExpr
fr
offset Int
n = JOp -> JExpr -> JExpr -> JExpr
InfixExpr JOp
SubOp JExpr
fr (forall a. ToJExpr a => a -> JExpr
toJExpr Int
n)
f :: Int -> Ident -> JStat
f Int
i Ident
ex = Ident
ex Ident -> JExpr -> JStat
||= JExpr -> JExpr -> JExpr
IdxExpr JExpr
stack (forall a. ToJExpr a => a -> JExpr
toJExpr (Int -> JExpr
offset (Int
iforall a. Num a => a -> a -> a
+Int
n)))
popN :: Int -> G JStat
popN :: Int -> G JStat
popN Int
n = Int -> G ()
addUnknownSlots Int
n forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> G JStat
adjSpN Int
n
bhStats :: StgToJSConfig -> Bool -> JStat
bhStats :: StgToJSConfig -> Bool -> JStat
bhStats StgToJSConfig
s Bool
pushUpd = forall a. Monoid a => [a] -> a
mconcat
[ if Bool
pushUpd then StgToJSConfig -> [JExpr] -> JStat
push' StgToJSConfig
s [JExpr
r1, FastString -> JExpr
var FastString
"h$upd_frame"] else forall a. Monoid a => a
mempty
, forall a. ToJExpr a => a -> JExpr
toJExpr StgReg
R1 JExpr -> FastString -> JExpr
.^ FastString
closureEntry_ JExpr -> JExpr -> JStat
|= FastString -> JExpr
var FastString
"h$blackhole"
, forall a. ToJExpr a => a -> JExpr
toJExpr StgReg
R1 JExpr -> FastString -> JExpr
.^ FastString
closureField1_ JExpr -> JExpr -> JStat
|= FastString -> JExpr
var FastString
"h$currentThread"
, forall a. ToJExpr a => a -> JExpr
toJExpr StgReg
R1 JExpr -> FastString -> JExpr
.^ FastString
closureField2_ JExpr -> JExpr -> JStat
|= JExpr
null_
]
updateThunk :: G JStat
updateThunk :: G JStat
updateThunk = do
StgToJSConfig
settings <- G StgToJSConfig
getSettings
let adjPushStack :: Int -> G ()
adjPushStack :: Int -> G ()
adjPushStack Int
n = do (Int -> Int) -> G ()
modifyStackDepth (forall a. Num a => a -> a -> a
+Int
n)
Int -> G ()
dropSlots Int
n
Int -> G ()
adjPushStack Int
2
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (StgToJSConfig -> JStat
updateThunk' StgToJSConfig
settings)
updateThunk' :: StgToJSConfig -> JStat
updateThunk' :: StgToJSConfig -> JStat
updateThunk' StgToJSConfig
settings =
if StgToJSConfig -> Bool
csInlineBlackhole StgToJSConfig
settings
then StgToJSConfig -> Bool -> JStat
bhStats StgToJSConfig
settings Bool
True
else JExpr -> [JExpr] -> JStat
ApplStat (FastString -> JExpr
var FastString
"h$bh") []