commit e283d072205ffa1b07b8d02a7a9891f901f5c358
parent ec9e6662287ed9f6d301d5e7b7bc73fa56e0c6f5
Author: William Casarin <jb55@jb55.com>
Date: Sun, 4 Jun 2023 12:58:01 -0700
fixes
Diffstat:
M | Makefile | | | 3 | ++- |
M | src/wasm.c | | | 190 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
M | src/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 */