feat(ast2ir): 添加数组初始化支持和AST转IR优化
添加了对未知长度数组的自动长度推导功能,支持字符串字面量和复合 初始化的数组长度计算。新增辅助函数resolve_array_length用于计算 数组实际长度,以及emit_array_initialization用于生成数组初始化 代码。 同时将AST转IR过程中的参数改为const引用,提高代码安全性。 新增IR构建器的借用检查机制,防止在借用期间进行重分配操作。 fix(ast): 为AST结构体添加详细注释说明字段用途
This commit is contained in:
@@ -328,7 +328,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
parse_value(ctx, value->data.get_elem_ptr.index, patches);
|
||||
// parse_value(ctx, value->data.get_elem_ptr.index, patches);
|
||||
|
||||
scc_reg_loc_t src_loc;
|
||||
scc_reg_loc_t idx_loc;
|
||||
@@ -337,8 +337,21 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
src_loc.kind = SCC_REG_KIND_STACK_ADDR;
|
||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
||||
load_value_to_reg(ctx, &idx_loc, SCC_AMD64_RDX);
|
||||
|
||||
// 获取 src_addr 所指向的类型的元素大小
|
||||
scc_ir_type_t *ptr_type = scc_ir_module_get_type_by_value(
|
||||
GET_MODULE(ctx), value->data.get_elem_ptr.src_addr);
|
||||
scc_ir_type_t *base_type = scc_ir_module_get_type(
|
||||
GET_MODULE(ctx), ptr_type->data.pointer.base);
|
||||
scc_ir_type_t ir_type = *base_type;
|
||||
if (ir_type.tag == SCC_IR_TYPE_ARRAY) {
|
||||
ir_type.tag = SCC_IR_TYPE_PTR;
|
||||
}
|
||||
int elem_size = scc_ir2mcode_type_width(GET_MODULE(ctx), &ir_type);
|
||||
// 然后生成 LEA 时使用 scale = elem_size
|
||||
scc_mcode_amd64_lea_r64_m64_sib(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX, SCC_AMD64_RDX, 1, 0);
|
||||
SCC_AMD64_RAX, SCC_AMD64_RDX,
|
||||
elem_size, 0);
|
||||
}
|
||||
store_value_from_reg(ctx, &loc_res, SCC_AMD64_RAX);
|
||||
break;
|
||||
@@ -483,28 +496,36 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
///< 调用函数
|
||||
case SCC_IR_VALUE_TAG_CALL: {
|
||||
scc_reg_loc_t loc;
|
||||
/*
|
||||
ABI
|
||||
RAX 不稳定的 返回值寄存器
|
||||
RCX 不稳定的 第一个整型自变量
|
||||
RDX 不稳定的 第二个整型自变量
|
||||
R8 不稳定的 第三个整型自变量
|
||||
R9 不稳定的 第四个整型自变量
|
||||
*/
|
||||
scc_vec_foreach(value->data.call.args, i) {
|
||||
usize nargs = scc_vec_size(value->data.call.args);
|
||||
// 影子空间 32 字节 + 每个额外参数 8 字节(按 8 字节对齐)
|
||||
usize stack_args_count = (nargs > 4) ? (nargs - 4) : 0;
|
||||
usize stack_args_size = stack_args_count * 8;
|
||||
usize total_stack_alloc = 32 + stack_args_size;
|
||||
|
||||
// 调整栈指针(保持 16 字节对齐)
|
||||
if (total_stack_alloc > 0) {
|
||||
scc_mcode_amd64_sub_rsp_imm32(&ctx->sect_mcode, total_stack_alloc);
|
||||
}
|
||||
|
||||
// 处理寄存器参数(前 4 个)
|
||||
for (usize i = 0; i < nargs && i < 4; i++) {
|
||||
parse_location(ctx, &loc, scc_vec_at(value->data.call.args, i));
|
||||
if (i == 0) {
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
// scc_mcode_amd64_push_r64();
|
||||
int reg[] = {SCC_AMD64_RCX, SCC_AMD64_RDX, SCC_AMD64_R8,
|
||||
SCC_AMD64_R9};
|
||||
load_value_to_reg(ctx, &loc, reg[i]);
|
||||
}
|
||||
|
||||
// 处理栈参数(第 5 个及以后)
|
||||
// 从右向左依次写入栈(即最后一个参数放在最高地址)
|
||||
for (usize i = 4; i < nargs; i++) {
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, scc_vec_at(value->data.call.args, i));
|
||||
// 加载到临时寄存器(如 RAX)
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RAX);
|
||||
// 计算栈偏移:影子空间(32) + (i-4)*8
|
||||
int offset = 32 + (i - 4) * 8;
|
||||
scc_mcode_amd64_mov_m64_disp32_r64(&ctx->sect_mcode, SCC_AMD64_RSP,
|
||||
offset, SCC_AMD64_RAX);
|
||||
}
|
||||
|
||||
scc_ir_func_t *func =
|
||||
@@ -530,7 +551,10 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
.sect_type = SCCF_SECT_CODE,
|
||||
.sym_idx = sym_idx,
|
||||
});
|
||||
|
||||
// 恢复栈指针
|
||||
if (total_stack_alloc > 0) {
|
||||
scc_mcode_amd64_add_rsp_imm32(&ctx->sect_mcode, total_stack_alloc);
|
||||
}
|
||||
// 处理返回值
|
||||
scc_ir_type_t *func_type =
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), func->type);
|
||||
@@ -604,22 +628,22 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
SCC_AMD64_RSP, ctx->stack_size);
|
||||
scc_reg_loc_t loc;
|
||||
scc_vec_foreach(func->params, i) {
|
||||
// scc_ir_value_t *param =
|
||||
// scc_ir_module_get_value(GET_MODULE(ctx), );
|
||||
scc_ir_value_ref_t node_ref = scc_vec_at(func->params, i);
|
||||
parse_location(ctx, &loc, node_ref);
|
||||
if (i == 0) {
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_R9);
|
||||
if (i < 4) {
|
||||
// 前 4 个参数:从寄存器存入槽位
|
||||
int reg[] = {SCC_AMD64_RCX, SCC_AMD64_RDX, SCC_AMD64_R8,
|
||||
SCC_AMD64_R9};
|
||||
store_value_from_reg(ctx, &loc, reg[i]);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
// 额外参数:从栈中加载到槽位
|
||||
// 偏移 = 16 (old rbp+retaddr) + 32 (shadow) + (i-4)*8
|
||||
int offset = 16 + 32 + (i - 4) * 8;
|
||||
// 临时将栈值加载到 RAX,再存储到槽位
|
||||
scc_mcode_amd64_mov_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RBP, offset);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
// scc_mcode_amd64_push_r64();
|
||||
}
|
||||
|
||||
for (usize i = 0; i < scc_vec_size(func->bblocks); i++) {
|
||||
@@ -759,6 +783,4 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
sccf_builder_add_text_section(ctx->builder, &text_section);
|
||||
|
||||
sccf_builder_add_data_section(ctx->builder, &ctx->sect_data);
|
||||
// FIXME maybe _entry and add crt
|
||||
ctx->builder->entry_symbol_name = "main";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user