protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit abe815d88e46970ecf8352305573312fb4386889
parent 999d867cd043058a356a2d451d87c6dededd11ae
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 23 Jul 2021 14:42:12 -0700

wasi: environ

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdefault.nix | 2+-
Msrc/wasm.c | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/wasm.h | 3+++
3 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/default.nix b/default.nix @@ -1,4 +1,4 @@ { pkgs ? import <nixpkgs> {} }: pkgs.mkShell { - buildInputs = with pkgs; [ gdb wabt emscripten wasmtime cloc ]; + buildInputs = with pkgs; [ gdb wabt emscripten wasmtime cloc wasm-pack ]; } diff --git a/src/wasm.c b/src/wasm.c @@ -338,14 +338,18 @@ static int wasi_proc_exit(struct wasm_interp *interp) } static int wasi_args_sizes_get(struct wasm_interp *interp); -static int wasi_get_args(struct wasm_interp *interp); +static int wasi_args_get(struct wasm_interp *interp); static int wasi_fd_write(struct wasm_interp *interp); +static int wasi_environ_sizes_get(struct wasm_interp *interp); +static int wasi_environ_get(struct wasm_interp *interp); static struct builtin BUILTINS[] = { - { .name = "args_get", .fn = wasi_get_args }, - { .name = "fd_write", .fn = wasi_fd_write }, - { .name = "args_sizes_get", .fn = wasi_args_sizes_get }, - { .name = "proc_exit", .fn = wasi_proc_exit }, + { .name = "args_get", .fn = wasi_args_get }, + { .name = "fd_write", .fn = wasi_fd_write }, + { .name = "environ_sizes_get", .fn = wasi_environ_sizes_get }, + { .name = "environ_get", .fn = wasi_environ_get }, + { .name = "args_sizes_get", .fn = wasi_args_sizes_get }, + { .name = "proc_exit", .fn = wasi_proc_exit }, }; static const int NUM_BUILTINS = sizeof(BUILTINS) / sizeof(*BUILTINS); @@ -4421,6 +4425,14 @@ static INLINE int store_i32(struct wasm_interp *interp, int offset, int i) return store_simple(interp, offset, &val); } +static INLINE int store_i64(struct wasm_interp *interp, int offset, int64_t i) +{ + struct val val; + make_i64_val(&val, i); + return store_simple(interp, offset, &val); +} + + static int interp_load(struct wasm_interp *interp, struct memarg *memarg, enum valtype type, int N, int sign) { @@ -4540,65 +4552,86 @@ static int wasi_fd_write(struct wasm_interp *interp) return stack_push_i32(interp, 0); } -static int wasi_get_args(struct wasm_interp *interp) +static int wasi_get_strs(struct wasm_interp *interp, int count, const char **strs) { struct val *argv, *argv_buf; struct cursor writer; int i; if (!(argv = get_local(interp, 0))) - return interp_error(interp, "argv"); + return interp_error(interp, "strs"); if (!(argv_buf = get_local(interp, 1))) - return interp_error(interp, "argv_buf"); - - if (!stack_push_i32(interp, 0)) - return interp_error(interp, "push ret"); + return interp_error(interp, "strs_buf"); make_cursor(interp->memory.start + argv_buf->num.i32, interp->memory.p, &writer); - debug("get args %d %d\n", argv->num.i32, argv_buf->num.i32); + debug("get strs %d %d\n", argv->num.i32, argv_buf->num.i32); - for (i = 0; i < interp->wasi.argc; i++) { + for (i = 0; i < count; i++) { if (!store_i32(interp, argv->num.i32 + i*4, writer.p - interp->memory.start)) { return interp_error(interp, "store argv %d ptr\n", i); } - if (!cursor_push(&writer, (u8*)interp->wasi.argv[i], - strlen(interp->wasi.argv[i])+1)) { + if (!cursor_push(&writer, (u8*)strs[i], strlen(strs[i])+1)) { return interp_error(interp,"write arg %d", i+1); } } - return 1; + return stack_push_i32(interp, 0); + } -static int wasi_args_sizes_get(struct wasm_interp *interp) +static int wasi_strs_sizes_get(struct wasm_interp *interp, int count, + const char **strs) { struct val *argc_addr, *argv_buf_size_addr; int i, size = 0; if (!(argc_addr = get_local(interp, 0))) - return interp_error(interp, "argc"); + return interp_error(interp, "strs count"); if (!(argv_buf_size_addr = get_local(interp, 1))) - return interp_error(interp, "argv_buf_size"); + return interp_error(interp, "strs buf_size"); - if (!store_i32(interp, argc_addr->num.i32, interp->wasi.argc)) + if (!store_i32(interp, argc_addr->num.i32, count)) return interp_error(interp, "store argc"); - for (i = 0; i < interp->wasi.argc; i++) - size += strlen(interp->wasi.argv[i])+1; + for (i = 0; i < count; i++) + size += strlen(strs[i])+1; if (!store_i32(interp, argv_buf_size_addr->num.i32, size)) { - return interp_error(interp, "store arg size"); + return interp_error(interp, "store strs size"); } return stack_push_i32(interp, 0); } +static int wasi_args_get(struct wasm_interp *interp) +{ + return wasi_get_strs(interp, interp->wasi.argc, interp->wasi.argv); +} + +static int wasi_environ_get(struct wasm_interp *interp) +{ + return wasi_get_strs(interp, interp->wasi.environc, + interp->wasi.environ); +} + +static int wasi_args_sizes_get(struct wasm_interp *interp) +{ + return wasi_strs_sizes_get(interp, interp->wasi.argc, + interp->wasi.argv); +} + +static int wasi_environ_sizes_get(struct wasm_interp *interp) +{ + return wasi_strs_sizes_get(interp, interp->wasi.environc, + interp->wasi.environ); +} + static int interp_store(struct wasm_interp *interp, struct memarg *memarg, enum valtype type, int N) diff --git a/src/wasm.h b/src/wasm.h @@ -635,6 +635,9 @@ struct module_inst { struct wasi { int argc; const char **argv; + + int environc; + const char **environ; }; struct wasm_interp {