Use userdata for WASI context. Test Simple WASI on multiple platforms.

#189
extensions
Volodymyr Shymanskyy 4 years ago
parent 05e18653c2
commit 66094b585d

@ -16,6 +16,10 @@ jobs:
- {target: clang-x86, cc: clang, flags: -DCMAKE_C_FLAGS="-m32", install: "gcc-multilib" }
- {target: gcc, cc: gcc, }
- {target: gcc-debug, cc: gcc, flags: -DCMAKE_BUILD_TYPE=Debug }
# Builds without uvwasi
- {target: gcc-no-uvwasi, cc: gcc, flags: -DBUILD_WASI=simple }
- {target: clang-no-uvwasi, cc: clang, flags: -DBUILD_WASI=simple }
# TODO: fails on numeric operations
#- {target: gcc-x86, cc: gcc, flags: "-m32", install: "gcc-multilib" }
@ -63,15 +67,23 @@ jobs:
build-mac:
runs-on: macos-latest
name: build-mac-${{ matrix.config.target }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
config:
- {target: uvwasi, }
- {target: no-uvwasi, flags: -DBUILD_WASI=simple }
steps:
- uses: actions/checkout@v2
- name: Configure
run: |
mkdir build
cd build
cmake ..
cmake ${{ matrix.config.flags }} ..
- name: Build
run: |
cmake --build build
@ -93,6 +105,11 @@ jobs:
- {target: msvc-x64, platform: "-A x64", toolset: "" }
- {target: clang-x86, platform: "-A Win32", toolset: "-T ClangCL" }
- {target: msvc-x86, platform: "-A Win32", toolset: "" }
# Builds without uvwasi
- {target: clang-x64-no-uvwasi, platform: "-A x64", toolset: "-T ClangCL", flags: "-DBUILD_WASI=simple" }
- {target: msvc-x64-no-uvwasi, platform: "-A x64", toolset: "", flags: "-DBUILD_WASI=simple" }
- {target: clang-x86-no-uvwasi, platform: "-A Win32", toolset: "-T ClangCL", flags: "-DBUILD_WASI=simple" }
- {target: msvc-x86-no-uvwasi, platform: "-A Win32", toolset: "", flags: "-DBUILD_WASI=simple" }
steps:
- uses: actions/checkout@v2
@ -100,7 +117,7 @@ jobs:
run: |
mkdir build
cd build
cmake ${{ matrix.config.platform }} ${{ matrix.config.toolset }} ..
cmake ${{ matrix.config.platform }} ${{ matrix.config.toolset }} ${{ matrix.config.flags }} ..
- name: Build
run: |
cmake --build build --config Release

@ -316,14 +316,18 @@ int main (int i_argc, const char* i_argv[])
if (argFunc and not argRepl) {
if (!strcmp(argFunc, "_start")) {
m3_wasi_context_t* wasi_ctx = m3_GetWasiContext();
// When passing args to WASI, include wasm filename as argv[0]
result = repl_call(runtime, argFunc, i_argc+1, i_argv-1);
wasi_ctx->argc = i_argc+1;
wasi_ctx->argv = i_argv-1;
result = repl_call(runtime, argFunc, 0, NULL);
if (result == m3Err_trapExit) {
return wasi_ctx->exit_code;
}
} else {
result = repl_call(runtime, argFunc, i_argc, i_argv);
}
if (result == m3Err_trapExit) {
return runtime->exit_code;
}
if (result) {
if (argDumpOnTrap) {
repl_dump(runtime);
@ -358,7 +362,7 @@ int main (int i_argc, const char* i_argv[])
result = repl_load(runtime, argv[1]);
} else if (!strcmp(":load-hex", argv[0])) { // :load-hex <size>\n <hex-encoded-binary>
result = repl_load_hex(runtime, atol(argv[1]));
} else if (!strcmp(":dump", argv[0])) { // :load <filename>
} else if (!strcmp(":dump", argv[0])) {
result = repl_dump(runtime);
} else if (argv[0][0] == ':') {
result = "no such command";
@ -372,10 +376,10 @@ int main (int i_argc, const char* i_argv[])
M3ErrorInfo info;
m3_GetErrorInfo (runtime, &info);
fprintf (stderr, " (%s)\n", info.message);
if (result == m3Err_trapExit) {
//TODO: if (result == m3Err_trapExit) {
// warn that exit was called
fprintf(stderr, M3_ARCH "-wasi: exit(%d)\n", runtime->exit_code);
}
// fprintf(stderr, M3_ARCH "-wasi: exit(%d)\n", runtime->exit_code);
//}
}
}

@ -27,7 +27,8 @@
extern char** environ;
#endif
uvwasi_t uvwasi;
static m3_wasi_context_t* wasi_context;
static uvwasi_t uvwasi;
typedef struct wasi_iovec_t
{
@ -45,14 +46,16 @@ m3ApiRawFunction(m3_wasi_unstable_args_get)
m3ApiGetArgMem (uint32_t * , argv)
m3ApiGetArgMem (char * , argv_buf)
if (runtime == NULL) { m3ApiReturn(UVWASI_EINVAL); }
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
for (u32 i = 0; i < runtime->argc; ++i)
if (context == NULL) { m3ApiReturn(UVWASI_EINVAL); }
for (u32 i = 0; i < context->argc; ++i)
{
m3ApiWriteMem32(&argv[i], m3ApiPtrToOffset(argv_buf));
size_t len = strlen (runtime->argv[i]);
memcpy (argv_buf, runtime->argv[i], len);
size_t len = strlen (context->argv[i]);
memcpy (argv_buf, context->argv[i], len);
argv_buf += len;
* argv_buf++ = 0;
}
@ -66,15 +69,17 @@ m3ApiRawFunction(m3_wasi_unstable_args_sizes_get)
m3ApiGetArgMem (uvwasi_size_t * , argc)
m3ApiGetArgMem (uvwasi_size_t * , argv_buf_size)
if (runtime == NULL) { m3ApiReturn(UVWASI_EINVAL); }
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
if (context == NULL) { m3ApiReturn(UVWASI_EINVAL); }
uvwasi_size_t buflen = 0;
for (u32 i = 0; i < runtime->argc; ++i)
for (u32 i = 0; i < context->argc; ++i)
{
buflen += strlen (runtime->argv[i]) + 1;
buflen += strlen (context->argv[i]) + 1;
}
m3ApiWriteMem32(argc, runtime->argc);
m3ApiWriteMem32(argc, context->argc);
m3ApiWriteMem32(argv_buf_size, buflen);
m3ApiReturn(UVWASI_ESUCCESS);
@ -428,7 +433,11 @@ m3ApiRawFunction(m3_wasi_unstable_proc_exit)
{
m3ApiGetArg (uint32_t, code)
runtime->exit_code = code;
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
if (context) {
context->exit_code = code;
}
m3ApiTrap(m3Err_trapExit);
}
@ -443,6 +452,11 @@ M3Result SuppressLookupFailure(M3Result i_result)
return i_result;
}
m3_wasi_context_t* m3_GetWasiContext()
{
return wasi_context;
}
M3Result m3_LinkWASI (IM3Module module)
{
@ -482,6 +496,11 @@ M3Result m3_LinkWASI (IM3Module module)
return "uvwasi_init failed";
}
wasi_context = (m3_wasi_context_t*)malloc(sizeof(m3_wasi_context_t));
wasi_context->exit_code = 0;
wasi_context->argc = 0;
wasi_context->argv = 0;
static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" };
// fd_seek is incompatible
@ -492,8 +511,8 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, "wasi_snapshot_preview1"
{
const char* wasi = namespaces[i];
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get, wasi_context)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get, wasi_context)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_unstable_clock_res_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(iI*)", &m3_wasi_unstable_clock_time_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_unstable_environ_get)));
@ -533,7 +552,7 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open",
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_unlink_file", "i(i*i)", )));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "poll_oneoff", "i(**i*)", &m3_wasi_unstable_poll_oneoff)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit, wasi_context)));
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_raise", "i(i)", )));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_unstable_random_get)));
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sched_yield", "i()", )));

@ -53,6 +53,8 @@
# define close _close
#endif
static m3_wasi_context_t* wasi_context;
typedef struct wasi_iovec_t
{
__wasi_size_t buf;
@ -187,14 +189,16 @@ m3ApiRawFunction(m3_wasi_unstable_args_get)
m3ApiGetArgMem (uint32_t * , argv)
m3ApiGetArgMem (char * , argv_buf)
if (runtime == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
if (context == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
for (u32 i = 0; i < runtime->argc; ++i)
for (u32 i = 0; i < context->argc; ++i)
{
m3ApiWriteMem32(&argv[i], m3ApiPtrToOffset(argv_buf));
size_t len = strlen (runtime->argv[i]);
memcpy (argv_buf, runtime->argv[i], len);
size_t len = strlen (context->argv[i]);
memcpy (argv_buf, context->argv[i], len);
argv_buf += len;
* argv_buf++ = 0;
}
@ -208,15 +212,17 @@ m3ApiRawFunction(m3_wasi_unstable_args_sizes_get)
m3ApiGetArgMem (__wasi_size_t * , argc)
m3ApiGetArgMem (__wasi_size_t * , argv_buf_size)
if (runtime == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
if (context == NULL) { m3ApiReturn(__WASI_ERRNO_INVAL); }
__wasi_size_t buflen = 0;
for (u32 i = 0; i < runtime->argc; ++i)
for (u32 i = 0; i < context->argc; ++i)
{
buflen += strlen (runtime->argv[i]) + 1;
buflen += strlen (context->argv[i]) + 1;
}
m3ApiWriteMem32(argc, runtime->argc);
m3ApiWriteMem32(argc, context->argc);
m3ApiWriteMem32(argv_buf_size, buflen);
m3ApiReturn(__WASI_ERRNO_SUCCESS);
@ -630,7 +636,11 @@ m3ApiRawFunction(m3_wasi_unstable_proc_exit)
{
m3ApiGetArg (uint32_t, code)
runtime->exit_code = code;
m3_wasi_context_t* context = (m3_wasi_context_t*)userdata;
if (context) {
context->exit_code = code;
}
m3ApiTrap(m3Err_trapExit);
}
@ -645,6 +655,11 @@ M3Result SuppressLookupFailure(M3Result i_result)
return i_result;
}
m3_wasi_context_t* m3_GetWasiContext()
{
return wasi_context;
}
M3Result m3_LinkWASI (IM3Module module)
{
@ -662,14 +677,19 @@ M3Result m3_LinkWASI (IM3Module module)
}
#endif
wasi_context = (m3_wasi_context_t*)malloc(sizeof(m3_wasi_context_t));
wasi_context->exit_code = 0;
wasi_context->argc = 0;
wasi_context->argv = 0;
static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" };
for (int i=0; i<2; i++)
{
const char* wasi = namespaces[i];
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get, wasi_context)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get, wasi_context)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_unstable_clock_res_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(iI*)", &m3_wasi_unstable_clock_time_get)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_unstable_environ_get)));
@ -709,7 +729,7 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open",
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_unlink_file", "i(i*i)", )));
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "poll_oneoff", "i(**i*)", &m3_wasi_unstable_poll_oneoff)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit)));
_ (SuppressLookupFailure (m3_LinkRawFunctionEx (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit, wasi_context)));
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_raise", "i(i)", )));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_unstable_random_get)));
//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sched_yield", "i()", )));

@ -12,8 +12,17 @@
d_m3BeginExternC
typedef struct m3_wasi_context_t
{
i32 exit_code;
u32 argc;
ccstr_t * argv;
} m3_wasi_context_t;
M3Result m3_LinkWASI (IM3Module io_module);
m3_wasi_context_t* m3_GetWasiContext();
d_m3EndExternC
#endif // m3_api_wasi_h

@ -748,10 +748,6 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char
IM3Module module = i_function->module;
IM3Runtime runtime = module->runtime;
runtime->argc = i_argc;
runtime->argv = i_argv;
if (i_function->name and strcmp (i_function->name, "_start") == 0) // WASI
i_argc = 0;
IM3FuncType ftype = i_function->funcType; m3log (runtime, "calling %s", SPrintFuncTypeSignature (ftype));
@ -821,60 +817,6 @@ _ ((M3Result) Call (i_function->compiled, (m3stack_t) stack, runtime->memo
_catch: return result;
}
#if 0
M3Result m3_CallMain (IM3Function i_function, uint32_t i_argc, const char * const * i_argv)
{
M3Result result = m3Err_none;
if (i_function->compiled)
{
IM3Module module = i_function->module;
IM3Runtime runtime = module->runtime;
u8 * linearMemory = runtime->memory.wasmPages;
m3stack_t stack = (m3stack_t) runtime->stack;
if (i_argc)
{
IM3Memory memory = & runtime->memory;
// FIX: memory allocation in general
i32 offset = AllocatePrivateHeap (memory, sizeof (i32) * i_argc);
i32 * pointers = (i32 *) (memory->wasmPages + offset);
for (u32 i = 0; i < i_argc; ++i)
{
size_t argLength = strlen (i_argv [i]) + 1;
if (argLength < 4000)
{
i32 o = AllocatePrivateHeap (memory, (i32) argLength);
memcpy (memory->wasmPages + o, i_argv [i], argLength);
* pointers++ = o;
}
else _throw ("insane argument string length");
}
stack [0] = i_argc;
stack [1] = offset;
}
_ ((M3Result)Call (i_function->compiled, stack, linearMemory, d_m3OpDefaultArgs));
//u64 value = * (u64 *) (stack);
//m3log (runtime, "return64: % " PRIu64 " return32: %" PRIu32, value, (u32) value);
}
else _throw (m3Err_missingCompiledCode);
_catch: return result;
}
#endif
void ReleaseCodePageNoTrack (IM3Runtime i_runtime, IM3CodePage i_codePage)
{
if (i_codePage)

@ -220,10 +220,6 @@ typedef struct M3Runtime
u32 stackSize;
u32 numStackSlots;
i32 exit_code;
u32 argc;
ccstr_t * argv;
void * userdata;
M3Memory memory;

@ -190,7 +190,7 @@ d_m3ErrorConst (trapStackOverflow, "[trap] stack overflow")
const char * const i_moduleName,
const char * const i_functionName,
const char * const i_signature,
M3RawCall i_function);
M3RawCall i_function);
M3Result m3_LinkRawFunctionEx (IM3Module io_module,
const char * const i_moduleName,

Loading…
Cancel
Save