1112 lines
50 KiB
Plaintext
1112 lines
50 KiB
Plaintext
import t, c
|
||
from stdint import *
|
||
import ast
|
||
import llvmlite
|
||
import memhub
|
||
import string
|
||
import stdio
|
||
import stdlib
|
||
import viperlib
|
||
import lib.core.VLogger as VLogger
|
||
import lib.core.Handles.HandlesTranslator as HT
|
||
import lib.core.Handles.HandlesType as HandlesType
|
||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||
import lib.core.Handles.HandlesVar as HandlesVar
|
||
import lib.core.Handles.HandlesEnum as HandlesEnum
|
||
import lib.core.StubMerger as StubMerger
|
||
|
||
|
||
# ============================================================
|
||
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
|
||
#
|
||
# 由 BuildPipeline/main 在 gen 创建后调用 set_global_gen 注入。
|
||
# P5-2 委托函数用本地 _g_gen(cast 成 Generator 类型)调
|
||
# ClassGenMixin 方法,避免函数体 import 包模块与类/模块名歧义。
|
||
# ============================================================
|
||
_g_gen: t.CVoid | t.CPtr = None
|
||
|
||
|
||
def set_global_gen(gen: t.CVoid | t.CPtr) -> None:
|
||
"""注入全局 gen 单例(BuildPipeline/main 调用)"""
|
||
global _g_gen
|
||
_g_gen = gen
|
||
|
||
|
||
# 枚举成员临时数组最大数量(本地常量)
|
||
ENUM_MEMBER_MAX_LOCAL: t.CDefine = 128
|
||
|
||
# REnum 变体表容量上限(本地常量)
|
||
RENUM_CLASS_MAX: t.CDefine = 64
|
||
|
||
# 作用域类型常量(本地副本,避免旧编译器跨模块 CDefine 查找 bug)
|
||
SCOPE_FUNCTION: t.CDefine = 1
|
||
RENUM_VARIANT_PER_CLASS: t.CDefine = 32
|
||
RENUM_FIELD_PER_VARIANT: t.CDefine = 16
|
||
|
||
|
||
# ============================================================
|
||
# HandlesClassDef - class 定义处理
|
||
#
|
||
# 解析 class 定义,创建 LLVM StructType 并注册字段信息
|
||
#
|
||
# 纯内存结构体(无方法)的 class 定义:
|
||
# class Point:
|
||
# x: t.CInt
|
||
# y: t.CInt
|
||
#
|
||
# 生成 LLVM 类型: { i32, i32 }
|
||
# 注册字段: x→index 0, y→index 1
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# _is_cenum_base — 检查 base 节点是否为 t.CEnum
|
||
#
|
||
# 支持 Name(id='CEnum') 和 Attribute(value=Name('t'), attr='CEnum')
|
||
# ============================================================
|
||
def _is_cenum_base(base_node: ast.AST | t.CPtr) -> int:
|
||
"""检查 base 节点是否为 t.CEnum,返回 1=是 / 0=否(委托到 gen._is_cenum_base)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_cenum_base(base_node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_enum_class — 检查 ClassDef 是否继承自 t.CEnum
|
||
# ============================================================
|
||
def _is_enum_class(cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""检查 ClassDef 是否继承自 t.CEnum,返回 1=是 / 0=否(委托到 gen._is_enum_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_enum_class(cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_cunion_base — 检查 base 节点是否为 t.CUnion
|
||
#
|
||
# 支持 Name(id='CUnion') 和 Attribute(value=Name('t'), attr='CUnion')
|
||
# ============================================================
|
||
def _is_cunion_base(base_node: ast.AST | t.CPtr) -> int:
|
||
"""检查 base 节点是否为 t.CUnion,返回 1=是 / 0=否(委托到 gen._is_cunion_base)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_cunion_base(base_node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_union_class — 检查 ClassDef 是否继承自 t.CUnion
|
||
# ============================================================
|
||
def _is_union_class(cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""检查 ClassDef 是否继承自 t.CUnion,返回 1=是 / 0=否(委托到 gen._is_union_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_union_class(cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_crenum_base — 检查 base 节点是否为 t.REnum
|
||
#
|
||
# 支持 Name(id='REnum') 和 Attribute(value=Name('t'), attr='REnum')
|
||
# ============================================================
|
||
def _is_crenum_base(base_node: ast.AST | t.CPtr) -> int:
|
||
"""检查 base 节点是否为 t.REnum,返回 1=是 / 0=否(委托到 gen._is_crenum_base)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_crenum_base(base_node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_renum_class — 检查 ClassDef 是否继承自 t.REnum
|
||
# ============================================================
|
||
def _is_renum_class(cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""检查 ClassDef 是否继承自 t.REnum,返回 1=是 / 0=否(委托到 gen._is_renum_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_renum_class(cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# VTable 装饰器检测和继承关系判断
|
||
# ============================================================
|
||
|
||
# 标记基类集合(非真实父类,仅作为类型标记)
|
||
_MARKER_BASES: t.CDefine = 9
|
||
# 使用字符串比较代替集合,标记基类列表
|
||
# Object, CVTable, Exception, CEnum, Enum, CStruct, CUnion, REnum, Struct(t.Struct)
|
||
|
||
|
||
# ============================================================
|
||
# _has_decorator — 检查 ClassDef/FunctionDef 的 decorator_list 中是否有指定装饰器
|
||
#
|
||
# 支持 @t.Name 和 @Name 两种形式
|
||
# 返回 1=有 / 0=无
|
||
# ============================================================
|
||
def _has_decorator(decorator_list: list[ast.AST | t.CPtr] | t.CPtr,
|
||
deco_name: str) -> int:
|
||
"""检查 decorator_list 中是否有指定装饰器名(委托到 gen._has_decorator)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._has_decorator(decorator_list, deco_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# 方法元数据(装饰器)支持
|
||
#
|
||
# 与 TPC 的 FuncMeta 对齐,按位掩码存储:
|
||
# META_STATIC @staticmethod 无 self 参数
|
||
# META_CLASS @classmethod cls 为首参(Ptr(struct_ty))
|
||
# META_PROP_GETTER @property / @x.getter obj.prop → call Class.prop(obj)
|
||
# META_PROP_SETTER @x.setter obj.prop = v → call Class.prop$set(obj, v)
|
||
# META_PROP_DELETER @x.deleter del obj.prop → call Class.prop$del(obj)
|
||
#
|
||
# setter/deleter 函数名带 $set/$del 后缀,避免与 getter 冲突(与 TPC 一致)。
|
||
# 元数据表用 stdlib 全局分配,跨模块持久(属性访问可能发生在其他模块)。
|
||
# 注册时机:_translate_oop_methods(含 mark_only=1 的 struct 预注册阶段),
|
||
# 确保在 App 源文件翻译前元数据已就绪(不依赖 includes 是否已全量翻译)。
|
||
# ============================================================
|
||
META_STATIC: t.CDefine = 1
|
||
META_CLASS: t.CDefine = 2
|
||
META_PROP_GETTER: t.CDefine = 4
|
||
META_PROP_SETTER: t.CDefine = 8
|
||
META_PROP_DELETER: t.CDefine = 16
|
||
|
||
META_MAX: t.CDefine = 512
|
||
META_KEY_LEN: t.CDefine = 128
|
||
|
||
|
||
# ============================================================
|
||
# _extract_func_meta — 从 decorator_list 提取方法元数据位掩码
|
||
#
|
||
# 支持(与 TPC HandlesFunctions._ExtractFuncMeta 对齐):
|
||
# @staticmethod / @property / @classmethod(Name 形式)
|
||
# @property.setter / @x.setter / @x.getter / @x.deleter(Attribute 形式)
|
||
# ============================================================
|
||
def _extract_func_meta(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> int:
|
||
"""从装饰器列表提取元数据位掩码,返回 0=无装饰器元数据(委托到 gen._extract_func_meta)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._extract_func_meta(decorator_list)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# register_method_meta — 注册方法元数据(ClassName.method → meta)
|
||
#
|
||
# 幂等:重复注册相同 key 时更新标志位。内存用 stdlib 全局分配。
|
||
# ============================================================
|
||
def register_method_meta(class_name: str, method_name: str,
|
||
meta: int) -> None:
|
||
"""注册方法元数据(幂等,委托到 gen.register_method_meta)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g.register_method_meta(class_name, method_name, meta)
|
||
|
||
|
||
# ============================================================
|
||
# lookup_method_meta — 查找方法元数据(ClassName.method → meta)
|
||
#
|
||
# 返回位掩码;未注册返回 0。跨模块持久,供属性访问/赋值/删除识别。
|
||
# ============================================================
|
||
def lookup_method_meta(class_name: str, method_name: str) -> int:
|
||
"""查找方法元数据位掩码,返回 0=未注册或非装饰器方法(委托到 gen.lookup_method_meta)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.lookup_method_meta(class_name, method_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _is_marker_base — 检查基类名是否为标记基类(非真实父类)
|
||
#
|
||
# 标记基类: Object, CVTable, Exception, CEnum, Enum, CStruct, CUnion, REnum, Struct(t.Struct)
|
||
# ============================================================
|
||
def _is_marker_base(base_name: str) -> int:
|
||
"""检查基类名是否为标记基类,返回 1=是 / 0=否
|
||
|
||
含 t.Struct:t.py 未定义 Struct 类(不被编译),`class X(t.Struct)`
|
||
的 Struct 只是"普通结构体"标记。若不当成标记基类,会被误判为真实父类:
|
||
- 自动启用虚表 → 结构体多出 i8* 槽位(与 TPC 的 {i32,i32} 布局不符)
|
||
- Phase A-pre(declare_only=1)父类延迟检查找不到 "Struct" → 类被延迟注册
|
||
→ forward_declare 时类型未注册 → 裸类形参退化为 i32 → 函数签名与
|
||
函数体 alloca(Ptr(struct))不一致 → llc 报 "'%p' defined with type
|
||
'i32' but expected 'ptr'"。
|
||
与 TPC(_resolve_base_kind 对 t.Struct 返回 None → 无父类)保持一致。
|
||
(委托到 gen._is_marker_base)
|
||
"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_marker_base(base_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _get_base_name — 从 base AST 节点提取基类名
|
||
#
|
||
# 支持 Name(id), Attribute(attr), Subscript(value, slice)
|
||
# 对于 Subscript(如 GSListNode[Value]),需要 pool 拼接特化名 "GSListNode[Value]"
|
||
# ============================================================
|
||
def _get_base_name(base_node: ast.AST | t.CPtr,
|
||
pool: memhub.MemBuddy | t.CPtr = None) -> str:
|
||
"""从 base AST 节点提取基类名,返回 None=失败
|
||
|
||
对于 Subscript 节点,需要 pool 分配内存拼接特化名;
|
||
pool=None 时降级返回基类名(不含类型实参)
|
||
(委托到 gen._get_base_name)
|
||
"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_base_name(base_node, pool)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _get_parent_class — 获取 ClassDef 的真实父类名(非标记基类)
|
||
#
|
||
# 遍历 bases,返回第一个非标记基类的名字,None=无真实父类
|
||
# 支持 Name, Attribute, Subscript 三种 base 节点
|
||
# 对于 Subscript(如 GSListNode[Value]),需要 trans.Pool 拼接特化名
|
||
# ============================================================
|
||
def _get_parent_class(cd: ast.ClassDef | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None) -> str:
|
||
"""获取 ClassDef 的真实父类名,返回 None=无真实父类(委托到 gen._get_parent_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_parent_class(cd, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _collect_parents — 收集 ClassDef 的所有真实父类名(多继承)
|
||
#
|
||
# 遍历 cd.bases,跳过 marker base(Object/CVTable/NoVTable 等),
|
||
# 收集全部真实父类名到 parents_buf(t.CSizeT 数组,每元素 str 指针)。
|
||
# 返回收集数量。
|
||
# ============================================================
|
||
def _collect_parents(pool: memhub.MemBuddy | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
parents_buf: t.CSizeT | t.CPtr,
|
||
max_parents: int) -> int:
|
||
"""收集所有非 marker 父类名到 parents_buf,返回数量(委托到 gen._collect_parents)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._collect_parents(pool, cd, parents_buf, max_parents)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _field_name_exists — 检查字段名是否已存在于收集数组(去重)
|
||
# ============================================================
|
||
def _field_name_exists(names_buf: t.CSizeT | t.CPtr,
|
||
count: int, name: str) -> int:
|
||
"""检查字段名是否已在 names_buf 中(先声明父类优先,重复跳过)(委托到 gen._field_name_exists)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._field_name_exists(names_buf, count, name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _class_body_has_field — 检查类体是否声明了字段(AnnAssign)
|
||
#
|
||
# 用于区分"无字段类"(接口/标记类,合法)与"注册不完整"
|
||
# (类体有字段但 FieldCount==0,漏注册报错)。
|
||
# ============================================================
|
||
def _class_body_has_field(cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""检查类体是否声明了字段(AnnAssign),0=纯方法/无字段类(委托到 gen._class_body_has_field)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._class_body_has_field(cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _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])(委托到 gen._trigger_base_specialization)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._trigger_base_specialization(trans, cd)
|
||
|
||
|
||
# ============================================================
|
||
# _has_any_func_cvtable — 检查类中是否有任何函数标记了 @t.CVTable
|
||
#
|
||
# 用于类级别未启用虚表时,检查函数级 @t.CVTable 是否触发虚表。
|
||
# 跳过 __init__ 和 __before_init__(构造函数不进入虚表)。
|
||
# ============================================================
|
||
def _has_any_func_cvtable(cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""检查类中是否有任何函数标记了 @t.CVTable,返回 1=有 / 0=无(委托到 gen._has_any_func_cvtable)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._has_any_func_cvtable(cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _should_method_be_virtual — 判断方法是否应该进入虚表
|
||
#
|
||
# 规则(优先级从高到低):
|
||
# 1. 函数有 @t.NoVTable → 排除(返回 0)
|
||
# 2. 函数有 @t.CVTable → 包含(返回 1)
|
||
# 3. 类有 @t.CVTable → 包含(返回 1)
|
||
# 4. 有继承关系(父类非 NoVTable)→ 包含(返回 1)
|
||
# 5. 默认 → 排除(返回 0)
|
||
# ============================================================
|
||
def _should_method_be_virtual(cd: ast.ClassDef | t.CPtr,
|
||
fd: ast.FunctionDef | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None) -> int:
|
||
"""判断方法是否应该进入虚表,返回 1=包含 / 0=排除(委托到 gen._should_method_be_virtual)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._should_method_be_virtual(cd, fd, trans)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _detect_vtable_status — 检测类是否应该启用虚表
|
||
#
|
||
# 规则:
|
||
# 1. @t.CVTable → 有虚表
|
||
# 2. 有真实父类且非 NoVTable → 有虚表(自动启用)
|
||
# 3. @t.NoVTable → 检查函数级 @t.CVTable,有则启用
|
||
# 4. 默认 → 检查函数级 @t.CVTable,有则启用
|
||
#
|
||
# 返回: 1=有虚表 / 0=无虚表
|
||
# ============================================================
|
||
def _detect_vtable_status(cd: ast.ClassDef | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None) -> int:
|
||
"""检测类是否应该启用虚表(委托到 gen._detect_vtable_status)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._detect_vtable_status(cd, trans)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _resolve_enum_member_type — 解析枚举成员的类型
|
||
#
|
||
# - t.State → 默认 i32
|
||
# - int / t.CInt8T / t.CInt16T / t.CInt32T / t.CInt64T 等 → 对应整数类型
|
||
# - 联合注解(t.State | t.CInt8T)递归查找实际类型
|
||
# ============================================================
|
||
def _resolve_enum_member_type(pool: memhub.MemBuddy | t.CPtr,
|
||
ann_node: ast.AST | t.CPtr,
|
||
imported_modules: str,
|
||
from_imports: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""解析枚举成员的类型注解为 LLVM 整数类型(委托到 gen._resolve_enum_member_type)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._resolve_enum_member_type(pool, ann_node, imported_modules, from_imports)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _is_state_annotation — 检查注解节点是否为 t.State
|
||
# ============================================================
|
||
def _is_state_annotation(node: ast.AST | t.CPtr) -> int:
|
||
"""检查注解节点是否为 t.State,返回 1=是 / 0=否(委托到 gen._is_state_annotation)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_state_annotation(node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _extract_int_value — 从 AST 节点提取整数值
|
||
#
|
||
# 支持 Constant(int) 和 UnaryOp(USub, Constant(int))
|
||
# ============================================================
|
||
def _extract_int_value(node: ast.AST | t.CPtr) -> t.CInt64T:
|
||
"""从 AST 节点提取整数值,失败返回 0(委托到 gen._extract_int_value)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._extract_int_value(node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _translate_enum_def — 翻译枚举类定义
|
||
#
|
||
# 遍历 class body 中的 AnnAssign,收集成员名、类型、值
|
||
# 自动赋值:无值时从上一值+1递增(首值默认 0)
|
||
# 基准类型:所有成员类型中 Bits 最大的(t.State 视为 i32)
|
||
# ============================================================
|
||
def _translate_enum_def(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""翻译枚举类定义,返回 0(委托到 gen._translate_enum_def)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_enum_def(trans, cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _get_type_size — 计算 LLVM 类型的字节大小
|
||
#
|
||
# 用于联合体确定最大字段大小
|
||
# ============================================================
|
||
def _get_type_size(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||
"""计算 LLVM 类型的字节大小(含对齐 padding)(委托到 gen._get_type_size)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_type_size(ty)
|
||
return 0
|
||
|
||
|
||
def _get_type_align(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||
"""返回类型的自然对齐(字节)(委托到 gen._get_type_align)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_type_align(ty)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _translate_union_def — 翻译联合体定义
|
||
#
|
||
# 联合体语法:
|
||
# class MyUnion(t.CUnion):
|
||
# a: t.CInt
|
||
# b: t.CFloat
|
||
# c: t.CInt64T
|
||
#
|
||
# 实现方式:
|
||
# - 收集所有字段类型
|
||
# - 计算最大字段字节大小 max_size
|
||
# - LLVM 类型 = Struct([Array(Int8, max_size)]) # { [N x i8] }
|
||
# - 注册到 HandlesStruct 并标记 IsUnion=1
|
||
# - 字段访问通过 bitcast 实现(HandlesExpr 中处理)
|
||
# ============================================================
|
||
def _translate_union_def(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""翻译联合体定义,返回 0(委托到 gen._translate_union_def)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_union_def(trans, cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _get_annotation_field_size — 计算注解类型的字节大小
|
||
#
|
||
# 用于 REnum 布局计算,不要求类型已注册(避免自引用死锁)。
|
||
# 联合类型 (A | B) 按指针 8 字节处理。
|
||
# 未知类型默认 8 字节(指针)。
|
||
# ============================================================
|
||
def _get_annotation_field_size(annotation: ast.AST | t.CPtr) -> int:
|
||
"""计算注解类型的字节大小,用于 REnum 布局计算(委托到 gen._get_annotation_field_size)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_annotation_field_size(annotation)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _translate_renum_def — 翻译 REnum 类定义
|
||
#
|
||
# REnum 语法:
|
||
# class LLVMType(t.REnum):
|
||
# class Int:
|
||
# Bits: t.CInt
|
||
# class Ptr:
|
||
# Pointee: LLVMType | t.CPtr
|
||
# ...
|
||
#
|
||
# 内存布局: {i32 __tag, <field1>, <field2>, ...}
|
||
# 每个字段位置取所有变体在该位置的最大字段大小:
|
||
# - max_size <= 4 → i32
|
||
# - max_size > 4 → i64(可容纳指针)
|
||
# 至少包含 {i32, i32}(tag + 最小 payload)
|
||
#
|
||
# 对应 TPC 中 HandlesClassDef._RegisterREnumMembers 的逻辑
|
||
# ============================================================
|
||
def _translate_renum_def(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr) -> int:
|
||
"""翻译 REnum 类定义,返回 0(委托到 gen._translate_renum_def)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_renum_def(trans, cd)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# REnum 变体表(全局静态分配)
|
||
#
|
||
# 存储 ClassName → [VariantName, TagValue] 映射,
|
||
# 供 translate_call 检测 ClassName.VariantName(args) 形式的变体构造调用。
|
||
#
|
||
# P5-2 后已迁入 gen 字段(ClassGenMixin.RenumClassNames/RenumClassCount/
|
||
# RenumVariantNames/RenumVariantTags),经下方委托函数访问。
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# REnum 字段别名表(全局静态分配)
|
||
#
|
||
# 存储 (class_name, field_name) → payload_index 映射,
|
||
# 供 translate_attribute 查找 REnum 变体字段。
|
||
#
|
||
# REnum 结构体布局为 {i32 __tag, _p1, _p2, ...},
|
||
# 但源码用变体字段名访问(如 ty.Pointee)。
|
||
# 此表将变体字段名映射到 payload 索引(_p1=1, _p2=2, ...)。
|
||
#
|
||
# 布局:
|
||
# _renum_alias_class[i] = 类名(str 指针,以 CSizeT 存储)
|
||
# _renum_alias_field[i] = 字段名(str 指针,以 CSizeT 存储)
|
||
# _renum_alias_index[i] = payload 索引(CSizeT)
|
||
# ============================================================
|
||
RENUM_ALIAS_MAX: t.CDefine = 512
|
||
|
||
|
||
# ============================================================
|
||
# _register_renum_variants — 注册 REnum 类的变体名和 tag 值
|
||
#
|
||
# 遍历 ClassDef 的 children,提取嵌套变体类的名称,
|
||
# 按 children 顺序分配 tag 值(0, 1, 2, ...)
|
||
#
|
||
# 参数:
|
||
# pool: 内存分配器
|
||
# class_name: REnum 类名(如 "LLVMType")
|
||
# cd: REnum 类的 ClassDef AST 节点
|
||
# variant_count: 变体数量(由 _translate_renum_def 预计算)
|
||
# ============================================================
|
||
def _register_renum_variants(pool: memhub.MemBuddy | t.CPtr,
|
||
class_name: str,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
variant_count: int):
|
||
"""注册 REnum 类的变体名和 tag 值到全局变体表(委托到 gen._register_renum_variants)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._register_renum_variants(pool, class_name, cd, variant_count)
|
||
|
||
|
||
# ============================================================
|
||
# _lookup_renum_variant — 查找变体所属的 REnum 类名
|
||
#
|
||
# 参数:
|
||
# variant_name: 变体名(如 "Int"、"Ptr")
|
||
#
|
||
# 返回:
|
||
# 成功: class_name (str)
|
||
# 失败: None
|
||
# 注: tag_value 可通过 _lookup_renum_variant_in_class(class_name, variant_name) 获取
|
||
# ============================================================
|
||
def _lookup_renum_variant(variant_name: str) -> str:
|
||
"""查找变体名所属的 REnum 类名
|
||
|
||
返回: class_name (str),或 None(委托到 gen._lookup_renum_variant)
|
||
"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_renum_variant(variant_name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _is_renum_class_name — 检查名称是否是已注册的 REnum 类名
|
||
#
|
||
# 用于 translate_call 检测 ClassName.Variant(args) 形式调用时,
|
||
# 先验证 ClassName 是否是 REnum 类。
|
||
# ============================================================
|
||
def _is_renum_class_name(class_name: str) -> int:
|
||
"""检查名称是否是已注册的 REnum 类名,返回 1=是 / 0=否(委托到 gen._is_renum_class_name)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_renum_class_name(class_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _lookup_renum_variant_in_class — 在指定 REnum 类中查找变体
|
||
#
|
||
# 参数:
|
||
# class_name: REnum 类名
|
||
# variant_name: 变体名
|
||
#
|
||
# 返回:
|
||
# 成功: tag_value (int)
|
||
# 失败: -1
|
||
# ============================================================
|
||
def _lookup_renum_variant_in_class(class_name: str, variant_name: str) -> int:
|
||
"""在指定 REnum 类中查找变体,返回 tag 值或 -1(委托到 gen._lookup_renum_variant_in_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_renum_variant_in_class(class_name, variant_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _register_renum_field_alias — 注册 REnum 变体字段名别名
|
||
#
|
||
# 将变体字段名(如 "Pointee")映射到 payload 索引(如 1),
|
||
# 供 translate_attribute 查找 REnum 变体字段。
|
||
#
|
||
# 参数:
|
||
# pool: 内存分配器
|
||
# class_name: REnum 类名(如 "LLVMType")
|
||
# field_name: 变体字段名(如 "Pointee")
|
||
# payload_idx: payload 索引(1=_p1, 2=_p2, ...)
|
||
# ============================================================
|
||
def _register_renum_field_alias(pool: memhub.MemBuddy | t.CPtr,
|
||
class_name: str,
|
||
field_name: str,
|
||
payload_idx: int):
|
||
"""注册 REnum 变体字段名别名到全局表(委托到 gen._register_renum_field_alias)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._register_renum_field_alias(pool, class_name, field_name, payload_idx)
|
||
|
||
|
||
# ============================================================
|
||
# _update_renum_alias_class_ptr — 更新别名表中的 class_name 指针
|
||
#
|
||
# register_struct 会通过 pool.alloc+strcpy 复制类名,导致 entry.Name
|
||
# 与原始 cd.name 是不同指针。别名注册时用 cd.name,查找时用 entry.Name,
|
||
# CSizeT 指针值比较会失败。此函数将别名表中所有匹配 old_ptr 的 class_name
|
||
# 更新为 new_ptr,确保注册和查找使用同一指针。
|
||
#
|
||
# 参数:
|
||
# old_ptr: 旧 class_name 指针值(CSizeT(cd.name))
|
||
# new_ptr: 新 class_name 指针值(CSizeT(entry.Name))
|
||
# ============================================================
|
||
def _update_renum_alias_class_ptr(old_ptr: t.CSizeT, new_ptr: t.CSizeT):
|
||
"""更新别名表中的 class_name 指针,从 old_ptr 更新为 new_ptr(委托到 gen._update_renum_alias_class_ptr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._update_renum_alias_class_ptr(old_ptr, new_ptr)
|
||
|
||
|
||
# ============================================================
|
||
# _lookup_renum_field_alias — 查找 REnum 变体字段名的 payload 索引
|
||
#
|
||
# 参数:
|
||
# class_name: REnum 类名(如 "LLVMType")
|
||
# field_name: 变体字段名(如 "Pointee")
|
||
#
|
||
# 返回:
|
||
# 成功: payload 索引(1, 2, ...)
|
||
# 失败: -1
|
||
# ============================================================
|
||
def _lookup_renum_field_alias(class_name: str, field_name: str) -> int:
|
||
"""查找 REnum 变体字段名的 payload 索引,返回索引或 -1
|
||
|
||
class_name: 用 CSizeT 指针值比较(_update_renum_alias_class_ptr 已统一指针)
|
||
field_name: 用 strcmp 内容比较(注册时 vnm.id 与查找时 at.attr 是不同指针)
|
||
(委托到 gen._lookup_renum_field_alias)
|
||
"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_renum_field_alias(class_name, field_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# translate_class_def — 翻译 class 定义
|
||
#
|
||
# 遍历 class body 中的 AnnAssign 语句,收集字段类型
|
||
# 创建 LLVM StructType 并注册到 HandlesStruct
|
||
# ============================================================
|
||
# ============================================================
|
||
# 泛型类模板存储
|
||
#
|
||
# 泛型类 class list[T]: 不直接发射 IR,而是存储为模板,
|
||
# 等遇到 list[int](pool) 实例化时触发 _specialize_generic_class。
|
||
#
|
||
# P5-2 收尾:已迁入 gen 字段(ClassGenMixin.GenericClassNames/
|
||
# GenericClassNodes/GenericClassSha1s),经下方委托函数访问。
|
||
# ============================================================
|
||
|
||
|
||
def _is_generic_class(tp: list[str] | t.CPtr) -> int:
|
||
"""检查 ClassDef 是否有类型参数(泛型类),返回 1=是 / 0=否(委托到 gen._is_generic_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_generic_class(tp)
|
||
return 0
|
||
|
||
|
||
def _register_generic_template(pool: memhub.MemBuddy | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
module_sha1: str):
|
||
"""注册泛型类模板(类名 + ClassDef 节点 + 来源模块 SHA1)(委托到 gen._register_generic_template)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._register_generic_template(pool, cd, module_sha1)
|
||
|
||
|
||
def _find_generic_template(class_name: str) -> ast.ClassDef | t.CPtr:
|
||
"""查找泛型类模板,返回 ClassDef 节点或 None(委托到 gen._find_generic_template)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._find_generic_template(class_name)
|
||
return None
|
||
|
||
|
||
def _find_generic_template_sha1(class_name: str) -> str:
|
||
"""查找泛型类模板的来源模块 SHA1,未找到返回 None(委托到 gen._find_generic_template_sha1)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._find_generic_template_sha1(class_name)
|
||
return None
|
||
|
||
|
||
def _mangle_generic_class_name(pool: memhub.MemBuddy | t.CPtr,
|
||
class_name: str,
|
||
type_args: list[str] | t.CPtr) -> str:
|
||
"""生成特化类名: list + [int] -> list[int](委托到 gen._mangle_generic_class_name)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._mangle_generic_class_name(pool, class_name, type_args)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 类型注解拷贝(用于泛型特化)
|
||
#
|
||
# _clone_annotation: 拷贝类型注解表达式,替换类型参数 T 为具体类型
|
||
# _clone_arguments: 拷贝 Arguments 节点,替换 arg annotation 中的 T
|
||
# _clone_classdef_for_spec: 拷贝 ClassDef 用于泛型特化
|
||
# ============================================================
|
||
|
||
def _clone_annotation(pool: memhub.MemBuddy | t.CPtr,
|
||
node: ast.AST | t.CPtr,
|
||
tp_names: list[str] | t.CPtr,
|
||
type_args: list[str] | t.CPtr) -> ast.AST | t.CPtr:
|
||
"""拷贝类型注解表达式,替换类型参数 T 为具体类型名(委托到 gen._clone_annotation)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._clone_annotation(pool, node, tp_names, type_args)
|
||
return None
|
||
|
||
|
||
def _clone_arguments(pool: memhub.MemBuddy | t.CPtr,
|
||
args: ast.AST | t.CPtr,
|
||
tp_names: list[str] | t.CPtr,
|
||
type_args: list[str] | t.CPtr) -> ast.AST | t.CPtr:
|
||
"""拷贝 Arguments 节点,替换 arg annotation 中的 T(委托到 gen._clone_arguments)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._clone_arguments(pool, args, tp_names, type_args)
|
||
return None
|
||
|
||
|
||
def _clone_classdef_for_spec(pool: memhub.MemBuddy | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
spec_name: str,
|
||
tp_names: list[str] | t.CPtr,
|
||
type_args: list[str] | t.CPtr) -> ast.ClassDef | t.CPtr:
|
||
"""拷贝 ClassDef 节点用于泛型特化(委托到 gen._clone_classdef_for_spec)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._clone_classdef_for_spec(pool, cd, spec_name, tp_names, type_args)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 泛型特化缓存(容量常量)
|
||
#
|
||
# 用扁平 stdlib 数组 + stdlib 深拷贝字符串,保证缓存条目
|
||
# 跨文件永久存活(1b 每文件 reset_to(mark1) 不会回收)。
|
||
# 缓存状态(_spec_keys/_spec_names/_spec_count)已迁移为
|
||
# ClassGenMixin.SpecKeys/SpecNames/SpecCount(P5-2 簇 C)。
|
||
# ============================================================
|
||
|
||
SPEC_CACHE_MAX: t.CDefine = 512
|
||
|
||
|
||
def _find_cached_spec(spec_key: str) -> str:
|
||
"""查找已缓存的特化名,未找到返回 None(委托到 gen._find_cached_spec)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._find_cached_spec(spec_key)
|
||
return None
|
||
|
||
|
||
def _cache_spec(pool: memhub.MemBuddy | t.CPtr, spec_key: str, spec_name: str):
|
||
"""缓存特化结果(stdlib 深拷贝存储,跨文件安全)(委托到 gen._cache_spec)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._cache_spec(pool, spec_key, spec_name)
|
||
|
||
|
||
# ============================================================
|
||
# _merge_template_imports - 特化翻译前并入模板模块的 imports
|
||
#
|
||
# 泛型特化(_specialize_generic_class)用触发方文件的 Translator 翻译
|
||
# 模板方法体,但模板方法体引用的模块(如 _list.vp 的 append 里
|
||
# string.memcpy 依赖 string)来自模板文件自身的 import。若不并入,
|
||
# 跨模块 fast-fail 检查会把 string.memcpy 误报为"模块 string 未导入"。
|
||
# 调用方负责在特化翻译后恢复 trans._imported_modules。
|
||
# ============================================================
|
||
def _merge_template_imports(trans: HT.Translator | t.CPtr,
|
||
template_sha1: str) -> None:
|
||
"""将模板模块的 imports 并入 trans._imported_modules(空格分隔)(委托到 gen._merge_template_imports)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._merge_template_imports(trans, template_sha1)
|
||
|
||
|
||
def _specialize_generic_class(trans: HT.Translator | t.CPtr,
|
||
class_name: str,
|
||
type_args: list[str] | t.CPtr) -> str:
|
||
"""特化泛型类,返回特化类名(委托到 gen._specialize_generic_class)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._specialize_generic_class(trans, class_name, type_args)
|
||
return None
|
||
|
||
|
||
def translate_class_def(trans: HT.Translator | t.CPtr,
|
||
node: ast.AST | t.CPtr) -> int:
|
||
"""翻译 class 定义,返回 0(委托到 gen.translate_class_def)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_class_def(trans, node)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# VTable 生成
|
||
#
|
||
# 生成 VTable 全局变量:
|
||
# @"SHA1.ClassName.vtable" = internal constant { i8*, i8*, ... } {
|
||
# i8* bitcast (ret (params)* @"SHA1.ClassName.method1" to i8*),
|
||
# ...
|
||
# }
|
||
#
|
||
# VTable 槽位顺序: class body 中 FunctionDef 的出现顺序
|
||
# ============================================================
|
||
|
||
VTBL_METHOD_MAX: t.CDefine = 32
|
||
|
||
|
||
# _vtable_strcat — 将 src 追加到 dst 末尾
|
||
def _vtable_strcat(dst: t.CChar | t.CPtr, dst_size: t.CSizeT,
|
||
src: t.CChar | t.CPtr):
|
||
"""将 src 追加到 dst 末尾(委托到 gen._vtable_strcat)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._vtable_strcat(dst, dst_size, src)
|
||
|
||
|
||
# _vtable_name_needs_quote — 检查 LLVM 标识符是否需要引号
|
||
def _vtable_name_needs_quote(name: str) -> int:
|
||
"""检查 LLVM 标识符是否需要引号(以数字开头或含 '.')(委托到 gen._vtable_name_needs_quote)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._vtable_name_needs_quote(name)
|
||
return 0
|
||
|
||
|
||
# _format_func_type_str — 从 Function 对象生成函数类型字符串
|
||
#
|
||
# 格式: ret_ty (param1_ty, param2_ty, ...)
|
||
# 例如: void ({i32, i32}*, i32)
|
||
def _format_func_type_str(pool: memhub.MemBuddy | t.CPtr,
|
||
buf: t.CChar | t.CPtr, buf_size: t.CSizeT,
|
||
func: llvmlite.Function | t.CPtr) -> int:
|
||
"""从 Function 对象生成函数类型字符串(委托到 gen._format_func_type_str)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._format_func_type_str(pool, buf, buf_size, func)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# vtable 收集暂存区(已迁移为 ClassGenMixin.VtFullNames/
|
||
# VtMethodNames/VtParentSha1s/VtMethodCount,P5-2 簇 D)
|
||
#
|
||
# _collect_vtable_methods 的收集结果,跨函数传递:
|
||
# - _translate_oop_methods 在翻译方法体之前先收集一次,
|
||
# 使方法体内的 self.虚方法 调用能查到 VTableMethods(虚分派依赖)
|
||
# - _generate_vtable 再收集一次,生成 vtable 全局变量
|
||
# method_names_buf 是 stdlib 分配,存入 StructEntry.VTableMethods
|
||
# 后跨模块持久(不得迁入 mb 池 reset 区间)。
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# _collect_vtable_methods — 收集类的虚方法信息
|
||
#
|
||
# 1. 继承父类虚方法(父类方法排在子类方法之前,保持槽位顺序一致)
|
||
# 2. 收集当前类虚方法(跳过已继承的)
|
||
#
|
||
# 结果存入 ClassGenMixin.VtFullNames/VtMethodNames/VtParentSha1s/
|
||
# VtMethodCount(原模块级 _g_vt_*),并设置 entry.VTableMethodCount /
|
||
# VTableMethods(stdlib 分配,供虚分派跨模块查询)。
|
||
#
|
||
# 返回 1=有虚方法 / 0=无方法或失败
|
||
# ============================================================
|
||
def _collect_vtable_methods(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
class_name: str) -> int:
|
||
"""收集虚方法信息,设置 entry.VTableMethods/VTableMethodCount(委托到 gen._collect_vtable_methods)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._collect_vtable_methods(trans, cd, class_name)
|
||
return 0
|
||
|
||
|
||
# _generate_vtable — 生成 VTable 全局变量
|
||
#
|
||
# 1. 收集 class body 中所有 FunctionDef 作为虚方法
|
||
# 2. 构造 VTable 类型 { i8*, i8*, ... }
|
||
# 3. 构造初始化字符串 { i8* bitcast (...), ... }
|
||
# 4. 创建全局变量 @"SHA1.ClassName.vtable"
|
||
# 5. 存储虚方法名列表到 StructEntry
|
||
def _generate_vtable(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
class_name: str) -> int:
|
||
"""生成 VTable 全局变量(委托到 gen._generate_vtable)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._generate_vtable(trans, cd, class_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# OOP 方法翻译
|
||
#
|
||
# 存在任意 FunctionDef 的 class 自动升级为 OOP 结构体。
|
||
# 方法翻译为 SHA1.ClassName.method_name(self: Ptr(StructTy), ...) 函数。
|
||
# self 参数直接注册为 SSA 值(不创建 alloca),使 self.field 能通过 GEP 直接访问。
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# _translate_oop_methods — 扫描 class body 中的方法并翻译
|
||
#
|
||
# 遍历 ClassDef.children,对每个 FunctionDef:
|
||
# - 标记 OOP(mark_as_oop)
|
||
# - 如果是 __init__,标记 has_init
|
||
# - 翻译方法(生成 SHA1.ClassName.method_name 函数)
|
||
# 翻译完所有方法后,生成 __before_init__ 函数
|
||
# ============================================================
|
||
def _translate_oop_methods(trans: HT.Translator | t.CPtr,
|
||
cd: ast.ClassDef | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str,
|
||
mark_only: int = 0) -> int:
|
||
"""扫描 class body 中的方法并翻译,生成 __before_init__
|
||
|
||
mark_only: 0=全量翻译(默认),1=只设置 IsOOP/HasNew/HasInit 标志(不翻译方法体)
|
||
(委托到 gen._translate_oop_methods)
|
||
"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_oop_methods(trans, cd, struct_ty, class_name, mark_only)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _translate_method — 翻译单个方法
|
||
#
|
||
# 生成: define <ret_ty> @SHA1.ClassName.method_name(Ptr(StructTy) %self, ...)
|
||
#
|
||
# self 参数处理:
|
||
# - 类型 Ptr(struct_ty),直接注册为 SSA 值(不创建 alloca)
|
||
# - 使 self.field 能通过 GEP 直接访问原始结构体
|
||
# ============================================================
|
||
def _translate_method(trans: HT.Translator | t.CPtr,
|
||
fd: ast.FunctionDef | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str) -> int:
|
||
"""翻译单个方法,返回 0(委托到 gen._translate_method)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_method(trans, fd, struct_ty, class_name)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _generate_before_init — 生成 __before_init__ 函数
|
||
#
|
||
# 生成: define void @SHA1.ClassName.__before_init__(Ptr(StructTy) %self)
|
||
#
|
||
# 执行:
|
||
# 1. store zeroinitializer 到 %self(零值填充)
|
||
# 2. 逐字段 store 默认值(如有)
|
||
# 3. ret void
|
||
# ============================================================
|
||
def _generate_before_init(trans: HT.Translator | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str) -> int:
|
||
"""生成 __before_init__ 函数,返回 0(委托到 gen._generate_before_init)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._generate_before_init(trans, struct_ty, class_name)
|
||
return 0
|