{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Language.JavaScript.Inline.Core.Instruction where
import Control.Concurrent.STM
import Control.Exception
import Data.Binary.Get
import qualified Data.ByteString.Lazy as LBS
import Data.Proxy
import Foreign
import Language.JavaScript.Inline.Core.Class
import Language.JavaScript.Inline.Core.Dict
import Language.JavaScript.Inline.Core.Export
import Language.JavaScript.Inline.Core.JSVal
import Language.JavaScript.Inline.Core.Message
import Language.JavaScript.Inline.Core.Session
import Language.JavaScript.Inline.Core.Utils
import System.Directory
import System.IO.Unsafe
evalWithDecoder ::
RawJSType ->
(Session -> LBS.ByteString -> IO a) ->
Session ->
JSExpr ->
IO a
evalWithDecoder :: RawJSType
-> (Session -> ByteString -> IO a) -> Session -> JSExpr -> IO a
evalWithDecoder RawJSType
_return_type Session -> ByteString -> IO a
_decoder _session :: Session
_session@Session {IO ()
TMVar (Either SomeException ByteString)
IPC
killSession :: Session -> IO ()
closeSession :: Session -> IO ()
fatalErrorInbox :: Session -> TMVar (Either SomeException ByteString)
ipc :: Session -> IPC
killSession :: IO ()
closeSession :: IO ()
fatalErrorInbox :: TMVar (Either SomeException ByteString)
ipc :: IPC
..} JSExpr
_code = do
TMVar (Either SomeException ByteString)
_inbox <- IO (TMVar (Either SomeException ByteString))
forall a. IO (TMVar a)
newEmptyTMVarIO
StablePtr (TMVar (Either SomeException ByteString))
_sp <- TMVar (Either SomeException ByteString)
-> IO (StablePtr (TMVar (Either SomeException ByteString)))
forall a. a -> IO (StablePtr a)
newStablePtr TMVar (Either SomeException ByteString)
_inbox
let _id :: Word64
_id = StablePtr (TMVar (Either SomeException ByteString)) -> Word64
forall a. StablePtr a -> Word64
word64FromStablePtr StablePtr (TMVar (Either SomeException ByteString))
_sp
Session -> MessageHS -> IO ()
sessionSend
Session
_session
JSEvalRequest :: Word64 -> JSExpr -> RawJSType -> MessageHS
JSEvalRequest
{ jsEvalRequestId :: Word64
jsEvalRequestId = Word64
_id,
code :: JSExpr
code = JSExpr
_code,
returnType :: RawJSType
returnType = RawJSType
_return_type
}
JSExpr -> IO ()
forall a. a -> IO ()
touch JSExpr
_code
IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
Either SomeException ByteString
_resp <- STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString)
forall a. STM a -> IO a
atomically (STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString))
-> STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString)
forall a b. (a -> b) -> a -> b
$ TMVar (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. TMVar a -> STM a
takeTMVar TMVar (Either SomeException ByteString)
_inbox STM (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. STM a -> STM a -> STM a
`orElse` TMVar (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. TMVar a -> STM a
readTMVar TMVar (Either SomeException ByteString)
fatalErrorInbox
StablePtr (TMVar (Either SomeException ByteString)) -> IO ()
forall a. StablePtr a -> IO ()
freeStablePtr StablePtr (TMVar (Either SomeException ByteString))
_sp
case Either SomeException ByteString
_resp of
Left SomeException
err -> SomeException -> IO a
forall e a. Exception e => e -> IO a
throwIO SomeException
err
Right ByteString
_result_buf -> Session -> ByteString -> IO a
_decoder Session
_session ByteString
_result_buf
eval :: forall a. FromJS a => Session -> JSExpr -> IO a
eval :: Session -> JSExpr -> IO a
eval Session
s JSExpr
c =
RawJSType
-> (Session -> ByteString -> IO a) -> Session -> JSExpr -> IO a
forall a.
RawJSType
-> (Session -> ByteString -> IO a) -> Session -> JSExpr -> IO a
evalWithDecoder (Proxy a -> RawJSType
forall a. FromJS a => Proxy a -> RawJSType
rawJSType (Proxy a
forall k (t :: k). Proxy t
Proxy @a)) Session -> ByteString -> IO a
forall a. FromJS a => Session -> ByteString -> IO a
fromJS Session
s (JSExpr -> IO a) -> JSExpr -> IO a
forall a b. (a -> b) -> a -> b
$
JSExpr
"((x, f) => (Boolean(x) && typeof x.then === 'function') ? x.then(f) : f(x))("
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> JSExpr
c
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> JSExpr
", "
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> Proxy a -> JSExpr
forall a. FromJS a => Proxy a -> JSExpr
toRawJSType (Proxy a
forall k (t :: k). Proxy t
Proxy @a)
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> JSExpr
")"
importCJS :: Session -> FilePath -> IO JSVal
importCJS :: Session -> FilePath -> IO JSVal
importCJS Session
s FilePath
p = do
FilePath
p' <- FilePath -> IO FilePath
makeAbsolute FilePath
p
Session -> JSExpr -> IO JSVal
forall a. FromJS a => Session -> JSExpr -> IO a
eval Session
s (JSExpr -> IO JSVal) -> JSExpr -> IO JSVal
forall a b. (a -> b) -> a -> b
$ JSExpr
"require(" JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> FilePath -> JSExpr
string FilePath
p' JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> JSExpr
")"
importMJS :: Session -> FilePath -> IO JSVal
importMJS :: Session -> FilePath -> IO JSVal
importMJS Session
s FilePath
p = do
FilePath
p' <- FilePath -> IO FilePath
makeAbsolute FilePath
p
Session -> JSExpr -> IO JSVal
forall a. FromJS a => Session -> JSExpr -> IO a
eval Session
s (JSExpr -> IO JSVal) -> JSExpr -> IO JSVal
forall a b. (a -> b) -> a -> b
$
JSExpr
"import('url').then(url => import(url.pathToFileURL("
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> FilePath -> JSExpr
string FilePath
p'
JSExpr -> JSExpr -> JSExpr
forall a. Semigroup a => a -> a -> a
<> JSExpr
")))"
string :: String -> JSExpr
string :: FilePath -> JSExpr
string = EncodedString -> JSExpr
forall a. ToJS a => a -> JSExpr
toJS (EncodedString -> JSExpr)
-> (FilePath -> EncodedString) -> FilePath -> JSExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> EncodedString
EncodedString (ByteString -> EncodedString)
-> (FilePath -> ByteString) -> FilePath -> EncodedString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ByteString
stringToLBS
exportAsyncOrSync :: forall f. Export f => Bool -> Session -> f -> IO JSVal
exportAsyncOrSync :: Bool -> Session -> f -> IO JSVal
exportAsyncOrSync Bool
_is_sync _session :: Session
_session@Session {IO ()
TMVar (Either SomeException ByteString)
IPC
killSession :: IO ()
closeSession :: IO ()
fatalErrorInbox :: TMVar (Either SomeException ByteString)
ipc :: IPC
killSession :: Session -> IO ()
closeSession :: Session -> IO ()
fatalErrorInbox :: Session -> TMVar (Either SomeException ByteString)
ipc :: Session -> IPC
..} f
f = do
TMVar (Either SomeException ByteString)
_inbox <- IO (TMVar (Either SomeException ByteString))
forall a. IO (TMVar a)
newEmptyTMVarIO
let args_type :: [(JSExpr, RawJSType)]
args_type =
(Dict FromJS -> (JSExpr, RawJSType))
-> [Dict FromJS] -> [(JSExpr, RawJSType)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Dict Proxy a
p) -> (Proxy a -> JSExpr
forall a. FromJS a => Proxy a -> JSExpr
toRawJSType Proxy a
p, Proxy a -> RawJSType
forall a. FromJS a => Proxy a -> RawJSType
rawJSType Proxy a
p)) ([Dict FromJS] -> [(JSExpr, RawJSType)])
-> [Dict FromJS] -> [(JSExpr, RawJSType)]
forall a b. (a -> b) -> a -> b
$
Proxy f -> [Dict FromJS]
forall f. Export f => Proxy f -> [Dict FromJS]
exportArgsFromJS (Proxy f
forall k (t :: k). Proxy t
Proxy @f)
f' :: [ByteString] -> IO JSExpr
f' = Session -> f -> [ByteString] -> IO JSExpr
forall f. Export f => Session -> f -> [ByteString] -> IO JSExpr
exportMonomorphize Session
_session f
f
StablePtr (TMVar (Either SomeException ByteString))
_sp_inbox <- TMVar (Either SomeException ByteString)
-> IO (StablePtr (TMVar (Either SomeException ByteString)))
forall a. a -> IO (StablePtr a)
newStablePtr TMVar (Either SomeException ByteString)
_inbox
StablePtr ([ByteString] -> IO JSExpr)
_sp_f <- ([ByteString] -> IO JSExpr)
-> IO (StablePtr ([ByteString] -> IO JSExpr))
forall a. a -> IO (StablePtr a)
newStablePtr [ByteString] -> IO JSExpr
f'
let _id_inbox :: Word64
_id_inbox = StablePtr (TMVar (Either SomeException ByteString)) -> Word64
forall a. StablePtr a -> Word64
word64FromStablePtr StablePtr (TMVar (Either SomeException ByteString))
_sp_inbox
_id_f :: Word64
_id_f = StablePtr ([ByteString] -> IO JSExpr) -> Word64
forall a. StablePtr a -> Word64
word64FromStablePtr StablePtr ([ByteString] -> IO JSExpr)
_sp_f
Session -> MessageHS -> IO ()
sessionSend
Session
_session
HSExportRequest :: Bool -> Word64 -> Word64 -> [(JSExpr, RawJSType)] -> MessageHS
HSExportRequest
{ exportIsSync :: Bool
exportIsSync = Bool
_is_sync,
exportRequestId :: Word64
exportRequestId = Word64
_id_inbox,
exportFuncId :: Word64
exportFuncId = Word64
_id_f,
argsType :: [(JSExpr, RawJSType)]
argsType = [(JSExpr, RawJSType)]
args_type
}
IO JSVal -> IO JSVal
forall a. IO a -> IO a
unsafeInterleaveIO (IO JSVal -> IO JSVal) -> IO JSVal -> IO JSVal
forall a b. (a -> b) -> a -> b
$ do
Either SomeException ByteString
_resp <- STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString)
forall a. STM a -> IO a
atomically (STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString))
-> STM (Either SomeException ByteString)
-> IO (Either SomeException ByteString)
forall a b. (a -> b) -> a -> b
$ TMVar (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. TMVar a -> STM a
takeTMVar TMVar (Either SomeException ByteString)
_inbox STM (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. STM a -> STM a -> STM a
`orElse` TMVar (Either SomeException ByteString)
-> STM (Either SomeException ByteString)
forall a. TMVar a -> STM a
readTMVar TMVar (Either SomeException ByteString)
fatalErrorInbox
StablePtr (TMVar (Either SomeException ByteString)) -> IO ()
forall a. StablePtr a -> IO ()
freeStablePtr StablePtr (TMVar (Either SomeException ByteString))
_sp_inbox
case Either SomeException ByteString
_resp of
Left SomeException
err -> SomeException -> IO JSVal
forall e a. Exception e => e -> IO a
throwIO SomeException
err
Right ByteString
_jsval_id_buf -> do
Word64
_jsval_id <- Get Word64 -> ByteString -> IO Word64
forall a. Typeable a => Get a -> ByteString -> IO a
runGetExact Get Word64
getWord64host ByteString
_jsval_id_buf
Bool -> Word64 -> IO () -> IO JSVal
newJSVal Bool
False Word64
_jsval_id (IO () -> IO JSVal) -> IO () -> IO JSVal
forall a b. (a -> b) -> a -> b
$ do
StablePtr ([ByteString] -> IO JSExpr) -> IO ()
forall a. StablePtr a -> IO ()
freeStablePtr StablePtr ([ByteString] -> IO JSExpr)
_sp_f
Session -> MessageHS -> IO ()
sessionSend Session
_session (MessageHS -> IO ()) -> MessageHS -> IO ()
forall a b. (a -> b) -> a -> b
$ Word64 -> MessageHS
JSValFree Word64
_jsval_id
export :: Export f => Session -> f -> IO JSVal
export :: Session -> f -> IO JSVal
export = Bool -> Session -> f -> IO JSVal
forall f. Export f => Bool -> Session -> f -> IO JSVal
exportAsyncOrSync Bool
False
exportSync :: Export f => Session -> f -> IO JSVal
exportSync :: Session -> f -> IO JSVal
exportSync = Bool -> Session -> f -> IO JSVal
forall f. Export f => Bool -> Session -> f -> IO JSVal
exportAsyncOrSync Bool
True