protoverse

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

commit eba34599d41a416614ceebac7bdd74bffa22f3cf
parent 26b860cbe12af5fe84515649bacc3d8eef94095c
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 18 Jul 2021 22:00:33 -0700

pop resolver multiple times during quick jumps

Diffstat:
Msrc/wasm.c | 61++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/src/wasm.c b/src/wasm.c @@ -2708,9 +2708,12 @@ static int interp_code(struct wasm_interp *interp); static int interp_call(struct wasm_interp *interp, int func_index) { - struct callframe frame, *prev_frame; + struct callframe frame; +#ifdef DEBUG + struct callframe *prev_frame; prev_frame = top_callframe(&interp->callframes); +#endif if (unlikely(!prepare_call(interp, func_index))) { interp_error(interp, "prepare"); @@ -2809,14 +2812,27 @@ static INLINE int resolve_label(struct label *label, struct cursor *code) static INLINE int pop_resolver(struct wasm_interp *interp, struct resolver *resolver) { +#ifdef DEBUG + int num_resolvers; +#endif + if (!cursor_pop(&interp->resolver_stack, (u8*)resolver, sizeof(*resolver))) { return interp_error(interp, "pop resolver"); } - debug("popped resolver %d i_%s i_%s %d\n", + +#ifdef DEBUG + if (unlikely(!count_local_resolvers(interp, &num_resolvers))) { + return interp_error(interp, "local resolvers fn start"); + }; +#endif + + debug("popped resolver %d i_%s i_%s %d local_resolvers:%d\n", resolver->label, instr_name(resolver->start_tag), instr_name(resolver->end_tag), - count_resolvers(interp)); + count_resolvers(interp), + num_resolvers + ); return 1; } @@ -2931,6 +2947,10 @@ static int push_label_checkpoint(struct wasm_interp *interp, struct label **labe struct resolver resolver; struct callframe *frame; +#ifdef DEBUG + int num_resolvers; +#endif + resolver.start_tag = start_tag; resolver.end_tag = end_tag; resolver.label = 0; @@ -2961,11 +2981,17 @@ static int push_label_checkpoint(struct wasm_interp *interp, struct label **labe return interp_error(interp, "push label index to resolver stack oob"); } - debug("pushed resolver %d i_%s i_%s %ld \n", +#ifdef DEBUG + if (unlikely(!count_local_resolvers(interp, &num_resolvers))) { + return interp_error(interp, "local resolvers fn start"); + }; +#endif + debug("pushed resolver %d i_%s i_%s %ld local_resolvers:%d \n", resolver.label, instr_name(resolver.start_tag), instr_name(resolver.end_tag), - cursor_count(&interp->resolver_stack, sizeof(resolver))); + cursor_count(&interp->resolver_stack, sizeof(resolver)), + num_resolvers); return 1; } @@ -2995,12 +3021,19 @@ static INLINE int jump_to_label(struct wasm_interp *interp, struct label *label) return interp_jump(interp, label->jump); } -static int pop_label_and_jump(struct wasm_interp *interp, int jump) +static int pop_label_and_jump(struct wasm_interp *interp, struct label *label, int times) { - if (!pop_label_checkpoint(interp)) - return interp_error(interp, "pop checkpoint"); + int i; + assert(is_label_resolved(label)); + + for (i = 0; i < times; i++) { + if (!cursor_drop(&interp->resolver_stack, + sizeof(struct resolver))) { + return interp_error(interp, "drop label"); + } + } - return interp_jump(interp, jump); + return interp_jump(interp, label->jump); } static int parse_block(struct expr_parser *p, struct block *block, u8 start_tag, u8 end_tag) @@ -3025,7 +3058,7 @@ static int parse_block(struct expr_parser *p, struct block *block, u8 start_tag, return interp_error(p->interp, "jump is before instr_pos ??"); } - return pop_label_and_jump(p->interp, label->jump); + return pop_label_and_jump(p->interp, label, 1); } if (!parse_instrs_until(p, end_tag, &block->instrs, &block->instrs_len)) @@ -3298,7 +3331,7 @@ static int branch_jump(struct wasm_interp *interp, u8 start_tag, u8 end_tag) } if (is_label_resolved(label)) { - return pop_label_and_jump(interp, label->jump); + return pop_label_and_jump(interp, label, 1); } make_interp_expr_parser(interp, &parser); @@ -3432,7 +3465,7 @@ static int unresolved_break(struct wasm_interp *interp, int index) // TODO: breaking from functions (return) if (is_label_resolved(label)) { - if (!pop_label_and_jump(interp, label->jump)) + if (!pop_label_and_jump(interp, label, 1)) return interp_error(interp, "pop and jump"); else continue; @@ -3462,7 +3495,7 @@ static int interp_br_jump(struct wasm_interp *interp, int index) } if (is_label_resolved(label)) { - return pop_label_and_jump(interp, label->jump); + return pop_label_and_jump(interp, label, index+1); } return unresolved_break(interp, index); @@ -4293,6 +4326,8 @@ static enum interp_end interp_code_end(struct wasm_interp *interp, return interp_error(interp, "count local resolvers"); } + debug("interp_code_end local resolvers: %d\n", num_resolvers); + if (num_resolvers == 0) { if (!cursor_popint(&interp->resolver_offsets, &offset)) { return interp_error(interp, "pop resolver_offsets");