|
29 | 29 | #include "emit.h" |
30 | 30 | #endif |
31 | 31 |
|
| 32 | +static int bad_16bit_jump(int32_t lab1, int32_t lab2) { |
| 33 | + if (lab2 - lab1 > INT16_MAX) return 1; |
| 34 | + if (lab2 - lab1 < INT16_MIN) return 1; |
| 35 | + return 0; |
| 36 | +} |
| 37 | + |
| 38 | +static void check_16bit_jump(JanetCompiler *c, int32_t lab1, int32_t lab2) { |
| 39 | + if (bad_16bit_jump(lab1, lab2)) { |
| 40 | + janetc_cerror(c, "bad 16-bit jump, too large"); |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +static int bad_24bit_jump(int32_t lab1, int32_t lab2) { |
| 45 | + if (lab2 - lab1 > 0xFFFFFF) return 1; |
| 46 | + if (lab2 - lab1 < -0x1000000) return 1; |
| 47 | + return 0; |
| 48 | +} |
| 49 | + |
| 50 | +static void check_24bit_jump(JanetCompiler *c, int32_t lab1, int32_t lab2) { |
| 51 | + if (bad_24bit_jump(lab1, lab2)) { |
| 52 | + janetc_cerror(c, "bad 24-bit jump, too large"); |
| 53 | + } |
| 54 | +} |
| 55 | + |
32 | 56 | static JanetSlot janetc_quote(JanetFopts opts, int32_t argn, const Janet *argv) { |
33 | 57 | if (argn != 1) { |
34 | 58 | janetc_cerror(opts.compiler, "expected 1 argument to quote"); |
@@ -209,6 +233,8 @@ static int destructure(JanetCompiler *c, |
209 | 233 | int32_t label_loop_exit = janet_v_count(c->buffer); |
210 | 234 |
|
211 | 235 | /* avoid shifting negative numbers */ |
| 236 | + check_16bit_jump(c, label_loop_cond_jump, label_loop_exit); |
| 237 | + check_24bit_jump(c, label_loop_start, label_loop_loop); |
212 | 238 | c->buffer[label_loop_cond_jump] |= (uint32_t)(label_loop_exit - label_loop_cond_jump) << 16; |
213 | 239 | c->buffer[label_loop_loop] |= (uint32_t)(label_loop_start - label_loop_loop) << 8; |
214 | 240 |
|
@@ -696,8 +722,12 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) { |
696 | 722 | /* Write jumps - only add jump lengths if jump actually emitted */ |
697 | 723 | labeld = janet_v_count(c->buffer); |
698 | 724 | if (labeljr < labeld) { |
| 725 | + check_16bit_jump(c, labeljr, labelr); |
699 | 726 | c->buffer[labeljr] |= (labelr - labeljr) << 16; |
700 | | - if (!tail && labeljd < labeld) c->buffer[labeljd] |= (labeld - labeljd) << 8; |
| 727 | + if (!tail && labeljd < labeld) { |
| 728 | + check_24bit_jump(c, labeljd, labeld); |
| 729 | + c->buffer[labeljd] |= (labeld - labeljd) << 8; |
| 730 | + } |
701 | 731 | } |
702 | 732 |
|
703 | 733 | if (tail) target.flags |= JANET_SLOT_RETURNED; |
@@ -938,12 +968,18 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv) |
938 | 968 |
|
939 | 969 | /* Calculate jumps */ |
940 | 970 | labeld = janet_v_count(c->buffer); |
941 | | - if (!infinite) c->buffer[labelc] |= (uint32_t)(labeld - labelc) << 16; |
| 971 | + if (!infinite) { |
| 972 | + check_16bit_jump(c, labelc, labeld); |
| 973 | + c->buffer[labelc] |= (uint32_t)(labeld - labelc) << 16; |
| 974 | + } |
| 975 | + |
| 976 | + check_24bit_jump(c, labeljt, labelwt); |
942 | 977 | c->buffer[labeljt] |= (uint32_t)(labelwt - labeljt) << 8; |
943 | 978 |
|
944 | 979 | /* Calculate breaks */ |
945 | 980 | for (int32_t i = labelwt; i < labeld; i++) { |
946 | 981 | if (c->buffer[i] == (0x80 | JOP_JUMP)) { |
| 982 | + check_24bit_jump(c, i, labeld); |
947 | 983 | c->buffer[i] = JOP_JUMP | ((labeld - i) << 8); |
948 | 984 | } |
949 | 985 | } |
|
0 commit comments