stage2 更多底层函数 stage1 layout正确使用 内置函数重新编写

This commit is contained in:
zzy committed 2026-09-17 22:03:23 +08:00
1 parent fb0ff9b663
commit 4141e7d574
15 files changed
+2588 -122

No files matched your search

+46 -63
View File
@@ -3,49 +3,24 @@
static usize align_up(usize x, usize a);
/* size/align/offset 统一取自 layout(spl_layout 是唯一准确来源)。 */
static const spl_layout_info_t *ir_layout(spl_ir2vm_t *ctx, spl_type_id_t tid) {
return spl_layout_info_of(ctx->layout, tid);
}
static usize ir_type_size(spl_ir2vm_t *ctx, spl_type_id_t tid) {
spl_type_node_t *tn = spl_type_node(ctx->type, tid);
if (!tn)
return 8;
switch (tn->kind) {
case SPL_TYPE_UNIT:
const spl_layout_info_t *info = ir_layout(ctx, tid);
if (!info)
return 0;
case SPL_TYPE_BOOL:
return (info->size_bits + 7) / 8;
}
static usize ir_type_align(spl_ir2vm_t *ctx, spl_type_id_t tid) {
const spl_layout_info_t *info = ir_layout(ctx, tid);
if (!info)
return 1;
case SPL_TYPE_INT:
return (tn->int_type.bits + 7) / 8;
case SPL_TYPE_FLOAT:
return (tn->float_type.bits + 7) / 8;
case SPL_TYPE_PTR:
return sizeof(void *);
case SPL_TYPE_FN:
return sizeof(void *);
case SPL_TYPE_ARRAY:
return ir_type_size(ctx, tn->array_type.element) * tn->array_type.len;
case SPL_TYPE_ENUM: {
usize tag_sz = ir_type_size(ctx, tn->agg_type.tag_type);
usize payload_align = 1;
usize payload_size = 0;
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
usize vs = ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
if (vs > payload_align)
payload_align = vs;
if (vs > payload_size)
payload_size = vs;
}
usize payload_off = align_up(tag_sz, payload_align);
return align_up(payload_off + payload_size, payload_align);
}
case SPL_TYPE_STRUCT:
case SPL_TYPE_UNION: {
usize s = 0;
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i)
s += ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
return s;
}
default:
return 8;
}
usize a = info->align_bits / 8;
return a ? a : 1;
}
static bool ir_is_aggregate(spl_ir2vm_t *ctx, spl_type_id_t tid) {
@@ -98,27 +73,13 @@ static usize ir_agg_field_off(spl_ir2vm_t *ctx, spl_type_id_t tid, usize idx) {
spl_type_node_t *tn = spl_type_node(ctx->type, tid);
if (!tn)
return 0;
if (tn->kind == SPL_TYPE_STRUCT || tn->kind == SPL_TYPE_UNION) {
usize off = 0;
for (usize i = 0; i < idx && i < vec_size(tn->agg_type.variants); ++i)
off += ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
return off;
}
if (tn->kind == SPL_TYPE_ARRAY)
return idx * ir_type_size(ctx, tn->array_type.element);
if (tn->kind == SPL_TYPE_ENUM) {
if (idx == 0)
return 0;
usize tag_sz = ir_type_size(ctx, tn->agg_type.tag_type);
usize payload_align = 1;
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
usize vs = ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
if (vs > payload_align)
payload_align = vs;
}
return align_up(tag_sz, payload_align);
}
return 0;
const spl_layout_info_t *info = ir_layout(ctx, tid);
if (!info || idx >= vec_size(info->field_bit_offsets))
return 0;
return vec_at(info->field_bit_offsets, idx) / 8;
}
static int get_or_add_native(spl_ir2vm_t *ctx, const char *name) {
@@ -752,12 +713,31 @@ static void cg_typeop(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
case SPL_IR_TYPE_SIZEOF:
v = ir_type_size(ctx, n->ir_sizeof.tid);
break;
case SPL_IR_TYPE_BITSIZEOF:
v = ir_type_size(ctx, n->bitsizeof.tid) * 8;
case SPL_IR_TYPE_BITSIZEOF: {
const spl_layout_info_t *info = ir_layout(ctx, n->bitsizeof.tid);
v = info ? info->size_bits : 0;
break;
}
case SPL_IR_TYPE_ALIGNOF:
v = ir_type_size(ctx, n->ir_alignof.tid);
v = ir_type_align(ctx, n->ir_alignof.tid);
break;
case SPL_IR_TYPE_OFFSETOF: {
usize idx = 0;
if (n->ir_offsetof.field_idx < vec_size(cg->irf->nodes)) {
const spl_ir_node_t *idx_node = &vec_at(cg->irf->nodes, n->ir_offsetof.field_idx);
if (idx_node->kind == SPL_IR_TYPE_CONST)
idx = (usize)idx_node->type_const.int_lit;
}
v = ir_agg_field_off(ctx, n->ir_offsetof.tid, idx);
break;
}
case SPL_IR_TYPE_FIELD_COUNT: {
spl_type_node_t *tn = spl_type_node(ctx->type, n->field_count.tid);
if (tn && (tn->kind == SPL_TYPE_STRUCT || tn->kind == SPL_TYPE_UNION ||
tn->kind == SPL_TYPE_ENUM || tn->kind == SPL_TYPE_SHAPE))
v = vec_size(tn->agg_type.variants);
break;
}
default:
return;
}
@@ -1028,6 +1008,8 @@ static void cg_node(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
case SPL_IR_TYPE_SIZEOF:
case SPL_IR_TYPE_BITSIZEOF:
case SPL_IR_TYPE_ALIGNOF:
case SPL_IR_TYPE_OFFSETOF:
case SPL_IR_TYPE_FIELD_COUNT:
cg_typeop(cg, ref, n);
break;
@@ -1142,11 +1124,12 @@ static usize spl_map_hash(usize k) { return MAP_HASH_INT(k); }
static int spl_map_cmp(usize a, usize b) { return MAP_CMP_INT(a, b); }
void spl_ir2vm_init(spl_ir2vm_t *ctx, const spl_ir_t *ir, const spl_type_t *type,
const spl_attr_t *attr) {
spl_layout_t *layout, const spl_attr_t *attr) {
Assert(ir != NULL && type != NULL && attr != NULL);
ctx->ir = ir;
ctx->type = type;
ctx->attr = attr;
ctx->layout = layout;
map_init(ctx->extern_native, spl_map_hash, spl_map_cmp);
spl_prog_init(&ctx->prog);