mirror of
https://github.com/janet-lang/janet
synced 2026-11-11 15:34:27 +00:00
Add casts to u32 before left shifts to address ubsan edge cases.
Common idiom that wasn't always applied, especially in emit.c and cfuns.c
This commit is contained in:
1 parent
88c42fff48
commit
8dbe828504
7 files changed
+45
-34
No files matched your search
+2
-2
@@ -188,7 +188,7 @@ static JanetSlot do_get(JanetFopts opts, JanetSlot *args) {
|
||||
janetc_copy(c, t, dflt_slot);
|
||||
if (target_is_default) janetc_freeslot(c, dflt_slot);
|
||||
int32_t current = janet_v_count(c->buffer);
|
||||
c->buffer[label] |= (current - label) << 16;
|
||||
c->buffer[label] |= (uint32_t)(current - label) << 16;
|
||||
return t;
|
||||
} else {
|
||||
return opreduce(opts, args, JOP_GET, 0, janet_wrap_nil(), janet_wrap_nil());
|
||||
@@ -345,7 +345,7 @@ static JanetSlot compreduce(
|
||||
int32_t end = janet_v_count(c->buffer);
|
||||
for (i = 0; i < janet_v_count(labels); i++) {
|
||||
int32_t label = labels[i];
|
||||
c->buffer[label] |= ((end - label) << 16);
|
||||
c->buffer[label] |= ((uint32_t)(end - label) << 16);
|
||||
}
|
||||
janet_v_free(labels);
|
||||
return t;
|
||||
|
||||
+5
-1
@@ -280,7 +280,11 @@ Shadowing janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym) {
|
||||
for (int32_t i = len - 1; i >= 0; i--) {
|
||||
SymPair *pair = scope->syms + i;
|
||||
if (pair->sym == sym) {
|
||||
janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug");
|
||||
if (is_global) {
|
||||
/* This can happen in a top level form like (def [x [x y]] [1 [2 3]])` where a symbol is reused in one expression */
|
||||
/* janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug"); */
|
||||
return JANETC_SHADOW_GLOBAL_HIDES_GLOBAL;
|
||||
}
|
||||
return JANETC_SHADOW_LOCAL_HIDES_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -441,19 +441,22 @@ JANET_CORE_FN(janet_core_range,
|
||||
start = janet_getnumber(argv, 0);
|
||||
stop = janet_getnumber(argv, 1);
|
||||
step = janet_getnumber(argv, 2);
|
||||
count = (step > 0) ? (stop - start) / step :
|
||||
((step < 0) ? (stop - start) / step : 0);
|
||||
count = (step > 0.0) ? (stop - start) / step :
|
||||
((step < 0.0) ? (stop - start) / step : 0.0);
|
||||
} else if (argc == 2) {
|
||||
start = janet_getnumber(argv, 0);
|
||||
stop = janet_getnumber(argv, 1);
|
||||
start = janet_getnumber(argv, 0.0);
|
||||
stop = janet_getnumber(argv, 1.0);
|
||||
count = stop - start;
|
||||
} else {
|
||||
stop = janet_getnumber(argv, 0);
|
||||
stop = janet_getnumber(argv, 0.0);
|
||||
count = stop;
|
||||
}
|
||||
count = (count > 0) ? count : 0;
|
||||
if (isinf(step)) {
|
||||
janet_panic("infinite step not allowed");
|
||||
}
|
||||
count = (count > 0.0) ? count : 0.0;
|
||||
int32_t int_count;
|
||||
janet_assert(count >= 0, "bad range code");
|
||||
janet_assert(count >= 0.0, "bad range code");
|
||||
if (count > (double) INT32_MAX) {
|
||||
janet_panicf("range is too large, %f elements", count);
|
||||
} else {
|
||||
|
||||
+17
-17
@@ -78,10 +78,10 @@ static int32_t janetc_const(JanetCompiler *c, Janet x) {
|
||||
static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
|
||||
switch (janet_type(k)) {
|
||||
case JANET_NIL:
|
||||
janetc_emit(c, (reg << 8) | JOP_LOAD_NIL);
|
||||
janetc_emit(c, ((uint32_t) reg << 8) | JOP_LOAD_NIL);
|
||||
break;
|
||||
case JANET_BOOLEAN:
|
||||
janetc_emit(c, (reg << 8) |
|
||||
janetc_emit(c, ((uint32_t) reg << 8) |
|
||||
(janet_unwrap_boolean(k) ? JOP_LOAD_TRUE : JOP_LOAD_FALSE));
|
||||
break;
|
||||
case JANET_NUMBER: {
|
||||
@@ -93,8 +93,8 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
|
||||
goto do_constant;
|
||||
uint32_t iu = (uint32_t)i;
|
||||
janetc_emit(c,
|
||||
(iu << 16) |
|
||||
(reg << 8) |
|
||||
((uint32_t) iu << 16) |
|
||||
((uint32_t) reg << 8) |
|
||||
JOP_LOAD_INTEGER);
|
||||
break;
|
||||
}
|
||||
@@ -102,8 +102,8 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
|
||||
do_constant: {
|
||||
int32_t cindex = janetc_const(c, k);
|
||||
janetc_emit(c,
|
||||
(cindex << 16) |
|
||||
(reg << 8) |
|
||||
((uint32_t) cindex << 16) |
|
||||
((uint32_t) reg << 8) |
|
||||
JOP_LOAD_CONSTANT);
|
||||
break;
|
||||
}
|
||||
@@ -120,8 +120,8 @@ static void janetc_movenear(JanetCompiler *c,
|
||||
/* If we also are a reference, deref the one element array */
|
||||
if (src.flags & JANET_SLOT_REF) {
|
||||
janetc_emit(c,
|
||||
(dest << 16) |
|
||||
(dest << 8) |
|
||||
((uint32_t) dest << 16) |
|
||||
((uint32_t) dest << 8) |
|
||||
JOP_GET_INDEX);
|
||||
}
|
||||
} else if (src.envindex >= 0) {
|
||||
@@ -147,15 +147,15 @@ static void janetc_moveback(JanetCompiler *c,
|
||||
int32_t refreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_5);
|
||||
janetc_loadconst(c, dest.constant, refreg);
|
||||
janetc_emit(c,
|
||||
(src << 16) |
|
||||
(refreg << 8) |
|
||||
((uint32_t) src << 16) |
|
||||
((uint32_t) refreg << 8) |
|
||||
JOP_PUT_INDEX);
|
||||
janetc_regalloc_freetemp(&c->scope->ra, refreg, JANETC_REGTEMP_5);
|
||||
} else if (dest.envindex >= 0) {
|
||||
/* Convert src to near reg */
|
||||
if (src > 255) {
|
||||
int32_t newsrc = JANETC_REGTEMP_5 + 0xF0;
|
||||
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | (newsrc << 8));
|
||||
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | ((uint32_t) newsrc << 8));
|
||||
src = newsrc;
|
||||
}
|
||||
janetc_emit(c,
|
||||
@@ -199,7 +199,7 @@ static int32_t janetc_regfar(JanetCompiler *c, JanetSlot s, JanetcRegisterTemp t
|
||||
janetc_movenear(c, nearreg, s);
|
||||
if (nearreg >= 0xF0) {
|
||||
reg = janetc_allocfar(c);
|
||||
janetc_emit(c, JOP_MOVE_FAR | (nearreg << 8) | (reg << 16));
|
||||
janetc_emit(c, JOP_MOVE_FAR | ((uint32_t) nearreg << 8) | ((uint32_t) reg << 16));
|
||||
janetc_regalloc_freetemp(&c->scope->ra, nearreg, tag);
|
||||
} else {
|
||||
reg = nearreg;
|
||||
@@ -268,7 +268,7 @@ void janetc_copy(
|
||||
static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, int wr) {
|
||||
int32_t reg = janetc_regnear(c, s, JANETC_REGTEMP_0);
|
||||
int32_t label = janet_v_count(c->buffer);
|
||||
janetc_emit(c, op | (reg << 8) | ((uint32_t)rest << 16));
|
||||
janetc_emit(c, op | ((uint32_t) reg << 8) | ((uint32_t) rest << 16));
|
||||
if (wr)
|
||||
janetc_moveback(c, s, reg);
|
||||
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
|
||||
@@ -278,7 +278,7 @@ static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, i
|
||||
int32_t janetc_emit_s(JanetCompiler *c, uint8_t op, JanetSlot s, int wr) {
|
||||
int32_t reg = janetc_regfar(c, s, JANETC_REGTEMP_0);
|
||||
int32_t label = janet_v_count(c->buffer);
|
||||
janetc_emit(c, op | (reg << 8));
|
||||
janetc_emit(c, op | ((uint32_t) reg << 8));
|
||||
if (wr)
|
||||
janetc_moveback(c, s, reg);
|
||||
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
|
||||
@@ -310,7 +310,7 @@ static int32_t emit2s(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
|
||||
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
|
||||
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
|
||||
int32_t label = janet_v_count(c->buffer);
|
||||
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)rest << 24));
|
||||
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t)rest << 24));
|
||||
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
|
||||
if (wr)
|
||||
janetc_moveback(c, s1, reg1);
|
||||
@@ -322,7 +322,7 @@ int32_t janetc_emit_ss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
|
||||
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
|
||||
int32_t reg2 = janetc_regfar(c, s2, JANETC_REGTEMP_1);
|
||||
int32_t label = janet_v_count(c->buffer);
|
||||
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16));
|
||||
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16));
|
||||
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
|
||||
if (wr)
|
||||
janetc_moveback(c, s1, reg1);
|
||||
@@ -343,7 +343,7 @@ int32_t janetc_emit_sss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2
|
||||
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
|
||||
int32_t reg3 = janetc_regnear(c, s3, JANETC_REGTEMP_2);
|
||||
int32_t label = janet_v_count(c->buffer);
|
||||
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)reg3 << 24));
|
||||
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t) reg3 << 24));
|
||||
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
|
||||
janetc_free_regnear(c, s3, reg3, JANETC_REGTEMP_2);
|
||||
if (wr)
|
||||
|
||||
+7
-7
@@ -723,10 +723,10 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
labeld = janet_v_count(c->buffer);
|
||||
if (labeljr < labeld) {
|
||||
check_16bit_jump(c, labeljr, labelr);
|
||||
c->buffer[labeljr] |= (labelr - labeljr) << 16;
|
||||
c->buffer[labeljr] |= (uint32_t) (labelr - labeljr) << 16;
|
||||
if (!tail && labeljd < labeld) {
|
||||
check_24bit_jump(c, labeljd, labeld);
|
||||
c->buffer[labeljd] |= (labeld - labeljd) << 8;
|
||||
c->buffer[labeljd] |= (uint32_t) (labeld - labeljd) << 8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -945,8 +945,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
}
|
||||
/* But now add tail recursion */
|
||||
int32_t tempself = janetc_regalloc_temp(&tempscope.ra, JANETC_REGTEMP_0);
|
||||
janetc_emit(c, JOP_LOAD_SELF | (tempself << 8));
|
||||
janetc_emit(c, JOP_TAILCALL | (tempself << 8));
|
||||
janetc_emit(c, JOP_LOAD_SELF | ((uint32_t) tempself << 8));
|
||||
janetc_emit(c, JOP_TAILCALL | ((uint32_t) tempself << 8));
|
||||
janetc_regalloc_freetemp(&c->scope->ra, tempself, JANETC_REGTEMP_0);
|
||||
/* Compile function */
|
||||
JanetFuncDef *def = janetc_pop_funcdef(c);
|
||||
@@ -955,8 +955,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
int32_t defindex = janetc_addfuncdef(c, def);
|
||||
/* And then load the closure and call it. */
|
||||
int32_t cloreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_0);
|
||||
janetc_emit(c, JOP_CLOSURE | (cloreg << 8) | (defindex << 16));
|
||||
janetc_emit(c, JOP_CALL | (cloreg << 8) | (cloreg << 16));
|
||||
janetc_emit(c, JOP_CLOSURE | ((uint32_t) cloreg << 8) | ((uint32_t) defindex << 16));
|
||||
janetc_emit(c, JOP_CALL | ((uint32_t) cloreg << 8) | ((uint32_t) cloreg << 16));
|
||||
janetc_regalloc_freetemp(&c->scope->ra, cloreg, JANETC_REGTEMP_0);
|
||||
c->scope->flags |= JANET_SCOPE_CLOSURE;
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
@@ -980,7 +980,7 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
for (int32_t i = labelwt; i < labeld; i++) {
|
||||
if (c->buffer[i] == (0x80 | JOP_JUMP)) {
|
||||
check_24bit_jump(c, i, labeld);
|
||||
c->buffer[i] = JOP_JUMP | ((labeld - i) << 8);
|
||||
c->buffer[i] = JOP_JUMP | ((uint32_t) (labeld - i) << 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,4 +156,6 @@
|
||||
(check-lint-compile '(let [outer1 "b"] outer1) "shadow local-to-global")
|
||||
(check-lint-compile '(do (def x "b") (def x "c")) "shadow local-to-local")
|
||||
|
||||
(check-lint-compile '(def [xxx [xxx yyy]] [1 [2 3]]) "shadow global-to-global one form")
|
||||
|
||||
(end-suite)
|
||||
@@ -207,4 +207,6 @@
|
||||
'(fn :short-fn [] (set (my-table [2 1]) (quote foo))))
|
||||
"Macro expand inside set preserves tuple type correctly")
|
||||
|
||||
(assert-error "no infinite step range" (range 3 3 math/inf))
|
||||
|
||||
(end-suite)
|
||||
Reference in new issue
Block a user