Some simple information syncing

This commit is contained in:
2026-07-28 21:08:58 +08:00
parent 1837339f69
commit 3633be1995
65 changed files with 1132 additions and 368581 deletions

View File

@@ -818,7 +818,7 @@ def _translate_enum_def(trans: HT.Translator | t.CPtr,
# 用于联合体确定最大字段大小
# ============================================================
def _get_type_size(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""计算 LLVM 类型的字节大小"""
"""计算 LLVM 类型的字节大小(含对齐 padding"""
if ty is None:
return 0
match ty:
@@ -831,20 +831,79 @@ def _get_type_size(ty: llvmlite.LLVMType | t.CPtr) -> int:
case llvmlite.LLVMType.Array(elem_ty, count):
return _get_type_size(elem_ty) * count
case llvmlite.LLVMType.Struct(fields, fcount, name):
# 计算结构体大小,考虑字段对齐 padding
# 规则: 每个字段的对齐 = 该字段类型的自然对齐
# 指针/i64 → 8, i32 → 4, i16 → 2, i8 → 1
# 结构体总大小需对齐到最大字段对齐的倍数
total: int = 0
max_align: int = 1
cur: llvmlite.ParamNode | t.CPtr = fields
i: int = 0
while cur is not None and i < fcount:
if cur.Ty is not None:
fty: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(cur.Ty)
total += _get_type_size(fty)
fsize: int = _get_type_size(fty)
falign: int = _get_type_align(fty)
# 对齐当前偏移到字段对齐边界
if falign > 0:
rem: int = total % falign
if rem != 0:
total += falign - rem
total += fsize
if falign > max_align:
max_align = falign
cur = cur.Next
i += 1
# 结构体总大小对齐到最大字段对齐的倍数
rem2: int = total % max_align
if rem2 != 0:
total += max_align - rem2
return total
case _:
return 8
def _get_type_align(ty: llvmlite.LLVMType | t.CPtr) -> int:
"""返回类型的自然对齐(字节)"""
if ty is None:
return 1
match ty:
case llvmlite.LLVMType.Int(bits):
if bits <= 8:
return 1
elif bits <= 16:
return 2
elif bits <= 32:
return 4
else:
return 8
case llvmlite.LLVMType.Float(bits):
if bits <= 32:
return 4
else:
return 8
case llvmlite.LLVMType.Ptr(pointee):
return 8
case llvmlite.LLVMType.Array(elem_ty, count):
return _get_type_align(elem_ty)
case llvmlite.LLVMType.Struct(fields, fcount, name):
# 结构体的对齐 = 最大字段对齐
max_align: int = 1
cur: llvmlite.ParamNode | t.CPtr = fields
i: int = 0
while cur is not None and i < fcount:
if cur.Ty is not None:
fty: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(cur.Ty)
fa: int = _get_type_align(fty)
if fa > max_align:
max_align = fa
cur = cur.Next
i += 1
return max_align
case _:
return 8
# ============================================================
# _translate_union_def — 翻译联合体定义
#
@@ -3003,17 +3062,21 @@ def _translate_method(trans: HT.Translator | t.CPtr,
return 0
# 提取默认参数信息(方法的 args[0] 是 self不含在 param_count 中)
md_defaults: list[ast.AST | t.CPtr] | t.CPtr = None
# 注意: 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__()
# 否则编译器无法识别属性返回的 list 类型GEP base 会变成 i32 0 导致 llc 报错
md_defaults: t.CVoid | t.CPtr = None
md_default_count: int = 0
md_param_count: int = 0
md_args_node: ast.Arguments | t.CPtr = fd.args
if md_args_node is not None:
md_ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(md_args_node)
if md_ags.args is not None:
md_param_count = md_ags.args.__len__() - 1
md_alist: list[ast.AST | t.CPtr] | t.CPtr = md_ags.args
md_param_count = md_alist.__len__() - 1
if md_ags.defaults is not None:
md_defaults = md_ags.defaults
md_default_count = md_ags.defaults.__len__()
md_dlist: list[ast.AST | t.CPtr] | t.CPtr = md_ags.defaults
md_defaults = md_dlist
md_default_count = md_dlist.__len__()
# 注册到函数表(用 ClassName.method_name 作为查找名,支持后缀匹配)
max_funcs: int = 256
@@ -3059,12 +3122,16 @@ def _translate_method(trans: HT.Translator | t.CPtr,
# 进入函数作用域
HandlesVar.enter_scope(trans.SymTab, SCOPE_FUNCTION)
# 注册 self 为 SSA 值(不创建 alloca,不 store
# 这样 self.field 通过 lookup_var 获取 Ptr(struct_ty) 后直接 GEP
self_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, self_ptr_ty, "%self")
HandlesVar.define_var(trans.SymTab, "self", self_val)
# 设置 self 的类型注解类名(属性访问 lookup_field 回退查找用)
HandlesVar.set_var_annot_class_name(trans.SymTab, "self", class_name)
# self 创建 alloca store(与其他参数一致
# 修复: 之前 self 注册为 SSA 值导致 translate_name_value 错误地 load 一次
# 将 Ptr(struct_ty) 变成 struct 值,引发变参函数 ABI 不匹配崩溃
self_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, self_ptr_ty)
if self_alloca is not None:
HandlesVar.define_var(trans.SymTab, "self", self_alloca)
# 设置 self 的类型注解类名(属性访问 lookup_field 回退查找用)
HandlesVar.set_var_annot_class_name(trans.SymTab, "self", class_name)
self_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, self_ptr_ty, "%self")
llvmlite.build_store(func_builder, self_val, self_alloca)
# 为其他参数创建 alloca 并 store与普通函数一致跳过索引 0 的 self 参数)
if args_node is not None: