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

+39 -13
View File
@@ -50,8 +50,9 @@ void spl_layout_init(spl_layout_t *layout, spl_layout_target_t *target) {
spl_layout_add_scalar(layout, 4, 4); /* i32 / u32 / f32 */
spl_layout_add_scalar(layout, 8, 8); /* i64 / u64 / f64 */
usize ps = sizeof(void *);
spl_layout_add_ptr(layout, 0, ps, ps);
usize ps = target && target->ptr_size ? target->ptr_size : sizeof(void *);
usize pa = target && target->ptr_align ? target->ptr_align : sizeof(void *);
spl_layout_add_ptr(layout, 0, ps, pa);
}
void spl_layout_drop(spl_layout_t *layout) {
@@ -145,6 +146,8 @@ static bool layout_agg(spl_layout_t *layout, spl_type_node_t *tn, spl_layout_inf
for (usize i = 0; i < n; ++i) {
spl_type_member_t *m = &vec_at(tn->agg_type.variants, i);
if (m->type_id == 0) /* 无载荷变体 */
continue;
spl_layout_info_t *fi = infos_at(layout, m->type_id);
if (!fi || !fi->resolved)
return false;
@@ -160,6 +163,21 @@ static bool layout_agg(spl_layout_t *layout, spl_type_node_t *tn, spl_layout_inf
tag_align_bits > payload_align_bits ? tag_align_bits : payload_align_bits;
out->size_bits = round_up_bits(payload_off + payload_size_bits, final_align_bits);
out->align_bits = final_align_bits;
/* 字段索引约定(与 ir2vm 一致):0 = tag,1..n = 各变体载荷(同一偏移)。 */
vec_push(out->field_bit_offsets, 0);
vec_push(out->field_bit_sizes, tag_info->size_bits);
for (usize i = 0; i < n; ++i) {
spl_type_member_t *m = &vec_at(tn->agg_type.variants, i);
usize fsize = 0;
if (m->type_id) {
spl_layout_info_t *fi = infos_at(layout, m->type_id);
if (fi)
fsize = fi->size_bits;
}
vec_push(out->field_bit_offsets, payload_off);
vec_push(out->field_bit_sizes, fsize);
}
return true;
}
@@ -175,22 +193,27 @@ static bool layout_agg(spl_layout_t *layout, spl_type_node_t *tn, spl_layout_inf
for (usize i = 0; i < n; ++i) {
spl_type_member_t *m = &vec_at(tn->agg_type.variants, i);
spl_layout_info_t *fi = infos_at(layout, m->type_id);
if (!fi || !fi->resolved)
return false;
usize field_align_bits = fi->align_bits ? fi->align_bits : 8;
usize fsize_bits = 0;
usize fsize_align = 8;
if (m->type_id) {
spl_layout_info_t *fi = infos_at(layout, m->type_id);
if (!fi || !fi->resolved)
return false;
fsize_bits = fi->size_bits;
fsize_align = fi->align_bits ? fi->align_bits : 8;
}
usize field_align_bits = fsize_align;
if (is_union) {
vec_push(out->field_bit_offsets, 0);
vec_push(out->field_bit_sizes, fi->size_bits);
if (fi->size_bits > out->size_bits)
out->size_bits = fi->size_bits;
vec_push(out->field_bit_sizes, fsize_bits);
if (fsize_bits > out->size_bits)
out->size_bits = fsize_bits;
} else {
offset_bits = round_up_bits(offset_bits, field_align_bits);
vec_push(out->field_bit_offsets, offset_bits);
vec_push(out->field_bit_sizes, fi->size_bits);
offset_bits += fi->size_bits;
vec_push(out->field_bit_sizes, fsize_bits);
offset_bits += fsize_bits;
}
if (field_align_bits > max_align_bits)
max_align_bits = field_align_bits;
@@ -266,9 +289,12 @@ static void resolve_type(spl_layout_t *layout, spl_type_t *type, spl_type_id_t i
case SPL_TYPE_UNION:
case SPL_TYPE_ENUM:
case SPL_TYPE_SHAPE: {
if (tn->kind == SPL_TYPE_ENUM && tn->agg_type.tag_type)
resolve_type(layout, type, tn->agg_type.tag_type);
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
spl_type_member_t *m = &vec_at(tn->agg_type.variants, i);
resolve_type(layout, type, m->type_id);
if (m->type_id)
resolve_type(layout, type, m->type_id);
}
layout_agg(layout, tn, info);
return;