修正了种子编译器的错误
This commit is contained in:
@@ -199,10 +199,16 @@ def _is_marker_base(base_name: str) -> int:
|
||||
# ============================================================
|
||||
# _get_base_name — 从 base AST 节点提取基类名
|
||||
#
|
||||
# 支持 Name(id), Attribute(attr), Subscript
|
||||
# 支持 Name(id), Attribute(attr), Subscript(value, slice)
|
||||
# 对于 Subscript(如 GSListNode[Value]),需要 pool 拼接特化名 "GSListNode[Value]"
|
||||
# ============================================================
|
||||
def _get_base_name(base_node: ast.AST | t.CPtr) -> str:
|
||||
"""从 base AST 节点提取基类名,返回 None=失败"""
|
||||
def _get_base_name(base_node: ast.AST | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr = None) -> str:
|
||||
"""从 base AST 节点提取基类名,返回 None=失败
|
||||
|
||||
对于 Subscript 节点,需要 pool 分配内存拼接特化名;
|
||||
pool=None 时降级返回基类名(不含类型实参)
|
||||
"""
|
||||
if base_node is None:
|
||||
return None
|
||||
k: int = base_node.kind()
|
||||
@@ -214,6 +220,40 @@ def _get_base_name(base_node: ast.AST | t.CPtr) -> str:
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(base_node)
|
||||
return at.attr
|
||||
# Subscript(value, slice) 形式 — 如 GSListNode[Value]
|
||||
if k == ast.ASTKind.Subscript:
|
||||
sub: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(base_node)
|
||||
if sub is None or sub.value is None or sub.slice is None:
|
||||
return None
|
||||
# 提取基类名(如 "GSListNode")
|
||||
base_nm: str = _get_base_name(sub.value, pool)
|
||||
if base_nm is None:
|
||||
return None
|
||||
# 提取类型实参名(如 "Value")
|
||||
slice_k: int = sub.slice.kind()
|
||||
arg_nm: str = None
|
||||
if slice_k == ast.ASTKind.Name:
|
||||
sl_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub.slice)
|
||||
arg_nm = sl_nm.id
|
||||
# 如果无法提取类型实参,返回基类名(降级)
|
||||
if arg_nm is None:
|
||||
return base_nm
|
||||
# 无 pool 时返回基类名(降级,无法拼接特化名)
|
||||
if pool is None:
|
||||
return base_nm
|
||||
# 拼接特化名 "GSListNode[Value]"
|
||||
base_len: t.CSizeT = string.strlen(base_nm)
|
||||
arg_len: t.CSizeT = string.strlen(arg_nm)
|
||||
total_len: t.CSizeT = base_len + arg_len + 3 # "[" + arg + "]" + NUL
|
||||
mangled: str = pool.alloc(total_len)
|
||||
if mangled is None:
|
||||
return base_nm # 降级
|
||||
mangled[0] = '\0'
|
||||
string.strcat(mangled, base_nm)
|
||||
string.strcat(mangled, "[")
|
||||
string.strcat(mangled, arg_nm)
|
||||
string.strcat(mangled, "]")
|
||||
return mangled
|
||||
return None
|
||||
|
||||
|
||||
@@ -221,11 +261,17 @@ def _get_base_name(base_node: ast.AST | t.CPtr) -> str:
|
||||
# _get_parent_class — 获取 ClassDef 的真实父类名(非标记基类)
|
||||
#
|
||||
# 遍历 bases,返回第一个非标记基类的名字,None=无真实父类
|
||||
# 支持 Name, Attribute, Subscript 三种 base 节点
|
||||
# 对于 Subscript(如 GSListNode[Value]),需要 trans.Pool 拼接特化名
|
||||
# ============================================================
|
||||
def _get_parent_class(cd: ast.ClassDef | t.CPtr) -> str:
|
||||
def _get_parent_class(cd: ast.ClassDef | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> str:
|
||||
"""获取 ClassDef 的真实父类名,返回 None=无真实父类"""
|
||||
if cd is None or cd.bases is None:
|
||||
return None
|
||||
pool: memhub.MemBuddy | t.CPtr = None
|
||||
if trans is not None:
|
||||
pool = trans.Pool
|
||||
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
|
||||
bn: t.CSizeT = bases.__len__()
|
||||
if bn == 0:
|
||||
@@ -234,12 +280,66 @@ def _get_parent_class(cd: ast.ClassDef | t.CPtr) -> str:
|
||||
base_node: ast.AST | t.CPtr = bases.get(bi)
|
||||
if base_node is None:
|
||||
continue
|
||||
bname: str = _get_base_name(base_node)
|
||||
bname: str = _get_base_name(base_node, pool)
|
||||
if bname is not None and _is_marker_base(bname) == 0:
|
||||
return bname
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _trigger_base_specialization — 触发 base 中 Subscript 的泛型特化
|
||||
#
|
||||
# 对于 class Value(GSListNode[Value]),GSListNode[Value] 是 Subscript 节点。
|
||||
# 在 translate_class_def 处理 Value 之前,需要先特化 GSListNode[Value],
|
||||
# 否则 find_struct_by_module("GSListNode[Value]") 返回 None,父类字段不被继承。
|
||||
#
|
||||
# 遍历 cd.bases,如果 base 是 Subscript,提取 class_name 和 type_args,
|
||||
# 调用 _specialize_generic_class 触发特化。
|
||||
# ============================================================
|
||||
def _trigger_base_specialization(trans: HT.Translator | t.CPtr,
|
||||
cd: ast.ClassDef | t.CPtr):
|
||||
"""触发 base 中 Subscript 的泛型特化(如 GSListNode[Value])"""
|
||||
if trans is None or cd is None or cd.bases is None:
|
||||
return
|
||||
pool: memhub.MemBuddy | t.CPtr = trans.Pool
|
||||
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
|
||||
bn: t.CSizeT = bases.__len__()
|
||||
if bn == 0:
|
||||
return
|
||||
for bi in range(bn):
|
||||
base_node: ast.AST | t.CPtr = bases.get(bi)
|
||||
if base_node is None:
|
||||
continue
|
||||
bk: int = base_node.kind()
|
||||
if bk != ast.ASTKind.Subscript:
|
||||
continue
|
||||
sub: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(base_node)
|
||||
if sub is None or sub.value is None or sub.slice is None:
|
||||
continue
|
||||
# 提取泛型类名(如 "GSListNode")
|
||||
gen_class_name: str = _get_base_name(sub.value, pool)
|
||||
if gen_class_name is None:
|
||||
continue
|
||||
# 跳过标记基类
|
||||
if _is_marker_base(gen_class_name) == 1:
|
||||
continue
|
||||
# 提取类型实参名(如 "Value")
|
||||
slice_k: int = sub.slice.kind()
|
||||
arg_nm: str = None
|
||||
if slice_k == ast.ASTKind.Name:
|
||||
sl_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub.slice)
|
||||
arg_nm = sl_nm.id
|
||||
if arg_nm is None:
|
||||
continue
|
||||
# 构建 type_args 列表
|
||||
type_args: list[str] | t.CPtr = list[str](pool, 1)
|
||||
if type_args is None:
|
||||
continue
|
||||
type_args.append(arg_nm)
|
||||
# 触发特化(_specialize_generic_class 有缓存,重复调用安全)
|
||||
_specialize_generic_class(trans, gen_class_name, type_args)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _has_any_func_cvtable — 检查类中是否有任何函数标记了 @t.CVTable
|
||||
#
|
||||
@@ -304,7 +404,7 @@ def _should_method_be_virtual(cd: ast.ClassDef | t.CPtr,
|
||||
return 1
|
||||
|
||||
# 4. 检查继承关系
|
||||
parent_name: str = _get_parent_class(cd)
|
||||
parent_name: str = _get_parent_class(cd, trans)
|
||||
if parent_name is not None:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
@@ -349,7 +449,7 @@ def _detect_vtable_status(cd: ast.ClassDef | t.CPtr,
|
||||
return _has_any_func_cvtable(cd)
|
||||
|
||||
# 检查是否有真实父类(继承自动启用 CVTable)
|
||||
parent_name: str = _get_parent_class(cd)
|
||||
parent_name: str = _get_parent_class(cd, trans)
|
||||
if parent_name is not None:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
@@ -1111,9 +1211,27 @@ def _specialize_generic_class(trans: HT.Translator | t.CPtr,
|
||||
|
||||
pool: memhub.MemBuddy | t.CPtr = trans.Pool
|
||||
|
||||
# ============================================================
|
||||
# 诊断输出:追踪 GSListNode 特化调用路径
|
||||
# ============================================================
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
stdio.printf("[SPEC] === _specialize_generic_class ===\n")
|
||||
stdio.printf("[SPEC] class=%s module=%s\n", class_name, trans.ModuleSha1)
|
||||
if type_args is not None:
|
||||
ta_n: t.CSizeT = type_args.__len__()
|
||||
ta_i: t.CSizeT
|
||||
for ta_i in range(ta_n):
|
||||
ta: str = type_args.get(ta_i)
|
||||
if ta is not None:
|
||||
stdio.printf("[SPEC] type_arg[%d]=%s\n", ta_i, ta)
|
||||
stdio.fflush(0)
|
||||
|
||||
# 1. 查找泛型模板
|
||||
template_cd: ast.ClassDef | t.CPtr = _find_generic_template(class_name)
|
||||
if template_cd is None:
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
stdio.printf("[SPEC] template NOT FOUND, return None\n")
|
||||
stdio.fflush(0)
|
||||
return None
|
||||
|
||||
# 2. 生成特化名
|
||||
@@ -1148,11 +1266,18 @@ def _specialize_generic_class(trans: HT.Translator | t.CPtr,
|
||||
string.strcat(spec_key, ">")
|
||||
cached: str = _find_cached_spec(spec_key)
|
||||
if cached is not None:
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
stdio.printf("[SPEC] CACHE HIT, return cached=%s\n", cached)
|
||||
stdio.fflush(0)
|
||||
return cached
|
||||
|
||||
# 4. 检查是否已注册(Phase B 重复特化)
|
||||
existing: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct(spec_name)
|
||||
if existing is not None:
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
stdio.printf("[SPEC] EXISTING registered, return spec_name=%s field_count=%d\n",
|
||||
spec_name, existing.FieldCount)
|
||||
stdio.fflush(0)
|
||||
_cache_spec(pool, spec_key, spec_name)
|
||||
return spec_name
|
||||
|
||||
@@ -1179,6 +1304,27 @@ def _specialize_generic_class(trans: HT.Translator | t.CPtr,
|
||||
trans.GenericTypeArgs = None
|
||||
HandlesType.clear_generic_context()
|
||||
|
||||
# 诊断输出:检查特化结果
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
result_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct(spec_name)
|
||||
if result_entry is not None:
|
||||
stdio.printf("[SPEC] DONE spec_name=%s field_count=%d\n",
|
||||
spec_name, result_entry.FieldCount)
|
||||
# 打印每个字段的类型信息
|
||||
ri: int
|
||||
for ri in range(result_entry.FieldCount):
|
||||
rfe: HandlesStruct.FieldEntry | t.CPtr = HandlesStruct._get_field_entry(
|
||||
result_entry, ri)
|
||||
if rfe is not None:
|
||||
rfn: str = HandlesStruct.get_field_name_ptr(rfe)
|
||||
rft: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_field_type_ptr(rfe)
|
||||
stdio.printf("[SPEC] field[%d] name=%s type=%d\n",
|
||||
ri, rfn if rfn is not None else "(null)",
|
||||
t.CSizeT(rft) if rft is not None else 0)
|
||||
else:
|
||||
stdio.printf("[SPEC] DONE but result NOT FOUND in struct table!\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
return spec_name
|
||||
|
||||
|
||||
@@ -1224,11 +1370,18 @@ def translate_class_def(trans: HT.Translator | t.CPtr,
|
||||
# SHA1 已在 register_struct 时设置,无需再补
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
# 触发 base 中 Subscript 的泛型特化(如 GSListNode[Value])
|
||||
# 必须在 _detect_vtable_status 和父类字段继承之前调用,
|
||||
# 否则 find_struct_by_module("GSListNode[Value]") 返回 None
|
||||
# ============================================================
|
||||
_trigger_base_specialization(trans, cd)
|
||||
|
||||
# ============================================================
|
||||
# VTable 检测:判断是否启用虚表
|
||||
# ============================================================
|
||||
has_vtable: int = _detect_vtable_status(cd, trans)
|
||||
parent_name: str = _get_parent_class(cd)
|
||||
parent_name: str = _get_parent_class(cd, trans)
|
||||
is_novtable_deco: int = 0
|
||||
if cd.decorator_list is not None:
|
||||
if _has_decorator(cd.decorator_list, "NoVTable") == 1:
|
||||
@@ -1473,11 +1626,9 @@ def translate_class_def(trans: HT.Translator | t.CPtr,
|
||||
if fname is not None and fty2 is not None:
|
||||
HandlesStruct.add_field(pool, entry, fname, fty2, fdef, fannot)
|
||||
|
||||
stdio.printf("[CLASS] registered %s with %d fields (vtable=%d)\n",
|
||||
class_name, field_count, has_vtable)
|
||||
|
||||
# Phase 1a 声明模式:只注册 struct,不翻译方法体
|
||||
# Phase 1a 声明模式:只注册 struct + 设置 OOP 标志,不翻译方法体
|
||||
if trans._declare_only == 1:
|
||||
_translate_oop_methods(trans, cd, struct_ty, class_name, 1)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -1844,8 +1995,6 @@ def _generate_vtable(trans: HT.Translator | t.CPtr,
|
||||
vt_self_entry.VTableMethods = method_names_buf
|
||||
vt_self_entry.VTableMethodCount = method_count
|
||||
|
||||
stdio.printf("[VTABLE] generated vtable for %s with %d methods\n",
|
||||
class_name, method_count)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1870,8 +2019,12 @@ def _generate_vtable(trans: HT.Translator | t.CPtr,
|
||||
def _translate_oop_methods(trans: HT.Translator | t.CPtr,
|
||||
cd: ast.ClassDef | t.CPtr,
|
||||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||||
class_name: str) -> int:
|
||||
"""扫描 class body 中的方法并翻译,生成 __before_init__"""
|
||||
class_name: str,
|
||||
mark_only: int = 0) -> int:
|
||||
"""扫描 class body 中的方法并翻译,生成 __before_init__
|
||||
|
||||
mark_only: 0=全量翻译(默认),1=只设置 IsOOP/HasNew/HasInit 标志(不翻译方法体)
|
||||
"""
|
||||
if trans is None or cd is None or struct_ty is None or class_name is None:
|
||||
return 0
|
||||
|
||||
@@ -1922,6 +2075,10 @@ def _translate_oop_methods(trans: HT.Translator | t.CPtr,
|
||||
if has_new != 0:
|
||||
oop_entry.HasNew = 1
|
||||
|
||||
# mark_only 模式:只设置标志,不翻译方法体
|
||||
if mark_only != 0:
|
||||
return 0
|
||||
|
||||
# 第二遍:翻译每个方法
|
||||
for ci in range(cn):
|
||||
stmt: ast.AST | t.CPtr = children.get(ci)
|
||||
|
||||
Reference in New Issue
Block a user