{-# LANGUAGE CPP #-} {-# LANGUAGE RecordWildCards #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Runtime.Interpreter.Wasm (spawnWasmInterp) where import GHC.Prelude import GHC.Runtime.Interpreter.Types #if !defined(mingw32_HOST_OS) import Control.Concurrent.MVar import Data.Maybe import GHC.Data.FastString import qualified GHC.Data.ShortText as ST import GHC.Platform import GHC.Unit import GHCi.Message import System.Directory import System.Environment.Blank import System.IO import qualified System.Posix.IO as Posix import System.Process #else import GHC.Utils.Panic #endif spawnWasmInterp :: WasmInterpConfig -> IO (ExtInterpInstance ()) #if !defined(mingw32_HOST_OS) -- See Note [The Wasm Dynamic Linker] for details spawnWasmInterp WasmInterpConfig {..} = do let Just ghci_unit_id = lookupPackageName wasmInterpUnitState (PackageName $ fsLit "ghci") ghci_unit_info = unsafeLookupUnitId wasmInterpUnitState ghci_unit_id ghci_so_dirs = map ST.unpack $ unitLibraryDynDirs ghci_unit_info [ghci_lib_name] = map ST.unpack $ unitLibraries ghci_unit_info ghci_so_name = ghci_lib_name ++ wasmInterpHsSoSuffix ghci_so_file = platformHsSOName wasmInterpTargetPlatform ghci_so_name Just ghci_so_path <- findFile ghci_so_dirs ghci_so_file (rfd1, wfd1) <- Posix.createPipe (rfd2, wfd2) <- Posix.createPipe Posix.setFdOption rfd1 Posix.CloseOnExec True Posix.setFdOption wfd2 Posix.CloseOnExec True ghc_env <- getEnvironment let dyld_env = [("GHCI_BROWSER", "1") | wasmInterpBrowser] ++ [("GHCI_BROWSER_HOST", wasmInterpBrowserHost), ("GHCI_BROWSER_PORT", show wasmInterpBrowserPort)] ++ [("GHCI_BROWSER_REDIRECT_WASI_CONSOLE", "1") | wasmInterpBrowserRedirectWasiConsole] ++ [("GHCI_BROWSER_PUPPETEER_LAUNCH_OPTS", f) | f <- maybeToList wasmInterpBrowserPuppeteerLaunchOpts] ++ [("GHCI_BROWSER_PLAYWRIGHT_BROWSER_TYPE", f) | f <- maybeToList wasmInterpBrowserPlaywrightBrowserType] ++ [("GHCI_BROWSER_PLAYWRIGHT_LAUNCH_OPTS", f) | f <- maybeToList wasmInterpBrowserPlaywrightLaunchOpts] ++ ghc_env (_, _, _, ph) <- createProcess ( proc wasmInterpDyLD $ [wasmInterpLibDir, ghci_so_path, show wfd1, show rfd2] ++ wasmInterpOpts ++ ["+RTS", "-H64m", "-RTS"] ) { env = Just dyld_env } Posix.closeFd wfd1 Posix.closeFd rfd2 rh <- Posix.fdToHandle rfd1 wh <- Posix.fdToHandle wfd2 hSetBuffering wh NoBuffering hSetBuffering rh NoBuffering interpPipe <- mkPipeFromHandles rh wh pending_frees <- newMVar [] lock <- newMVar () pure $ ExtInterpInstance { instProcess = InterpProcess { interpHandle = ph, interpPipe, interpLock = lock }, instPendingFrees = pending_frees, instExtra = () } #else -- Due to difficulty of using inherited pipe file descriptor in -- nodejs, unfortunately we don't support Win32 host yet spawnWasmInterp _ = sorry "Wasm iserv doesn't work on Win32 host yet" #endif