protoverse

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

commit e283d072205ffa1b07b8d02a7a9891f901f5c358
parent ec9e6662287ed9f6d301d5e7b7bc73fa56e0c6f5
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  4 Jun 2023 12:58:01 -0700

fixes

Diffstat:
MMakefile | 3++-
Msrc/wasm.c | 190++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/wasm.h | 32++++++++++++++++++++++++++++++++
3 files changed, 145 insertions(+), 80 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ -CFLAGS = -O0 -g -std=gnu90 -Wall -Wextra \ +CFLAGS = -O0 -g -std=gnu90 -Wall -Wextra -Werror \ -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes \ -Wmissing-declarations -Wdeclaration-after-statement -fno-stack-protector \ -Wno-unused-function @@ -19,6 +19,7 @@ OBJS = src/io.o \ SRCS=$(OBJS:.o=.c) WASMS = wasm/hello.wasm \ + wasm/unresolved_br.wasm \ wasm/primal.wasm all: protoverse bench test libprotoverse.a wasm diff --git a/src/wasm.c b/src/wasm.c @@ -33,11 +33,6 @@ struct expr_parser { struct cursor *stack; // optional }; -static INLINE struct callframe *top_callframes(struct cursor *cur, int top) -{ - return (struct callframe*)cursor_topn(cur, sizeof(struct callframe), top); -} - static INLINE int cursor_popval(struct cursor *cur, struct val *val) { return cursor_pop(cur, (unsigned char*)val, sizeof(*val)); @@ -122,13 +117,6 @@ static INLINE int read_mem_u32(struct wasm_interp *interp, u32 ptr, u32 *i) return read_mem(interp, ptr, sizeof(*i), i); } -static INLINE int mem_ptr_i32(struct wasm_interp *interp, u32 ptr, int **i) -{ - if (!(*i = (int*)interp_mem_ptr(interp, ptr, sizeof(int)))) - return interp_error(interp, "int memptr"); - return 1; -} - static INLINE int mem_ptr_f32(struct wasm_interp *interp, u32 ptr, float **i) { if (!(*i = (float*)interp_mem_ptr(interp, ptr, sizeof(float)))) @@ -175,22 +163,29 @@ static INLINE struct val *get_local(struct wasm_interp *interp, u32 ind) return &frame->locals[ind]; } -int get_params(struct wasm_interp *interp, struct val** vals, u32 num_vals) +int get_var_params(struct wasm_interp *interp, struct val **vals, u32 *num_vals) { - struct callframe *frame; + struct callframe *frame; - if (unlikely(!(frame = top_callframe(&interp->callframes)))) - return interp_error(interp, "no callframe?"); + if (unlikely(!(frame = top_callframe(&interp->callframes)))) + return interp_error(interp, "no callframe?"); - if (unlikely(num_vals != frame->func->functype->params.num_valtypes)) { - return interp_error(interp, - "requested %d params, but there are %d", - num_vals, frame->func->functype->params.num_valtypes); - } + *num_vals = frame->func->functype->params.num_valtypes; + *vals = frame->locals; + + return 1; +} - *vals = frame->locals; +int get_params(struct wasm_interp *interp, struct val** vals, u32 num_vals) +{ + u32 nvals; + if (!get_var_params(interp, vals, &nvals)) + return 0; + + if (nvals != num_vals) + return interp_error(interp, "requested %d params, but there are %d", num_vals, nvals); - return 1; + return 1; } static INLINE int stack_popval(struct wasm_interp *interp, struct val *val) @@ -406,20 +401,6 @@ void print_callstack(struct wasm_interp *interp) } } -static INLINE int cursor_pushval(struct cursor *cur, struct val *val) -{ - return cursor_push(cur, (u8*)val, sizeof(*val)); -} - -static INLINE int cursor_push_i32(struct cursor *stack, int i) -{ - struct val val; - val.type = val_i32; - val.num.i32 = i; - - return cursor_pushval(stack, &val); -} - static INLINE int cursor_push_i64(struct cursor *stack, s64 i) { struct val val; @@ -475,11 +456,6 @@ static INLINE int stack_push_u64(struct wasm_interp *interp, u64 i) } -static INLINE int stack_push_i32(struct wasm_interp *interp, int i) -{ - return cursor_push_i32(&interp->stack, i); -} - static INLINE void make_i32_val(struct val *val, int v) { val->type = val_i32; @@ -2768,7 +2744,7 @@ static int parse_importdesc(struct wasm_parser *p, struct importdesc *desc) static int find_builtin(struct builtin *builtins, int num_builtins, const char *name) { struct builtin *b; - u32 i; + int i; for (i = 0; i < num_builtins; i++) { b = &builtins[i]; @@ -4045,6 +4021,7 @@ static int call_function(struct wasm_interp *interp, int func_index) static int interp_call(struct wasm_interp *interp, int func_index) { + int res; #ifdef DEBUG struct callframe prev_frame; @@ -4052,7 +4029,7 @@ static int interp_call(struct wasm_interp *interp, int func_index) memcpy(&prev_frame, top_callframe(&interp->callframes), sizeof(struct callframe)); #endif - int res = call_function(interp, func_index); + res = call_function(interp, func_index); if (unlikely(!res)) return 0; @@ -4222,12 +4199,51 @@ static INLINE int resolve_label(struct label *label, struct cursor *code) return 1; } +static INLINE struct resolver *top_resolver_stack(struct cursor *stack, int index) +{ + struct resolver *p = (struct resolver*)stack->p; + p = &p[-(index+1)]; + if (p < (struct resolver*)stack->start) + return NULL; + return p; +} + +static INLINE struct resolver *top_resolver(struct wasm_interp *interp, u32 index) +{ + return top_resolver_stack(&interp->resolver_stack, index); +} + +static void print_resolver_stack(struct wasm_interp *interp) { + int count, i, start_pos, end_pos; + struct label *label; + + printf("resolver stack: "); + count = (int)cursor_count(&interp->resolver_stack, sizeof(struct resolver)); + + for (i = 0; i < count; i++) { + struct resolver *r = top_resolver(interp, i); + if (i != 0) + printf(", "); + + label = index_frame_label(interp, r->label); + + start_pos = label_instr_pos(label); + end_pos = label->jump; + + printf("%s@%d:%s@%d", instr_name(r->start_tag), start_pos, instr_name(r->end_tag), end_pos); + } + printf("\n"); +} + static INLINE int pop_resolver(struct wasm_interp *interp, struct resolver *resolver) { + #if 0 int num_resolvers; struct label *label; + debug("pop label "); + print_resolver_stack(interp); #endif if (!cursor_pop(&interp->resolver_stack, (u8*)resolver, sizeof(*resolver))) { @@ -4278,6 +4294,7 @@ static int pop_label(struct wasm_interp *interp, return 1; } + static INLINE int pop_label_checkpoint(struct wasm_interp *interp) { struct resolver resolver; @@ -4378,6 +4395,8 @@ static int push_label_checkpoint(struct wasm_interp *interp, struct label **labe #if 0 int num_resolvers; + debug("push label "); + print_resolver_stack(interp); #endif resolver.start_tag = start_tag; @@ -4438,7 +4457,7 @@ static int interp_jump(struct wasm_interp *interp, int jmp) return interp_error(interp, "no callframe?"); } - //debug("jumping to %04x\n", jmp); + debug("jumping to %04x\n", jmp); frame->code.p = frame->code.start + jmp; if (unlikely(frame->code.p >= frame->code.end)) { @@ -4449,19 +4468,6 @@ static int interp_jump(struct wasm_interp *interp, int jmp) return 1; } -static INLINE struct resolver *top_resolver_stack(struct cursor *stack, int index) -{ - struct resolver *p = (struct resolver*)stack->p; - p = &p[-(index+1)]; - if (p < (struct resolver*)stack->start) - return NULL; - return p; -} - -static INLINE struct resolver *top_resolver(struct wasm_interp *interp, u32 index) -{ - return top_resolver_stack(&interp->resolver_stack, index); -} static int pop_label_and_skip(struct wasm_interp *interp, struct label *label, int times) @@ -5021,6 +5027,7 @@ static int if_jump(struct wasm_interp *interp, struct label *label) struct expr expr; struct expr_parser parser; struct label *else_label; + struct cursor *codeptr; u8 stopped_at; if (!label) { @@ -5028,7 +5035,16 @@ static int if_jump(struct wasm_interp *interp, struct label *label) } if (is_label_resolved(label)) { - return pop_label_and_skip(interp, label, 1); + //debug("if_jump resolved label "); + //print_resolver_stack(interp); + if (!pop_label_and_skip(interp, label, 1)) + return interp_error(interp, "pop if after resolved jump"); + if (!(codeptr = interp_codeptr(interp)) && codeptr->p - 1 >= codeptr->start) + return interp_error(interp, "codeptr looking for else"); + stopped_at = *(codeptr->p-1); + if (stopped_at == i_else && !push_label_checkpoint(interp, &else_label, i_else, i_end)) + return interp_error(interp, "push else label"); + return 1; } make_interp_expr_parser(interp, &parser); @@ -5297,6 +5313,7 @@ static int interp_br_jump(struct wasm_interp *interp, u32 index) struct label *label; if (unlikely(!(label = top_label(interp, index)))) { + //print_resolver_stack(interp); return interp_return(interp); } @@ -6594,8 +6611,8 @@ static int interp_code(struct wasm_interp *interp) } } - if (ret == BUILTIN_SUSPEND) - return BUILTIN_SUSPEND; + if (ret == BUILTIN_SUSPEND) + return BUILTIN_SUSPEND; } return 1; @@ -7170,13 +7187,42 @@ int wasm_interp_init(struct wasm_interp *interp, struct module *module) void wasm_parser_free(struct wasm_parser *parser) { - free(parser->mem.start); + if (parser->mem.start) { + free(parser->mem.start); + parser->mem.start = 0; + } } void wasm_interp_free(struct wasm_interp *interp) { - free(interp->mem.start); - free(interp->memory.start); + if (interp->mem.start) { + free(interp->mem.start); + interp->mem.start = 0; + } + if (interp->memory.start) { + free(interp->memory.start); + interp->memory.start = 0; + } +} + +int interp_wasm_module_resume(struct wasm_interp *interp, int *retval) +{ + int res = interp_code(interp); + + if (res == 1) { + stack_pop_i32(interp, retval); + debug("interp success!!\n"); + } else if (interp->quitting) { + stack_pop_i32(interp, retval); + debug("process exited\n"); + } else if (res == BUILTIN_SUSPEND) { + return BUILTIN_SUSPEND; + } else { + *retval = 8; + return interp_error(interp, "interp_code"); + } + + return 1; } int interp_wasm_module(struct wasm_interp *interp, int *retval) @@ -7210,21 +7256,7 @@ int interp_wasm_module(struct wasm_interp *interp, int *retval) return interp_error(interp, "call start function"); } - int res = interp_code(interp); - if (res == 1) { - stack_pop_i32(interp, retval); - debug("interp success!!\n"); - } else if (interp->quitting) { - stack_pop_i32(interp, retval); - debug("process exited\n"); - } else if (res == BUILTIN_SUSPEND) { - return BUILTIN_SUSPEND; - } else { - *retval = 8; - return interp_error(interp, "interp_code"); - } - - return 1; + return interp_wasm_module_resume(interp, retval); } int run_wasm(unsigned char *wasm, unsigned long len, diff --git a/src/wasm.h b/src/wasm.h @@ -771,12 +771,14 @@ void wasm_parser_free(struct wasm_parser *parser); void wasm_parser_init(struct wasm_parser *p, u8 *wasm, size_t wasm_len, size_t arena_size, struct builtin *, int num_builtins); void wasm_interp_free(struct wasm_interp *interp); int interp_wasm_module(struct wasm_interp *interp, int *retval); +int interp_wasm_module_resume(struct wasm_interp *interp, int *retval); void print_error_backtrace(struct errors *errors); void setup_wasi(struct wasm_interp *interp, int argc, const char **argv, char **env); void print_callstack(struct wasm_interp *interp); // builtin helpers int get_params(struct wasm_interp *interp, struct val** vals, u32 num_vals); +int get_var_params(struct wasm_interp *interp, struct val** vals, u32 *num_vals); u8 *interp_mem_ptr(struct wasm_interp *interp, u32 ptr, int size); static INLINE struct callframe *top_callframe(struct cursor *cur) @@ -804,5 +806,35 @@ static INLINE int mem_ptr_str(struct wasm_interp *interp, u32 ptr, return 1; } +static INLINE int mem_ptr_i32(struct wasm_interp *interp, u32 ptr, int **i) +{ + if (!(*i = (int*)interp_mem_ptr(interp, ptr, sizeof(int)))) + return interp_error(interp, "int memptr"); + return 1; +} + +static INLINE int cursor_pushval(struct cursor *cur, struct val *val) +{ + return cursor_push(cur, (u8*)val, sizeof(*val)); +} + +static INLINE int cursor_push_i32(struct cursor *stack, int i) +{ + struct val val; + val.type = val_i32; + val.num.i32 = i; + + return cursor_pushval(stack, &val); +} + +static INLINE int stack_push_i32(struct wasm_interp *interp, int i) +{ + return cursor_push_i32(&interp->stack, i); +} + +static INLINE struct callframe *top_callframes(struct cursor *cur, int top) +{ + return (struct callframe*)cursor_topn(cur, sizeof(struct callframe), top); +} #endif /* PROTOVERSE_WASM_H */