基本稳定可以编译 Test

This commit is contained in:
TermiNexus committed 2026-08-05 20:12:08 +08:00
1 parent a3b9bdc409
commit 8ad500c4da
12 files changed
+738 -119

No files matched your search

+255 -56
View File
@@ -2843,18 +2843,24 @@ def _call_method_on_ptr(pool: memhub.MemBuddy | t.CPtr,
if mdf_defaults is not None and mdf_default_count > 0 and mdf_pi >= mdf_offset:
mdf_di: int = mdf_pi - mdf_offset
if mdf_di < mdf_default_count:
mdf_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(mdf_defaults), t.CPtr))
mdf_node: ast.AST | t.CPtr = mdf_defaults_list.get(mdf_di)
if mdf_node is not None:
mdf_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
builder, pool, mod, mdf_node, None, 0, trans)
if mdf_val is not None:
llvmlite.value_set_next(mdf_val, None)
llvmlite.value_set_next(tail, mdf_val)
tail = mdf_val
total_count += 1
mdf_pi += 1
continue
# 优先用 stdlib 常量快照重建(mdf_gd.Defaults 的 pool 内 AST 可能已被 reset 回收)
mdf_val: llvmlite.Value | t.CPtr = None
if mdf_gd is not None:
mdf_val = _build_const_from_snapshot(
pool, mod, mdf_gd, mdf_di, trans, builder)
if mdf_val is None:
mdf_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(mdf_defaults), t.CPtr))
mdf_node: ast.AST | t.CPtr = mdf_defaults_list.get(mdf_di)
if mdf_node is not None:
mdf_val = HandlesExpr.translate_value(
builder, pool, mod, mdf_node, None, 0, trans)
if mdf_val is not None:
llvmlite.value_set_next(mdf_val, None)
llvmlite.value_set_next(tail, mdf_val)
tail = mdf_val
total_count += 1
mdf_pi += 1
continue
# 无默认值时用零值兜底(需要 found_func 获取参数类型)
if found_func is not None:
param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
@@ -3498,18 +3504,24 @@ def _translate_method_call(pool: memhub.MemBuddy | t.CPtr,
if mdf_defaults is not None and mdf_default_count > 0 and mdf_pi >= mdf_offset:
mdf_di: int = mdf_pi - mdf_offset
if mdf_di < mdf_default_count:
mdf_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(mdf_defaults), t.CPtr))
mdf_node: ast.AST | t.CPtr = mdf_defaults_list.get(mdf_di)
if mdf_node is not None:
mdf_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
builder, pool, mod, mdf_node, None, 0, trans)
if mdf_val is not None:
llvmlite.value_set_next(mdf_val, None)
llvmlite.value_set_next(tail, mdf_val)
tail = mdf_val
total_count += 1
mdf_pi += 1
continue
# 优先用 stdlib 常量快照重建(mdf_gd.Defaults 的 pool 内 AST 可能已被 reset 回收)
mdf_val: llvmlite.Value | t.CPtr = None
if mdf_gd is not None:
mdf_val = _build_const_from_snapshot(
pool, mod, mdf_gd, mdf_di, trans, builder)
if mdf_val is None:
mdf_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(mdf_defaults), t.CPtr))
mdf_node: ast.AST | t.CPtr = mdf_defaults_list.get(mdf_di)
if mdf_node is not None:
mdf_val = HandlesExpr.translate_value(
builder, pool, mod, mdf_node, None, 0, trans)
if mdf_val is not None:
llvmlite.value_set_next(mdf_val, None)
llvmlite.value_set_next(tail, mdf_val)
tail = mdf_val
total_count += 1
mdf_pi += 1
continue
# 无默认值时用零值兜底(需要 found_func 获取参数类型)
if found_func is not None:
param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
@@ -4947,18 +4959,24 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
while df_di < df_default_count:
df_param_idx: int = df_offset + df_di
if df_param_idx >= can:
df_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(df_defaults), t.CPtr))
df_default_node: ast.AST | t.CPtr = df_defaults_list.get(df_di)
if df_default_node is not None:
df_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
builder, pool, mod, df_default_node, None, 0, trans)
if df_arg_val is not None:
df_arg_val.Next = None
if head is None:
head = df_arg_val
else:
tail.Next = df_arg_val
tail = df_arg_val
# 优先用 stdlib 常量快照重建(gd_entry.Defaults 的 pool 内 AST 可能已被 reset 回收)
df_arg_val: llvmlite.Value | t.CPtr = None
if gd_entry is not None:
df_arg_val = _build_const_from_snapshot(
pool, mod, gd_entry, df_di, trans, builder)
if df_arg_val is None:
df_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(df_defaults), t.CPtr))
df_default_node: ast.AST | t.CPtr = df_defaults_list.get(df_di)
if df_default_node is not None:
df_arg_val = HandlesExpr.translate_value(
builder, pool, mod, df_default_node, None, 0, trans)
if df_arg_val is not None:
df_arg_val.Next = None
if head is None:
head = df_arg_val
else:
tail.Next = df_arg_val
tail = df_arg_val
df_di += 1
# 使用模块中的实际函数名(可能带 SHA1 前缀,如 "83210a72e829a086.atoi")
@@ -5569,6 +5587,10 @@ class FuncEntry:
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
DefaultCount: int # 默认值数量
ParamCount: int # 形参数量(不含 self)
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
TypeStr: t.CChar | t.CPtr
# ============================================================
# 初始化函数表
@@ -5610,13 +5632,15 @@ def add_func_to_table(funcs: FuncEntry | t.CPtr,
max_count: int,
defaults: t.CVoid | t.CPtr = None,
default_count: int = 0,
param_count: int = 0) -> int:
param_count: int = 0,
pool: memhub.MemBuddy | t.CPtr = None) -> int:
"""添加函数到函数表,返回 0 成功
Args:
defaults: ast.Arguments.defaults 列表节点指针,None=无默认值
default_count: 默认值数量(len(defaults))
param_count: 形参数量(不含 self,len(args.args))
pool: 内存池(用于生成 TypeStr;None 时 TypeStr 为空,vtable 回退读 Func 对象)
"""
if name is None or func is None or funcs is None:
return 1
@@ -5631,7 +5655,7 @@ def add_func_to_table(funcs: FuncEntry | t.CPtr,
entry.DefaultCount = default_count
entry.ParamCount = param_count
# 同时注册到全局函数表(供跨模块 vtable 初始化查找)
_register_global_func(name, func)
_register_global_func(name, func, pool)
# 同时注册到全局默认参数表(供跨模块调用时填充默认值)
if default_count > 0:
_register_global_defaults(name, defaults, default_count, param_count)
@@ -5662,10 +5686,64 @@ def _init_global_func_table() -> int:
_global_func_count = 0
return 1
def _register_global_func(name: str, func: llvmlite.Function | t.CPtr) -> int:
# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储)
#
# 格式: ret_ty (param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。
# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。
# 返回 None 表示失败。
def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr,
func: llvmlite.Function | t.CPtr) -> t.CChar | t.CPtr:
"""生成函数类型文本(stdlib 分配)"""
if func is None:
return None
# 类型文本可能较长(SHA1 限定命名结构体 + 多参数),用 1024 缓冲
ty_buf: t.CChar | t.CPtr = pool.alloc(1024)
if ty_buf is None:
return None
ty_buf[0] = '\0'
# 返回类型
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(func)
ret_part: t.CChar | t.CPtr = pool.alloc(512)
if ret_part is not None and ret_ty is not None:
ret_part[0] = '\0'
llvmlite.TypePrint(ret_part, 512, ret_ty, pool)
string.strcat(ty_buf, ret_part)
string.strcat(ty_buf, " (")
# 参数类型
cur: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
first: int = 1
param_part: t.CChar | t.CPtr = pool.alloc(512)
while cur is not None:
if first == 0:
string.strcat(ty_buf, ", ")
if param_part is not None:
param_part[0] = '\0'
param_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(cur)
if param_ty is not None:
llvmlite.TypePrint(param_part, 512, param_ty, pool)
string.strcat(ty_buf, param_part)
cur = llvmlite.param_get_next(cur)
first = 0
string.strcat(ty_buf, ")")
# 深拷贝到 stdlib 区(TypeStr 跨文件永久存活)
ts_len: t.CSizeT = string.strlen(ty_buf)
ts_copy: t.CChar | t.CPtr = stdlib.malloc(ts_len + 1)
if ts_copy is None:
return None
string.strcpy(ts_copy, ty_buf)
return ts_copy
def _register_global_func(name: str, func: llvmlite.Function | t.CPtr,
pool: memhub.MemBuddy | t.CPtr = None) -> int:
"""注册函数到全局表(已存在则跳过),返回 0 成功
直接操作全局表,不调用 add_func_to_table,避免递归。
pool 用于生成 TypeStr(None 时 TypeStr 为空)。
"""
global _global_func_count
if name is None or func is None:
@@ -5681,11 +5759,38 @@ def _register_global_func(name: str, func: llvmlite.Function | t.CPtr) -> int:
entry_size: t.CSizeT = FuncEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(_global_funcs) + _global_func_count * entry_size
entry: FuncEntry | t.CPtr = (FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
entry.Name = name
# Name 深拷贝到 stdlib 区:全局表跨文件永久存活,pool 内名字会被 1b 每文件
# reset_to(mark1) 回收导致悬空(vtable 生成 find_func_global 后 strcmp 崩溃)
name_len: t.CSizeT = string.strlen(name)
name_copy: t.CChar | t.CPtr = stdlib.malloc(name_len + 1)
if name_copy is None:
return 1
string.strcpy(name_copy, name)
entry.Name = name_copy
entry.Func = func
# TypeStr 不在此生成:函数参数在 add_func_to_table 之后才添加,
# 需由调用方在参数添加完成后调用 update_global_func_typestr 补全。
_global_func_count += 1
return 0
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
name: str,
func: llvmlite.Function | t.CPtr) -> int:
"""更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)
调用时机:add_func_to_table 注册后、llvmlite.add_param 全部执行完。
生成 ret_ty (param1_ty, ...) 类型文本(stdlib 深拷贝),
供 vtable 生成在 func 被 1b reset 后使用。
"""
if name is None or func is None:
return 1
entry: FuncEntry | t.CPtr = find_func_entry_global(name)
if entry is None:
return 1
entry.TypeStr = _build_func_type_str(pool, func)
return 0
def find_func_global(name: str) -> llvmlite.Function | t.CPtr:
"""在全局函数表中按名称查找,返回 Function 指针或 None"""
if name is None or _global_funcs is None:
@@ -5693,6 +5798,20 @@ def find_func_global(name: str) -> llvmlite.Function | t.CPtr:
return find_func_in_table(_global_funcs, _global_func_count, name)
def find_func_entry_global(name: str) -> FuncEntry | t.CPtr:
"""在全局函数表中按名称查找,返回完整 FuncEntry(含 TypeStr)或 None"""
if name is None or _global_funcs is None:
return None
entry_size: t.CSizeT = FuncEntry.__sizeof__()
for i in range(_global_func_count):
entry_addr: t.CUInt64T = t.CUInt64T(_global_funcs) + i * entry_size
entry: FuncEntry | t.CPtr = (FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
return entry
return None
# ============================================================
# 全局默认参数注册表(跨模块默认参数填充)
#
@@ -5705,9 +5824,15 @@ GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
class FuncDefaultsEntry:
"""默认参数表条目"""
Name: str
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
DefaultCount: int
ParamCount: int # 形参数量(不含 self)
# 常量快照(stdlib 分配,跨文件永久存活):
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
ConstKinds: t.CInt | t.CPtr # const_kind 数组(DefaultCount 个 i32)
ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64)
ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
_global_defaults: FuncDefaultsEntry | t.CPtr = None
_global_defaults_count: int = 0
@@ -5730,7 +5855,11 @@ def _register_global_defaults(name: str,
defaults: t.CVoid | t.CPtr,
default_count: int,
param_count: int) -> int:
"""注册函数默认参数到全局表,返回 0 成功"""
"""注册函数默认参数到全局表,返回 0 成功
注册时提取每个默认值 Constant 的常量快照到 stdlib(ConstKinds/ConstInts/ConstStrs),
跨模块调用时优先用快照重建常量 IR,避免读取被 reset 回收的 pool 内 AST。
"""
global _global_defaults_count
if name is None or defaults is None:
return 1
@@ -5744,26 +5873,96 @@ def _register_global_defaults(name: str,
entry_size: t.CSizeT = FuncDefaultsEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(_global_defaults) + _global_defaults_count * entry_size
entry: FuncDefaultsEntry | t.CPtr = (FuncDefaultsEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
entry.Name = name
# Name 深拷贝到 stdlib(全局表跨文件永久存活)
nm_len: t.CSizeT = string.strlen(name)
nm_copy: t.CChar | t.CPtr = stdlib.malloc(nm_len + 1)
if nm_copy is None:
return 1
string.strcpy(nm_copy, name)
entry.Name = nm_copy
entry.Defaults = defaults
entry.DefaultCount = default_count
entry.ParamCount = param_count
# 提取常量快照到 stdlib
if default_count > 0:
kinds: t.CInt | t.CPtr = stdlib.malloc(default_count * 4)
ints: t.CInt64T | t.CPtr = stdlib.malloc(default_count * 8)
strs: t.CSizeT | t.CPtr = stdlib.malloc(default_count * 8)
if kinds is not None and ints is not None and strs is not None:
string.memset(kinds, 0, default_count * 4)
string.memset(ints, 0, default_count * 8)
string.memset(strs, 0, default_count * 8)
dl: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(defaults), t.CPtr))
di: int
for di in range(default_count):
dnode: ast.AST | t.CPtr = dl.get(di)
if dnode is not None and dnode.kind() == ast.ASTKind.Constant:
dcn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(dnode)
kinds[di] = dcn.const_kind
ints[di] = dcn.int_val
if dcn.const_kind == ast.CONST_STR and dcn.str_val is not None:
slen: t.CSizeT = string.strlen(dcn.str_val)
scopy: t.CChar | t.CPtr = stdlib.malloc(slen + 1)
if scopy is not None:
string.strcpy(scopy, dcn.str_val)
strs[di] = t.CSizeT(scopy)
entry.ConstKinds = kinds
entry.ConstInts = ints
entry.ConstStrs = strs
_global_defaults_count += 1
return 0
def find_func_defaults(name: str) -> FuncDefaultsEntry | t.CPtr:
"""按函数名查找默认参数信息,返回 FuncDefaultsEntry 或 None"""
if name is None or _global_defaults is None:
return None
entry_size: t.CSizeT = FuncDefaultsEntry.__sizeof__()
i: int = 0
while i < _global_defaults_count:
entry_addr: t.CUInt64T = t.CUInt64T(_global_defaults) + i * entry_size
entry: FuncDefaultsEntry | t.CPtr = (FuncDefaultsEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
return entry
i += 1
def find_func_defaults(name: str) -> FuncDefaultsEntry | t.CPtr:
"""按函数名查找默认参数信息,返回 FuncDefaultsEntry 或 None"""
if name is None or _global_defaults is None:
return None
entry_size: t.CSizeT = FuncDefaultsEntry.__sizeof__()
i: int = 0
while i < _global_defaults_count:
entry_addr: t.CUInt64T = t.CUInt64T(_global_defaults) + i * entry_size
entry: FuncDefaultsEntry | t.CPtr = (FuncDefaultsEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
return entry
i += 1
return None
# _build_const_from_snapshot — 从常量快照重建常量 IR 值
#
# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收,
# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。
# 返回 llvmlite.Value*,失败返回 None。
def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
gd_entry: FuncDefaultsEntry | t.CPtr,
di: int,
trans: HT.Translator | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr:
"""从快照重建第 di 个默认值常量 IR"""
if gd_entry is None or gd_entry.ConstKinds is None or gd_entry.ConstInts is None:
return None
if di < 0 or di >= gd_entry.DefaultCount:
return None
kind: t.CInt = gd_entry.ConstKinds[di]
ival: t.CInt64T = gd_entry.ConstInts[di]
if kind == ast.CONST_INT:
if ival > 2147483647 or ival < -2147483648:
return llvmlite.const_int64(pool, ival)
return llvmlite.const_int32(pool, ival)
elif kind == ast.CONST_BOOL:
if ival != 0:
return llvmlite.const_int32(pool, 1)
return llvmlite.const_int32(pool, 0)
elif kind == ast.CONST_NONE:
i8_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool)
i8_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty)
return llvmlite.ConstNull(pool, i8_ptr_ty, "null")
elif kind == ast.CONST_STR:
if gd_entry.ConstStrs is not None and gd_entry.ConstStrs[di] != 0:
sv: str = (str | t.CPtr)(t.CVoid(gd_entry.ConstStrs[di], t.CPtr))
return HandlesExpr.create_global_string(builder, pool, mod, sv, trans)
# 无法重建的(如 CONST_FLOAT/复杂表达式)返回 None,调用方回退到 AST
return None
def find_func_entry_in_table(funcs: FuncEntry | t.CPtr,