1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-05 05:10:26 +00:00

Add constant checking in sysir middle end.

This commit is contained in:
Calvin Rose 2024-10-05 12:05:04 -05:00
parent 6577a18cef
commit 80ed6538d0
2 changed files with 43 additions and 5 deletions

View File

@ -67,6 +67,6 @@
#### ####
#(dump) (dump)
(dumpc) #(dumpc)
#(dumpx64) #(dumpx64)

View File

@ -1076,6 +1076,7 @@ static int check_const_valid(JanetSysIR *sysir, Janet constant, uint32_t t) {
case JANET_BOOLEAN: case JANET_BOOLEAN:
return p == JANET_PRIM_BOOLEAN; return p == JANET_PRIM_BOOLEAN;
case JANET_STRING: case JANET_STRING:
case JANET_SYMBOL:
case JANET_POINTER: case JANET_POINTER:
return p == JANET_PRIM_POINTER; return p == JANET_PRIM_POINTER;
case JANET_NUMBER: case JANET_NUMBER:
@ -1105,6 +1106,20 @@ static int check_const_valid(JanetSysIR *sysir, Janet constant, uint32_t t) {
} }
} }
/* Check if a register is const-valid. Const-valid here means
* that, if the register is a constant, the constant literal type-matches
* the register type. */
static void rcheck_const_valid(JanetSysIR *sysir, uint32_t r) {
if (r >= JANET_SYS_MAX_OPERAND) {
/* r is a constant */
JanetSysConstant jsc = sysir->constants[r - JANET_SYS_CONSTANT_PREFIX];
int valid = check_const_valid(sysir, jsc.value, jsc.type);
if (!valid) {
janet_panicf("invalid constant %v, expected value of type %p", jsc.value, tname(sysir, jsc.type));
}
}
}
static void janet_sysir_type_check(JanetSysIR *sysir) { static void janet_sysir_type_check(JanetSysIR *sysir) {
/* Assert no unknown types */ /* Assert no unknown types */
@ -1139,6 +1154,7 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_RETURN: { case JANET_SYSOP_RETURN: {
uint32_t ret_type = 0; uint32_t ret_type = 0;
if (instruction.ret.has_value) { if (instruction.ret.has_value) {
rcheck_const_valid(sysir, instruction.ret.value);
ret_type = sysir->types[instruction.ret.value]; ret_type = sysir->types[instruction.ret.value];
} }
if (found_return) { if (found_return) {
@ -1162,19 +1178,25 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
break; break;
} }
case JANET_SYSOP_MOVE: case JANET_SYSOP_MOVE:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_equal(sysir, instruction.two.dest, instruction.two.src); rcheck_equal(sysir, instruction.two.dest, instruction.two.src);
break; break;
case JANET_SYSOP_CAST: case JANET_SYSOP_CAST:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_cast(sysir, instruction.two.dest, instruction.two.src); rcheck_cast(sysir, instruction.two.dest, instruction.two.src);
break; break;
case JANET_SYSOP_POINTER_ADD: case JANET_SYSOP_POINTER_ADD:
case JANET_SYSOP_POINTER_SUBTRACT: case JANET_SYSOP_POINTER_SUBTRACT:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
rcheck_pointer_math(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.rhs); rcheck_pointer_math(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.rhs);
break; break;
case JANET_SYSOP_ADD: case JANET_SYSOP_ADD:
case JANET_SYSOP_SUBTRACT: case JANET_SYSOP_SUBTRACT:
case JANET_SYSOP_MULTIPLY: case JANET_SYSOP_MULTIPLY:
case JANET_SYSOP_DIVIDE: case JANET_SYSOP_DIVIDE:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
tcheck_number(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.dest])); tcheck_number(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.dest]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs); rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs); rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
@ -1182,24 +1204,31 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_BAND: case JANET_SYSOP_BAND:
case JANET_SYSOP_BOR: case JANET_SYSOP_BOR:
case JANET_SYSOP_BXOR: case JANET_SYSOP_BXOR:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.dest])); tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.dest]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs); rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs); rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
break; break;
case JANET_SYSOP_BNOT: case JANET_SYSOP_BNOT:
rcheck_const_valid(sysir, instruction.two.src);
tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.two.src])); tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.two.src]));
rcheck_equal(sysir, instruction.two.dest, instruction.two.src); rcheck_equal(sysir, instruction.two.dest, instruction.two.src);
break; break;
case JANET_SYSOP_SHL: case JANET_SYSOP_SHL:
case JANET_SYSOP_SHR: case JANET_SYSOP_SHR:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.lhs])); tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.three.lhs]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs); rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs); rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
break; break;
case JANET_SYSOP_LOAD: case JANET_SYSOP_LOAD:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_pointer_equals(sysir, instruction.two.src, instruction.two.dest); rcheck_pointer_equals(sysir, instruction.two.src, instruction.two.dest);
break; break;
case JANET_SYSOP_STORE: case JANET_SYSOP_STORE:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_pointer_equals(sysir, instruction.two.dest, instruction.two.src); rcheck_pointer_equals(sysir, instruction.two.dest, instruction.two.src);
break; break;
case JANET_SYSOP_GT: case JANET_SYSOP_GT:
@ -1208,6 +1237,8 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_NEQ: case JANET_SYSOP_NEQ:
case JANET_SYSOP_GTE: case JANET_SYSOP_GTE:
case JANET_SYSOP_LTE: case JANET_SYSOP_LTE:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
/* TODO - allow arrays */ /* TODO - allow arrays */
rcheck_number_or_pointer(sysir, instruction.three.lhs); rcheck_number_or_pointer(sysir, instruction.three.lhs);
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs); rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
@ -1220,18 +1251,25 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_BRANCH: case JANET_SYSOP_BRANCH:
case JANET_SYSOP_BRANCH_NOT: case JANET_SYSOP_BRANCH_NOT:
rcheck_boolean(sysir, instruction.branch.cond); rcheck_boolean(sysir, instruction.branch.cond);
rcheck_const_valid(sysir, instruction.branch.cond);
break; break;
case JANET_SYSOP_SYSCALL: case JANET_SYSOP_SYSCALL:
rcheck_integer(sysir, instruction.call.callee); rcheck_integer(sysir, instruction.call.callee);
rcheck_const_valid(sysir, instruction.call.callee);
break; break;
case JANET_SYSOP_CALL: case JANET_SYSOP_CALL:
rcheck_pointer(sysir, instruction.call.callee); rcheck_pointer(sysir, instruction.call.callee);
rcheck_const_valid(sysir, instruction.call.callee);
break; break;
case JANET_SYSOP_ARRAY_GETP: case JANET_SYSOP_ARRAY_GETP:
rcheck_array_getp(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.lhs); rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
rcheck_array_getp(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.rhs);
break; break;
case JANET_SYSOP_ARRAY_PGETP: case JANET_SYSOP_ARRAY_PGETP:
rcheck_array_pgetp(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.lhs); rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
rcheck_array_pgetp(sysir, instruction.three.dest, instruction.three.rhs, instruction.three.rhs);
break; break;
case JANET_SYSOP_FIELD_GETP: case JANET_SYSOP_FIELD_GETP:
rcheck_fgetp(sysir, instruction.field.r, instruction.field.st, instruction.field.field); rcheck_fgetp(sysir, instruction.field.r, instruction.field.st, instruction.field.field);
@ -1695,7 +1733,7 @@ void janet_sys_ir_lower_to_ir(JanetSysIRLinkage *linkage, JanetArray *into) {
build_tuple[0] = janet_csymbolv("type-array"); build_tuple[0] = janet_csymbolv("type-array");
build_tuple[1] = janet_sys_get_desttype(linkage, instruction.array.dest_type); build_tuple[1] = janet_sys_get_desttype(linkage, instruction.array.dest_type);
build_tuple[2] = janet_sys_get_desttype(linkage, instruction.array.type); build_tuple[2] = janet_sys_get_desttype(linkage, instruction.array.type);
build_tuple[4] = janet_wrap_number((double) instruction.array.fixed_count); build_tuple[3] = janet_wrap_number((double) instruction.array.fixed_count);
break; break;
} }
const Janet *tuple = janet_tuple_end(build_tuple); const Janet *tuple = janet_tuple_end(build_tuple);