commit 62863d4b4929c337da75ed84457c6d175e51a4b7
parent 954621d2d19e878daa9c0d5db47cae947d31a48e
Author: William Casarin <jb55@jb55.com>
Date: Fri, 23 Jul 2021 00:12:42 -0700
fd_write: print all iovecs
Diffstat:
3 files changed, 81 insertions(+), 62 deletions(-)
diff --git a/src/protoverse.c b/src/protoverse.c
@@ -151,7 +151,7 @@ int main(int argc, const char *argv[])
perror("mmap");
return 1;
}
- if (!run_wasm(wasm_data, len)) {
+ if (!run_wasm(wasm_data, len, argc, argv)) {
return 2;
}
munmap(wasm_data, len);
diff --git a/src/wasm.c b/src/wasm.c
@@ -119,7 +119,7 @@ static struct val *get_fn_local(struct wasm_interp *interp, int fn, u32 ind)
return &func->locals[ind].val;
}
-static struct val *get_local(struct wasm_interp *interp, u32 ind)
+static INLINE struct val *get_local(struct wasm_interp *interp, u32 ind)
{
struct callframe *frame;
@@ -2754,13 +2754,11 @@ static INLINE int interp_local_tee(struct wasm_interp *interp, u32 index)
{
struct val *val;
- if (unlikely(!(val = stack_topval(interp)))) {
+ if (unlikely(!(val = stack_topval(interp))))
return interp_error(interp, "pop");
- }
- if (unlikely(!set_local(interp, index, val))) {
+ if (unlikely(!set_local(interp, index, val)))
return interp_error(interp, "set local");
- }
return 1;
}
@@ -2769,13 +2767,11 @@ static int interp_local_set(struct wasm_interp *interp, u32 index)
{
struct val val;
- if (unlikely(!interp_local_tee(interp, index))) {
+ if (unlikely(!interp_local_tee(interp, index)))
return interp_error(interp, "tee set");
- }
- if (unlikely(!stack_popval(interp, &val))) {
+ if (unlikely(!stack_popval(interp, &val)))
return interp_error(interp, "pop");
- }
return 1;
}
@@ -3623,7 +3619,7 @@ static int pop_label_and_skip(struct wasm_interp *interp, struct label *label,
int i;
struct resolver resolver;
assert(is_label_resolved(label));
-
+
if (unlikely(times == 0))
return interp_error(interp, "can't pop label 0 times");
@@ -3642,7 +3638,7 @@ static int pop_label_and_break(struct wasm_interp *interp, struct label *label,
int i;
struct resolver resolver;
assert(is_label_resolved(label));
-
+
if (unlikely(times == 0))
return interp_error(interp, "can't pop label 0 times");
@@ -3663,7 +3659,7 @@ static int pop_label_and_break(struct wasm_interp *interp, struct label *label,
if (!(label = index_frame_label(interp, resolver.label))) {
return interp_error(interp, "index label");
}
-
+
return break_jump(interp, &resolver, label);
}
@@ -4450,64 +4446,65 @@ static INLINE int load_i32(struct wasm_interp *interp, int *i)
static int builtin_fd_write(struct wasm_interp *interp)
{
- struct val *fd, *iovs, *iovs_len, *written;
- int iovec_data = 0;
- int str_len = 0;
+ struct val *fd, *iovs_ptr, *iovs_len, *written;
+ int i, ind, iovec_data = 0, str_len = 0, wrote = 0;
- if (!(fd = get_local(interp, 0)))
+ if (unlikely(!(fd = get_local(interp, 0))))
return interp_error(interp, "fd");
- if (!(iovs = get_local(interp, 1)))
- return interp_error(interp, "iovs");
+ if (unlikely(!(iovs_ptr = get_local(interp, 1))))
+ return interp_error(interp, "iovs_ptr");
- if (!(iovs_len = get_local(interp, 2)))
+ if (unlikely(!(iovs_len = get_local(interp, 2))))
return interp_error(interp, "iovs_len");
- if (!(written = get_local(interp, 3)))
+ if (unlikely(!(written = get_local(interp, 3))))
return interp_error(interp, "written");
- debug("fd_write %d %d %d %d\n",
- fd->num.i32,
- iovs->num.i32,
- iovs_len->num.i32,
- written->num.i32
- );
+ if (unlikely(fd->num.i32 >= 10))
+ return interp_error(interp, "weird fd %d", fd->num.i32);
- if (!stack_push_i32(interp, iovs->num.i32)) {
- return interp_error(interp, "push iovec ptr");
- }
+ written->num.i32 = 0;
+ for (i = 0; i < iovs_len->num.i32; i++) {
+ ind = 8*i;
- if (!load_i32(interp, &iovec_data)) {
- return interp_error(interp, "load iovec data");
- }
+ if (unlikely(!stack_push_i32(interp, iovs_ptr->num.i32 + ind)))
+ return interp_error(interp, "push iovec ptr");
- if (!stack_push_i32(interp, iovs->num.i32 + 4)) {
- return interp_error(interp, "push iovec ptr");
- }
+ if (unlikely(!load_i32(interp, &iovec_data)))
+ return interp_error(interp, "load iovec data");
- if (!load_i32(interp, &str_len)) {
- return interp_error(interp, "load iovec data");
- }
+ if (unlikely(!stack_push_i32(interp,
+ iovs_ptr->num.i32 + (ind+4)))) {
+ return interp_error(interp, "push strlen ptr");
+ }
- debug("fd_write len %d\n", str_len);
+ if (unlikely(!load_i32(interp, &str_len)))
+ return interp_error(interp, "load iovec data");
- if (interp->memory.start + iovec_data + str_len >=
- interp->memory.p) {
- return interp_error(interp, "fd_write oob");
- }
+ if (unlikely(interp->memory.start + iovec_data + str_len >=
+ interp->memory.p)) {
+ return interp_error(interp, "fd_write oob");
+ }
- if (fd->num.i32 >= 10) {
- return interp_error(interp, "weird fd %d", fd->num.i32);
- }
+ debug("fd_write #iovec %d/%d len %d '%.*s'\n",
+ i+1,
+ iovs_len->num.i32,
+ str_len,
+ str_len,
+ interp->memory.start + iovec_data);
+
+ wrote = write(fd->num.i32,
+ interp->memory.start + iovec_data,
+ str_len
+ );
- written->num.i32 = write(fd->num.i32,
- interp->memory.start + iovec_data,
- str_len
- );
+ if (wrote != str_len) {
+ return interp_error(interp, "written %d != %d",
+ written->num.i32, str_len);
+ }
- if (written->num.i32 != str_len) {
- return interp_error(interp, "written %d != %d",
- written->num.i32, str_len);
+ written->num.i32 += wrote;
}
return stack_push_i32(interp, written->num.i32);
@@ -4534,6 +4531,7 @@ static int builtin_get_args(struct wasm_interp *interp)
static int builtin_get_args_sizes(struct wasm_interp *interp)
{
struct val *argc_addr, *argv_buf_size_addr;
+ int i;
if (!(argc_addr = get_local(interp, 0)))
return interp_error(interp, "argc");
@@ -4541,14 +4539,16 @@ static int builtin_get_args_sizes(struct wasm_interp *interp)
if (!(argv_buf_size_addr = get_local(interp, 1)))
return interp_error(interp, "argv_buf_size");
- if (!store_i32(interp, argc_addr->num.i32, 1984))
+ if (!store_i32(interp, argc_addr->num.i32, interp->wasi.argc))
return interp_error(interp, "store argc");
- if (!store_i32(interp, argv_buf_size_addr->num.i32, 1))
- return interp_error(interp, "store arg buf size");
-
- debug("get_args_sizes %d %d\n", argc_addr->num.i32,
- argv_buf_size_addr->num.i32);
+ for (i = 0; i < interp->wasi.argc; i++) {
+ if (!store_i32(interp, argv_buf_size_addr->num.i32 + i*4,
+ strlen(interp->wasi.argv[i]))) {
+ return interp_error(interp, "store arg size %d/%d",
+ i+1, interp->wasi.argc);
+ }
+ }
return stack_push_i32(interp, 0);
}
@@ -5469,9 +5469,11 @@ static int alloc_locals(struct module *module, struct cursor *mem,
for (j = 0; j < func->wasm_func->num_locals; j++) {
for (k = 0; k < func->wasm_func->locals[j].val.num.u32; k++, ind++) {
+ /*
debug("initializing function %d local %d to type %s\n",
i, ind, valtype_name(
func->wasm_func->locals[j].val.type));
+ */
func->locals[ind].val.type =
func->wasm_func->locals[j].val.type;
@@ -5785,6 +5787,12 @@ static int reset_memory(struct wasm_interp *interp)
return 1;
}
+static void setup_wasi(struct wasm_interp *interp, int argc, const char **argv)
+{
+ interp->wasi.argc = argc;
+ interp->wasi.argv = argv;
+}
+
int wasm_interp_init(struct wasm_interp *interp, struct module *module)
{
unsigned char *mem, *heap, *start;
@@ -5797,6 +5805,8 @@ int wasm_interp_init(struct wasm_interp *interp, struct module *module)
memset(interp, 0, sizeof(*interp));
+ setup_wasi(interp, 0, NULL);
+
interp->quitting = 0;
interp->module = module;
@@ -5972,7 +5982,8 @@ int interp_wasm_module(struct wasm_interp *interp)
return 1;
}
-int run_wasm(unsigned char *wasm, unsigned long len)
+int run_wasm(unsigned char *wasm, unsigned long len,
+ int argc, const char **argv)
{
struct wasm_parser p;
struct wasm_interp interp;
@@ -5989,6 +6000,8 @@ int run_wasm(unsigned char *wasm, unsigned long len)
return 0;
}
+ setup_wasi(&interp, argc, argv);
+
if (!interp_wasm_module(&interp)) {
print_error_backtrace(&interp.errors);
}
diff --git a/src/wasm.h b/src/wasm.h
@@ -632,9 +632,15 @@ struct module_inst {
unsigned char *globals_init;
};
+struct wasi {
+ int argc;
+ const char **argv;
+};
+
struct wasm_interp {
struct module *module;
struct module_inst module_inst;
+ struct wasi wasi;
int prev_resolvers, quitting;
@@ -671,7 +677,7 @@ struct wasm_parser {
};
-int run_wasm(unsigned char *wasm, unsigned long len);
+int run_wasm(unsigned char *wasm, unsigned long len, int argc, const char **argv);
int parse_wasm(struct wasm_parser *p);
int wasm_interp_init(struct wasm_interp *interp, struct module *module);
void wasm_parser_free(struct wasm_parser *parser);