universalisos/guests/wasm3-app/main.c

121 lines
3.6 KiB
C

#include <stdint.h>
#include <stddef.h>
#include "wasm3.h"
/* POSIX ABI declarations */
extern int posix_read(int fd, void *buf, size_t count);
extern int posix_write(int fd, const void *buf, size_t count);
extern int posix_open(const char *pathname, int flags, int mode);
extern int posix_close(int fd);
extern int posix_yield(void);
extern void posix_exit(int status);
extern int posix_getpid(void);
/* Wasm3 WASI-like / Env wrapper for posix_write */
m3ApiRawFunction(m3_posix_write) {
m3ApiReturnType(int32_t)
m3ApiGetArg(int32_t, fd)
m3ApiGetArgMem(const void*, buf)
m3ApiGetArg(int32_t, count)
int32_t res = posix_write(fd, buf, count);
m3ApiReturn(res);
}
m3ApiRawFunction(m3_posix_read) {
m3ApiReturnType(int32_t)
m3ApiGetArg(int32_t, fd)
m3ApiGetArgMem(void*, buf)
m3ApiGetArg(int32_t, count)
int32_t res = posix_read(fd, buf, count);
m3ApiReturn(res);
}
m3ApiRawFunction(m3_posix_exit) {
m3ApiGetArg(int32_t, status)
posix_exit(status);
m3ApiTrap(m3Err_trapExit);
}
#define WASM_MEM_SIZE 65536
extern const uint8_t hello_wasm[];
extern const uint32_t hello_wasm_len;
int main() {
posix_write(1, "WASM Runtime Booting...\n", 24);
IM3Environment env = m3_NewEnvironment();
if (!env) {
posix_write(1, "m3_NewEnvironment failed\n", 25);
posix_exit(1);
}
IM3Runtime runtime = m3_NewRuntime(env, WASM_MEM_SIZE, NULL);
if (!runtime) {
posix_write(1, "m3_NewRuntime failed\n", 21);
posix_exit(1);
}
IM3Module module;
M3Result result = m3_ParseModule(env, &module, hello_wasm, hello_wasm_len);
if (result) {
posix_write(1, "m3_ParseModule failed\n", 22);
posix_exit(1);
}
result = m3_LoadModule(runtime, module);
if (result) {
posix_write(1, "m3_LoadModule failed\n", 21);
posix_exit(1);
}
/* Link POSIX imports */
result = m3_LinkRawFunction(module, "env", "write", "i(iii)", &m3_posix_write);
if (result) {
posix_write(1, "Link write failed: ", 19);
int l = 0; while (result[l]) l++;
posix_write(1, result, l); posix_write(1, "\n", 1);
}
result = m3_LinkRawFunction(module, "env", "read", "i(iii)", &m3_posix_read);
if (result) {
posix_write(1, "Link read failed: ", 18);
int l = 0; while (result[l]) l++;
posix_write(1, result, l); posix_write(1, "\n", 1);
}
result = m3_LinkRawFunction(module, "env", "exit", "v(i)", &m3_posix_exit);
if (result) {
posix_write(1, "Link exit failed: ", 18);
int l = 0; while (result[l]) l++;
posix_write(1, result, l); posix_write(1, "\n", 1);
}
/* Also link the WASI variants in case the module was compiled with WASI sdk */
m3_LinkRawFunction(module, "wasi_snapshot_preview1", "fd_write", "i(iii)", &m3_posix_write);
/* For a true WASI fd_write, the signature and struct are different, but for a simple hello module we might hand-compile it or just use 'env' */
IM3Function f;
result = m3_FindFunction(&f, runtime, "_start");
if (!result) {
posix_write(1, "Running _start...\n", 18);
result = m3_CallV(f);
if (result) {
posix_write(1, "Execution failed\n", 17);
} else {
posix_write(1, "Execution finished\n", 19);
}
} else {
posix_write(1, "Function _start not found: ", 27);
// result is a string
const char *err = result;
int errlen = 0;
while (err[errlen]) errlen++;
posix_write(1, err, errlen);
posix_write(1, "\n", 1);
}
posix_exit(0);
return 0;
}