{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE JavaScriptFFI #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE EmptyDataDecls #-}
module GHCJS.Foreign.Export
( Export
, export
, withExport
, derefExport
, releaseExport
) where
import Control.Exception (bracket)
import GHC.Exts (Any)
import GHC.Fingerprint
import Data.Typeable
import Data.Word
import Unsafe.Coerce
import qualified GHC.Exts as Exts
import GHCJS.Prim
import GHCJS.Types
newtype Export a = Export JSVal
instance IsJSVal (Export a)
export :: Typeable a => a -> IO (Export a)
export x = js_export w1 w2 (unsafeCoerce x)
where
Fingerprint w1 w2 = typeRepFingerprint (typeOf x)
withExport :: Typeable a => a -> (Export a -> IO b) -> IO b
withExport x m = bracket (export x) releaseExport m
derefExport :: forall a. Typeable a => Export a -> IO (Maybe a)
derefExport e = do
let Fingerprint w1 w2 = typeRepFingerprint (typeOf (undefined :: a))
r <- js_derefExport w1 w2 e
if isNull r
then return Nothing
else Just . unsafeCoerce <$> js_toHeapObject r
releaseExport :: Export a -> IO ()
releaseExport e = js_releaseExport e
foreign import javascript unsafe
"h$exportValue"
js_export :: Word64 -> Word64 -> Any -> IO (Export a)
foreign import javascript unsafe
"h$derefExport"
js_derefExport :: Word64 -> Word64 -> Export a -> IO JSVal
foreign import javascript unsafe
"$r = $1;" js_toHeapObject :: JSVal -> IO Any
foreign import javascript unsafe
"h$releaseExport"
js_releaseExport :: Export a -> IO ()