fix: 技术债修复 — codegen malloc→arena + .codegraphignore
- codegen.c: VarEntry/FnEntry/ptypes 全部改用 arena_alloc,消除 malloc/free - codegen_module 新增 Arena* 参数,main.c 传入主 arena - 新增 .codegraphignore 排除 build/ 和 .codegraph/ - 基于 Codex 分析报告第7节技术债务
This commit is contained in:
+10
-6
@@ -3,7 +3,6 @@
|
||||
#include <llvm-c/Types.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// === 内部状态 ===
|
||||
typedef struct VarEntry {
|
||||
@@ -22,6 +21,7 @@ typedef struct FnEntry {
|
||||
} FnEntry;
|
||||
|
||||
typedef struct {
|
||||
Arena* arena; // 代码生成阶段分配器
|
||||
LLVMContextRef context; // LLVM 19+ 需要显式 Context
|
||||
LLVMModuleRef module;
|
||||
LLVMBuilderRef builder;
|
||||
@@ -60,7 +60,8 @@ static LLVMValueRef find_var(CgCtx* ctx, const char* name) {
|
||||
}
|
||||
|
||||
static void add_var(CgCtx* ctx, const char* name, LLVMValueRef alloca) {
|
||||
VarEntry* e = malloc(sizeof(*e));
|
||||
VarEntry* e = arena_alloc(ctx->arena, sizeof(*e));
|
||||
if (!e) return;
|
||||
e->name = name; e->alloca = alloca; e->next = ctx->var_table;
|
||||
ctx->var_table = e;
|
||||
}
|
||||
@@ -73,7 +74,8 @@ static LLVMValueRef find_fn(CgCtx* ctx, const char* name) {
|
||||
}
|
||||
|
||||
static void add_fn(CgCtx* ctx, const char* name, LLVMValueRef fn) {
|
||||
FnEntry* e = malloc(sizeof(*e));
|
||||
FnEntry* e = arena_alloc(ctx->arena, sizeof(*e));
|
||||
if (!e) return;
|
||||
e->name = name; e->fn = fn;
|
||||
e->ret = TYPE_VOID;
|
||||
e->params = NULL;
|
||||
@@ -305,8 +307,10 @@ static void codegen_stmt(CgCtx* ctx, AstNode* node) {
|
||||
}
|
||||
|
||||
// === 程序级代码生成 ===
|
||||
LLVMModuleRef codegen_module(AstNode* ast, const char* name, const char** error_msg) {
|
||||
LLVMModuleRef codegen_module(AstNode* ast, Arena* codegen_arena,
|
||||
const char* name, const char** error_msg) {
|
||||
CgCtx ctx = {0};
|
||||
ctx.arena = codegen_arena;
|
||||
ctx.context = LLVMContextCreate();
|
||||
if (!ctx.context) {
|
||||
*error_msg = "无法创建 LLVM Context";
|
||||
@@ -326,7 +330,8 @@ LLVMModuleRef codegen_module(AstNode* ast, const char* name, const char** error_
|
||||
// 第一遍:声明所有 L 函数
|
||||
for (size_t i = 0; i < ast->as.program.fn_count; i++) {
|
||||
AstNode* fn = ast->as.program.functions[i];
|
||||
LLVMTypeRef* ptypes = malloc(fn->as.function.param_count * sizeof(LLVMTypeRef));
|
||||
LLVMTypeRef* ptypes = arena_alloc(ctx.arena,
|
||||
fn->as.function.param_count * sizeof(LLVMTypeRef));
|
||||
for (size_t j = 0; j < fn->as.function.param_count; j++)
|
||||
ptypes[j] = to_llvm_type(&ctx, fn->as.function.params[j]->as.parameter.type);
|
||||
LLVMTypeRef fty = LLVMFunctionType(
|
||||
@@ -334,7 +339,6 @@ LLVMModuleRef codegen_module(AstNode* ast, const char* name, const char** error_
|
||||
ptypes, (unsigned)fn->as.function.param_count, false);
|
||||
LLVMValueRef lfn = LLVMAddFunction(ctx.module, fn->as.function.name, fty);
|
||||
add_fn(&ctx, fn->as.function.name, lfn);
|
||||
free(ptypes);
|
||||
}
|
||||
|
||||
// 第二遍:生成函数体
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
#define CODEGEN_H
|
||||
|
||||
#include "ast.h"
|
||||
#include "arena.h"
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
// 生成 LLVM Module。模块已 verify,可直接 dump 或写入文件。
|
||||
// codegen_arena 用于内部分配(VarEntry/FnEntry 等),需在整个 Module 生命周期保持存活。
|
||||
// 出错时返回 NULL 并设置 *error_msg。
|
||||
LLVMModuleRef codegen_module(AstNode* ast, const char* module_name,
|
||||
const char** error_msg);
|
||||
LLVMModuleRef codegen_module(AstNode* ast, Arena* codegen_arena,
|
||||
const char* module_name, const char** error_msg);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user