stage1 - 全面重构 stage1 编译器架构:类型系统(arena + items)、IR 发射层(spl_emit.h/c)、统一所有 emit 调用点。
- 实现 as 类型转换运算符、修复 &&/|| 短路求值 bug。 - 在 splc1.spl 中实现 Vec/Map/Emit 基础库(~50 个方法)。 - 修复实例方法调用中 self 参数被错误丢弃的 bug。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/* spl_emit.c — IR emission: frame allocator + Layer 1/2 ops */
|
||||
|
||||
#include "spl_emit.h"
|
||||
#include "spl_comp.h"
|
||||
#include "spl_type.h"
|
||||
#include <string.h>
|
||||
|
||||
@@ -11,15 +12,13 @@
|
||||
void spl_emit_init(spl_emit_t *e, spl_prog_t *prog) {
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->prog = prog;
|
||||
vec_init(e->call_fixups);
|
||||
vec_init(e->call_fixup_funcs);
|
||||
vec_init(e->fixups);
|
||||
}
|
||||
|
||||
void spl_emit_drop(spl_emit_t *e) {
|
||||
if (!e)
|
||||
return;
|
||||
vec_free(e->call_fixups);
|
||||
vec_free(e->call_fixup_funcs);
|
||||
vec_free(e->fixups);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
@@ -30,8 +29,7 @@ int fa_alloc_type(spl_frame_alloc_t *fa, spl_type_ctx_t *tctx, int type_idx) {
|
||||
return fa_alloc(fa, spl_type_size(tctx, type_idx));
|
||||
}
|
||||
|
||||
static spl_val_t emit_raw(spl_emit_t *e, uint16_t opcode, uint16_t type,
|
||||
spl_val_t imm) {
|
||||
spl_val_t emit_raw(spl_emit_t *e, uint16_t opcode, uint16_t type, spl_val_t imm) {
|
||||
return spl_prog_emit(e->prog, opcode, type, imm);
|
||||
}
|
||||
|
||||
@@ -46,19 +44,11 @@ void emit_rot(spl_emit_t *e) { emit_raw(e, SPL_ROT, SPL_VOID, 0); }
|
||||
void emit_pick(spl_emit_t *e, int n) { emit_raw(e, SPL_PICK, SPL_VOID, n); }
|
||||
|
||||
void emit_push_i32(spl_emit_t *e, int v) { emit_raw(e, SPL_PUSH, SPL_I32, (spl_val_t)v); }
|
||||
void emit_push_usize(spl_emit_t *e, usize v) {
|
||||
emit_raw(e, SPL_PUSH, SPL_USIZE, (spl_val_t)v);
|
||||
}
|
||||
void emit_push_u64(spl_emit_t *e, uint64_t v) {
|
||||
emit_raw(e, SPL_PUSH, SPL_U64, (spl_val_t)v);
|
||||
}
|
||||
void emit_push_f64(spl_emit_t *e, uint64_t v) {
|
||||
emit_raw(e, SPL_PUSH, SPL_F64, (spl_val_t)v);
|
||||
}
|
||||
void emit_push_usize(spl_emit_t *e, usize v) { emit_raw(e, SPL_PUSH, SPL_USIZE, (spl_val_t)v); }
|
||||
void emit_push_u64(spl_emit_t *e, uint64_t v) { emit_raw(e, SPL_PUSH, SPL_U64, (spl_val_t)v); }
|
||||
void emit_push_f64(spl_emit_t *e, uint64_t v) { emit_raw(e, SPL_PUSH, SPL_F64, (spl_val_t)v); }
|
||||
void emit_push_ptr(spl_emit_t *e, spl_val_t v) { emit_raw(e, SPL_PUSH, SPL_PTR, v); }
|
||||
void emit_push_type(spl_emit_t *e, uint16_t bt, spl_val_t v) {
|
||||
emit_raw(e, SPL_PUSH, bt, v);
|
||||
}
|
||||
void emit_push_type(spl_emit_t *e, uint16_t bt, spl_val_t v) { emit_raw(e, SPL_PUSH, bt, v); }
|
||||
|
||||
void emit_load_ptr(spl_emit_t *e) { emit_raw(e, SPL_LOAD, SPL_PTR, 0); }
|
||||
void emit_load_usize(spl_emit_t *e) { emit_raw(e, SPL_LOAD, SPL_USIZE, 0); }
|
||||
@@ -95,9 +85,7 @@ void emit_laddr(spl_emit_t *e, int offset) { emit_raw(e, SPL_LADDR, SPL_PTR, off
|
||||
void emit_gaddr(spl_emit_t *e, int idx) { emit_raw(e, SPL_GADDR, SPL_PTR, idx); }
|
||||
|
||||
void emit_call(spl_emit_t *e, int nargs) { emit_raw(e, SPL_CALL, SPL_VOID, nargs); }
|
||||
void emit_ncall(spl_emit_t *e, int nargs) {
|
||||
emit_raw(e, SPL_NCALL, SPL_VOID, nargs);
|
||||
}
|
||||
void emit_ncall(spl_emit_t *e, int nargs) { emit_raw(e, SPL_NCALL, SPL_VOID, nargs); }
|
||||
|
||||
void emit_alloc(spl_emit_t *e, int slots) { emit_raw(e, SPL_ALLOC, SPL_VOID, slots); }
|
||||
void emit_binop(spl_emit_t *e, uint16_t op, uint16_t bt) { emit_raw(e, op, bt, 0); }
|
||||
@@ -143,8 +131,8 @@ void emit_copy_addr_to_addr(spl_emit_t *e, usize nslots, int depth) {
|
||||
emit_drop(e);
|
||||
}
|
||||
|
||||
void emit_load_to_var(spl_emit_t *e, spl_type_ctx_t *tctx, int ptr_slot_offset,
|
||||
usize byte_offset, int data_type_idx, int var_offset) {
|
||||
void emit_load_to_var(spl_emit_t *e, spl_type_ctx_t *tctx, int ptr_slot_offset, usize byte_offset,
|
||||
int data_type_idx, int var_offset) {
|
||||
emit_laddr(e, ptr_slot_offset);
|
||||
emit_load_ptr(e);
|
||||
emit_ptr_add(e, byte_offset);
|
||||
@@ -176,8 +164,8 @@ void emit_ptr_add(spl_emit_t *e, usize byte_off) {
|
||||
spl_val_t emit_call_with_fixup(spl_emit_t *e, int nargs, int func_idx) {
|
||||
spl_val_t fixup_addr = emit_raw(e, SPL_PUSH, SPL_PTR, 0);
|
||||
emit_call(e, nargs);
|
||||
vec_push(e->call_fixups, fixup_addr);
|
||||
vec_push(e->call_fixup_funcs, func_idx);
|
||||
spl_fixup_entry_t fe = {fixup_addr, func_idx};
|
||||
vec_push(e->fixups, fe);
|
||||
return fixup_addr;
|
||||
}
|
||||
|
||||
@@ -192,12 +180,54 @@ void emit_return(spl_emit_t *e, spl_type_ctx_t *tctx, int ret_type_idx) {
|
||||
}
|
||||
|
||||
void emit_patch_call_fixups(spl_emit_t *e, spl_prog_t *prog) {
|
||||
for (usize i = 0; i < vec_size(e->call_fixups); i++) {
|
||||
spl_val_t insn_idx = vec_at(e->call_fixups, i);
|
||||
int pfi = vec_at(e->call_fixup_funcs, i);
|
||||
if (pfi >= 0 && pfi < (int)vec_size(prog->funcs)) {
|
||||
spl_val_t addr = vec_at(prog->funcs, pfi).address;
|
||||
vec_at(prog->insns, insn_idx).imm = addr;
|
||||
for (usize i = 0; i < vec_size(e->fixups); i++) {
|
||||
spl_fixup_entry_t *fe = &vec_at(e->fixups, i);
|
||||
if (fe->func_idx >= 0 && fe->func_idx < (int)vec_size(prog->funcs)) {
|
||||
spl_val_t addr = vec_at(prog->funcs, fe->func_idx).address;
|
||||
vec_at(prog->insns, fe->insn_idx).imm = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spl_emit_ret(spl_comp_t *ctx, int ret_type_idx) {
|
||||
if (spl_type_needs_multi_slot(&ctx->tctx, ret_type_idx)) {
|
||||
emit_laddr(&ctx->emit, (int)sizeof(spl_val_t));
|
||||
emit_swap(&ctx->emit);
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, ret_type_idx), 0);
|
||||
}
|
||||
emit_return(&ctx->emit, &ctx->tctx, ret_type_idx);
|
||||
}
|
||||
|
||||
void spl_emit_store_init(spl_comp_t *ctx, int var_offset, int var_type_idx) {
|
||||
if (var_type_idx >= 0 && (spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_STRUCT ||
|
||||
spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_ENUM)) {
|
||||
usize sz = spl_type_size(&ctx->tctx, var_type_idx);
|
||||
if (sz <= sizeof(spl_val_t)) {
|
||||
emit_store_to_laddr(&ctx->emit, var_offset,
|
||||
spl_type_emit_type(&ctx->tctx, var_type_idx));
|
||||
} else {
|
||||
usize nslots = (sz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
||||
emit_frame_copy(&ctx->emit, var_offset, nslots);
|
||||
}
|
||||
} else if (var_type_idx >= 0 && spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_ARRAY) {
|
||||
int elem_idx = spl_type_elem_type(&ctx->tctx, var_type_idx);
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, elem_idx);
|
||||
usize stride = spl_type_elem_stride(&ctx->tctx, elem_idx);
|
||||
int arr_len = (int)spl_type_array_len(&ctx->tctx, var_type_idx);
|
||||
for (int i = arr_len - 1; i >= 0; i--) {
|
||||
emit_laddr(&ctx->emit, var_offset + (int)(i * stride));
|
||||
emit_swap(&ctx->emit);
|
||||
if (elem_idx >= 0 && !spl_type_is_scalar(&ctx->tctx, elem_idx)) {
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, elem_idx), 0);
|
||||
} else {
|
||||
emit_store_type(&ctx->emit, bt);
|
||||
}
|
||||
}
|
||||
} else if (var_type_idx >= 0 && spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_SLICE) {
|
||||
emit_store_to_laddr(&ctx->emit, var_offset + (int)sizeof(spl_val_t), SPL_USIZE);
|
||||
emit_store_to_laddr(&ctx->emit, var_offset, SPL_PTR);
|
||||
} else {
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, var_type_idx);
|
||||
emit_store_to_laddr(&ctx->emit, var_offset, bt);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user