{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE OverloadedStrings #-}
module GHC.StgToJS.FFI
( genPrimCall
, genForeignCall
)
where
import GHC.Prelude
import GHC.JS.JStg.Syntax
import GHC.JS.Ident
import GHC.JS.Make
import GHC.StgToJS.Arg
import GHC.StgToJS.ExprCtx
import GHC.StgToJS.Monad
import GHC.StgToJS.Types
import GHC.StgToJS.Literal
import GHC.StgToJS.Regs
import GHC.StgToJS.Utils
import GHC.StgToJS.Ids
import GHC.Types.RepType
import GHC.Types.ForeignCall
import GHC.Types.Unique.Map
import GHC.Stg.Syntax
import GHC.Builtin.PrimOps
import GHC.Builtin.Types.Prim
import GHC.Core.Type hiding (typeSize)
import GHC.Utils.Misc
import GHC.Utils.Outputable (renderWithContext, defaultSDocContext, ppr)
import GHC.Data.FastString
import Data.Char
import Data.Monoid
import qualified Data.List as L
genPrimCall :: ExprCtx -> PrimCall -> [StgArg] -> Type -> G (JStgStat, ExprResult)
genPrimCall :: ExprCtx -> PrimCall -> [StgArg] -> Type -> G (JStgStat, ExprResult)
genPrimCall ExprCtx
ctx (PrimCall FastString
lbl Unit
_) [StgArg]
args Type
t = do
j <- Bool
-> Bool
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPattern Bool
False Bool
False Bool
False (String
"h$" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
lbl) Type
t ((TypedExpr -> [JStgExpr]) -> [TypedExpr] -> [JStgExpr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap TypedExpr -> [JStgExpr]
typex_expr ([TypedExpr] -> [JStgExpr]) -> [TypedExpr] -> [JStgExpr]
forall a b. (a -> b) -> a -> b
$ ExprCtx -> [TypedExpr]
ctxTarget ExprCtx
ctx) [StgArg]
args
return (j, ExprInline)
parseFFIPattern :: Bool
-> Bool
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPattern :: Bool
-> Bool
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPattern Bool
catchExcep Bool
async Bool
jscc String
pat Type
t [JStgExpr]
es [StgArg]
as
| Bool
catchExcep = do
c <- Bool
-> Bool -> String -> Type -> [JStgExpr] -> [StgArg] -> G JStgStat
parseFFIPatternA Bool
async Bool
jscc String
pat Type
t [JStgExpr]
es [StgArg]
as
let ex = FastString -> Ident
global FastString
"except"
return (TryStat c ex (ReturnStat (ApplExpr (var "h$throwJSException") [toJExpr ex])) mempty)
| Bool
otherwise = Bool
-> Bool -> String -> Type -> [JStgExpr] -> [StgArg] -> G JStgStat
parseFFIPatternA Bool
async Bool
jscc String
pat Type
t [JStgExpr]
es [StgArg]
as
parseFFIPatternA :: Bool
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPatternA :: Bool
-> Bool -> String -> Type -> [JStgExpr] -> [StgArg] -> G JStgStat
parseFFIPatternA Bool
True Bool
True String
pat Type
t [JStgExpr]
es [StgArg]
as = do
cb <- G Ident
freshIdent
x <- freshIdent
d <- freshIdent
stat <- parseFFIPattern' (Just (toJExpr cb)) True pat t es as
return $ mconcat
[ x ||= (toJExpr (jhFromList [("mv", null_)]))
, cb ||= ApplExpr (var "h$mkForeignCallback") [toJExpr x]
, stat
, IfStat (InfixExpr StrictEqOp (toJExpr x .^ "mv") null_)
(mconcat
[ toJExpr x .^ "mv" |= UOpExpr NewOp (ApplExpr (var "h$MVar") [])
, sp |= Add sp one_
, (IdxExpr stack sp) |= var "h$unboxFFIResult"
, ReturnStat $ ApplExpr (var "h$takeMVar") [toJExpr x .^ "mv"]
])
(mconcat
[ d ||= toJExpr x .^ "mv"
, copyResult (toJExpr d)
])
]
where nrst :: Int
nrst = Type -> Int
typeSize Type
t
copyResult :: JStgExpr -> JStgStat
copyResult JStgExpr
d = [JStgExpr] -> [JStgExpr] -> JStgStat
HasDebugCallStack => [JStgExpr] -> [JStgExpr] -> JStgStat
assignAllEqual [JStgExpr]
es ((Int -> JStgExpr) -> [Int] -> [JStgExpr]
forall a b. (a -> b) -> [a] -> [b]
map (JStgExpr -> JStgExpr -> JStgExpr
IdxExpr JStgExpr
d (JStgExpr -> JStgExpr) -> (Int -> JStgExpr) -> Int -> JStgExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr) [Int
0..Int
nrstInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1])
parseFFIPatternA Bool
_async Bool
javascriptCc String
pat Type
t [JStgExpr]
es [StgArg]
as =
Maybe JStgExpr
-> Bool -> String -> Type -> [JStgExpr] -> [StgArg] -> G JStgStat
parseFFIPattern' Maybe JStgExpr
forall a. Maybe a
Nothing Bool
javascriptCc String
pat Type
t [JStgExpr]
es [StgArg]
as
parseFFIPattern' :: Maybe JStgExpr
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPattern' :: Maybe JStgExpr
-> Bool -> String -> Type -> [JStgExpr] -> [StgArg] -> G JStgStat
parseFFIPattern' Maybe JStgExpr
callback Bool
javascriptCc String
pat Type
t [JStgExpr]
ret [StgArg]
args
| Bool -> Bool
not Bool
javascriptCc = String -> G JStgStat
mkApply String
pat
| Bool
otherwise = String -> G JStgStat
mkApply String
pat
where
tgt :: [JStgExpr]
tgt = Int -> [JStgExpr] -> [JStgExpr]
forall a. Int -> [a] -> [a]
take (Type -> Int
typeSize Type
t) [JStgExpr]
ret
mkApply :: String -> G JStgStat
mkApply String
f
| Just JStgExpr
cb <- Maybe JStgExpr
callback = do
(stats, as) <- [(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]]))
-> StateT GenState IO [(JStgStat, [JStgExpr])]
-> StateT GenState IO ([JStgStat], [[JStgExpr]])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StgArg -> StateT GenState IO (JStgStat, [JStgExpr]))
-> [StgArg] -> StateT GenState IO [(JStgStat, [JStgExpr])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Bool -> StgArg -> StateT GenState IO (JStgStat, [JStgExpr])
genFFIArg Bool
javascriptCc) [StgArg]
args
cs <- getSettings
return $ traceCall cs as <> mconcat stats <> ApplStat f' (concat as++[cb])
|
(JStgExpr
t:[JStgExpr]
ts') <- [JStgExpr]
tgt = do
(stats, as) <- [(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]]))
-> StateT GenState IO [(JStgStat, [JStgExpr])]
-> StateT GenState IO ([JStgStat], [[JStgExpr]])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StgArg -> StateT GenState IO (JStgStat, [JStgExpr]))
-> [StgArg] -> StateT GenState IO [(JStgStat, [JStgExpr])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Bool -> StgArg -> StateT GenState IO (JStgStat, [JStgExpr])
genFFIArg Bool
javascriptCc) [StgArg]
args
cs <- getSettings
return $ traceCall cs as
<> mconcat stats
<> (t |= ApplExpr f' (concat as) )
<> copyResult ts'
| Bool
otherwise = do
(stats, as) <- [(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(JStgStat, [JStgExpr])] -> ([JStgStat], [[JStgExpr]]))
-> StateT GenState IO [(JStgStat, [JStgExpr])]
-> StateT GenState IO ([JStgStat], [[JStgExpr]])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StgArg -> StateT GenState IO (JStgStat, [JStgExpr]))
-> [StgArg] -> StateT GenState IO [(JStgStat, [JStgExpr])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Bool -> StgArg -> StateT GenState IO (JStgStat, [JStgExpr])
genFFIArg Bool
javascriptCc) [StgArg]
args
cs <- getSettings
return $ traceCall cs as <> mconcat stats <> ApplStat f' (concat as)
where f' :: JStgExpr
f' = Ident -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr (FastString -> Ident
global (FastString -> Ident) -> FastString -> Ident
forall a b. (a -> b) -> a -> b
$ String -> FastString
mkFastString String
f)
copyResult :: [a] -> JStgStat
copyResult [a]
rs = [JStgStat] -> JStgStat
forall a. Monoid a => [a] -> a
mconcat ([JStgStat] -> JStgStat) -> [JStgStat] -> JStgStat
forall a b. (a -> b) -> a -> b
$ (StgRet -> a -> JStgStat) -> [StgRet] -> [a] -> [JStgStat]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\StgRet
t a
r -> a -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr a
r JStgExpr -> JStgExpr -> JStgStat
|= StgRet -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr StgRet
t) (StgRet -> [StgRet]
forall a. Enum a => a -> [a]
enumFrom StgRet
Ret1) [a]
rs
traceCall :: StgToJSConfig -> [[JStgExpr]] -> JStgStat
traceCall StgToJSConfig
cs [[JStgExpr]]
as
| StgToJSConfig -> Bool
csTraceForeign StgToJSConfig
cs = JStgExpr -> [JStgExpr] -> JStgStat
ApplStat (FastString -> JStgExpr
var FastString
"h$traceForeign") [String -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr String
pat, [[JStgExpr]] -> JStgExpr
forall a. ToJExpr a => a -> JStgExpr
toJExpr [[JStgExpr]]
as]
| Bool
otherwise = JStgStat
forall a. Monoid a => a
mempty
genFFIArg :: Bool -> StgArg -> G (JStgStat, [JStgExpr])
genFFIArg :: Bool -> StgArg -> StateT GenState IO (JStgStat, [JStgExpr])
genFFIArg Bool
_isJavaScriptCc (StgLitArg Literal
l) = (JStgStat
forall a. Monoid a => a
mempty,) ([JStgExpr] -> (JStgStat, [JStgExpr]))
-> StateT GenState IO [JStgExpr]
-> StateT GenState IO (JStgStat, [JStgExpr])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasDebugCallStack => Literal -> StateT GenState IO [JStgExpr]
Literal -> StateT GenState IO [JStgExpr]
genLit Literal
l
genFFIArg Bool
isJavaScriptCc a :: StgArg
a@(StgVarArg Id
i)
| Bool -> Bool
not Bool
isJavaScriptCc Bool -> Bool -> Bool
&&
(TyCon
tycon TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
byteArrayPrimTyCon Bool -> Bool -> Bool
|| TyCon
tycon TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
mutableByteArrayPrimTyCon) =
(\JStgExpr
x -> (JStgStat
forall a. Monoid a => a
mempty,[JStgExpr
x, JStgExpr
zero_])) (JStgExpr -> (JStgStat, [JStgExpr]))
-> StateT GenState IO JStgExpr
-> StateT GenState IO (JStgStat, [JStgExpr])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Id -> StateT GenState IO JStgExpr
varForId Id
i
| JSRep -> Bool
isVoid JSRep
r = (JStgStat, [JStgExpr]) -> StateT GenState IO (JStgStat, [JStgExpr])
forall a. a -> StateT GenState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (JStgStat
forall a. Monoid a => a
mempty, [])
| JSRep -> Bool
isMultiVar JSRep
r = (JStgStat
forall a. Monoid a => a
mempty,) ([JStgExpr] -> (JStgStat, [JStgExpr]))
-> StateT GenState IO [JStgExpr]
-> StateT GenState IO (JStgStat, [JStgExpr])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> StateT GenState IO JStgExpr)
-> [Int] -> StateT GenState IO [JStgExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Id -> Int -> StateT GenState IO JStgExpr
varForIdN Id
i) [Int
1..JSRep -> Int
varSize JSRep
r]
| Bool
otherwise = (\JStgExpr
x -> (JStgStat
forall a. Monoid a => a
mempty,[JStgExpr
x])) (JStgExpr -> (JStgStat, [JStgExpr]))
-> StateT GenState IO JStgExpr
-> StateT GenState IO (JStgStat, [JStgExpr])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Id -> StateT GenState IO JStgExpr
varForId Id
i
where
tycon :: TyCon
tycon = HasDebugCallStack => Type -> TyCon
Type -> TyCon
tyConAppTyCon (Type -> Type
unwrapType Type
arg_ty)
arg_ty :: Type
arg_ty = StgArg -> Type
stgArgType StgArg
a
r :: JSRep
r = HasDebugCallStack => Type -> JSRep
Type -> JSRep
unaryTypeJSRep Type
arg_ty
genForeignCall :: HasDebugCallStack
=> ExprCtx
-> ForeignCall
-> Type
-> [JStgExpr]
-> [StgArg]
-> G (JStgStat, ExprResult)
genForeignCall :: HasDebugCallStack =>
ExprCtx
-> ForeignCall
-> Type
-> [JStgExpr]
-> [StgArg]
-> G (JStgStat, ExprResult)
genForeignCall ExprCtx
_ctx
(CCall (CCallSpec (StaticTarget SourceText
_ FastString
tgt Maybe Unit
Nothing Bool
True)
CCallConv
JavaScriptCallConv
Safety
PlayRisky))
Type
_t
[JStgExpr
obj]
[StgArg]
args
| FastString
tgt FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== String -> FastString
fsLit String
"h$buildObject"
, Just [(FastString, StgArg)]
pairs <- [StgArg] -> Maybe [(FastString, StgArg)]
getObjectKeyValuePairs [StgArg]
args = do
pairs' <- ((FastString, StgArg) -> StateT GenState IO (FastString, JStgExpr))
-> [(FastString, StgArg)]
-> StateT GenState IO [(FastString, JStgExpr)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\(FastString
k,StgArg
v) -> HasDebugCallStack => StgArg -> StateT GenState IO [JStgExpr]
StgArg -> StateT GenState IO [JStgExpr]
genArg StgArg
v StateT GenState IO [JStgExpr]
-> ([JStgExpr] -> StateT GenState IO (FastString, JStgExpr))
-> StateT GenState IO (FastString, JStgExpr)
forall a b.
StateT GenState IO a
-> (a -> StateT GenState IO b) -> StateT GenState IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \[JStgExpr]
vs -> (FastString, JStgExpr) -> StateT GenState IO (FastString, JStgExpr)
forall a. a -> StateT GenState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FastString
k, [JStgExpr] -> JStgExpr
forall a. HasCallStack => [a] -> a
head [JStgExpr]
vs)) [(FastString, StgArg)]
pairs
return ( (|=) obj (ValExpr (JHash $ listToUniqMap pairs'))
, ExprInline
)
genForeignCall ExprCtx
ctx (CCall (CCallSpec CCallTarget
ccTarget CCallConv
cconv Safety
safety)) Type
t [JStgExpr]
tgt [StgArg]
args = do
Maybe RealSrcSpan
-> FastString
-> Safety
-> CCallConv
-> [FastString]
-> FastString
-> G ()
emitForeign (ExprCtx -> Maybe RealSrcSpan
ctxSrcSpan ExprCtx
ctx) (String -> FastString
mkFastString String
lbl) Safety
safety CCallConv
cconv ((StgArg -> FastString) -> [StgArg] -> [FastString]
forall a b. (a -> b) -> [a] -> [b]
map StgArg -> FastString
showArgType [StgArg]
args) (Type -> FastString
showType Type
t)
(,ExprResult
exprResult) (JStgStat -> (JStgStat, ExprResult))
-> G JStgStat -> G (JStgStat, ExprResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool
-> Bool
-> Bool
-> String
-> Type
-> [JStgExpr]
-> [StgArg]
-> G JStgStat
parseFFIPattern Bool
catchExcep Bool
async Bool
isJsCc String
lbl Type
t [JStgExpr]
tgt' [StgArg]
args
where
isJsCc :: Bool
isJsCc = CCallConv
cconv CCallConv -> CCallConv -> Bool
forall a. Eq a => a -> a -> Bool
== CCallConv
JavaScriptCallConv
lbl :: String
lbl | (StaticTarget SourceText
_ FastString
clbl Maybe Unit
_mpkg Bool
_isFunPtr) <- CCallTarget
ccTarget
= let clbl' :: String
clbl' = FastString -> String
unpackFS FastString
clbl
in if | Bool
isJsCc -> String
clbl'
| String
wrapperPrefix String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`L.isPrefixOf` String
clbl' ->
(String
"h$" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
2 (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isDigit (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Int -> String -> String
forall a. Int -> [a] -> [a]
drop (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
wrapperPrefix) String
clbl'))
| Bool
otherwise -> String
"h$" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
clbl'
| Bool
otherwise = String
"h$callDynamic"
exprResult :: ExprResult
exprResult | Bool
async = ExprResult
ExprCont
| Bool
otherwise = ExprResult
ExprInline
catchExcep :: Bool
catchExcep = (CCallConv
cconv CCallConv -> CCallConv -> Bool
forall a. Eq a => a -> a -> Bool
== CCallConv
JavaScriptCallConv) Bool -> Bool -> Bool
&&
Safety -> Bool
playSafe Safety
safety Bool -> Bool -> Bool
|| Safety -> Bool
playInterruptible Safety
safety
async :: Bool
async | Bool
isJsCc = Safety -> Bool
playInterruptible Safety
safety
| Bool
otherwise = Safety -> Bool
playInterruptible Safety
safety Bool -> Bool -> Bool
|| Safety -> Bool
playSafe Safety
safety
tgt' :: [JStgExpr]
tgt' | Bool
async = Int -> [JStgExpr] -> [JStgExpr]
forall a. Int -> [a] -> [a]
take ([JStgExpr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [JStgExpr]
tgt) [JStgExpr]
jsRegsFromR1
| Bool
otherwise = [JStgExpr]
tgt
wrapperPrefix :: String
wrapperPrefix = String
"ghczuwrapperZC"
getObjectKeyValuePairs :: [StgArg] -> Maybe [(FastString, StgArg)]
getObjectKeyValuePairs :: [StgArg] -> Maybe [(FastString, StgArg)]
getObjectKeyValuePairs [] = [(FastString, StgArg)] -> Maybe [(FastString, StgArg)]
forall a. a -> Maybe a
Just []
getObjectKeyValuePairs (StgArg
k:StgArg
v:[StgArg]
xs)
| Just FastString
t <- StgArg -> Maybe FastString
argJSStringLitUnfolding StgArg
k =
([(FastString, StgArg)] -> [(FastString, StgArg)])
-> Maybe [(FastString, StgArg)] -> Maybe [(FastString, StgArg)]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FastString
t,StgArg
v)(FastString, StgArg)
-> [(FastString, StgArg)] -> [(FastString, StgArg)]
forall a. a -> [a] -> [a]
:) ([StgArg] -> Maybe [(FastString, StgArg)]
getObjectKeyValuePairs [StgArg]
xs)
getObjectKeyValuePairs [StgArg]
_ = Maybe [(FastString, StgArg)]
forall a. Maybe a
Nothing
argJSStringLitUnfolding :: StgArg -> Maybe FastString
argJSStringLitUnfolding :: StgArg -> Maybe FastString
argJSStringLitUnfolding (StgVarArg Id
_v) = Maybe FastString
forall a. Maybe a
Nothing
argJSStringLitUnfolding StgArg
_ = Maybe FastString
forall a. Maybe a
Nothing
showArgType :: StgArg -> FastString
showArgType :: StgArg -> FastString
showArgType StgArg
a = Type -> FastString
showType (StgArg -> Type
stgArgType StgArg
a)
showType :: Type -> FastString
showType :: Type -> FastString
showType Type
t
| Just TyCon
tc <- Type -> Maybe TyCon
tyConAppTyCon_maybe (Type -> Type
unwrapType Type
t) =
String -> FastString
mkFastString (SDocContext -> SDoc -> String
renderWithContext SDocContext
defaultSDocContext (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc))
| Bool
otherwise = FastString
"<unknown>"