Skip to content

Commit

Permalink
Add constant checking in sysir middle end.
Browse files Browse the repository at this point in the history
  • Loading branch information
bakpakin committed Oct 5, 2024
1 parent 6577a18 commit 80ed653
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
4 changes: 2 additions & 2 deletions examples/sysir/samples.janet
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@

####

#(dump)
(dumpc)
(dump)
#(dumpc)
#(dumpx64)
44 changes: 41 additions & 3 deletions src/core/sysir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,7 @@ static int check_const_valid(JanetSysIR *sysir, Janet constant, uint32_t t) {
case JANET_BOOLEAN:
return p == JANET_PRIM_BOOLEAN;
case JANET_STRING:
case JANET_SYMBOL:
case JANET_POINTER:
return p == JANET_PRIM_POINTER;
case JANET_NUMBER:
Expand Down Expand Up @@ -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) {

/* Assert no unknown types */
Expand Down Expand Up @@ -1139,6 +1154,7 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_RETURN: {
uint32_t ret_type = 0;
if (instruction.ret.has_value) {
rcheck_const_valid(sysir, instruction.ret.value);
ret_type = sysir->types[instruction.ret.value];
}
if (found_return) {
Expand All @@ -1162,44 +1178,57 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
break;
}
case JANET_SYSOP_MOVE:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_equal(sysir, instruction.two.dest, instruction.two.src);
break;
case JANET_SYSOP_CAST:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_cast(sysir, instruction.two.dest, instruction.two.src);
break;
case JANET_SYSOP_POINTER_ADD:
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);
break;
case JANET_SYSOP_ADD:
case JANET_SYSOP_SUBTRACT:
case JANET_SYSOP_MULTIPLY:
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]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
break;
case JANET_SYSOP_BAND:
case JANET_SYSOP_BOR:
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]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
break;
case JANET_SYSOP_BNOT:
rcheck_const_valid(sysir, instruction.two.src);
tcheck_integer(sysir, tcheck_array_element(sysir, sysir->types[instruction.two.src]));
rcheck_equal(sysir, instruction.two.dest, instruction.two.src);
break;
case JANET_SYSOP_SHL:
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]));
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
rcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
break;
case JANET_SYSOP_LOAD:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_pointer_equals(sysir, instruction.two.src, instruction.two.dest);
break;
case JANET_SYSOP_STORE:
rcheck_const_valid(sysir, instruction.two.src);
rcheck_pointer_equals(sysir, instruction.two.dest, instruction.two.src);
break;
case JANET_SYSOP_GT:
Expand All @@ -1208,6 +1237,8 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_NEQ:
case JANET_SYSOP_GTE:
case JANET_SYSOP_LTE:
rcheck_const_valid(sysir, instruction.three.lhs);
rcheck_const_valid(sysir, instruction.three.rhs);
/* TODO - allow arrays */
rcheck_number_or_pointer(sysir, instruction.three.lhs);
rcheck_equal(sysir, instruction.three.lhs, instruction.three.rhs);
Expand All @@ -1220,18 +1251,25 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
case JANET_SYSOP_BRANCH:
case JANET_SYSOP_BRANCH_NOT:
rcheck_boolean(sysir, instruction.branch.cond);
rcheck_const_valid(sysir, instruction.branch.cond);
break;
case JANET_SYSOP_SYSCALL:
rcheck_integer(sysir, instruction.call.callee);
rcheck_const_valid(sysir, instruction.call.callee);
break;
case JANET_SYSOP_CALL:
rcheck_pointer(sysir, instruction.call.callee);
rcheck_const_valid(sysir, instruction.call.callee);
break;
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;
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;
case JANET_SYSOP_FIELD_GETP:
rcheck_fgetp(sysir, instruction.field.r, instruction.field.st, instruction.field.field);
Expand Down Expand Up @@ -1695,7 +1733,7 @@ void janet_sys_ir_lower_to_ir(JanetSysIRLinkage *linkage, JanetArray *into) {
build_tuple[0] = janet_csymbolv("type-array");
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[4] = janet_wrap_number((double) instruction.array.fixed_count);
build_tuple[3] = janet_wrap_number((double) instruction.array.fixed_count);
break;
}
const Janet *tuple = janet_tuple_end(build_tuple);
Expand Down

0 comments on commit 80ed653

Please sign in to comment.