commit 6d5354ef9d578eea5005d93eceda11f967a5ee52
parent 7b339344a860bcb148b919539d6f249f63e81293
Author: William Casarin <jb55@jb55.com>
Date: Wed, 14 Jul 2021 07:53:41 -0700
label resolution seems to be working ok...
Diffstat:
M | src/wasm.c | | | 114 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 65 insertions(+), 49 deletions(-)
diff --git a/src/wasm.c b/src/wasm.c
@@ -2102,12 +2102,11 @@ static inline int label_is_resolved(struct label *label)
return label->instr_pos & 0x80000000;
}
-
static int resolve_label(struct wasm_interp *interp)
{
struct label *label;
struct callframe *frame;
- u32 label_ind = 0;
+ u16 label_ind = 0;
if (!cursor_pop(&interp->resolver_stack, (u8*)&label_ind, sizeof(label_ind))) {
interp_error(interp, "couldn't pop jump resolver stack");
@@ -2121,9 +2120,13 @@ static int resolve_label(struct wasm_interp *interp)
assert(label);
assert(!label_is_resolved(label));
+
label->jump = frame->code.p - frame->code.start;
label->instr_pos |= 0x80000000;
+ debug("resolving label %d (instr pos %04X) to %04X\n", label_ind,
+ label_instr_pos(label), label->jump);
+
return 1;
}
@@ -2147,50 +2150,21 @@ static int parse_instrs_until(struct wasm_interp *interp, u8 stop_instr,
parsed_instrs->p = code->p;
for (;;) {
- if (!pull_byte(code, &tag) && tag == stop_instr) {
- parsed_instrs->end = code->p;
- return 1;
+ if (!pull_byte(code, &tag)) {
+ interp_error(interp, "oob");
+ return 0;
}
if (!parse_instr(interp, tag, &op)) {
interp_error(interp, "parse %s instr (0x%x)", instr_name(tag), tag);
return 0;
}
- }
-}
-
-
-static int parse_block(struct wasm_interp *interp, struct block *block, u8 end_tag)
-{
- struct cursor *code;
-
- if (!(code = interp_codeptr(interp))) {
- interp_error(interp, "codeptr");
- return 0;
- }
-
- if (!parse_blocktype(code, &interp->errors, &block->type)) {
- interp_error(interp, "blocktype");
- return 0;
- }
- if (!label_checkpoint(interp)) {
- interp_error(interp, "checkpoint");
- return 0;
- }
-
- if (!parse_instrs_until(interp, end_tag, &block->instrs)) {
- interp_error(interp, "checkpoint");
- return 0;
+ if (tag == stop_instr) {
+ parsed_instrs->end = code->p;
+ return 1;
+ }
}
-
- return resolve_label(interp);
-}
-
-static inline int parse_memarg(struct cursor *code, struct memarg *memarg)
-{
- return leb128_read(code, &memarg->offset) &&
- leb128_read(code, &memarg->align);
}
static inline u16 *func_num_labels(struct wasm_interp *interp, int fn)
@@ -2201,12 +2175,6 @@ static inline u16 *func_num_labels(struct wasm_interp *interp, int fn)
return num;
}
-static inline void set_label_pos(struct label *label, u32 pos)
-{
- assert(!(pos & 0x80000000));
- label->instr_pos = pos;
-}
-
static int find_label(struct wasm_interp *interp, int fn, u32 instr_pos)
{
u16 *num_labels, i;
@@ -2226,6 +2194,12 @@ static int find_label(struct wasm_interp *interp, int fn, u32 instr_pos)
return -1;
}
+static inline void set_label_pos(struct label *label, u32 pos)
+{
+ assert(!(pos & 0x80000000));
+ label->instr_pos = pos;
+}
+
// upsert an unresolved label
static int upsert_label(struct wasm_interp *interp, int fn,
u32 instr_pos, int *ind)
@@ -2259,6 +2233,7 @@ static int upsert_label(struct wasm_interp *interp, int fn,
return 2;
}
+
static int label_checkpoint(struct wasm_interp *interp)
{
u32 instr_pos;
@@ -2299,6 +2274,7 @@ static int label_checkpoint(struct wasm_interp *interp)
return 1;
}
+ debug("pushing %d to resolver stack\n", ind);
if (!cursor_push_u16(&interp->resolver_stack, ind)) {
interp_error(interp, "push label index to resolver stack oob");
return 0;
@@ -2308,6 +2284,42 @@ static int label_checkpoint(struct wasm_interp *interp)
}
+static int parse_block(struct wasm_interp *interp, struct block *block, u8 end_tag)
+{
+ struct cursor *code;
+
+ debug("parsing block");
+
+ if (!(code = interp_codeptr(interp))) {
+ interp_error(interp, "codeptr");
+ return 0;
+ }
+
+ if (!parse_blocktype(code, &interp->errors, &block->type)) {
+ interp_error(interp, "blocktype");
+ return 0;
+ }
+
+ if (!label_checkpoint(interp)) {
+ interp_error(interp, "checkpoint");
+ return 0;
+ }
+
+ if (!parse_instrs_until(interp, end_tag, &block->instrs)) {
+ interp_error(interp, "checkpoint");
+ return 0;
+ }
+
+ return resolve_label(interp);
+}
+
+static inline int parse_memarg(struct cursor *code, struct memarg *memarg)
+{
+ return leb128_read(code, &memarg->offset) &&
+ leb128_read(code, &memarg->align);
+}
+
+
static int parse_instr(struct wasm_interp *interp, u8 tag, struct instr *op)
{
struct cursor *code;
@@ -2317,6 +2329,9 @@ static int parse_instr(struct wasm_interp *interp, u8 tag, struct instr *op)
return 0;
}
+ debug("%04lX parsing instr %s (0x%02x)\n", code->p - 1 - code->start,
+ instr_name(tag), tag);
+
switch (tag) {
// two-byte instrs
case i_memory_size:
@@ -2480,7 +2495,7 @@ static int branch_jump(struct wasm_interp *interp, u8 end_tag)
return 0;
}
- return 1;
+ return resolve_label(interp);
}
static int interp_if(struct wasm_interp *interp)
@@ -2512,15 +2527,15 @@ static int interp_if(struct wasm_interp *interp)
return 0;
}
- return 0;
+ return 1;
}
static int interp_instr(struct wasm_interp *interp, unsigned char tag)
{
interp->ops++;
- debug("0x%03lX %s\n",
- interp_codeptr(interp)->p - interp_codeptr(interp)->start,
+ debug("%04lX %s\n",
+ interp_codeptr(interp)->p - 1 - interp_codeptr(interp)->start,
instr_name(tag));
switch (tag) {
@@ -2535,7 +2550,8 @@ static int interp_instr(struct wasm_interp *interp, unsigned char tag)
case i_if: return interp_if(interp);
case i_call: return interp_call(interp);
default:
- interp_error(interp, "unhandled instruction 0x%x", tag);
+ interp_error(interp, "unhandled instruction %s 0x%x",
+ instr_name(tag), tag);
return 0;
}