From bd54c432efcce64608bcdddabe72dc34a9d45ae7 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 7 Aug 2024 22:03:33 +0900 Subject: [PATCH 01/12] add hello_multi_memory.wat --- wat/wasi/hello_multi_memory.wat | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wat/wasi/hello_multi_memory.wat diff --git a/wat/wasi/hello_multi_memory.wat b/wat/wasi/hello_multi_memory.wat new file mode 100644 index 00000000..a6a0ae46 --- /dev/null +++ b/wat/wasi/hello_multi_memory.wat @@ -0,0 +1,22 @@ +;; print hello, using the secondary linear memory + +(module + (func $fd_write (import "wasi_snapshot_preview1" "fd_write") (param i32 i32 i32 i32) (result i32)) + (func $proc_exit (import "wasi_snapshot_preview1" "proc_exit") (param i32)) + (func (export "_start") + i32.const 1 + i32.const 0 + i32.const 1 + i32.const 0 + call $fd_write + i32.const 0 + i32.ne + call $proc_exit + ) + (memory (export "default") 0) ;; not used + (memory (export "memory") 1) ;; wasi should use this one + + ;; iov_base = 0x100, iov_len = 6 + (data (memory 1) (i32.const 0) "\00\01\00\00\06\00\00\00") + (data (memory 1) (i32.const 0x100) "hello\n") +) From a4c05d4b251060f846dbda97702cba41b41c89ef Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 7 Aug 2024 23:01:28 +0900 Subject: [PATCH 02/12] Use the correct memory for host func Instead of assuming memory index 0, look up an export with the name "memory". --- lib/cconv.c | 30 +++++++++++++++++++++++++++ lib/cconv.h | 2 ++ lib/exec_context.h | 2 +- lib/host_instance.c | 43 +++++++++++++++++++-------------------- lib/host_instance.h | 10 ++++----- libdyld/dyld_dlfcn.c | 4 ++-- libwasi/wasi_abi_path.c | 2 +- libwasi/wasi_abi_poll.c | 6 +++--- libwasi/wasi_abi_random.c | 2 +- libwasi/wasi_subr.c | 8 ++++---- 10 files changed, 69 insertions(+), 40 deletions(-) diff --git a/lib/cconv.c b/lib/cconv.c index 2be557ff..5b9050df 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -3,6 +3,7 @@ * a part of core wasm. */ +#include "cconv.h" #include "exec.h" #include "instance.h" #include "module.h" @@ -11,6 +12,18 @@ static const struct name name_func_table = NAME_FROM_CSTR_LITERAL("__indirect_function_table"); +/* + * the export name "memory" is defined by wasi. + * https://github.com/WebAssembly/WASI/blob/main/legacy/README.md + * it's widely used for non-wasi interfaces as well. + * + * Note: some runtimes, including old versions of toywasm, assume + * the memidx 0 even for wasi. it would end up with some + * incompatibilities with multi-memory proposal. + */ +static const struct name name_default_memory = + NAME_FROM_CSTR_LITERAL("memory"); + /* * dereference a C function pointer. * that is, get the func inst pointed by the pointer. @@ -48,3 +61,20 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, *fip = func; return 0; } + +int +cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp) +{ + const struct module *m = ctx->instance->module; + int ret; + /* + * XXX searching exports on each call can be too slow. + */ + ret = module_find_export(m, &name_default_memory, EXTERNTYPE_MEMORY, + memidxp); + if (ret != 0) { + return trap_with_id(ctx, TRAP_DEFAULT_MEMORY_NOT_FOUND, + "default memory not found"); + } + return 0; +} diff --git a/lib/cconv.h b/lib/cconv.h index 4c9ebd40..6cfd0ae4 100644 --- a/lib/cconv.h +++ b/lib/cconv.h @@ -13,4 +13,6 @@ int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, uint32_t wasmfuncptr, const struct functype *ft, const struct funcinst **fip); +int cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp); + __END_EXTERN_C diff --git a/lib/exec_context.h b/lib/exec_context.h index 6d841ef2..cada2ee8 100644 --- a/lib/exec_context.h +++ b/lib/exec_context.h @@ -92,7 +92,7 @@ enum trapid { TRAP_UNCAUGHT_EXCEPTION, TRAP_THROW_REF_NULL, TRAP_UNRESOLVED_IMPORTED_FUNC, - TRAP_INVALID_MEMORY, + TRAP_DEFAULT_MEMORY_NOT_FOUND, }; enum exec_event { diff --git a/lib/host_instance.c b/lib/host_instance.c index 2dac7536..26dc51f8 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -4,6 +4,7 @@ #include #include +#include "cconv.h" #include "exec.h" #include "host_instance.h" #include "instance.h" @@ -159,13 +160,18 @@ int host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, size_t len, size_t align) { + uint32_t memidx; void *p; int ret; + ret = cconv_default_memory(ctx, &memidx); + if (ret != 0) { + return ret; + } ret = host_func_check_align(ctx, wasmaddr, align); if (ret != 0) { return ret; } - ret = memory_getptr(ctx, 0, wasmaddr, 0, len, &p); + ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p); if (ret != 0) { return ret; } @@ -177,13 +183,18 @@ int host_func_copyout(struct exec_context *ctx, const void *hostaddr, uint32_t wasmaddr, size_t len, size_t align) { + uint32_t memidx; void *p; int ret; + ret = cconv_default_memory(ctx, &memidx); + if (ret != 0) { + return ret; + } ret = host_func_check_align(ctx, wasmaddr, align); if (ret != 0) { return ret; } - ret = memory_getptr(ctx, 0, wasmaddr, 0, len, &p); + ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p); if (ret != 0) { return ret; } @@ -191,24 +202,12 @@ host_func_copyout(struct exec_context *ctx, const void *hostaddr, return 0; } -static int -check_memidx(struct exec_context *ctx, uint32_t memidx) -{ - const struct module *m = ctx->instance->module; - if (memidx < m->nmems + m->nimportedmems) { - return 0; - } - return trap_with_id( - ctx, TRAP_INVALID_MEMORY, - "access to invalid memidx %" PRIx32 " in a host call", memidx); -} - int -host_func_memory_getptr(struct exec_context *ctx, uint32_t memidx, - uint32_t ptr, uint32_t offset, uint32_t size, - void **pp) +host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset, + uint32_t size, void **pp) { - int ret = check_memidx(ctx, memidx); + uint32_t memidx; + int ret = cconv_default_memory(ctx, &memidx); if (ret != 0) { return ret; } @@ -216,11 +215,11 @@ host_func_memory_getptr(struct exec_context *ctx, uint32_t memidx, } int -host_func_memory_getptr2(struct exec_context *ctx, uint32_t memidx, - uint32_t ptr, uint32_t offset, uint32_t size, - void **pp, bool *movedp) +host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, + uint32_t size, void **pp, bool *movedp) { - int ret = check_memidx(ctx, memidx); + uint32_t memidx; + int ret = cconv_default_memory(ctx, &memidx); if (ret != 0) { return ret; } diff --git a/lib/host_instance.h b/lib/host_instance.h index 239495ee..4ece06fb 100644 --- a/lib/host_instance.h +++ b/lib/host_instance.h @@ -89,12 +89,10 @@ int host_func_copyout(struct exec_context *ctx, const void *hostaddr, uint32_t wasmaddr, size_t len, size_t align); int host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, size_t len, size_t align); -int host_func_memory_getptr(struct exec_context *ctx, uint32_t memidx, - uint32_t ptr, uint32_t offset, uint32_t size, - void **pp); -int host_func_memory_getptr2(struct exec_context *ctx, uint32_t memidx, - uint32_t ptr, uint32_t offset, uint32_t size, - void **pp, bool *movedp); +int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset, + uint32_t size, void **pp); +int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, + uint32_t size, void **pp, bool *movedp); int host_func_trap(struct exec_context *ctx, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3))); struct restart_info; diff --git a/libdyld/dyld_dlfcn.c b/libdyld/dyld_dlfcn.c index cf29bcb5..4388c5fc 100644 --- a/libdyld/dyld_dlfcn.c +++ b/libdyld/dyld_dlfcn.c @@ -75,7 +75,7 @@ dyld_dlfcn_load_object(struct exec_context *ctx, struct host_instance *hi, } void *vp; - ret = host_func_memory_getptr(ctx, 0, namep, 0, namelen, &vp); + ret = host_func_getptr(ctx, namep, 0, namelen, &vp); if (ret != 0) { user_ret = 1; goto fail; @@ -169,7 +169,7 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi, const struct dyld_dynamic_object *dobj = &VEC_ELEM(d->dynobjs, idx); void *vp; - ret = host_func_memory_getptr(ctx, 0, namep, 0, namelen, &vp); + ret = host_func_getptr(ctx, namep, 0, namelen, &vp); if (ret != 0) { user_ret = 1; goto fail; diff --git a/libwasi/wasi_abi_path.c b/libwasi/wasi_abi_path.c index 540ea804..effbed03 100644 --- a/libwasi/wasi_abi_path.c +++ b/libwasi/wasi_abi_path.c @@ -267,7 +267,7 @@ wasi_path_readlink(struct exec_context *ctx, struct host_instance *hi, * https://github.com/bytecodealliance/wasmtime/commit/24b607cf751930c51f2b6449cdfbf2e81dce1c31 */ void *p; - host_ret = host_func_memory_getptr(ctx, 0, buf, 0, buflen, &p); + host_ret = host_func_getptr(ctx, buf, 0, buflen, &p); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_abi_poll.c b/libwasi/wasi_abi_poll.c index c80c35e1..5b2c8a0f 100644 --- a/libwasi/wasi_abi_poll.c +++ b/libwasi/wasi_abi_poll.c @@ -4,6 +4,7 @@ #include #include +#include "cconv.h" #include "endian.h" #include "exec_context.h" #include "restart.h" @@ -51,7 +52,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = host_func_memory_getptr(ctx, 0, in, 0, insize, &p); + host_ret = host_func_getptr(ctx, in, 0, insize, &p); if (host_ret != 0) { goto fail; } @@ -62,8 +63,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = - host_func_memory_getptr2(ctx, 0, out, 0, outsize, &p, &moved); + host_ret = host_func_getptr2(ctx, out, 0, outsize, &p, &moved); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_abi_random.c b/libwasi/wasi_abi_random.c index 5894afd5..1c89c791 100644 --- a/libwasi/wasi_abi_random.c +++ b/libwasi/wasi_abi_random.c @@ -29,7 +29,7 @@ wasi_random_get(struct exec_context *ctx, struct host_instance *hi, uint32_t buflen = HOST_FUNC_PARAM(ft, params, 1, i32); int ret = 0; void *p; - int host_ret = host_func_memory_getptr(ctx, 0, buf, 0, buflen, &p); + int host_ret = host_func_getptr(ctx, buf, 0, buflen, &p); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_subr.c b/libwasi/wasi_subr.c index bb80ecdc..3f75b03f 100644 --- a/libwasi/wasi_subr.c +++ b/libwasi/wasi_subr.c @@ -80,8 +80,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, if (host_ret != 0) { goto fail; } - host_ret = host_func_memory_getptr( - ctx, 0, iov_uaddr, 0, iov_count * sizeof(struct wasi_iov), &p); + host_ret = host_func_getptr(ctx, iov_uaddr, 0, + iov_count * sizeof(struct wasi_iov), &p); if (host_ret != 0) { goto fail; } @@ -93,8 +93,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, uint32_t iov_len = le32_decode(&iov_in_module[i].iov_len); xlog_trace("iov [%" PRIu32 "] base %" PRIx32 " len %" PRIu32, i, iov_base, iov_len); - host_ret = host_func_memory_getptr2(ctx, 0, iov_base, 0, - iov_len, &p, &moved); + host_ret = host_func_getptr2(ctx, iov_base, 0, iov_len, &p, + &moved); if (host_ret != 0) { goto fail; } From 959a7dbc2798ddfff24dcf5193816f82e8b2339d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Aug 2024 02:00:46 +0900 Subject: [PATCH 03/12] host_instance.c: reduce code dup a bit --- lib/host_instance.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/lib/host_instance.c b/lib/host_instance.c index 26dc51f8..7dd53806 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -160,18 +160,13 @@ int host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, size_t len, size_t align) { - uint32_t memidx; void *p; int ret; - ret = cconv_default_memory(ctx, &memidx); - if (ret != 0) { - return ret; - } ret = host_func_check_align(ctx, wasmaddr, align); if (ret != 0) { return ret; } - ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p); + ret = host_func_getptr(ctx, wasmaddr, 0, len, &p); if (ret != 0) { return ret; } @@ -183,18 +178,13 @@ int host_func_copyout(struct exec_context *ctx, const void *hostaddr, uint32_t wasmaddr, size_t len, size_t align) { - uint32_t memidx; void *p; int ret; - ret = cconv_default_memory(ctx, &memidx); - if (ret != 0) { - return ret; - } ret = host_func_check_align(ctx, wasmaddr, align); if (ret != 0) { return ret; } - ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p); + ret = host_func_getptr(ctx, wasmaddr, 0, len, &p); if (ret != 0) { return ret; } @@ -206,12 +196,7 @@ int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset, uint32_t size, void **pp) { - uint32_t memidx; - int ret = cconv_default_memory(ctx, &memidx); - if (ret != 0) { - return ret; - } - return memory_getptr(ctx, memidx, ptr, offset, size, pp); + return host_func_getptr2(ctx, ptr, offset, size, pp, NULL); } int From 4480dccd40ee6e521dedd62673f696a0f25e27f9 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Aug 2024 02:05:46 +0900 Subject: [PATCH 04/12] cconv_default_memory: add an explicit instance argument to be consistent with cconv_deref_func_ptr --- lib/cconv.c | 5 +++-- lib/cconv.h | 3 ++- lib/host_instance.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/cconv.c b/lib/cconv.c index 5b9050df..0f24c3b6 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -63,9 +63,10 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, } int -cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp) +cconv_default_memory(struct exec_context *ctx, const struct instance *inst, + uint32_t *memidxp) { - const struct module *m = ctx->instance->module; + const struct module *m = inst->module; int ret; /* * XXX searching exports on each call can be too slow. diff --git a/lib/cconv.h b/lib/cconv.h index 6cfd0ae4..ea221c3e 100644 --- a/lib/cconv.h +++ b/lib/cconv.h @@ -13,6 +13,7 @@ int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, uint32_t wasmfuncptr, const struct functype *ft, const struct funcinst **fip); -int cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp); +int cconv_default_memory(struct exec_context *ctx, const struct instance *inst, + uint32_t *memidxp); __END_EXTERN_C diff --git a/lib/host_instance.c b/lib/host_instance.c index 7dd53806..04bef8d5 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -204,7 +204,7 @@ host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, uint32_t size, void **pp, bool *movedp) { uint32_t memidx; - int ret = cconv_default_memory(ctx, &memidx); + int ret = cconv_default_memory(ctx, ctx->instance, &memidx); if (ret != 0) { return ret; } From 73efa97acd2b663492069587dbda927131308f7f Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Aug 2024 02:16:18 +0900 Subject: [PATCH 05/12] host_func_getptr2: use meminst, not memidx to prepare for other strategies to pick a memory to use. --- lib/cconv.c | 6 ++++-- lib/cconv.h | 3 ++- lib/host_instance.c | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/cconv.c b/lib/cconv.c index 0f24c3b6..43daef2b 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -64,18 +64,20 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, int cconv_default_memory(struct exec_context *ctx, const struct instance *inst, - uint32_t *memidxp) + struct meminst **mip) { const struct module *m = inst->module; + uint32_t memidx; int ret; /* * XXX searching exports on each call can be too slow. */ ret = module_find_export(m, &name_default_memory, EXTERNTYPE_MEMORY, - memidxp); + &memidx); if (ret != 0) { return trap_with_id(ctx, TRAP_DEFAULT_MEMORY_NOT_FOUND, "default memory not found"); } + *mip = VEC_ELEM(inst->mems, memidx); return 0; } diff --git a/lib/cconv.h b/lib/cconv.h index ea221c3e..f22eb8d2 100644 --- a/lib/cconv.h +++ b/lib/cconv.h @@ -6,6 +6,7 @@ struct exec_context; struct instance; struct functype; struct funcinst; +struct meminst; __BEGIN_EXTERN_C @@ -14,6 +15,6 @@ int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, const struct funcinst **fip); int cconv_default_memory(struct exec_context *ctx, const struct instance *inst, - uint32_t *memidxp); + struct meminst **mip); __END_EXTERN_C diff --git a/lib/host_instance.c b/lib/host_instance.c index 04bef8d5..5b5bbfa4 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -203,12 +203,23 @@ int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, uint32_t size, void **pp, bool *movedp) { - uint32_t memidx; - int ret = cconv_default_memory(ctx, ctx->instance, &memidx); + struct meminst *meminst; + int ret = cconv_default_memory(ctx, ctx->instance, &meminst); if (ret != 0) { return ret; } - return memory_getptr2(ctx, memidx, ptr, offset, size, pp, movedp); + ret = memory_instance_getptr2(meminst, ptr, offset, size, pp, movedp); + if (ret == ETOYWASMTRAP) { + ret = trap_with_id( + ctx, TRAP_OUT_OF_BOUNDS_MEMORY_ACCESS, + "host function invalid memory access at %08" PRIx32 + " + %08" PRIx32 ", size %" PRIu32 + ", meminst size %" PRIu32 ", pagesize %" PRIu32, + ptr, offset, size, meminst->size_in_pages, + 1 << memtype_page_shift(meminst->type)); + assert(ret != 0); + } + return ret; } int From 5c8e2f77dcd91e9154389789cc99da8ca50f98ce Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Aug 2024 02:25:44 +0900 Subject: [PATCH 06/12] host_func_getptr/host_func_getptr2: remove offset argument there are no foreseeable users. let's simplify. --- lib/host_instance.c | 22 +++++++++++----------- lib/host_instance.h | 8 ++++---- libdyld/dyld_dlfcn.c | 4 ++-- libwasi/wasi_abi_path.c | 2 +- libwasi/wasi_abi_poll.c | 4 ++-- libwasi/wasi_abi_random.c | 2 +- libwasi/wasi_subr.c | 6 +++--- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/host_instance.c b/lib/host_instance.c index 5b5bbfa4..9f784035 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -166,7 +166,7 @@ host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, if (ret != 0) { return ret; } - ret = host_func_getptr(ctx, wasmaddr, 0, len, &p); + ret = host_func_getptr(ctx, wasmaddr, len, &p); if (ret != 0) { return ret; } @@ -184,7 +184,7 @@ host_func_copyout(struct exec_context *ctx, const void *hostaddr, if (ret != 0) { return ret; } - ret = host_func_getptr(ctx, wasmaddr, 0, len, &p); + ret = host_func_getptr(ctx, wasmaddr, len, &p); if (ret != 0) { return ret; } @@ -193,29 +193,29 @@ host_func_copyout(struct exec_context *ctx, const void *hostaddr, } int -host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset, - uint32_t size, void **pp) +host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t size, + void **pp) { - return host_func_getptr2(ctx, ptr, offset, size, pp, NULL); + return host_func_getptr2(ctx, ptr, size, pp, NULL); } int -host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, - uint32_t size, void **pp, bool *movedp) +host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t size, + void **pp, bool *movedp) { struct meminst *meminst; int ret = cconv_default_memory(ctx, ctx->instance, &meminst); if (ret != 0) { return ret; } - ret = memory_instance_getptr2(meminst, ptr, offset, size, pp, movedp); + ret = memory_instance_getptr2(meminst, ptr, 0, size, pp, movedp); if (ret == ETOYWASMTRAP) { ret = trap_with_id( ctx, TRAP_OUT_OF_BOUNDS_MEMORY_ACCESS, "host function invalid memory access at %08" PRIx32 - " + %08" PRIx32 ", size %" PRIu32 - ", meminst size %" PRIu32 ", pagesize %" PRIu32, - ptr, offset, size, meminst->size_in_pages, + ", size %" PRIu32 ", meminst size %" PRIu32 + ", pagesize %" PRIu32, + ptr, size, meminst->size_in_pages, 1 << memtype_page_shift(meminst->type)); assert(ret != 0); } diff --git a/lib/host_instance.h b/lib/host_instance.h index 4ece06fb..69b0c677 100644 --- a/lib/host_instance.h +++ b/lib/host_instance.h @@ -89,10 +89,10 @@ int host_func_copyout(struct exec_context *ctx, const void *hostaddr, uint32_t wasmaddr, size_t len, size_t align); int host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, size_t len, size_t align); -int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset, - uint32_t size, void **pp); -int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset, - uint32_t size, void **pp, bool *movedp); +int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t size, + void **pp); +int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t size, + void **pp, bool *movedp); int host_func_trap(struct exec_context *ctx, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3))); struct restart_info; diff --git a/libdyld/dyld_dlfcn.c b/libdyld/dyld_dlfcn.c index 4388c5fc..f5a7a25d 100644 --- a/libdyld/dyld_dlfcn.c +++ b/libdyld/dyld_dlfcn.c @@ -75,7 +75,7 @@ dyld_dlfcn_load_object(struct exec_context *ctx, struct host_instance *hi, } void *vp; - ret = host_func_getptr(ctx, namep, 0, namelen, &vp); + ret = host_func_getptr(ctx, namep, namelen, &vp); if (ret != 0) { user_ret = 1; goto fail; @@ -169,7 +169,7 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi, const struct dyld_dynamic_object *dobj = &VEC_ELEM(d->dynobjs, idx); void *vp; - ret = host_func_getptr(ctx, namep, 0, namelen, &vp); + ret = host_func_getptr(ctx, namep, namelen, &vp); if (ret != 0) { user_ret = 1; goto fail; diff --git a/libwasi/wasi_abi_path.c b/libwasi/wasi_abi_path.c index effbed03..08c20ef2 100644 --- a/libwasi/wasi_abi_path.c +++ b/libwasi/wasi_abi_path.c @@ -267,7 +267,7 @@ wasi_path_readlink(struct exec_context *ctx, struct host_instance *hi, * https://github.com/bytecodealliance/wasmtime/commit/24b607cf751930c51f2b6449cdfbf2e81dce1c31 */ void *p; - host_ret = host_func_getptr(ctx, buf, 0, buflen, &p); + host_ret = host_func_getptr(ctx, buf, buflen, &p); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_abi_poll.c b/libwasi/wasi_abi_poll.c index 5b2c8a0f..d26c7047 100644 --- a/libwasi/wasi_abi_poll.c +++ b/libwasi/wasi_abi_poll.c @@ -52,7 +52,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr(ctx, in, 0, insize, &p); + host_ret = host_func_getptr(ctx, in, insize, &p); if (host_ret != 0) { goto fail; } @@ -63,7 +63,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr2(ctx, out, 0, outsize, &p, &moved); + host_ret = host_func_getptr2(ctx, out, outsize, &p, &moved); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_abi_random.c b/libwasi/wasi_abi_random.c index 1c89c791..e1035434 100644 --- a/libwasi/wasi_abi_random.c +++ b/libwasi/wasi_abi_random.c @@ -29,7 +29,7 @@ wasi_random_get(struct exec_context *ctx, struct host_instance *hi, uint32_t buflen = HOST_FUNC_PARAM(ft, params, 1, i32); int ret = 0; void *p; - int host_ret = host_func_getptr(ctx, buf, 0, buflen, &p); + int host_ret = host_func_getptr(ctx, buf, buflen, &p); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_subr.c b/libwasi/wasi_subr.c index 3f75b03f..98413663 100644 --- a/libwasi/wasi_subr.c +++ b/libwasi/wasi_subr.c @@ -80,7 +80,7 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr(ctx, iov_uaddr, 0, + host_ret = host_func_getptr(ctx, iov_uaddr, iov_count * sizeof(struct wasi_iov), &p); if (host_ret != 0) { goto fail; @@ -93,8 +93,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, uint32_t iov_len = le32_decode(&iov_in_module[i].iov_len); xlog_trace("iov [%" PRIu32 "] base %" PRIx32 " len %" PRIu32, i, iov_base, iov_len); - host_ret = host_func_getptr2(ctx, iov_base, 0, iov_len, &p, - &moved); + host_ret = + host_func_getptr2(ctx, iov_base, iov_len, &p, &moved); if (host_ret != 0) { goto fail; } From bcbd0ad3f682cb35930040c1ea7e89c728985911 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Aug 2024 23:44:37 +0900 Subject: [PATCH 07/12] host_instance.c: take a meminst explicity --- cli/repl.c | 6 ++++ lib/cconv.c | 11 +++----- lib/cconv.h | 3 +- lib/host_instance.c | 42 +++++++++++++++------------- lib/host_instance.h | 20 +++++++------ libwasi/wasi.c | 6 ++++ libwasi/wasi.h | 2 ++ libwasi/wasi_abi_clock.c | 10 ++++--- libwasi/wasi_abi_environ.c | 12 ++++---- libwasi/wasi_abi_fd.c | 57 +++++++++++++++++++++++--------------- libwasi/wasi_abi_path.c | 20 +++++++------ libwasi/wasi_abi_poll.c | 9 +++--- libwasi/wasi_abi_prestat.c | 7 +++-- libwasi/wasi_abi_random.c | 4 ++- libwasi/wasi_abi_sock.c | 20 ++++++++----- libwasi/wasi_impl.h | 7 +++-- libwasi/wasi_path_subr.c | 3 +- libwasi/wasi_subr.c | 11 ++++---- libwasi/wasi_subr.h | 7 +++-- 19 files changed, 151 insertions(+), 106 deletions(-) diff --git a/cli/repl.c b/cli/repl.c index fea1d51d..548ec83f 100644 --- a/cli/repl.c +++ b/cli/repl.c @@ -20,6 +20,7 @@ #include #include +#include "cconv.h" #include "endian.h" #include "exec_context.h" #include "exec_debug.h" @@ -680,6 +681,11 @@ repl_load_from_buf(struct repl_state *state, const char *modname, report_clear(&report); goto fail; } +#if defined(TOYWASM_ENABLE_WASI) + if (state->wasi != NULL) { + wasi_instance_set_memory(state->wasi, cconv_default_memory(mod->inst)); + } +#endif ret = repl_exec_init(state, mod, trap_ok); if (ret != 0) { xlog_printf("repl_exec_init failed\n"); diff --git a/lib/cconv.c b/lib/cconv.c index 43daef2b..f56b3903 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -62,9 +62,8 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, return 0; } -int -cconv_default_memory(struct exec_context *ctx, const struct instance *inst, - struct meminst **mip) +struct meminst * +cconv_default_memory(const struct instance *inst) { const struct module *m = inst->module; uint32_t memidx; @@ -75,9 +74,7 @@ cconv_default_memory(struct exec_context *ctx, const struct instance *inst, ret = module_find_export(m, &name_default_memory, EXTERNTYPE_MEMORY, &memidx); if (ret != 0) { - return trap_with_id(ctx, TRAP_DEFAULT_MEMORY_NOT_FOUND, - "default memory not found"); + return NULL; } - *mip = VEC_ELEM(inst->mems, memidx); - return 0; + return VEC_ELEM(inst->mems, memidx); } diff --git a/lib/cconv.h b/lib/cconv.h index f22eb8d2..00587163 100644 --- a/lib/cconv.h +++ b/lib/cconv.h @@ -14,7 +14,6 @@ int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, uint32_t wasmfuncptr, const struct functype *ft, const struct funcinst **fip); -int cconv_default_memory(struct exec_context *ctx, const struct instance *inst, - struct meminst **mip); +struct meminst *cconv_default_memory(const struct instance *inst); __END_EXTERN_C diff --git a/lib/host_instance.c b/lib/host_instance.c index 9f784035..890904b4 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -157,8 +157,8 @@ host_func_check_align(struct exec_context *ctx, uint32_t wasmaddr, } int -host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, - size_t len, size_t align) +host_func_copyin(struct exec_context *ctx, struct meminst *mem, void *hostaddr, + uint32_t wasmaddr, size_t len, size_t align) { void *p; int ret; @@ -166,7 +166,7 @@ host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, if (ret != 0) { return ret; } - ret = host_func_getptr(ctx, wasmaddr, len, &p); + ret = host_func_getptr(ctx, mem, wasmaddr, len, &p); if (ret != 0) { return ret; } @@ -175,8 +175,9 @@ host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr, } int -host_func_copyout(struct exec_context *ctx, const void *hostaddr, - uint32_t wasmaddr, size_t len, size_t align) +host_func_copyout(struct exec_context *ctx, struct meminst *mem, + const void *hostaddr, uint32_t wasmaddr, size_t len, + size_t align) { void *p; int ret; @@ -184,7 +185,7 @@ host_func_copyout(struct exec_context *ctx, const void *hostaddr, if (ret != 0) { return ret; } - ret = host_func_getptr(ctx, wasmaddr, len, &p); + ret = host_func_getptr(ctx, mem, wasmaddr, len, &p); if (ret != 0) { return ret; } @@ -193,31 +194,32 @@ host_func_copyout(struct exec_context *ctx, const void *hostaddr, } int -host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t size, - void **pp) +host_func_getptr(struct exec_context *ctx, struct meminst *mem, uint32_t ptr, + uint32_t size, void **pp) { - return host_func_getptr2(ctx, ptr, size, pp, NULL); + return host_func_getptr2(ctx, mem, ptr, size, pp, NULL); } int -host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t size, - void **pp, bool *movedp) +host_func_getptr2(struct exec_context *ctx, struct meminst *mem, uint32_t ptr, + uint32_t size, void **pp, bool *movedp) { - struct meminst *meminst; - int ret = cconv_default_memory(ctx, ctx->instance, &meminst); - if (ret != 0) { - return ret; + if (mem == NULL) { + return trap_with_id( + ctx, TRAP_OUT_OF_BOUNDS_MEMORY_ACCESS, + "host function invalid memory access at %08" PRIx32 + ", size %" PRIu32 ", no memory", + ptr, size); } - ret = memory_instance_getptr2(meminst, ptr, 0, size, pp, movedp); + int ret = memory_instance_getptr2(mem, ptr, 0, size, pp, movedp); if (ret == ETOYWASMTRAP) { - ret = trap_with_id( + return trap_with_id( ctx, TRAP_OUT_OF_BOUNDS_MEMORY_ACCESS, "host function invalid memory access at %08" PRIx32 ", size %" PRIu32 ", meminst size %" PRIu32 ", pagesize %" PRIu32, - ptr, size, meminst->size_in_pages, - 1 << memtype_page_shift(meminst->type)); - assert(ret != 0); + ptr, size, mem->size_in_pages, + 1 << memtype_page_shift(mem->type)); } return ret; } diff --git a/lib/host_instance.h b/lib/host_instance.h index 69b0c677..53e2ef03 100644 --- a/lib/host_instance.h +++ b/lib/host_instance.h @@ -63,7 +63,7 @@ struct host_func { #endif struct host_instance { - struct mem_context *mctx; + int dummy; }; struct host_module { @@ -85,14 +85,16 @@ void host_func_dump_params(const struct functype *ft, const struct cell *params); int host_func_check_align(struct exec_context *ctx, uint32_t wasmaddr, size_t align); -int host_func_copyout(struct exec_context *ctx, const void *hostaddr, - uint32_t wasmaddr, size_t len, size_t align); -int host_func_copyin(struct exec_context *ctx, void *hostaddr, - uint32_t wasmaddr, size_t len, size_t align); -int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t size, - void **pp); -int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t size, - void **pp, bool *movedp); +int host_func_copyout(struct exec_context *ctx, struct meminst *mem, + const void *hostaddr, uint32_t wasmaddr, size_t len, + size_t align); +int host_func_copyin(struct exec_context *ctx, struct meminst *mem, + void *hostaddr, uint32_t wasmaddr, size_t len, + size_t align); +int host_func_getptr(struct exec_context *ctx, struct meminst *mem, + uint32_t ptr, uint32_t size, void **pp); +int host_func_getptr2(struct exec_context *ctx, struct meminst *mem, + uint32_t ptr, uint32_t size, void **pp, bool *movedp); int host_func_trap(struct exec_context *ctx, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3))); struct restart_info; diff --git a/libwasi/wasi.c b/libwasi/wasi.c index ebfc5bc5..9632ed30 100644 --- a/libwasi/wasi.c +++ b/libwasi/wasi.c @@ -181,6 +181,12 @@ wasi_instance_create(struct mem_context *mctx, return 0; } +void +wasi_instance_set_memory(struct wasi_instance *inst, struct meminst *mem) +{ + inst->memory = mem; +} + void wasi_instance_set_args(struct wasi_instance *inst, int argc, const char *const *argv) diff --git a/libwasi/wasi.h b/libwasi/wasi.h index 5e6fcf04..7deda7fc 100644 --- a/libwasi/wasi.h +++ b/libwasi/wasi.h @@ -3,6 +3,7 @@ struct wasi_instance; struct import_object; struct mem_context; +struct meminst; __BEGIN_EXTERN_C @@ -18,6 +19,7 @@ __BEGIN_EXTERN_C int wasi_instance_create(struct mem_context *mctx, struct wasi_instance **instp); +void wasi_instance_set_memory(struct wasi_instance *inst, struct meminst *mem); void wasi_instance_set_args(struct wasi_instance *inst, int argc, const char *const *argv); void wasi_instance_set_environ(struct wasi_instance *inst, int nenvs, diff --git a/libwasi/wasi_abi_clock.c b/libwasi/wasi_abi_clock.c index 455d0e4e..97ec14fa 100644 --- a/libwasi/wasi_abi_clock.c +++ b/libwasi/wasi_abi_clock.c @@ -17,6 +17,7 @@ wasi_clock_res_get(struct exec_context *ctx, struct host_instance *hi, struct cell *results) { WASI_TRACE; + struct wasi_instance *wasi = (void *)hi; HOST_FUNC_CONVERT_PARAMS(ft, params); uint32_t clockid = HOST_FUNC_PARAM(ft, params, 0, i32); uint32_t retp = HOST_FUNC_PARAM(ft, params, 1, i32); @@ -35,8 +36,8 @@ wasi_clock_res_get(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint64_t result = host_to_le64(timespec_to_ns(&ts)); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U64_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U64_ALIGN); fail: if (host_ret == 0) { HOST_FUNC_RESULT_SET(ft, results, 0, i32, @@ -52,6 +53,7 @@ wasi_clock_time_get(struct exec_context *ctx, struct host_instance *hi, struct cell *results) { WASI_TRACE; + struct wasi_instance *wasi = (void *)hi; HOST_FUNC_CONVERT_PARAMS(ft, params); uint32_t clockid = HOST_FUNC_PARAM(ft, params, 0, i32); #if 0 /* REVISIT what to do with the precision? */ @@ -73,8 +75,8 @@ wasi_clock_time_get(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint64_t result = host_to_le64(timespec_to_ns(&ts)); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U64_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U64_ALIGN); fail: if (host_ret == 0) { HOST_FUNC_RESULT_SET(ft, results, 0, i32, diff --git a/libwasi/wasi_abi_environ.c b/libwasi/wasi_abi_environ.c index 3ca4d5e1..b8995482 100644 --- a/libwasi/wasi_abi_environ.c +++ b/libwasi/wasi_abi_environ.c @@ -19,8 +19,8 @@ args_environ_sizes_get(struct exec_context *ctx, struct wasi_instance *wasi, uint32_t argv_buf_sizep = HOST_FUNC_PARAM(ft, params, 1, i32); int host_ret; uint32_t argc_le32 = host_to_le32(argc); - host_ret = wasi_copyout(ctx, &argc_le32, argcp, sizeof(argc_le32), - WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &argc_le32, argcp, + sizeof(argc_le32), WASI_U32_ALIGN); if (host_ret != 0) { goto fail; } @@ -30,8 +30,8 @@ args_environ_sizes_get(struct exec_context *ctx, struct wasi_instance *wasi, argv_buf_size += strlen(argv[i]) + 1; } argv_buf_size = host_to_le32(argv_buf_size); - host_ret = wasi_copyout(ctx, &argv_buf_size, argv_buf_sizep, - sizeof(argv_buf_size), 1); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &argv_buf_size, + argv_buf_sizep, sizeof(argv_buf_size), 1); fail: if (host_ret == 0) { int ret = 0; /* never fail */ @@ -69,13 +69,13 @@ args_environ_get(struct exec_context *ctx, struct wasi_instance *wasi, } for (i = 0; i < argc; i++) { size_t sz = strlen(argv[i]) + 1; - host_ret = wasi_copyout(ctx, argv[i], + host_ret = wasi_copyout(ctx, wasi_memory(wasi), argv[i], le32_to_host(wasm_argv[i]), sz, 1); if (host_ret != 0) { goto fail; } } - host_ret = wasi_copyout(ctx, wasm_argv, argvp, + host_ret = wasi_copyout(ctx, wasi_memory(wasi), wasm_argv, argvp, argc * sizeof(*wasm_argv), WASI_U32_ALIGN); fail: free(wasm_argv); diff --git a/libwasi/wasi_abi_fd.c b/libwasi/wasi_abi_fd.c index 237c3468..bd51d640 100644 --- a/libwasi/wasi_abi_fd.c +++ b/libwasi/wasi_abi_fd.c @@ -191,7 +191,8 @@ wasi_fd_write(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -210,7 +211,8 @@ wasi_fd_write(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); ret = 0; fail: wasi_fdinfo_release(wasi, fdinfo); @@ -248,7 +250,8 @@ wasi_fd_pwrite(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -267,7 +270,8 @@ wasi_fd_pwrite(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); ret = 0; fail: wasi_fdinfo_release(wasi, fdinfo); @@ -304,7 +308,8 @@ wasi_fd_read(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -340,7 +345,8 @@ wasi_fd_read(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); ret = 0; fail: wasi_fdinfo_release(wasi, fdinfo); @@ -378,7 +384,8 @@ wasi_fd_pread(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -397,7 +404,8 @@ wasi_fd_pread(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); ret = 0; fail: wasi_fdinfo_release(wasi, fdinfo); @@ -476,7 +484,8 @@ wasi_fd_readdir(struct exec_context *ctx, struct host_instance *hi, break; } /* it's ok to return unaligned structure */ - host_ret = wasi_copyout(ctx, &wde, buf, sizeof(wde), 1); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &wde, buf, + sizeof(wde), 1); if (host_ret != 0) { goto fail; } @@ -488,7 +497,8 @@ wasi_fd_readdir(struct exec_context *ctx, struct host_instance *hi, n = buflen; /* signal buffer full */ break; } - host_ret = wasi_copyout(ctx, d_name, buf, namlen, 1); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), d_name, buf, + namlen, 1); if (host_ret != 0) { goto fail; } @@ -497,7 +507,8 @@ wasi_fd_readdir(struct exec_context *ctx, struct host_instance *hi, } toywasm_mutex_unlock(&wasi->lock); uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); fail_unlocked: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -611,8 +622,8 @@ wasi_fd_fdstat_get(struct exec_context *ctx, struct host_instance *hi, */ st.fs_rights_inheriting = ~UINT64_C(0); - host_ret = wasi_copyout(ctx, &st, stat_addr, sizeof(st), - WASI_FDSTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &st, stat_addr, + sizeof(st), WASI_FDSTAT_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -717,8 +728,8 @@ wasi_fd_seek(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint64_t result = host_to_le64(off); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U64_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U64_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -772,8 +783,8 @@ wasi_unstable_fd_seek(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint64_t result = host_to_le64(off); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U64_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U64_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -811,8 +822,8 @@ wasi_fd_tell(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint64_t result = host_to_le64(off); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U64_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U64_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -980,8 +991,8 @@ wasi_fd_filestat_get(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyout(ctx, &wst, retp, sizeof(wst), - WASI_FILESTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &wst, retp, + sizeof(wst), WASI_FILESTAT_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -1020,8 +1031,8 @@ wasi_unstable_fd_filestat_get(struct exec_context *ctx, if (ret != 0) { goto fail; } - host_ret = wasi_copyout(ctx, &uwst, retp, sizeof(uwst), - WASI_UNSTABLE_FILESTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &uwst, retp, + sizeof(uwst), WASI_UNSTABLE_FILESTAT_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { diff --git a/libwasi/wasi_abi_path.c b/libwasi/wasi_abi_path.c index 08c20ef2..aec91934 100644 --- a/libwasi/wasi_abi_path.c +++ b/libwasi/wasi_abi_path.c @@ -76,7 +76,8 @@ wasi_path_open(struct exec_context *ctx, struct host_instance *hi, fdinfo = NULL; xlog_trace("-> new wasi fd %" PRIu32, wasifd); uint32_t r = host_to_le32(wasifd); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); if (host_ret != 0) { /* XXX close wasifd? */ goto fail; @@ -209,7 +210,8 @@ wasi_path_symlink(struct exec_context *ctx, struct host_instance *hi, ret = ENOMEM; goto fail; } - host_ret = wasi_copyin(ctx, target_buf, target, targetlen, 1); + host_ret = wasi_copyin(ctx, wasi_memory(wasi), target_buf, target, + targetlen, 1); if (host_ret != 0) { goto fail; } @@ -267,7 +269,7 @@ wasi_path_readlink(struct exec_context *ctx, struct host_instance *hi, * https://github.com/bytecodealliance/wasmtime/commit/24b607cf751930c51f2b6449cdfbf2e81dce1c31 */ void *p; - host_ret = host_func_getptr(ctx, buf, buflen, &p); + host_ret = host_func_getptr(ctx, wasi_memory(wasi), buf, buflen, &p); if (host_ret != 0) { goto fail; } @@ -277,8 +279,8 @@ wasi_path_readlink(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t result = le32_to_host(n); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U32_ALIGN); if (host_ret != 0) { goto fail; } @@ -412,8 +414,8 @@ wasi_path_filestat_get(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyout(ctx, &wst, retp, sizeof(wst), - WASI_FILESTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &wst, retp, + sizeof(wst), WASI_FILESTAT_ALIGN); fail: path_clear(wasi, &pi); if (host_ret == 0) { @@ -461,8 +463,8 @@ wasi_unstable_path_filestat_get(struct exec_context *ctx, if (ret != 0) { goto fail; } - host_ret = wasi_copyout(ctx, &uwst, retp, sizeof(uwst), - WASI_UNSTABLE_FILESTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &uwst, retp, + sizeof(uwst), WASI_UNSTABLE_FILESTAT_ALIGN); fail: path_clear(wasi, &pi); if (host_ret == 0) { diff --git a/libwasi/wasi_abi_poll.c b/libwasi/wasi_abi_poll.c index d26c7047..cefba73b 100644 --- a/libwasi/wasi_abi_poll.c +++ b/libwasi/wasi_abi_poll.c @@ -52,7 +52,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr(ctx, in, insize, &p); + host_ret = host_func_getptr(ctx, wasi_memory(wasi), in, insize, &p); if (host_ret != 0) { goto fail; } @@ -63,7 +63,8 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr2(ctx, out, outsize, &p, &moved); + host_ret = host_func_getptr2(ctx, wasi_memory(wasi), out, outsize, &p, + &moved); if (host_ret != 0) { goto fail; } @@ -222,8 +223,8 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, } assert(events + nevents == ev); uint32_t result = host_to_le32(nevents); - host_ret = wasi_copyout(ctx, &result, retp, sizeof(result), - WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &result, retp, + sizeof(result), WASI_U32_ALIGN); ret = 0; fail: for (i = 0; i < nfdinfos; i++) { diff --git a/libwasi/wasi_abi_prestat.c b/libwasi/wasi_abi_prestat.c index 167a6045..d2b67f49 100644 --- a/libwasi/wasi_abi_prestat.c +++ b/libwasi/wasi_abi_prestat.c @@ -40,8 +40,8 @@ wasi_fd_prestat_get(struct exec_context *ctx, struct host_instance *hi, prestat_path = fdinfo_prestat->wasm_path; } st.dir_name_len = host_to_le32(strlen(prestat_path)); - host_ret = - wasi_copyout(ctx, &st, retp, sizeof(st), WASI_PRESTAT_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &st, retp, sizeof(st), + WASI_PRESTAT_ALIGN); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { @@ -89,7 +89,8 @@ wasi_fd_prestat_dir_name(struct exec_context *ctx, struct host_instance *hi, ret = EINVAL; goto fail; } - host_ret = wasi_copyout(ctx, prestat_path, path, len, 1); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), prestat_path, path, + len, 1); fail: wasi_fdinfo_release(wasi, fdinfo); if (host_ret == 0) { diff --git a/libwasi/wasi_abi_random.c b/libwasi/wasi_abi_random.c index e1035434..e77e8153 100644 --- a/libwasi/wasi_abi_random.c +++ b/libwasi/wasi_abi_random.c @@ -24,12 +24,14 @@ wasi_random_get(struct exec_context *ctx, struct host_instance *hi, struct cell *results) { WASI_TRACE; + struct wasi_instance *wasi = (void *)hi; HOST_FUNC_CONVERT_PARAMS(ft, params); uint32_t buf = HOST_FUNC_PARAM(ft, params, 0, i32); uint32_t buflen = HOST_FUNC_PARAM(ft, params, 1, i32); int ret = 0; void *p; - int host_ret = host_func_getptr(ctx, buf, buflen, &p); + int host_ret = + host_func_getptr(ctx, wasi_memory(wasi), buf, buflen, &p); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_abi_sock.c b/libwasi/wasi_abi_sock.c index 64dcca0e..c3c3fc84 100644 --- a/libwasi/wasi_abi_sock.c +++ b/libwasi/wasi_abi_sock.c @@ -103,7 +103,8 @@ wasi_sock_accept(struct exec_context *ctx, struct host_instance *hi, } hostchildfd = -1; uint32_t r = host_to_le32(wasichildfd); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); if (host_ret != 0) { /* XXX close wasichildfd? */ goto fail; @@ -170,7 +171,8 @@ wasi_sock_recv(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -216,13 +218,15 @@ wasi_sock_recv(struct exec_context *ctx, struct host_instance *hi, roflags = WASI_ROFLAG_RECV_DATA_TRUNCATED; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); if (host_ret != 0) { goto fail; } uint16_t roflags_wasm = host_to_le16(roflags); - host_ret = wasi_copyout(ctx, &roflags_wasm, roflagsp, - sizeof(roflags_wasm), WASI_U16_ALIGN); + host_ret = + wasi_copyout(ctx, wasi_memory(wasi), &roflags_wasm, roflagsp, + sizeof(roflags_wasm), WASI_U16_ALIGN); if (host_ret != 0) { goto fail; } @@ -268,7 +272,8 @@ wasi_sock_send(struct exec_context *ctx, struct host_instance *hi, if (ret != 0) { goto fail; } - host_ret = wasi_copyin_iovec(ctx, iov_addr, iov_count, &hostiov, &ret); + host_ret = wasi_copyin_iovec(ctx, wasi_memory(wasi), iov_addr, + iov_count, &hostiov, &ret); if (host_ret != 0 || ret != 0) { goto fail; } @@ -298,7 +303,8 @@ wasi_sock_send(struct exec_context *ctx, struct host_instance *hi, goto fail; } uint32_t r = host_to_le32(n); - host_ret = wasi_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + host_ret = wasi_copyout(ctx, wasi_memory(wasi), &r, retp, sizeof(r), + WASI_U32_ALIGN); ret = 0; fail: wasi_fdinfo_release(wasi, fdinfo); diff --git a/libwasi/wasi_impl.h b/libwasi/wasi_impl.h index 13460ba7..7984a78c 100644 --- a/libwasi/wasi_impl.h +++ b/libwasi/wasi_impl.h @@ -54,6 +54,8 @@ struct wasi_instance { struct wasi_table fdtable[WASI_NTABLES] GUARDED_VAR( lock); /* indexed by wasi fd */ + struct meminst *memory; + int argc; const char *const *argv; int nenvs; @@ -70,8 +72,9 @@ struct wasi_instance { uint32_t wasi_convert_errno(int host_errno); -#define wasi_copyout(c, h, w, l, a) host_func_copyout(c, h, w, l, a) -#define wasi_copyin(c, h, w, l, a) host_func_copyin(c, h, w, l, a) +#define wasi_copyout(c, m, h, w, l, a) host_func_copyout(c, m, h, w, l, a) +#define wasi_copyin(c, m, h, w, l, a) host_func_copyin(c, m, h, w, l, a) +#define wasi_memory(i) (i)->memory struct exec_context; struct wasi_instance; diff --git a/libwasi/wasi_path_subr.c b/libwasi/wasi_path_subr.c index e1cdd400..fb8ce503 100644 --- a/libwasi/wasi_path_subr.c +++ b/libwasi/wasi_path_subr.c @@ -43,7 +43,8 @@ wasi_copyin_and_convert_path(struct exec_context *ctx, ret = ENOMEM; goto fail; } - host_ret = wasi_copyin(ctx, wasmpath, path, pathlen, 1); + host_ret = wasi_copyin(ctx, wasi_memory(wasi), wasmpath, path, pathlen, + 1); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_subr.c b/libwasi/wasi_subr.c index 98413663..c45afb35 100644 --- a/libwasi/wasi_subr.c +++ b/libwasi/wasi_subr.c @@ -59,8 +59,9 @@ wasi_userfd_reject_directory(struct wasi_fdinfo *fdinfo) } int -wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, - uint32_t iov_count, struct iovec **resultp, int *usererrorp) +wasi_copyin_iovec(struct exec_context *ctx, struct meminst *mem, + uint32_t iov_uaddr, uint32_t iov_count, + struct iovec **resultp, int *usererrorp) { struct iovec *hostiov = NULL; void *p; @@ -80,7 +81,7 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, if (host_ret != 0) { goto fail; } - host_ret = host_func_getptr(ctx, iov_uaddr, + host_ret = host_func_getptr(ctx, mem, iov_uaddr, iov_count * sizeof(struct wasi_iov), &p); if (host_ret != 0) { goto fail; @@ -93,8 +94,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, uint32_t iov_len = le32_decode(&iov_in_module[i].iov_len); xlog_trace("iov [%" PRIu32 "] base %" PRIx32 " len %" PRIu32, i, iov_base, iov_len); - host_ret = - host_func_getptr2(ctx, iov_base, iov_len, &p, &moved); + host_ret = host_func_getptr2(ctx, mem, iov_base, iov_len, &p, + &moved); if (host_ret != 0) { goto fail; } diff --git a/libwasi/wasi_subr.h b/libwasi/wasi_subr.h index 7775c5e5..86e02c24 100644 --- a/libwasi/wasi_subr.h +++ b/libwasi/wasi_subr.h @@ -5,10 +5,11 @@ struct wasi_filestet; struct wasi_unstable_filestat; struct exec_context; struct iovec; +struct meminst; int wasi_unstable_convert_filestat(const struct wasi_filestat *wst, struct wasi_unstable_filestat *uwst); int wasi_userfd_reject_directory(struct wasi_fdinfo *fdinfo); -int wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr, - uint32_t iov_count, struct iovec **resultp, - int *usererrorp); +int wasi_copyin_iovec(struct exec_context *ctx, struct meminst *mem, + uint32_t iov_uaddr, uint32_t iov_count, + struct iovec **resultp, int *usererrorp); From 9188ec21f81e13f29fee522a2dc11abb81a963b5 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 10 Aug 2024 12:51:14 +0900 Subject: [PATCH 08/12] move the "memory" reference to host_instance maybe it's a bit clear to do: ``` struct host_instance_using_cconv { struct host_instance hi; struct meminst *mem; struct tableinst *func_table; } ``` but i didn't bother to do that right now. i might revisit later. also, do the same for the table as well. also, make the repl initialize them accordingly. (only for memory, just because wasi doesn't happen to use function pointers.) --- cli/repl.c | 21 +++++++++--- lib/cconv.c | 62 ++++++++++++++++++---------------- lib/cconv.h | 6 ++-- lib/host_instance.h | 6 +++- libwasi/wasi.c | 2 +- libwasi/wasi_impl.h | 4 +-- libwasi_threads/wasi_threads.c | 10 +++++- libwasi_threads/wasi_threads.h | 4 +++ 8 files changed, 73 insertions(+), 42 deletions(-) diff --git a/cli/repl.c b/cli/repl.c index 548ec83f..510e9a42 100644 --- a/cli/repl.c +++ b/cli/repl.c @@ -589,6 +589,21 @@ repl_exec_init(struct repl_state *state, struct repl_module_state *mod, return ret; } +static void +set_memory(struct repl_state *state, struct meminst *mem) +{ +#if defined(TOYWASM_ENABLE_WASI) + if (state->wasi != NULL) { + wasi_instance_set_memory(state->wasi, mem); + } +#if defined(TOYWASM_ENABLE_WASI_THREADS) + if (state->wasi_threads != NULL) { + wasi_threads_instance_set_memory(state->wasi_threads, mem); + } +#endif +#endif +} + static int repl_load_from_buf(struct repl_state *state, const char *modname, struct repl_module_state *mod, bool trap_ok) @@ -681,11 +696,7 @@ repl_load_from_buf(struct repl_state *state, const char *modname, report_clear(&report); goto fail; } -#if defined(TOYWASM_ENABLE_WASI) - if (state->wasi != NULL) { - wasi_instance_set_memory(state->wasi, cconv_default_memory(mod->inst)); - } -#endif + set_memory(state, cconv_memory(mod->inst)); ret = repl_exec_init(state, mod, trap_ok); if (ret != 0) { xlog_printf("repl_exec_init failed\n"); diff --git a/lib/cconv.c b/lib/cconv.c index f56b3903..5542b414 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -3,24 +3,27 @@ * a part of core wasm. */ +#include + #include "cconv.h" #include "exec.h" #include "instance.h" #include "module.h" #include "type.h" -static const struct name name_func_table = - NAME_FROM_CSTR_LITERAL("__indirect_function_table"); - /* - * the export name "memory" is defined by wasi. + * the export name "memory" and "__indirect_function_table" are + * defined by wasi. * https://github.com/WebAssembly/WASI/blob/main/legacy/README.md - * it's widely used for non-wasi interfaces as well. + * they are widely used for non-wasi interfaces as well. * * Note: some runtimes, including old versions of toywasm, assume * the memidx 0 even for wasi. it would end up with some * incompatibilities with multi-memory proposal. */ + +static const struct name name_func_table = + NAME_FROM_CSTR_LITERAL("__indirect_function_table"); static const struct name name_default_memory = NAME_FROM_CSTR_LITERAL("memory"); @@ -30,30 +33,18 @@ static const struct name name_default_memory = * raise a trap on an error. */ int -cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, +cconv_deref_func_ptr(struct exec_context *ctx, const struct tableinst *t, uint32_t wasmfuncptr, const struct functype *ft, const struct funcinst **fip) { - const struct module *m = inst->module; - uint32_t tableidx; - int ret; - /* - * XXX searching exports on each call can be too slow. - */ - ret = module_find_export(m, &name_func_table, EXTERNTYPE_TABLE, - &tableidx); - if (ret != 0) { -do_trap: + if (t == NULL) { return trap_with_id(ctx, TRAP_INDIRECT_FUNCTION_TABLE_NOT_FOUND, "__indirect_function_table is not found"); } - const struct tableinst *t = VEC_ELEM(inst->tables, tableidx); - if (t->type->et != TYPE_funcref) { - goto do_trap; - } + assert(t->type->et == TYPE_funcref); const struct funcinst *func; - ret = table_get_func(ctx, t, wasmfuncptr, ft, &func); + int ret = table_get_func(ctx, t, wasmfuncptr, ft, &func); if (ret != 0) { /* Note: table_get_func raises a trap inside */ return ret; @@ -63,18 +54,31 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, } struct meminst * -cconv_default_memory(const struct instance *inst) +cconv_memory(const struct instance *inst) { const struct module *m = inst->module; uint32_t memidx; - int ret; - /* - * XXX searching exports on each call can be too slow. - */ - ret = module_find_export(m, &name_default_memory, EXTERNTYPE_MEMORY, - &memidx); + int ret = module_find_export(m, &name_default_memory, + EXTERNTYPE_MEMORY, &memidx); if (ret != 0) { return NULL; } - return VEC_ELEM(inst->mems, memidx); + return VEC_ELEM(inst->mems, memidx); +} + +struct tableinst * +cconv_func_table(const struct instance *inst) +{ + const struct module *m = inst->module; + uint32_t tableidx; + int ret = module_find_export(m, &name_func_table, EXTERNTYPE_TABLE, + &tableidx); + if (ret != 0) { + return NULL; + } + struct tableinst *t = VEC_ELEM(inst->tables, tableidx); + if (t->type->et != TYPE_funcref) { + return NULL; + } + return t; } diff --git a/lib/cconv.h b/lib/cconv.h index 00587163..a9f8ee96 100644 --- a/lib/cconv.h +++ b/lib/cconv.h @@ -7,13 +7,15 @@ struct instance; struct functype; struct funcinst; struct meminst; +struct tableinst; __BEGIN_EXTERN_C -int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst, +int cconv_deref_func_ptr(struct exec_context *ctx, const struct tableinst *t, uint32_t wasmfuncptr, const struct functype *ft, const struct funcinst **fip); -struct meminst *cconv_default_memory(const struct instance *inst); +struct meminst *cconv_memory(const struct instance *inst); +struct tableinst *cconv_func_table(const struct instance *inst); __END_EXTERN_C diff --git a/lib/host_instance.h b/lib/host_instance.h index 53e2ef03..802d8c2f 100644 --- a/lib/host_instance.h +++ b/lib/host_instance.h @@ -63,9 +63,13 @@ struct host_func { #endif struct host_instance { - int dummy; + struct meminst *memory; + struct tableinst *func_table; }; +#define host_func_memory(hi) (hi)->memory +#define host_func_func_table(hi) (hi)->func_table + struct host_module { const struct name *module_name; const struct host_func *funcs; diff --git a/libwasi/wasi.c b/libwasi/wasi.c index 9632ed30..b19a1a13 100644 --- a/libwasi/wasi.c +++ b/libwasi/wasi.c @@ -184,7 +184,7 @@ wasi_instance_create(struct mem_context *mctx, void wasi_instance_set_memory(struct wasi_instance *inst, struct meminst *mem) { - inst->memory = mem; + wasi_memory(inst) = mem; } void diff --git a/libwasi/wasi_impl.h b/libwasi/wasi_impl.h index 7984a78c..8ad5b807 100644 --- a/libwasi/wasi_impl.h +++ b/libwasi/wasi_impl.h @@ -54,8 +54,6 @@ struct wasi_instance { struct wasi_table fdtable[WASI_NTABLES] GUARDED_VAR( lock); /* indexed by wasi fd */ - struct meminst *memory; - int argc; const char *const *argv; int nenvs; @@ -74,7 +72,7 @@ uint32_t wasi_convert_errno(int host_errno); #define wasi_copyout(c, m, h, w, l, a) host_func_copyout(c, m, h, w, l, a) #define wasi_copyin(c, m, h, w, l, a) host_func_copyin(c, m, h, w, l, a) -#define wasi_memory(i) (i)->memory +#define wasi_memory(i) host_func_memory(&(i)->hi) struct exec_context; struct wasi_instance; diff --git a/libwasi_threads/wasi_threads.c b/libwasi_threads/wasi_threads.c index a3bacc36..fe166552 100644 --- a/libwasi_threads/wasi_threads.c +++ b/libwasi_threads/wasi_threads.c @@ -123,6 +123,13 @@ wasi_threads_instance_destroy(struct wasi_threads_instance *inst) mem_free(mctx, inst, sizeof(*inst)); } +void +wasi_threads_instance_set_memory(struct wasi_threads_instance *inst, + struct meminst *mem) +{ + inst->hi.memory = mem; +} + void wasi_threads_setup_exec_context(struct wasi_threads_instance *wasi_threads, struct exec_context *ctx) @@ -547,7 +554,8 @@ wasi_thread_spawn(struct exec_context *ctx, struct host_instance *hi, le32_encode(&r.u.tid, tid); } HOST_FUNC_FREE_CONVERTED_PARAMS(); - return host_func_copyout(ctx, &r, retp, sizeof(r), WASI_U32_ALIGN); + return host_func_copyout(ctx, host_func_memory(&wasi->hi), &r, retp, + sizeof(r), WASI_U32_ALIGN); } static int diff --git a/libwasi_threads/wasi_threads.h b/libwasi_threads/wasi_threads.h index 79bd7078..5cabd657 100644 --- a/libwasi_threads/wasi_threads.h +++ b/libwasi_threads/wasi_threads.h @@ -4,6 +4,7 @@ struct wasi_threads_instance; struct import_object; +struct meminst; struct sched; struct exec_context; struct trap_info; @@ -14,6 +15,9 @@ void wasi_threads_instance_destroy(struct wasi_threads_instance *inst); int wasi_threads_instance_create(struct mem_context *mctx, struct wasi_threads_instance **instp); +void wasi_threads_instance_set_memory(struct wasi_threads_instance *inst, + struct meminst *mem); + /* * wasi_threads_instance_set_thread_spawn_args: set wasi-threads parameters * From 8706b5eef7c7d842ad28f1954cb89350bf648cbb Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 10 Aug 2024 13:38:29 +0900 Subject: [PATCH 09/12] adapt dyld dyld_func_table is currently unused. but i added it for consistency. it would be necessary if an embedder provides host functions which use function pointers. --- cli/repl.c | 6 ++++++ libdyld/dyld.c | 44 ++++++++++++++++++++++++++++++++------------ libdyld/dyld.h | 6 ++++++ libdyld/dyld_dlfcn.c | 18 ++++++++---------- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/cli/repl.c b/cli/repl.c index 510e9a42..648116a7 100644 --- a/cli/repl.c +++ b/cli/repl.c @@ -744,6 +744,12 @@ toywasm_repl_load(struct repl_state *state, const char *modname, if (ret != 0) { return ret; } + set_memory(state, dyld_memory(d)); + ret = dyld_execute_init_funcs(d); + if (ret != 0) { + dyld_clear(d); + return ret; + } state->modules.lsize++; return 0; } diff --git a/libdyld/dyld.c b/libdyld/dyld.c index f5123801..dc4740a5 100644 --- a/libdyld/dyld.c +++ b/libdyld/dyld.c @@ -671,7 +671,7 @@ dyld_object_destroy(struct dyld_object *obj) } static int -dyld_execute_init_func(struct dyld_object *obj, const struct name *name) +dyld_execute_obj_init_func1(struct dyld_object *obj, const struct name *name) { struct module *m = obj->module; uint32_t funcidx; @@ -700,16 +700,21 @@ dyld_execute_init_func(struct dyld_object *obj, const struct name *name) return ret; } +/* + * dyld_execute_obj_init_func: + * + * execute at most one of the init functions given by the names. + */ static int -dyld_execute_init_funcs(struct dyld_object *obj, const struct name *names, - size_t nnames) +dyld_execute_obj_init_func(struct dyld_object *obj, const struct name *names, + size_t nnames) { xlog_trace("dyld: executing init funcs for object %.*s", CSTR(obj->name)); unsigned int i; for (i = 0; i < nnames; i++) { const struct name *funcname = &names[i]; - int ret = dyld_execute_init_func(obj, funcname); + int ret = dyld_execute_obj_init_func1(obj, funcname); if (ret == ENOENT) { xlog_trace("dyld: %.*s doesn't have %.*s", CSTR(obj->name), CSTR(funcname)); @@ -765,15 +770,15 @@ dyld_execute_all_init_funcs(struct dyld *d, struct dyld_object *start) } LIST_FOREACH(obj, &list, tq) { - int ret = dyld_execute_init_funcs(obj, reloc_funcs, - ARRAYCOUNT(reloc_funcs)); + int ret = dyld_execute_obj_init_func(obj, reloc_funcs, + ARRAYCOUNT(reloc_funcs)); if (ret != 0) { return ret; } } LIST_FOREACH(obj, &list, tq) { - int ret = dyld_execute_init_funcs(obj, ctor_funcs, - ARRAYCOUNT(ctor_funcs)); + int ret = dyld_execute_obj_init_func(obj, ctor_funcs, + ARRAYCOUNT(ctor_funcs)); if (ret != 0) { return ret; } @@ -1374,16 +1379,19 @@ dyld_load(struct dyld *d, const char *filename) global_set_i32(&d->heap_base, base); global_set_i32(&d->heap_end, end); } - ret = dyld_execute_all_init_funcs(d, obj); - if (ret != 0) { - goto fail; - } return 0; fail: dyld_clear(d); return ret; } +int +dyld_execute_init_funcs(struct dyld *d) +{ + struct dyld_object *obj = LIST_FIRST(&d->objs); + return dyld_execute_all_init_funcs(d, obj); +} + void dyld_clear(struct dyld *d) { @@ -1428,3 +1436,15 @@ dyld_main_object_instance(struct dyld *d) const struct dyld_object *obj = LIST_FIRST(&d->objs); return obj->instance; } + +struct meminst * +dyld_memory(struct dyld *d) +{ + return d->meminst; +} + +struct tableinst * +dyld_func_table(struct dyld *d) +{ + return d->tableinst; +} diff --git a/libdyld/dyld.h b/libdyld/dyld.h index 78b2bf9a..50659371 100644 --- a/libdyld/dyld.h +++ b/libdyld/dyld.h @@ -1,5 +1,6 @@ #include +#include "host_instance.h" #include "list.h" #include "platform.h" #include "toywasm_config.h" @@ -86,11 +87,16 @@ __BEGIN_EXTERN_C struct import_object; struct mem_context; +struct meminst; +struct tableinst; void dyld_init(struct dyld *d, struct mem_context *mctx); void dyld_clear(struct dyld *d); int dyld_load(struct dyld *d, const char *filename); +int dyld_execute_init_funcs(struct dyld *d); struct instance *dyld_main_object_instance(struct dyld *d); +struct meminst *dyld_memory(struct dyld *d); +struct tableinst *dyld_func_table(struct dyld *d); void dyld_options_set_defaults(struct dyld_options *opts); int import_object_create_for_dyld(struct mem_context *mctx, struct dyld *d, struct import_object **impp); diff --git a/libdyld/dyld_dlfcn.c b/libdyld/dyld_dlfcn.c index f5a7a25d..de722a0d 100644 --- a/libdyld/dyld_dlfcn.c +++ b/libdyld/dyld_dlfcn.c @@ -17,7 +17,6 @@ #include "dyld_impl.h" #include "endian.h" #include "exec_context.h" -#include "host_instance.h" #include "mem.h" #include "xlog.h" @@ -75,9 +74,8 @@ dyld_dlfcn_load_object(struct exec_context *ctx, struct host_instance *hi, } void *vp; - ret = host_func_getptr(ctx, namep, namelen, &vp); - if (ret != 0) { - user_ret = 1; + host_ret = host_func_getptr(ctx, dyld_memory(d), namep, namelen, &vp); + if (host_ret != 0) { goto fail; } @@ -117,8 +115,8 @@ dyld_dlfcn_load_object(struct exec_context *ctx, struct host_instance *hi, "dyld: dyld:load_object succeeded for %.*s, handle %" PRIu32, CSTR(name), handle); uint32_t handle_le = host_to_le32(handle); - host_ret = - host_func_copyout(ctx, &handle_le, retp, sizeof(handle_le), 4); + host_ret = host_func_copyout(ctx, dyld_memory(d), &handle_le, retp, + sizeof(handle_le), 4); user_ret = 0; fail: if (host_ret == 0) { @@ -169,9 +167,8 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi, const struct dyld_dynamic_object *dobj = &VEC_ELEM(d->dynobjs, idx); void *vp; - ret = host_func_getptr(ctx, namep, namelen, &vp); - if (ret != 0) { - user_ret = 1; + host_ret = host_func_getptr(ctx, dyld_memory(d), namep, namelen, &vp); + if (host_ret != 0) { goto fail; } struct name name; @@ -198,7 +195,8 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi, "dyld: dyld:resolve_symbol succeeded for %.*s, addr %" PRIu32, CSTR(&name), addr); uint32_t addr_le = host_to_le32(addr); - host_ret = host_func_copyout(ctx, &addr_le, retp, sizeof(addr_le), 4); + host_ret = host_func_copyout(ctx, dyld_memory(d), &addr_le, retp, + sizeof(addr_le), 4); user_ret = 0; fail: if (host_ret == 0) { From 49d3d8195b3d7887370055fc8551a61f53b579aa Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 10 Aug 2024 15:47:07 +0900 Subject: [PATCH 10/12] adapt examples i'm not entirely happy with the use of a callback. i may revisit this later. --- examples/hostfunc/hostfunc.c | 27 +++++++++++++++------------ examples/hostfunc/main.c | 16 ++++++++++++++-- examples/log_execution/main.c | 2 +- examples/runwasi/main.c | 4 ++-- examples/runwasi/runwasi.c | 30 +++++++++++++++++++++++------- examples/runwasi/runwasi.h | 21 +++++++++++++++------ examples/runwasi_cstruct/main.c | 8 ++++---- 7 files changed, 74 insertions(+), 34 deletions(-) diff --git a/examples/hostfunc/hostfunc.c b/examples/hostfunc/hostfunc.c index aece56ac..f9bfab66 100644 --- a/examples/hostfunc/hostfunc.c +++ b/examples/hostfunc/hostfunc.c @@ -20,7 +20,8 @@ print_backtrace(const char *func, const struct exec_context *ctx) } static int -load(struct exec_context *ctx, uint32_t pp, uint32_t *resultp) +load(struct exec_context *ctx, struct host_instance *hi, uint32_t pp, + uint32_t *resultp) { int host_ret; uint32_t le32; @@ -29,19 +30,21 @@ load(struct exec_context *ctx, uint32_t pp, uint32_t *resultp) * *resultp = *(*pp)++ */ - host_ret = host_func_copyin(ctx, &le32, pp, 4, 4); + host_ret = + host_func_copyin(ctx, host_func_memory(hi), &le32, pp, 4, 4); if (host_ret != 0) { goto fail; } uint32_t p = le32_to_host(le32); - host_ret = host_func_copyin(ctx, &le32, p, 4, 4); + host_ret = host_func_copyin(ctx, host_func_memory(hi), &le32, p, 4, 4); if (host_ret != 0) { goto fail; } uint32_t result = le32_to_host(le32); p += 4; le32 = host_to_le32(p); - host_ret = host_func_copyout(ctx, &le32, pp, 4, 4); + host_ret = + host_func_copyout(ctx, host_func_memory(hi), &le32, pp, 4, 4); if (host_ret != 0) { goto fail; } @@ -51,18 +54,18 @@ load(struct exec_context *ctx, uint32_t pp, uint32_t *resultp) } static int -load_func(struct exec_context *ctx, const struct functype *ft, uint32_t pp, - const struct funcinst **fip) +load_func(struct exec_context *ctx, struct host_instance *hi, + const struct functype *ft, uint32_t pp, const struct funcinst **fip) { int host_ret; uint32_t funcptr; - host_ret = load(ctx, pp, &funcptr); + host_ret = load(ctx, hi, pp, &funcptr); if (host_ret != 0) { goto fail; } const struct funcinst *func; - host_ret = - cconv_deref_func_ptr(ctx, ctx->instance, funcptr, ft, &func); + host_ret = cconv_deref_func_ptr(ctx, host_func_func_table(hi), funcptr, + ft, &func); if (host_ret != 0) { goto fail; } @@ -83,7 +86,7 @@ my_host_inst_load(struct exec_context *ctx, struct host_instance *hi, print_backtrace(__func__, ctx); uint32_t result; - host_ret = load(ctx, pp, &result); + host_ret = load(ctx, hi, pp, &result); if (host_ret == 0) { HOST_FUNC_RESULT_SET(ft, results, 0, i32, result); } @@ -103,7 +106,7 @@ my_host_inst_load_call(struct exec_context *ctx, struct host_instance *hi, print_backtrace(__func__, ctx); const struct funcinst *func; - host_ret = load_func(ctx, ft, pp, &func); + host_ret = load_func(ctx, hi, ft, pp, &func); if (host_ret != 0) { goto fail; } @@ -182,7 +185,7 @@ my_host_inst_load_call_add(struct exec_context *ctx, struct host_instance *hi, * ours. (ft) */ const struct funcinst *func; - host_ret = load_func(ctx, ft, pp, &func); + host_ret = load_func(ctx, hi, ft, pp, &func); if (host_ret != 0) { goto fail; } diff --git a/examples/hostfunc/main.c b/examples/hostfunc/main.c index 8c571bee..e8a8fb5d 100644 --- a/examples/hostfunc/main.c +++ b/examples/hostfunc/main.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,14 @@ #include "runwasi.h" #include "runwasi_cli_args.h" +static void +set_resources(void *v, struct meminst *mem, struct tableinst *func_table) +{ + struct host_instance *hi = v; + hi->memory = mem; + hi->func_table = func_table; +} + int main(int argc, char **argv) { @@ -37,15 +46,18 @@ main(int argc, char **argv) } struct mem_context mctx; mem_context_init(&mctx); + struct host_instance hi; + hi.memory = NULL; + hi.func_table = NULL; struct import_object *import_obj; - ret = import_object_create_for_my_host_inst(&mctx, NULL, &import_obj); + ret = import_object_create_for_my_host_inst(&mctx, &hi, &import_obj); if (ret != 0) { exit(1); } ret = runwasi(&mctx, a->filename, a->ndirs, a->dirs, a->nenvs, (const char *const *)a->envs, a->argc, (const char *const *)a->argv, stdio_fds, import_obj, - &wasi_exit_code); + set_resources, &hi, &wasi_exit_code); import_object_destroy(&mctx, import_obj); mem_context_clear(&mctx); free(a->dirs); diff --git a/examples/log_execution/main.c b/examples/log_execution/main.c index e78feeaa..3b264656 100644 --- a/examples/log_execution/main.c +++ b/examples/log_execution/main.c @@ -51,7 +51,7 @@ main(int argc, char **argv) ret = runwasi(&mctx, a->filename, a->ndirs, a->dirs, a->nenvs, (const char *const *)a->envs, a->argc, (const char *const *)a->argv, stdio_fds, import_obj, - &wasi_exit_code); + NULL, NULL, &wasi_exit_code); import_object_destroy(&mctx, import_obj); mem_context_clear(&mctx); free(a->dirs); diff --git a/examples/runwasi/main.c b/examples/runwasi/main.c index ab65aee8..0148cd43 100644 --- a/examples/runwasi/main.c +++ b/examples/runwasi/main.c @@ -37,8 +37,8 @@ main(int argc, char **argv) mem_context_init(&mctx); ret = runwasi(&mctx, a->filename, a->ndirs, a->dirs, a->nenvs, (const char *const *)a->envs, a->argc, - (const char *const *)a->argv, stdio_fds, NULL, - &wasi_exit_code); + (const char *const *)a->argv, stdio_fds, NULL, NULL, + NULL, &wasi_exit_code); mem_context_clear(&mctx); free(a->dirs); free(a->envs); diff --git a/examples/runwasi/runwasi.c b/examples/runwasi/runwasi.c index 33e298ec..12a86b60 100644 --- a/examples/runwasi/runwasi.c +++ b/examples/runwasi/runwasi.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,11 +12,14 @@ #include "runwasi.h" int -runwasi_module(struct mem_context *mctx, const struct module *m, - unsigned int ndirs, char **dirs, unsigned int nenvs, - const char *const *envs, int argc, const char *const *argv, - const int stdio_fds[3], struct import_object *base_imports, - uint32_t *wasi_exit_code_p) +runwasi_module( + struct mem_context *mctx, const struct module *m, unsigned int ndirs, + char **dirs, unsigned int nenvs, const char *const *envs, int argc, + const char *const *argv, const int stdio_fds[3], + struct import_object *base_imports, + void (*set_host_instance_resources)(void *hi_arg, struct meminst *mem, + struct tableinst *func_table), + void *hi_arg, uint32_t *wasi_exit_code_p) { struct wasi_instance *wasi = NULL; struct import_object *wasi_import_object = NULL; @@ -93,6 +97,13 @@ runwasi_module(struct mem_context *mctx, const struct module *m, } report_clear(&report); + struct meminst *mem = cconv_memory(inst); + struct tableinst *func_table = cconv_func_table(inst); + wasi_instance_set_memory(wasi, mem); + if (set_host_instance_resources != NULL) { + set_host_instance_resources(hi_arg, mem, func_table); + } + /* * execute the module */ @@ -140,7 +151,10 @@ int runwasi(struct mem_context *mctx, const char *filename, unsigned int ndirs, char **dirs, unsigned int nenvs, const char *const *envs, int argc, const char *const *argv, const int stdio_fds[3], - struct import_object *base_imports, uint32_t *wasi_exit_code_p) + struct import_object *base_imports, + void (*set_host_instance_resources)(void *hi_arg, struct meminst *mem, + struct tableinst *func_table), + void *hi_arg, uint32_t *wasi_exit_code_p) { struct module *m = NULL; int ret; @@ -167,7 +181,9 @@ runwasi(struct mem_context *mctx, const char *filename, unsigned int ndirs, load_context_clear(&lctx); ret = runwasi_module(mctx, m, ndirs, dirs, nenvs, envs, argc, argv, - stdio_fds, base_imports, wasi_exit_code_p); + stdio_fds, base_imports, + set_host_instance_resources, hi_arg, + wasi_exit_code_p); fail: if (m != NULL) { diff --git a/examples/runwasi/runwasi.h b/examples/runwasi/runwasi.h index 6432b6c5..ff6f6f16 100644 --- a/examples/runwasi/runwasi.h +++ b/examples/runwasi/runwasi.h @@ -3,14 +3,23 @@ struct mem_context; struct import_object; struct module; +struct meminst; +struct tableinst; -int runwasi_module(struct mem_context *mctx, const struct module *m, - unsigned int ndirs, char **dirs, unsigned int nenvs, - const char *const *envs, int argc, const char *const *argv, - const int stdio_fds[3], struct import_object *base_imports, - uint32_t *wasi_exit_code_p); +int runwasi_module( + struct mem_context *mctx, const struct module *m, unsigned int ndirs, + char **dirs, unsigned int nenvs, const char *const *envs, int argc, + const char *const *argv, const int stdio_fds[3], + struct import_object *base_imports, + void (*set_host_instance_resources)(void *hi_arg, struct meminst *mem, + struct tableinst *func_table), + void *hi_arg, uint32_t *wasi_exit_code_p); int runwasi(struct mem_context *mctx, const char *filename, unsigned int ndirs, char **dirs, unsigned int nenvs, const char *const *envs, int argc, const char *const *argv, const int stdio_fds[3], - struct import_object *base_imports, uint32_t *wasi_exit_code_p); + struct import_object *base_imports, + void (*set_host_instance_resources)(void *hi_arg, + struct meminst *mem, + struct tableinst *func_table), + void *hi_arg, uint32_t *wasi_exit_code_p); diff --git a/examples/runwasi_cstruct/main.c b/examples/runwasi_cstruct/main.c index 1a35d215..7adcde36 100644 --- a/examples/runwasi_cstruct/main.c +++ b/examples/runwasi_cstruct/main.c @@ -37,10 +37,10 @@ main(int argc, char **argv) } struct mem_context mctx; mem_context_init(&mctx); - ret = runwasi_module(&mctx, &g_wasm_module, a->ndirs, a->dirs, a->nenvs, - (const char *const *)a->envs, a->argc, - (const char *const *)a->argv, stdio_fds, NULL, - &wasi_exit_code); + ret = runwasi_module(&mctx, &g_wasm_module, a->ndirs, a->dirs, + a->nenvs, (const char *const *)a->envs, a->argc, + (const char *const *)a->argv, stdio_fds, NULL, + NULL, NULL, &wasi_exit_code); mem_context_clear(&mctx); free(a->dirs); free(a->envs); From 2be448e8f457ee009cf145c042abf6663f3ab2c9 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 10 Aug 2024 16:22:34 +0900 Subject: [PATCH 11/12] tweak trap messages on no suitable memory/table for host functions --- lib/cconv.c | 6 +++--- lib/exec_context.h | 2 +- lib/host_instance.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/cconv.c b/lib/cconv.c index 5542b414..ba6b2174 100644 --- a/lib/cconv.c +++ b/lib/cconv.c @@ -38,9 +38,9 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct tableinst *t, const struct funcinst **fip) { if (t == NULL) { - return trap_with_id(ctx, - TRAP_INDIRECT_FUNCTION_TABLE_NOT_FOUND, - "__indirect_function_table is not found"); + return trap_with_id( + ctx, TRAP_INDIRECT_FUNCTION_TABLE_NOT_FOUND, + "no suitable table for indirect function table"); } assert(t->type->et == TYPE_funcref); const struct funcinst *func; diff --git a/lib/exec_context.h b/lib/exec_context.h index cada2ee8..902647da 100644 --- a/lib/exec_context.h +++ b/lib/exec_context.h @@ -92,7 +92,7 @@ enum trapid { TRAP_UNCAUGHT_EXCEPTION, TRAP_THROW_REF_NULL, TRAP_UNRESOLVED_IMPORTED_FUNC, - TRAP_DEFAULT_MEMORY_NOT_FOUND, + TRAP_MEMORY_NOT_FOUND, }; enum exec_event { diff --git a/lib/host_instance.c b/lib/host_instance.c index 890904b4..8ef837e2 100644 --- a/lib/host_instance.c +++ b/lib/host_instance.c @@ -206,9 +206,9 @@ host_func_getptr2(struct exec_context *ctx, struct meminst *mem, uint32_t ptr, { if (mem == NULL) { return trap_with_id( - ctx, TRAP_OUT_OF_BOUNDS_MEMORY_ACCESS, + ctx, TRAP_MEMORY_NOT_FOUND, "host function invalid memory access at %08" PRIx32 - ", size %" PRIu32 ", no memory", + ", size %" PRIu32 ", no suitable memory", ptr, size); } int ret = memory_instance_getptr2(mem, ptr, 0, size, pp, movedp); From 14cb1aee76b17bc9137d7ff4b62e0a6dbc45a4da Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 10 Aug 2024 16:44:29 +0900 Subject: [PATCH 12/12] skip thread_spawn-simple cf. https://github.com/WebAssembly/wasi-testsuite/pull/100 --- test/wasi-testsuite-skip.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/wasi-testsuite-skip.json b/test/wasi-testsuite-skip.json index 25cee8e5..09a371f3 100644 --- a/test/wasi-testsuite-skip.json +++ b/test/wasi-testsuite-skip.json @@ -12,5 +12,8 @@ "symlink_create": "this implementation doesn't care symlink contents", "symlink_filestat": "rights system not implemented.", "truncation_rights": "rights system not implemented." + }, + "WASI threads proposal": { + "thread_spawn-simple": "https://github.com/WebAssembly/wasi-testsuite/pull/100" } }