fix: 5项立即修复 + 2项尽快修复

立即:
- lexer: token数组容量改为src_len+16 + idx越界防御
- symbol: 4个函数arena_alloc加NULL检查
- codegen: verify_err fallback用arena_strdup替代静态字符串
- codegen: cleanup_list从固定64改为arena动态扩容
- lexer: 标识符/字符串字面量65535字符上限

尽快:
- to_llvm_type: TYPE_STRUCT/TYPE_UNKNOWN/TYPE_ERROR显式case
- LLVMGetValueType2不存在(LLVM 22仍用旧名), 保留GlobalGetValueType
This commit is contained in:
2026-06-05 13:12:00 +08:00
parent af0725caca
commit a7fca5964e
3 changed files with 32 additions and 8 deletions
+16 -4
View File
@@ -50,8 +50,9 @@ typedef struct {
LLVMValueRef strlen_fn;
LLVMValueRef memcpy_fn;
// 自动内存管理: 追踪需要 free 的 str alloca
LLVMValueRef cleanup_list[64];
LLVMValueRef* cleanup_list;
size_t cleanup_count;
size_t cleanup_cap;
} CgCtx;
// === 类型映射(需要 Context===
@@ -61,6 +62,9 @@ static LLVMTypeRef to_llvm_type(CgCtx* ctx, TypeKind kind) {
case TYPE_F64: return LLVMDoubleTypeInContext(ctx->context);
case TYPE_BOOL: return LLVMInt1TypeInContext(ctx->context);
case TYPE_STR: return LLVMPointerType(LLVMInt8TypeInContext(ctx->context), 0);
case TYPE_STRUCT:
case TYPE_UNKNOWN:
case TYPE_ERROR:
default: return LLVMVoidTypeInContext(ctx->context);
}
}
@@ -350,9 +354,16 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
// === 自动内存管理: 作用域退出时释放 str 堆分配 ===
static void cleanup_add(CgCtx* ctx, LLVMValueRef alloca) {
if (ctx->cleanup_count < 64) {
ctx->cleanup_list[ctx->cleanup_count++] = alloca;
if (ctx->cleanup_count >= ctx->cleanup_cap) {
size_t new_cap = ctx->cleanup_cap ? ctx->cleanup_cap * 2 : 16;
LLVMValueRef* new_list = arena_alloc(ctx->arena, new_cap * sizeof(LLVMValueRef));
if (!new_list) return;
if (ctx->cleanup_list)
memcpy(new_list, ctx->cleanup_list, ctx->cleanup_count * sizeof(LLVMValueRef));
ctx->cleanup_list = new_list;
ctx->cleanup_cap = new_cap;
}
ctx->cleanup_list[ctx->cleanup_count++] = alloca;
}
// 释放从 mark 位置开始的所有 str 变量
@@ -645,7 +656,8 @@ LLVMModuleRef codegen_module(AstNode* ast, Arena* codegen_arena,
// 验证模块(使用 ReturnStatus 以获取完整错误消息)
char* verify_err = NULL;
if (LLVMVerifyModule(ctx.module, LLVMReturnStatusAction, &verify_err)) {
*error_msg = verify_err ? verify_err : "模块验证失败(错误消息为 NULL";
*error_msg = verify_err ? verify_err
: arena_strdup(ctx.arena, "LLVM 模块验证失败");
LLVMDisposeBuilder(ctx.builder);
*out_context = ctx.context;
return NULL;