feat(ir2mcode): 添加IR到机器码转换功能并修复函数命名

添加了完整的scc_ir2mcode实现,将MIR指令转换为机器码,
同时修复了头文件中的函数命名错误(scc_mir2sccf改为scc_ir2sccf)。

BREAKING CHANGE: 函数名从scc_mir2sccf更改为scc_ir2sccf

fix(vec): 修复向量循环和内存释放问题

修改了scc_vec_foreach宏使用+= 1避免潜在的编译器警告,
并添加了空指针检查以防止重复释放内存导致的崩溃。

refactor(hashtable): 优化哈希表接口设计

将scc_hashtable_get参数改为const类型,提供更好的只读访问安全性。

test: 添加break/continue和goto语句测试用例

新增18_break_continue.c和19_goto.c测试用例,
并对齐expect.toml文件格式以便于维护。
This commit is contained in:
zzy
2026-05-03 21:34:40 +08:00
parent b06c4fe3cc
commit 676f3ec82c
9 changed files with 90 additions and 21 deletions

View File

@@ -4,6 +4,6 @@
#include <scc_mir_module.h> #include <scc_mir_module.h>
#include <sccf_builder.h> #include <sccf_builder.h>
void scc_mir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module); void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module);
#endif /* __SCC_IR2SCCF_H__ */ #endif /* __SCC_IR2SCCF_H__ */

View File

@@ -0,0 +1,38 @@
#include <scc_ir2mcode.h>
#include <scc_mcode.h>
#include <scc_mir_module.h>
#include <x86/scc_x86_encode.h>
#include <x86/scc_x86_iform.h>
#include <x86/scc_x86_reg.h>
void mir_x86_to_mcode(scc_mcode_t *mcode, const scc_mir_instr_t *ins) {
// scc_x86_operand_value_t ops[8] = {0};
// for (int i = 0; i < ins->num_operands; i += 1) {
// }
scc_x86_encode_inst(mcode, ins->opcode, (void *)&ins->operands);
}
static void scc_emit_mcode(scc_mcode_t *mcode,
const scc_mir_instr_t *mir_instr) {
// TODO
mir_x86_to_mcode(mcode, mir_instr);
}
void scc_ir2mcode(scc_mcode_t *mcode, const scc_mir_module_t *mir_module) {
scc_vec_foreach(mir_module->cfg_module.funcs, i) {
if (i == 0)
continue;
scc_mir_func_t *func = &scc_vec_at(mir_module->cfg_module.funcs, i);
scc_vec_foreach(func->bblocks, i) {
scc_cfg_bblock_id_t id = scc_vec_at(func->bblocks, i);
const scc_cfg_bblock_t *bb =
scc_cfg_module_unsafe_get_bblock(&mir_module->cfg_module, id);
scc_mir_instr_vec_t *instrs = SCC_MIR_BBLOCK_VALUES(bb);
scc_vec_foreach(*instrs, i) {
const scc_mir_instr_t *ins = &scc_vec_at(*instrs, i);
scc_emit_mcode(mcode, ins);
}
}
}
}

View File

@@ -34,7 +34,7 @@ static inline void scc_ir_symbol_to_sect_data(const scc_cfg_symbol_t *symbol,
// } // }
} }
void scc_mir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) { void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) {
// mir_module->symbol_metas // mir_module->symbol_metas
// mir_module->cfg_module.funcs // mir_module->cfg_module.funcs
sccf_builder_init(builder); sccf_builder_init(builder);

View File

@@ -89,7 +89,7 @@ typedef size_t usize;
#define scc_vec_size(vec) ((vec).size) #define scc_vec_size(vec) ((vec).size)
#define scc_vec_cap(vec) ((vec).cap) #define scc_vec_cap(vec) ((vec).cap)
#define scc_vec_foreach(vec, idx) \ #define scc_vec_foreach(vec, idx) \
for (usize idx = 0; idx < scc_vec_size(vec); ++idx) for (usize idx = 0; idx < scc_vec_size(vec); idx += 1)
/** /**
* @def scc_vec_push(vec, value) * @def scc_vec_push(vec, value)
@@ -146,6 +146,8 @@ typedef size_t usize;
*/ */
#define scc_vec_free(vec) \ #define scc_vec_free(vec) \
do { \ do { \
if ((vec).data == nullptr) \
break; \
__scc_vec_free((vec).data); \ __scc_vec_free((vec).data); \
(vec).data = nullptr; \ (vec).data = nullptr; \
(vec).size = (vec).cap = 0; \ (vec).size = (vec).cap = 0; \

View File

@@ -91,7 +91,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value);
* @param key 查找键指针 * @param key 查找键指针
* @return 找到返回值指针未找到返回nullptr * @return 找到返回值指针未找到返回nullptr
*/ */
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key); void *scc_hashtable_get(const scc_hashtable_t *ht, const void *key);
/** /**
* @brief 删除键值对 * @brief 删除键值对

View File

@@ -144,7 +144,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value) {
return old_value; return old_value;
} }
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key) { void *scc_hashtable_get(const scc_hashtable_t *ht, const void *key) {
if (ht->entries.cap == 0) if (ht->entries.cap == 0)
return nullptr; return nullptr;

View File

@@ -2,22 +2,24 @@
# windows powershell: echo $LASTEXITCODE # windows powershell: echo $LASTEXITCODE
# nushell: echo $env.LAST_EXIT_CODE # nushell: echo $env.LAST_EXIT_CODE
# bash: echo $? # bash: echo $?
"./return_val_cases/01_return.c" = 65536 "./return_val_cases/01_return.c" = 65536
"./return_val_cases/02_decl_expr.c" = 1 "./return_val_cases/02_decl_expr.c" = 1
"./return_val_cases/03_decl_init.c" = 11 "./return_val_cases/03_decl_init.c" = 11
"./return_val_cases/04_if.c" = 1 "./return_val_cases/04_if.c" = 1
"./return_val_cases/05_else.c" = 2 "./return_val_cases/05_else.c" = 2
"./return_val_cases/06_fcall.c" = 3 "./return_val_cases/06_fcall.c" = 3
"./return_val_cases/07_while.c" = 10 "./return_val_cases/07_while.c" = 10
"./return_val_cases/08_do_while.c" = 128 "./return_val_cases/08_do_while.c" = 128
"./return_val_cases/09_for.c" = 10 "./return_val_cases/09_for.c" = 10
"./return_val_cases/10_main.c" = 3 "./return_val_cases/10_main.c" = 3
"./return_val_cases/11_recursive.c" = 120 "./return_val_cases/11_recursive.c" = 120
"./return_val_cases/12_logic.c" = 10 "./return_val_cases/12_logic.c" = 10
"./return_val_cases/13_array.c" = 1198 "./return_val_cases/13_array.c" = 1198
"./return_val_cases/14_pointer.c" = 2 "./return_val_cases/14_pointer.c" = 2
"./return_val_cases/15_array_subscript.c" = 1198 "./return_val_cases/15_array_subscript.c" = 1198
"./return_val_cases/16_enum.c" = 5 "./return_val_cases/16_enum.c" = 5
"./return_val_cases/17_more_arg.c" = 45 "./return_val_cases/17_more_arg.c" = 45
"./return_val_cases/18_break_continue.c" = 676
"./return_val_cases/19_goto.c" = 676
[stdout_val_cases] [stdout_val_cases]
"./stdout_val_cases/01_include.c" = "Hello World!\n" "./stdout_val_cases/01_include.c" = "Hello World!\n"

View File

@@ -0,0 +1,13 @@
int main(void) {
char buff[] = "hello buffer";
int res = 0;
for (int i = 0; buff[i] != 0; i += 1) {
if (i < 2)
continue;
if (i > 8)
break;
res += buff[i];
}
return res;
}

View File

@@ -0,0 +1,14 @@
int main(void) {
char buff[] = "hello buffer";
int res = 0;
for (int i = 0; buff[i] != 0; i += 1) {
if (i < 2)
goto the_continue;
if (i > 8)
goto the_break;
res += buff[i];
the_continue:;
}
the_break:
return res;
}