From 7150c6753933f12a2ba63769fb7b3a44cfcddd3d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 26 Nov 2020 10:34:31 +0900 Subject: Make `OP_JMP*` operand address to be relative. Jump target address is `operand (16bit)` + `address of next instruction`. In addition, `ilen` was made `uint32_t` so that `iseq` length limitation of 65536 is removed. Only jump target address should be within signed 16bit (-32768 .. 32767). --- src/codedump.c | 15 ++++++++++----- src/vm.c | 11 ++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/codedump.c b/src/codedump.c index 4f793b753..94d4f24c0 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -271,21 +271,26 @@ codedump(mrb_state *mrb, const mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_JMP, S); - printf("OP_JMP\t\t%03d\n", a); + i = pc - irep->iseq; + printf("OP_JMP\t\t%03d\n", (int)i+(int16_t)a); break; CASE(OP_JMPUW, S); - printf("OP_JMPUW\t\t%03d\n", a); + i = pc - irep->iseq; + printf("OP_JMPUW\t\t%03d\n", (int)i+(int16_t)a); break; CASE(OP_JMPIF, BS); - printf("OP_JMPIF\tR%d\t%03d\t", a, b); + i = pc - irep->iseq; + printf("OP_JMPIF\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; CASE(OP_JMPNOT, BS); - printf("OP_JMPNOT\tR%d\t%03d\t", a, b); + i = pc - irep->iseq; + printf("OP_JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; CASE(OP_JMPNIL, BS); - printf("OP_JMPNIL\tR%d\t%03d\t", a, b); + i = pc - irep->iseq; + printf("OP_JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; CASE(OP_SENDV, BB); diff --git a/src/vm.c b/src/vm.c index a0d4c967b..85835149a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1274,26 +1274,26 @@ RETRY_TRY_BLOCK: } CASE(OP_JMP, S) { - pc = irep->iseq+a; + pc += (int16_t)a; JUMP; } CASE(OP_JMPIF, BS) { if (mrb_test(regs[a])) { - pc = irep->iseq+b; + pc += (int16_t)b; JUMP; } NEXT; } CASE(OP_JMPNOT, BS) { if (!mrb_test(regs[a])) { - pc = irep->iseq+b; + pc += (int16_t)b; JUMP; } NEXT; } CASE(OP_JMPNIL, BS) { if (mrb_nil_p(regs[a])) { - pc = irep->iseq+b; + pc += (int16_t)b; JUMP; } NEXT; @@ -1306,6 +1306,7 @@ RETRY_TRY_BLOCK: mrb_assert(mrb_integer_p(target)); a = (uint32_t)mrb_integer(target); mrb_assert(a >= 0 && a < irep->ilen); + a = a - (pc - irep->iseq); } CHECKPOINT_MAIN(RBREAK_TAG_JUMP) { ch = catch_handler_find(mrb, mrb->c->ci, pc, MRB_CATCH_FILTER_ENSURE); @@ -1319,7 +1320,7 @@ RETRY_TRY_BLOCK: CHECKPOINT_END(RBREAK_TAG_JUMP); mrb->exc = NULL; /* clear break object */ - pc = irep->iseq + a; + pc += (int16_t)a; JUMP; } -- cgit v1.2.3