diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-09-19 16:56:32 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-09-19 16:56:32 +0300 |
commit | d567612fd6344204c6c8438b8fe7fe7dbd54d924 (patch) | |
tree | af8f09821c108718e8659a391aa1f12762d4fba8 | |
parent | 798c891dc6ed0016810f7363bc5914764d3c0fc7 (diff) | |
download | ejit-master.tar.gz ejit-master.zip |
-rw-r--r-- | src/compile/compile.c | 11 | ||||
-rw-r--r-- | tests/z_double_label.c | 38 |
2 files changed, 43 insertions, 6 deletions
diff --git a/src/compile/compile.c b/src/compile/compile.c index 2c72b91..f6bf144 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -2070,12 +2070,11 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t label = 0; for (size_t ii = 0; ii < insns_len(&f->insns); ++ii) { /* if we've hit a label, add it to our vector of label addresses */ - if (label < labels_len(&f->labels)) { - if (*labels_at(&f->labels, label) == ii) { - compile_label(j, ii, &addrs); - resolve_relocs(j, &relocs, &addrs, ii); - label++; - } + while (label < labels_len(&f->labels) + && *labels_at(&f->labels, label) == ii) { + compile_label(j, ii, &addrs); + resolve_relocs(j, &relocs, &addrs, ii); + label++; } struct ejit_insn i = *insns_at(&f->insns, ii); diff --git a/tests/z_double_label.c b/tests/z_double_label.c new file mode 100644 index 0000000..4817d8c --- /dev/null +++ b/tests/z_double_label.c @@ -0,0 +1,38 @@ +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" + +int main(int argc, char *argv[]) +{ + (void)argv; + bool do_jit = argc > 1; + struct ejit_func *f = ejit_create_func(EJIT_INT32, 0, NULL); + ejit_movi(f, EJIT_GPR(0), 0); + + struct ejit_reloc l1 = ejit_jmp(f); + struct ejit_label mid = ejit_label(f); + struct ejit_reloc l2 = ejit_jmp(f); + + /* patch relocs to same address with two separate labels. */ + ejit_patch(f, l1, ejit_label(f)); + ejit_patch(f, l2, ejit_label(f)); + + /* we came from the first jump, jump to the end */ + struct ejit_reloc end = ejit_beqi(f, EJIT_GPR(0), 1); + + /* set r0 to 1 to indicate that we've done the first jump */ + ejit_movi(f, EJIT_GPR(0), 1); + + /* jump in between the two jumps */ + ejit_patch(f, ejit_jmp(f), mid); + + ejit_patch(f, end, ejit_label(f)); + ejit_reti(f, 0); + + + ejit_select_compile_func(f, 1, 0, false, do_jit, true); + + assert(ejit_run_func_i(f, 0, NULL) == 0); + + ejit_destroy_func(f); +} |