From 676f3ec82c296d5e1796faeec36f0c409f5e7ffe Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Sun, 3 May 2026 21:34:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(ir2mcode):=20=E6=B7=BB=E5=8A=A0IR=E5=88=B0?= =?UTF-8?q?=E6=9C=BA=E5=99=A8=E7=A0=81=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E5=A4=8D=E5=87=BD=E6=95=B0=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加了完整的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文件格式以便于维护。 --- libs/ir2mcode/include/scc_ir2sccf.h | 2 +- libs/ir2mcode/src/scc_ir2mcode.c | 38 +++++++++++++++++++ libs/ir2mcode/src/scc_ir2sccf.c | 2 +- runtime/scc_core/include/scc_core_vec.h | 4 +- runtime/scc_utils/include/scc_hashtable.h | 2 +- runtime/scc_utils/src/hashtable.c | 2 +- tests/simple/expect.toml | 34 +++++++++-------- .../return_val_cases/18_break_continue.c | 13 +++++++ tests/simple/return_val_cases/19_goto.c | 14 +++++++ 9 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 libs/ir2mcode/src/scc_ir2mcode.c create mode 100644 tests/simple/return_val_cases/18_break_continue.c create mode 100644 tests/simple/return_val_cases/19_goto.c diff --git a/libs/ir2mcode/include/scc_ir2sccf.h b/libs/ir2mcode/include/scc_ir2sccf.h index e2a25de..1fe26dd 100644 --- a/libs/ir2mcode/include/scc_ir2sccf.h +++ b/libs/ir2mcode/include/scc_ir2sccf.h @@ -4,6 +4,6 @@ #include #include -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__ */ diff --git a/libs/ir2mcode/src/scc_ir2mcode.c b/libs/ir2mcode/src/scc_ir2mcode.c new file mode 100644 index 0000000..50fbc9b --- /dev/null +++ b/libs/ir2mcode/src/scc_ir2mcode.c @@ -0,0 +1,38 @@ +#include +#include +#include + +#include +#include +#include + +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); + } + } + } +} diff --git a/libs/ir2mcode/src/scc_ir2sccf.c b/libs/ir2mcode/src/scc_ir2sccf.c index ba75545..fb5957b 100644 --- a/libs/ir2mcode/src/scc_ir2sccf.c +++ b/libs/ir2mcode/src/scc_ir2sccf.c @@ -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->cfg_module.funcs sccf_builder_init(builder); diff --git a/runtime/scc_core/include/scc_core_vec.h b/runtime/scc_core/include/scc_core_vec.h index a7d538e..43bf838 100644 --- a/runtime/scc_core/include/scc_core_vec.h +++ b/runtime/scc_core/include/scc_core_vec.h @@ -89,7 +89,7 @@ typedef size_t usize; #define scc_vec_size(vec) ((vec).size) #define scc_vec_cap(vec) ((vec).cap) #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) @@ -146,6 +146,8 @@ typedef size_t usize; */ #define scc_vec_free(vec) \ do { \ + if ((vec).data == nullptr) \ + break; \ __scc_vec_free((vec).data); \ (vec).data = nullptr; \ (vec).size = (vec).cap = 0; \ diff --git a/runtime/scc_utils/include/scc_hashtable.h b/runtime/scc_utils/include/scc_hashtable.h index f7f3419..3c2c8a6 100644 --- a/runtime/scc_utils/include/scc_hashtable.h +++ b/runtime/scc_utils/include/scc_hashtable.h @@ -91,7 +91,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value); * @param key 查找键指针 * @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 删除键值对 diff --git a/runtime/scc_utils/src/hashtable.c b/runtime/scc_utils/src/hashtable.c index 62cf797..7e56840 100644 --- a/runtime/scc_utils/src/hashtable.c +++ b/runtime/scc_utils/src/hashtable.c @@ -144,7 +144,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *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) return nullptr; diff --git a/tests/simple/expect.toml b/tests/simple/expect.toml index 6e05d6b..27528f8 100644 --- a/tests/simple/expect.toml +++ b/tests/simple/expect.toml @@ -2,22 +2,24 @@ # windows powershell: echo $LASTEXITCODE # nushell: echo $env.LAST_EXIT_CODE # bash: echo $? -"./return_val_cases/01_return.c" = 65536 -"./return_val_cases/02_decl_expr.c" = 1 -"./return_val_cases/03_decl_init.c" = 11 -"./return_val_cases/04_if.c" = 1 -"./return_val_cases/05_else.c" = 2 -"./return_val_cases/06_fcall.c" = 3 -"./return_val_cases/07_while.c" = 10 -"./return_val_cases/08_do_while.c" = 128 -"./return_val_cases/09_for.c" = 10 -"./return_val_cases/10_main.c" = 3 -"./return_val_cases/11_recursive.c" = 120 -"./return_val_cases/12_logic.c" = 10 -"./return_val_cases/13_array.c" = 1198 -"./return_val_cases/14_pointer.c" = 2 +"./return_val_cases/01_return.c" = 65536 +"./return_val_cases/02_decl_expr.c" = 1 +"./return_val_cases/03_decl_init.c" = 11 +"./return_val_cases/04_if.c" = 1 +"./return_val_cases/05_else.c" = 2 +"./return_val_cases/06_fcall.c" = 3 +"./return_val_cases/07_while.c" = 10 +"./return_val_cases/08_do_while.c" = 128 +"./return_val_cases/09_for.c" = 10 +"./return_val_cases/10_main.c" = 3 +"./return_val_cases/11_recursive.c" = 120 +"./return_val_cases/12_logic.c" = 10 +"./return_val_cases/13_array.c" = 1198 +"./return_val_cases/14_pointer.c" = 2 "./return_val_cases/15_array_subscript.c" = 1198 -"./return_val_cases/16_enum.c" = 5 -"./return_val_cases/17_more_arg.c" = 45 +"./return_val_cases/16_enum.c" = 5 +"./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/01_include.c" = "Hello World!\n" diff --git a/tests/simple/return_val_cases/18_break_continue.c b/tests/simple/return_val_cases/18_break_continue.c new file mode 100644 index 0000000..c82f901 --- /dev/null +++ b/tests/simple/return_val_cases/18_break_continue.c @@ -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; +} diff --git a/tests/simple/return_val_cases/19_goto.c b/tests/simple/return_val_cases/19_goto.c new file mode 100644 index 0000000..d918c24 --- /dev/null +++ b/tests/simple/return_val_cases/19_goto.c @@ -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; +}