mirror of
https://github.com/janet-lang/janet
synced 2025-01-10 07:30:26 +00:00
Add better support for arrays and struct fields in IR.
Also add option for named registers.
This commit is contained in:
parent
de2440d458
commit
8007806c8e
@ -4,11 +4,12 @@
|
||||
(prim 1 f64)
|
||||
(struct 2 0 1)
|
||||
(pointer 3 0)
|
||||
(array 4 1 1024)
|
||||
(bind 0 0)
|
||||
(bind 1 0)
|
||||
(bind 2 0)
|
||||
(bind 3 1)
|
||||
(bind 4 1)
|
||||
(bind bob 1)
|
||||
(bind 5 1)
|
||||
(bind 6 2)
|
||||
(constant 0 10)
|
||||
@ -17,10 +18,8 @@
|
||||
(add 2 1 0)
|
||||
(constant 3 1.77)
|
||||
(call 3 sin 3)
|
||||
(cast 4 2)
|
||||
(fset 2 6 0)
|
||||
(fset 3 6 1)
|
||||
(add 5 4 3)
|
||||
(cast bob 2)
|
||||
(add 5 bob 3)
|
||||
(jump :location)
|
||||
(return 5))
|
||||
:parameter-count 0
|
||||
|
175
src/core/sysir.c
175
src/core/sysir.c
@ -22,11 +22,13 @@
|
||||
|
||||
/* TODO
|
||||
* [ ] named fields (for debugging mostly)
|
||||
* [ ] named registers and types
|
||||
* [ ] better type errors (perhaps mostly for compiler debugging - full type system goes on top)
|
||||
* [ ] x86/x64 machine code target
|
||||
* [ ] target specific extensions - custom instructions and custom primitives
|
||||
* [ ] better casting semantics
|
||||
* [ ] fixed-size array types
|
||||
* [ ] separate pointer arithmetic from generalized arithmetic (easier to instrument code for safety)?
|
||||
* [x] fixed-size array types
|
||||
* [ ] recursive pointer types
|
||||
* [ ] union types?
|
||||
* [ ] incremental compilation - save type definitions for later
|
||||
@ -37,7 +39,7 @@
|
||||
* [x] composite types - support for load, store, move, and function args.
|
||||
* [x] Have some mechanism for field access (dest = src.offset)
|
||||
* [x] Related, move type creation as opcodes like in SPIRV - have separate virtual "type slots" and value slots for this.
|
||||
* [ ] support for stack allocation of arrays
|
||||
* [x] support for stack allocation of arrays
|
||||
* [ ] more math intrinsics
|
||||
* [x] source mapping (using built in Janet source mapping metadata on tuples)
|
||||
* [ ] better C interface for building up IR
|
||||
@ -65,6 +67,7 @@ typedef enum {
|
||||
JANET_PRIM_POINTER,
|
||||
JANET_PRIM_BOOLEAN,
|
||||
JANET_PRIM_STRUCT,
|
||||
JANET_PRIM_ARRAY,
|
||||
} JanetPrim;
|
||||
|
||||
typedef struct {
|
||||
@ -73,6 +76,7 @@ typedef struct {
|
||||
} JanetPrimName;
|
||||
|
||||
static const JanetPrimName prim_names[] = {
|
||||
{"array", JANET_PRIM_ARRAY},
|
||||
{"boolean", JANET_PRIM_BOOLEAN},
|
||||
{"f32", JANET_PRIM_F32},
|
||||
{"f64", JANET_PRIM_F64},
|
||||
@ -120,9 +124,11 @@ typedef enum {
|
||||
JANET_SYSOP_TYPE_STRUCT,
|
||||
JANET_SYSOP_TYPE_BIND,
|
||||
JANET_SYSOP_ARG,
|
||||
JANET_SYSOP_FIELD_GET,
|
||||
JANET_SYSOP_FIELD_SET,
|
||||
JANET_SYSOP_TYPE_POINTER
|
||||
JANET_SYSOP_FIELD_GETP,
|
||||
JANET_SYSOP_ARRAY_GETP,
|
||||
JANET_SYSOP_ARRAY_PGETP,
|
||||
JANET_SYSOP_TYPE_POINTER,
|
||||
JANET_SYSOP_TYPE_ARRAY
|
||||
} JanetSysOp;
|
||||
|
||||
typedef struct {
|
||||
@ -133,6 +139,9 @@ typedef struct {
|
||||
static const JanetSysInstrName sys_op_names[] = {
|
||||
{"add", JANET_SYSOP_ADD},
|
||||
{"address", JANET_SYSOP_ADDRESS},
|
||||
{"agetp", JANET_SYSOP_ARRAY_GETP},
|
||||
{"apgetp", JANET_SYSOP_ARRAY_PGETP},
|
||||
{"array", JANET_SYSOP_TYPE_ARRAY},
|
||||
{"band", JANET_SYSOP_BAND},
|
||||
{"bind", JANET_SYSOP_TYPE_BIND},
|
||||
{"bnot", JANET_SYSOP_BNOT},
|
||||
@ -144,8 +153,7 @@ static const JanetSysInstrName sys_op_names[] = {
|
||||
{"constant", JANET_SYSOP_CONSTANT},
|
||||
{"divide", JANET_SYSOP_DIVIDE},
|
||||
{"eq", JANET_SYSOP_EQ},
|
||||
{"fget", JANET_SYSOP_FIELD_GET},
|
||||
{"fset", JANET_SYSOP_FIELD_SET},
|
||||
{"fgetp", JANET_SYSOP_FIELD_GETP},
|
||||
{"gt", JANET_SYSOP_GT},
|
||||
{"gte", JANET_SYSOP_GTE},
|
||||
{"jump", JANET_SYSOP_JUMP},
|
||||
@ -175,6 +183,10 @@ typedef struct {
|
||||
struct {
|
||||
uint32_t type;
|
||||
} pointer;
|
||||
struct {
|
||||
uint32_t type;
|
||||
uint64_t fixed_count;
|
||||
} array;
|
||||
};
|
||||
} JanetSysTypeInfo;
|
||||
|
||||
@ -248,6 +260,11 @@ typedef struct {
|
||||
uint32_t dest_type;
|
||||
uint32_t type;
|
||||
} pointer;
|
||||
struct {
|
||||
uint32_t dest_type;
|
||||
uint32_t type;
|
||||
uint64_t fixed_count;
|
||||
} array;
|
||||
};
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
@ -266,6 +283,7 @@ typedef struct {
|
||||
JanetSysTypeField *field_defs;
|
||||
JanetSysInstruction *instructions;
|
||||
Janet *constants;
|
||||
JanetTable *register_names;
|
||||
uint32_t parameter_count;
|
||||
} JanetSysIR;
|
||||
|
||||
@ -284,6 +302,16 @@ static void instr_assert_min_length(JanetTuple tup, int32_t minlen, Janet x) {
|
||||
}
|
||||
|
||||
static uint32_t instr_read_operand(Janet x, JanetSysIR *ir) {
|
||||
if (janet_checktype(x, JANET_SYMBOL)) {
|
||||
Janet check = janet_table_get(ir->register_names, x);
|
||||
if (janet_checktype(check, JANET_NUMBER)) {
|
||||
return (uint32_t) janet_unwrap_number(check);
|
||||
} else {
|
||||
uint32_t operand = ir->register_count++;
|
||||
janet_table_put(ir->register_names, x, janet_wrap_number(operand));
|
||||
return operand;
|
||||
}
|
||||
}
|
||||
if (!janet_checkuint(x)) janet_panicf("expected non-negative integer operand, got %v", x);
|
||||
uint32_t operand = (uint32_t) janet_unwrap_number(x);
|
||||
if (operand >= ir->register_count) {
|
||||
@ -299,6 +327,12 @@ static uint32_t instr_read_field(Janet x, JanetSysIR *ir) {
|
||||
return operand;
|
||||
}
|
||||
|
||||
static uint64_t instr_read_u64(Janet x, JanetSysIR *ir) {
|
||||
if (!janet_checkuint64(x)) janet_panicf("expected unsigned 64 bit integer, got %v", x);
|
||||
(void) ir;
|
||||
return janet_getuinteger64(&x, 0);
|
||||
}
|
||||
|
||||
static uint32_t instr_read_type_operand(Janet x, JanetSysIR *ir) {
|
||||
if (!janet_checkuint(x)) janet_panicf("expected non-negative integer operand, got %v", x);
|
||||
uint32_t operand = (uint32_t) janet_unwrap_number(x);
|
||||
@ -322,6 +356,7 @@ static JanetPrim instr_read_prim(Janet x) {
|
||||
}
|
||||
|
||||
static uint32_t instr_read_label(JanetSysIR *sysir, Janet x, JanetTable *labels) {
|
||||
(void) sysir;
|
||||
uint32_t ret = 0;
|
||||
Janet check = janet_table_get(labels, x);
|
||||
if (!janet_checktype(check, JANET_NIL)) {
|
||||
@ -331,9 +366,6 @@ static uint32_t instr_read_label(JanetSysIR *sysir, Janet x, JanetTable *labels)
|
||||
if (!janet_checkuint(x)) janet_panicf("expected non-negative integer label, got %v", x);
|
||||
ret = (uint32_t) janet_unwrap_number(x);
|
||||
}
|
||||
if (ret >= sysir->instruction_count) {
|
||||
janet_panicf("label outside of range [0, %u), got %u", sysir->instruction_count, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -396,6 +428,8 @@ static void janet_sysir_init_instructions(JanetSysIR *out, JanetView instruction
|
||||
case JANET_SYSOP_LTE:
|
||||
case JANET_SYSOP_EQ:
|
||||
case JANET_SYSOP_NEQ:
|
||||
case JANET_SYSOP_ARRAY_GETP:
|
||||
case JANET_SYSOP_ARRAY_PGETP:
|
||||
instr_assert_length(tuple, 4, opvalue);
|
||||
instruction.three.dest = instr_read_operand(tuple[1], out);
|
||||
instruction.three.lhs = instr_read_operand(tuple[2], out);
|
||||
@ -450,8 +484,7 @@ static void janet_sysir_init_instructions(JanetSysIR *out, JanetView instruction
|
||||
instruction.two.src = instr_read_operand(tuple[2], out);
|
||||
janet_v_push(ir, instruction);
|
||||
break;
|
||||
case JANET_SYSOP_FIELD_GET:
|
||||
case JANET_SYSOP_FIELD_SET:
|
||||
case JANET_SYSOP_FIELD_GETP:
|
||||
instr_assert_length(tuple, 4, opvalue);
|
||||
instruction.field.r = instr_read_operand(tuple[1], out);
|
||||
instruction.field.st = instr_read_operand(tuple[2], out);
|
||||
@ -503,6 +536,14 @@ static void janet_sysir_init_instructions(JanetSysIR *out, JanetView instruction
|
||||
janet_v_push(ir, instruction);
|
||||
break;
|
||||
}
|
||||
case JANET_SYSOP_TYPE_ARRAY: {
|
||||
instr_assert_length(tuple, 4, opvalue);
|
||||
instruction.array.dest_type = instr_read_type_operand(tuple[1], out);
|
||||
instruction.array.type = instr_read_type_operand(tuple[2], out);
|
||||
instruction.array.fixed_count = instr_read_u64(tuple[3], out);
|
||||
janet_v_push(ir, instruction);
|
||||
break;
|
||||
}
|
||||
case JANET_SYSOP_TYPE_STRUCT: {
|
||||
instr_assert_min_length(tuple, 1, opvalue);
|
||||
instruction.type_types.dest_type = instr_read_type_operand(tuple[1], out);
|
||||
@ -626,6 +667,13 @@ static void janet_sysir_init_types(JanetSysIR *sysir) {
|
||||
type_defs[type_def].pointer.type = instruction.pointer.type;
|
||||
break;
|
||||
}
|
||||
case JANET_SYSOP_TYPE_ARRAY: {
|
||||
uint32_t type_def = instruction.array.dest_type;
|
||||
type_defs[type_def].prim = JANET_PRIM_ARRAY;
|
||||
type_defs[type_def].array.type = instruction.array.type;
|
||||
type_defs[type_def].array.fixed_count = instruction.array.fixed_count;
|
||||
break;
|
||||
}
|
||||
case JANET_SYSOP_TYPE_BIND: {
|
||||
uint32_t type = instruction.type_bind.type;
|
||||
uint32_t dest = instruction.type_bind.dest;
|
||||
@ -647,6 +695,13 @@ static void tcheck_boolean(JanetSysIR *sysir, uint32_t reg1) {
|
||||
}
|
||||
}
|
||||
|
||||
static void tcheck_array(JanetSysIR *sysir, uint32_t reg1) {
|
||||
uint32_t t1 = sysir->types[reg1];
|
||||
if (sysir->type_defs[t1].prim != JANET_PRIM_ARRAY) {
|
||||
janet_panicf("type failure, expected array, got type-id:%d", t1); /* TODO improve this */
|
||||
}
|
||||
}
|
||||
|
||||
static void tcheck_number(JanetSysIR *sysir, uint32_t reg1) {
|
||||
JanetPrim t1 = sysir->type_defs[sysir->types[reg1]].prim;
|
||||
if (t1 == JANET_PRIM_BOOLEAN ||
|
||||
@ -677,6 +732,18 @@ static void tcheck_pointer(JanetSysIR *sysir, uint32_t reg1) {
|
||||
}
|
||||
}
|
||||
|
||||
static void tcheck_pointer_equals(JanetSysIR *sysir, uint32_t preg, uint32_t elreg) {
|
||||
uint32_t t1 = sysir->types[preg];
|
||||
if (sysir->type_defs[t1].prim != JANET_PRIM_POINTER) {
|
||||
janet_panicf("type failure, expected pointer, got type-id:%d", t1);
|
||||
}
|
||||
uint32_t tp = sysir->type_defs[t1].pointer.type;
|
||||
uint32_t t2 = sysir->types[elreg];
|
||||
if (t2 != tp) {
|
||||
janet_panicf("type failure, type-id:%d is not compatible with a pointer to type-id:%d", t2, tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcheck_struct(JanetSysIR *sysir, uint32_t reg1) {
|
||||
uint32_t t1 = sysir->types[reg1];
|
||||
if (sysir->type_defs[t1].prim != JANET_PRIM_STRUCT) {
|
||||
@ -706,6 +773,32 @@ static void tcheck_constant(JanetSysIR *sysir, uint32_t dest, Janet c) {
|
||||
/* TODO - validate the the constant C can be represented as dest */
|
||||
}
|
||||
|
||||
static void tcheck_array_getp(JanetSysIR *sysir, uint32_t dest, uint32_t lhs, uint32_t rhs) {
|
||||
tcheck_array(sysir, lhs);
|
||||
tcheck_integer(sysir, rhs);
|
||||
tcheck_pointer(sysir, dest);
|
||||
uint32_t dtype = sysir->type_defs[sysir->types[dest]].pointer.type;
|
||||
uint32_t eltype = sysir->type_defs[sysir->types[lhs]].array.type;
|
||||
if (dtype != eltype) {
|
||||
janet_panicf("type failure, type-id:%d does not match type-id:%d", dtype, eltype);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcheck_array_pgetp(JanetSysIR *sysir, uint32_t dest, uint32_t lhs, uint32_t rhs) {
|
||||
tcheck_pointer(sysir, lhs);
|
||||
tcheck_integer(sysir, rhs);
|
||||
tcheck_pointer(sysir, dest);
|
||||
uint32_t aptype = sysir->type_defs[sysir->types[lhs]].pointer.type;
|
||||
if (sysir->type_defs[aptype].prim != JANET_PRIM_ARRAY) {
|
||||
janet_panicf("type failure, expected array type but got type-id:%d", aptype);
|
||||
}
|
||||
uint32_t dtype = sysir->type_defs[sysir->types[dest]].pointer.type;
|
||||
uint32_t eltype = sysir->type_defs[aptype].array.type;
|
||||
if (dtype != eltype) {
|
||||
janet_panicf("type failure, type-id:%d does not match type-id:%d", dtype, eltype);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add and subtract can be used for pointer math as well as normal arithmetic. Unlike C, only
|
||||
* allow pointer on lhs for addition. */
|
||||
static void tcheck_pointer_math(JanetSysIR *sysir, uint32_t dest, uint32_t lhs, uint32_t rhs) {
|
||||
@ -730,9 +823,15 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
|
||||
case JANET_SYSOP_TYPE_PRIMITIVE:
|
||||
case JANET_SYSOP_TYPE_STRUCT:
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
case JANET_SYSOP_TYPE_BIND:
|
||||
case JANET_SYSOP_ARG:
|
||||
break;
|
||||
case JANET_SYSOP_JUMP:
|
||||
;
|
||||
if (instruction.jump.to >= sysir->instruction_count) {
|
||||
janet_panicf("label outside of range [0, %u), got %u", sysir->instruction_count, instruction.jump.to);
|
||||
}
|
||||
break;
|
||||
case JANET_SYSOP_RETURN: {
|
||||
uint32_t ret_type = sysir->types[instruction.one.src];
|
||||
@ -780,10 +879,10 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
|
||||
tcheck_equal(sysir, instruction.three.dest, instruction.three.lhs);
|
||||
break;
|
||||
case JANET_SYSOP_LOAD:
|
||||
tcheck_pointer(sysir, instruction.two.src);
|
||||
tcheck_pointer_equals(sysir, instruction.two.src, instruction.two.dest);
|
||||
break;
|
||||
case JANET_SYSOP_STORE:
|
||||
tcheck_pointer(sysir, instruction.two.dest);
|
||||
tcheck_pointer_equals(sysir, instruction.two.dest, instruction.two.src);
|
||||
break;
|
||||
case JANET_SYSOP_GT:
|
||||
case JANET_SYSOP_LT:
|
||||
@ -800,6 +899,9 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
|
||||
break;
|
||||
case JANET_SYSOP_BRANCH:
|
||||
tcheck_boolean(sysir, instruction.branch.cond);
|
||||
if (instruction.branch.to >= sysir->instruction_count) {
|
||||
janet_panicf("label outside of range [0, %u), got %u", sysir->instruction_count, instruction.branch.to);
|
||||
}
|
||||
break;
|
||||
case JANET_SYSOP_CONSTANT:
|
||||
tcheck_constant(sysir, instruction.constant.dest, sysir->constants[instruction.constant.constant]);
|
||||
@ -807,8 +909,14 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
|
||||
case JANET_SYSOP_CALL:
|
||||
tcheck_pointer(sysir, instruction.call.callee);
|
||||
break;
|
||||
case JANET_SYSOP_FIELD_GET:
|
||||
case JANET_SYSOP_FIELD_SET:
|
||||
case JANET_SYSOP_ARRAY_GETP:
|
||||
tcheck_array_getp(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.lhs);
|
||||
break;
|
||||
case JANET_SYSOP_ARRAY_PGETP:
|
||||
tcheck_array_pgetp(sysir, instruction.three.dest, instruction.three.lhs, instruction.three.lhs);
|
||||
break;
|
||||
case JANET_SYSOP_FIELD_GETP:
|
||||
tcheck_pointer(sysir, instruction.field.r);
|
||||
tcheck_struct(sysir, instruction.field.st);
|
||||
uint32_t struct_type = sysir->types[instruction.field.st];
|
||||
if (instruction.field.field >= sysir->type_defs[struct_type].st.field_count) {
|
||||
@ -817,8 +925,9 @@ static void janet_sysir_type_check(JanetSysIR *sysir) {
|
||||
uint32_t field_type = sysir->type_defs[struct_type].st.field_start + instruction.field.field;
|
||||
uint32_t tfield = sysir->field_defs[field_type].type;
|
||||
uint32_t tdest = sysir->types[instruction.field.r];
|
||||
if (tfield != tdest) {
|
||||
janet_panicf("field of type type-id:%d does not match type-id:%d", tfield, tdest);
|
||||
uint32_t tpdest = sysir->type_defs[tdest].pointer.type;
|
||||
if (tfield != tpdest) {
|
||||
janet_panicf("field of type type-id:%d does not match type-id:%d", tfield, tpdest);
|
||||
}
|
||||
break;
|
||||
case JANET_SYSOP_CALLK:
|
||||
@ -841,6 +950,7 @@ void janet_sys_ir_init_from_table(JanetSysIR *ir, JanetTable *table) {
|
||||
ir->constant_count = 0;
|
||||
ir->return_type = 0;
|
||||
ir->parameter_count = 0;
|
||||
ir->register_names = janet_table(0);
|
||||
Janet assembly = janet_table_get(table, janet_ckeywordv("instructions"));
|
||||
Janet param_count = janet_table_get(table, janet_ckeywordv("parameter-count"));
|
||||
Janet link_namev = janet_table_get(table, janet_ckeywordv("link-name"));
|
||||
@ -867,7 +977,7 @@ static const char *c_prim_names[] = {
|
||||
"int64_t",
|
||||
"float",
|
||||
"double",
|
||||
"char *",
|
||||
"void *",
|
||||
"bool"
|
||||
};
|
||||
|
||||
@ -887,6 +997,7 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
case JANET_SYSOP_TYPE_PRIMITIVE:
|
||||
case JANET_SYSOP_TYPE_STRUCT:
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
break;
|
||||
}
|
||||
if (instruction.line > 0) {
|
||||
@ -911,11 +1022,13 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
janet_formatb(buffer, "typedef _t%u *_t%u;\n", instruction.pointer.type, instruction.pointer.dest_type);
|
||||
break;
|
||||
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
janet_formatb(buffer, "typedef struct { _t%u els[%u]; } _t%u;\n", instruction.array.type, instruction.array.fixed_count, instruction.array.dest_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit header */
|
||||
/* Emit function header */
|
||||
janet_formatb(buffer, "_t%u %s(", ir->return_type, (ir->link_name != NULL) ? ir->link_name : janet_cstring("_thunk"));
|
||||
for (uint32_t i = 0; i < ir->parameter_count; i++) {
|
||||
if (i) janet_buffer_push_cstring(buffer, ", ");
|
||||
@ -936,6 +1049,7 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
case JANET_SYSOP_TYPE_BIND:
|
||||
case JANET_SYSOP_TYPE_STRUCT:
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
case JANET_SYSOP_ARG:
|
||||
continue;
|
||||
default:
|
||||
@ -951,6 +1065,7 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
case JANET_SYSOP_TYPE_BIND:
|
||||
case JANET_SYSOP_TYPE_STRUCT:
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
case JANET_SYSOP_ARG:
|
||||
break;
|
||||
case JANET_SYSOP_CONSTANT: {
|
||||
@ -1036,7 +1151,7 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
janet_formatb(buffer, ");\n");
|
||||
break;
|
||||
case JANET_SYSOP_CAST:
|
||||
/* TODO - making casting rules explicit instead of just from C */
|
||||
/* TODO - make casting rules explicit instead of just whatever C does */
|
||||
janet_formatb(buffer, "_r%u = (_t%u) _r%u;\n", instruction.two.dest, ir->types[instruction.two.dest], instruction.two.src);
|
||||
break;
|
||||
case JANET_SYSOP_MOVE:
|
||||
@ -1046,16 +1161,19 @@ void janet_sys_ir_lower_to_c(JanetSysIR *ir, JanetBuffer *buffer) {
|
||||
janet_formatb(buffer, "_r%u = ~_r%u;\n", instruction.two.dest, instruction.two.src);
|
||||
break;
|
||||
case JANET_SYSOP_LOAD:
|
||||
janet_formatb(buffer, "_r%u = *((%s *) _r%u);\n", instruction.two.dest, c_prim_names[ir->types[instruction.two.dest]], instruction.two.src);
|
||||
janet_formatb(buffer, "_r%u = *(_r%u);\n", instruction.two.dest, instruction.two.src);
|
||||
break;
|
||||
case JANET_SYSOP_STORE:
|
||||
janet_formatb(buffer, "*((%s *) _r%u) = _r%u;\n", c_prim_names[ir->types[instruction.two.src]], instruction.two.dest, instruction.two.src);
|
||||
janet_formatb(buffer, "*(_r%u) = _r%u;\n", instruction.two.dest, instruction.two.src);
|
||||
break;
|
||||
case JANET_SYSOP_FIELD_GET:
|
||||
janet_formatb(buffer, "_r%u = _r%u._f%u;\n", instruction.field.r, instruction.field.st, instruction.field.field);
|
||||
case JANET_SYSOP_FIELD_GETP:
|
||||
janet_formatb(buffer, "_r%u = &(_r%u._f%u);\n", instruction.field.r, instruction.field.st, instruction.field.field);
|
||||
break;
|
||||
case JANET_SYSOP_FIELD_SET:
|
||||
janet_formatb(buffer, "_r%u._f%u = _r%u;\n", instruction.field.st, instruction.field.field, instruction.field.r);
|
||||
case JANET_SYSOP_ARRAY_GETP:
|
||||
janet_formatb(buffer, "_r%u = &(_r%u.els[_r%u]);\n", instruction.three.dest, instruction.three.lhs, instruction.three.rhs);
|
||||
break;
|
||||
case JANET_SYSOP_ARRAY_PGETP:
|
||||
janet_formatb(buffer, "_r%u = &(_r%u->els[_r%u]);\n", instruction.three.dest, instruction.three.lhs, instruction.three.rhs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1079,6 +1197,7 @@ static int sysir_gc(void *p, size_t s) {
|
||||
static int sysir_gcmark(void *p, size_t s) {
|
||||
JanetSysIR *ir = (JanetSysIR *)p;
|
||||
(void) s;
|
||||
janet_mark(janet_wrap_table(ir->register_names));
|
||||
for (uint32_t i = 0; i < ir->constant_count; i++) {
|
||||
janet_mark(ir->constants[i]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user