protoverse

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

commit 2783bc8393fb132dd45a6499621d5175bb0813ca
parent 262c1e1d06b048aebacfd6902d7afad408c72665
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 24 Jul 2021 11:02:30 -0700

fix resolver offset issue on if tag

Diffstat:
Msrc/protoverse.c | 4+++-
Msrc/wasm.c | 59++++++++++++++++++++++++++++++++---------------------------
2 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/src/protoverse.c b/src/protoverse.c @@ -99,9 +99,11 @@ static int usage(void) } +extern char **environ; -int main(int argc, const char *argv[], char **env) +int main(int argc, const char *argv[]) { + char **env = environ; const char *space, *code_file; const char *cmd; unsigned char *wasm_data; diff --git a/src/wasm.c b/src/wasm.c @@ -603,6 +603,24 @@ static INLINE int cursor_push_callframe(struct cursor *cur, struct callframe *fr return cursor_push(cur, (u8*)frame, sizeof(*frame)); } +static INLINE int count_resolvers(struct wasm_interp *interp) +{ + return cursor_count(&interp->resolver_stack, sizeof(struct resolver)); +} + +static INLINE int push_callframe(struct wasm_interp *interp, struct callframe *frame) +{ + u32 offset; + + offset = count_resolvers(interp); + /* push label resolver offsets, used to keep track of per-func resolvers */ + /* TODO: maybe move this data to struct func? */ + if (unlikely(!cursor_push_int(&interp->resolver_offsets, offset))) + return interp_error(interp, "push resolver offset"); + + return cursor_push_callframe(&interp->callframes, frame); +} + static INLINE int cursor_drop_callframe(struct cursor *cur) { //debug("dropping callframe %d fn:%d\n", callframe_cnt--, top_callframe(cur)->fn); @@ -3076,6 +3094,7 @@ static INLINE int count_local_resolvers(struct wasm_interp *interp, int *count) return interp_error(interp, "resolver offset oob?"); } *count = (interp->resolver_stack.p - p) / sizeof(struct resolver); + //debug("offset %d count %d stack.p - p %ld\n", offset, *count, interp->resolver_stack.p - p); return 1; } @@ -3132,8 +3151,8 @@ static INLINE int call_wasm_func(struct wasm_interp *interp, struct wasm_func *f assert(func->code.code_len > 0); - if (unlikely(!cursor_push_callframe(&interp->callframes, &callframe))) - return interp_error(interp, "oob cursor_pushcode"); + if (unlikely(!push_callframe(interp, &callframe))) + return interp_error(interp, "push callframe"); /* if (unlikely(!interp_code(interp))) { @@ -3157,9 +3176,8 @@ static INLINE int call_builtin_func(struct wasm_interp *interp, struct builtin * /* update current function and push it to the callframe as well */ callframe.fn = fn; - if (unlikely(!cursor_push_callframe(&interp->callframes, &callframe))) { + if (unlikely(!push_callframe(interp, &callframe))) return interp_error(interp, "oob cursor_pushcode"); - } if (!builtin->fn(interp)) return interp_error(interp, "builtin trap"); @@ -3186,11 +3204,6 @@ static INLINE int call_func(struct wasm_interp *interp, struct func *func, int f return interp_error(interp, "corrupt func type: %02x", func->type); } -static INLINE int count_resolvers(struct wasm_interp *interp) -{ - return cursor_count(&interp->resolver_stack, sizeof(struct resolver)); -} - static void make_default_val(struct val *val) { switch (val->type) { @@ -3221,7 +3234,7 @@ static int prepare_call(struct wasm_interp *interp, struct func *func, struct local *local; enum valtype paramtype; struct val val; - u32 i, ind, offset; + u32 i, ind; /* push params as locals */ for (i = 0; i < func->functype->params.num_valtypes; i++) { @@ -3255,12 +3268,6 @@ static int prepare_call(struct wasm_interp *interp, struct func *func, memcpy(&func->locals[ind], &val, sizeof(struct val)); } - offset = count_resolvers(interp); - /* push label resolver offsets, used to keep track of per-func resolvers */ - /* TODO: maybe move this data to struct func? */ - if (unlikely(!cursor_push_int(&interp->resolver_offsets, offset))) - return interp_error(interp, "push resolver offset"); - for (i=func->functype->params.num_valtypes; i < func->num_locals; i++) { local = &func->locals[i]; @@ -4094,16 +4101,11 @@ static int parse_instr(struct expr_parser *p, u8 tag, struct instr *op) return note_error(p->errs, p->code, "unhandled tag: 0x%x", tag); } -static int if_jump(struct wasm_interp *interp, u8 start_tag, u8 end_tag) +static int if_jump(struct wasm_interp *interp, struct label *label) { u8 *instrs; u32 instrs_len; struct expr_parser parser; - struct label *label; - - if (!push_label_checkpoint(interp, &label, start_tag, end_tag)) { - return interp_error(interp, "label checkpoint"); - } if (!label) { return interp_error(interp, "no label?"); @@ -4116,10 +4118,8 @@ static int if_jump(struct wasm_interp *interp, u8 start_tag, u8 end_tag) make_interp_expr_parser(interp, &parser); // consume instructions, use resolver stack to resolve jumps - if (!parse_instrs_until(&parser, end_tag, &instrs, &instrs_len)) { - return interp_error(interp, "parse instrs start @ %s end @ %s", - instr_name(start_tag), - instr_name(end_tag)); + if (!parse_instrs_until(&parser, i_if, &instrs, &instrs_len)) { + return interp_error(interp, "parse instrs start (if)"); } return pop_label_checkpoint(interp); @@ -4152,6 +4152,7 @@ static int interp_if(struct wasm_interp *interp) struct val cond; struct blocktype blocktype; struct cursor *code; + struct label *label; if (unlikely(!(code = interp_codeptr(interp)))) { return interp_error(interp, "empty callstack?"); @@ -4165,11 +4166,15 @@ static int interp_if(struct wasm_interp *interp) return interp_error(interp, "if pop val"); } + if (!push_label_checkpoint(interp, &label, i_if, i_if)) { + return interp_error(interp, "label checkpoint"); + } + if (cond.num.i32 == 1) { return 1; } - if (unlikely(!if_jump(interp, i_if, i_if))) { + if (unlikely(!if_jump(interp, label))) { return interp_error(interp, "jump"); }