mirror of
https://github.com/anoma/juvix.git
synced 2024-12-15 01:52:11 +03:00
433e882189
* Export all functions with alphanum names in entrypoint Set the export_name attribute on every function signature that has a fully alpha numeric name. * Adds a non-WASI target to compile command WASM libraries we want to run in the browser and in Anoma VM do not have access to the WASI runtime. For this usecase we need a target runtime that does not use the WASI runtime. A `wasi-` prefix is added to existing compile targets and introduce a new standalone target. This target does not have IO functions like `putStrLn` and `exit` calls `__builtin_trap` which corresponds to the `unreachable` WASM instruction. In the non-exhaustive case error a debug message is emitted to tell the user which function had the error. This is now abstracted to a `debug` function in the runtime which calls `putStrLn` in the case of WASI and is no-op in the case of non-WASI. Tests are added which check that exported names can be called with the correct name and result. * Moves walloc to a common directory
159 lines
4.8 KiB
Haskell
159 lines
4.8 KiB
Haskell
module BackendC.Base where
|
|
|
|
import Base
|
|
import Data.FileEmbed
|
|
import Data.Text.IO qualified as TIO
|
|
import Juvix.Pipeline
|
|
import Juvix.Translation.MicroJuvixToMiniC as MiniC
|
|
import System.IO.Extra (withTempDir)
|
|
import System.Process qualified as P
|
|
|
|
clangCompile ::
|
|
(FilePath -> FilePath -> [String]) ->
|
|
MiniC.MiniCResult ->
|
|
(FilePath -> IO Text) ->
|
|
(String -> IO ()) ->
|
|
IO Text
|
|
clangCompile mkClangArgs cResult execute step =
|
|
withTempDir
|
|
( \dirPath -> do
|
|
let cOutputFile = dirPath </> "out.c"
|
|
wasmOutputFile = dirPath </> "out.wasm"
|
|
TIO.writeFile cOutputFile (cResult ^. MiniC.resultCCode)
|
|
step "WASM generation"
|
|
P.callProcess
|
|
"clang"
|
|
(mkClangArgs wasmOutputFile cOutputFile)
|
|
step "WASM execution"
|
|
execute wasmOutputFile
|
|
)
|
|
|
|
wasmClangAssertion :: WASMInfo -> FilePath -> FilePath -> ((String -> IO ()) -> Assertion)
|
|
wasmClangAssertion WASMInfo {..} mainFile expectedFile step = do
|
|
step "Check clang and wasmer are on path"
|
|
assertCmdExists "clang"
|
|
assertCmdExists "wasmer"
|
|
|
|
step "C Generation"
|
|
let entryPoint = defaultEntryPoint mainFile
|
|
p :: MiniC.MiniCResult <- runIO (upToMiniC entryPoint)
|
|
|
|
expected <- TIO.readFile expectedFile
|
|
|
|
let execute :: FilePath -> IO Text
|
|
execute outputFile =
|
|
pack
|
|
<$> P.readProcess
|
|
"wasmer"
|
|
(["run", outputFile, "--invoke", unpack _wasmInfoFunctionName] <> (unpack <$> _wasmInfoFunctionArgs))
|
|
""
|
|
|
|
step "Compile C with wasm standalone runtime"
|
|
actualStandalone <- clangCompile standaloneArgs p execute step
|
|
step "Compare expected and actual program output"
|
|
assertEqDiff ("Check: WASM output = " <> expectedFile) actualStandalone expected
|
|
|
|
wasiClangAssertion :: StdlibMode -> FilePath -> FilePath -> Text -> ((String -> IO ()) -> Assertion)
|
|
wasiClangAssertion stdlibMode mainFile expectedFile stdinText step = do
|
|
step "Check clang and wasmer are on path"
|
|
assertCmdExists "clang"
|
|
assertCmdExists "wasmer"
|
|
|
|
step "Lookup WASI_SYSROOT_PATH"
|
|
sysrootPath <-
|
|
assertEnvVar
|
|
"Env var WASI_SYSROOT_PATH missing. Set to the location of the wasi-clib sysroot"
|
|
"WASI_SYSROOT_PATH"
|
|
|
|
step "C Generation"
|
|
let entryPoint = (defaultEntryPoint mainFile) {_entryPointNoStdlib = stdlibMode == StdlibExclude}
|
|
p :: MiniC.MiniCResult <- runIO (upToMiniC entryPoint)
|
|
|
|
expected <- TIO.readFile expectedFile
|
|
|
|
let execute :: FilePath -> IO Text
|
|
execute outputFile = pack <$> P.readProcess "wasmer" [outputFile] (unpack stdinText)
|
|
|
|
step "Compile C with standalone runtime"
|
|
actualStandalone <- clangCompile (wasiStandaloneArgs sysrootPath) p execute step
|
|
step "Compare expected and actual program output"
|
|
assertEqDiff ("check: WASM output = " <> expectedFile) actualStandalone expected
|
|
|
|
step "Compile C with libc runtime"
|
|
actualLibc <- clangCompile (libcArgs sysrootPath) p execute step
|
|
step "Compare expected and actual program output"
|
|
assertEqDiff ("check: WASM output = " <> expectedFile) actualLibc expected
|
|
|
|
builtinRuntime :: FilePath
|
|
builtinRuntime = $(makeRelativeToProject "minic-runtime/builtins" >>= strToExp)
|
|
|
|
standaloneArgs :: FilePath -> FilePath -> [String]
|
|
standaloneArgs wasmOutputFile cOutputFile =
|
|
[ "-nodefaultlibs",
|
|
"-std=c99",
|
|
"-Oz",
|
|
"-I",
|
|
takeDirectory minicRuntime,
|
|
"-I",
|
|
builtinRuntime,
|
|
"-Werror",
|
|
"--target=wasm32",
|
|
"-nostartfiles",
|
|
"-Wl,--no-entry",
|
|
"-o",
|
|
wasmOutputFile,
|
|
wallocPath,
|
|
cOutputFile
|
|
]
|
|
where
|
|
minicRuntime :: FilePath
|
|
minicRuntime = $(makeRelativeToProject "minic-runtime/standalone/minic-runtime.h" >>= strToExp)
|
|
wallocPath :: FilePath
|
|
wallocPath = $(makeRelativeToProject "minic-runtime/walloc/walloc.c" >>= strToExp)
|
|
|
|
wasiStandaloneArgs :: FilePath -> FilePath -> FilePath -> [String]
|
|
wasiStandaloneArgs sysrootPath wasmOutputFile cOutputFile =
|
|
[ "-nodefaultlibs",
|
|
"-std=c99",
|
|
"-Oz",
|
|
"-I",
|
|
takeDirectory minicRuntime,
|
|
"-I",
|
|
builtinRuntime,
|
|
"-Werror",
|
|
"--target=wasm32-wasi",
|
|
"--sysroot",
|
|
sysrootPath,
|
|
"-o",
|
|
wasmOutputFile,
|
|
wallocPath,
|
|
cOutputFile
|
|
]
|
|
where
|
|
minicRuntime :: FilePath
|
|
minicRuntime = $(makeRelativeToProject "minic-runtime/wasi-standalone/minic-runtime.h" >>= strToExp)
|
|
wallocPath :: FilePath
|
|
wallocPath = $(makeRelativeToProject "minic-runtime/walloc/walloc.c" >>= strToExp)
|
|
|
|
libcArgs :: FilePath -> FilePath -> FilePath -> [String]
|
|
libcArgs sysrootPath wasmOutputFile cOutputFile =
|
|
[ "-nodefaultlibs",
|
|
"-std=c99",
|
|
"-Oz",
|
|
"-I",
|
|
takeDirectory minicRuntime,
|
|
"-I",
|
|
builtinRuntime,
|
|
"-Werror",
|
|
"-lc",
|
|
"--target=wasm32-wasi",
|
|
"--sysroot",
|
|
sysrootPath,
|
|
"-o",
|
|
wasmOutputFile,
|
|
cOutputFile
|
|
]
|
|
where
|
|
minicRuntime :: FilePath
|
|
minicRuntime = $(makeRelativeToProject "minic-runtime/wasi-libc/minic-runtime.h" >>= strToExp)
|