修正了部分代码的表达方式,最后可用版本,mlirlite 已基本完善
This commit is contained in:
1 parent
951b89be36
commit
a7af34bd7e
36 files changed
+1755
-3656
No files matched your search
+155
-330
File diff suppressed because it is too large.
Load diff
+169
-335
File diff suppressed because it is too large.
Load diff
@@ -16,37 +16,32 @@ import lib.core.Gen.Generator as Generator
|
||||
# 方法元数据/类元数据/装饰器/异常表容量与编码;本地副本避免跨模块 CDefine 查找)
|
||||
# ============================================================
|
||||
# 方法元数据 flag 位(对齐 TPC HandlesBase _METHOD_META_*)
|
||||
META_TLS: t.CDefine = 32
|
||||
define META_TLS = 32
|
||||
# 类编译期元数据表容量上限(__provides__/__requires__/__require_must__)
|
||||
CLASS_META_MAX: t.CDefine = 256
|
||||
define CLASS_META_MAX = 256
|
||||
# 自定义装饰器 wrapper 表容量上限(带 @decor 的函数数)
|
||||
DECOR_FUNC_MAX: t.CDefine = 64
|
||||
define DECOR_FUNC_MAX = 64
|
||||
# 装饰器表槽内函数名/wrapper 名长度(含 NUL)
|
||||
DECOR_NAME_LEN: t.CDefine = 128
|
||||
define DECOR_NAME_LEN = 128
|
||||
# 异常类注册表容量上限(class X(Exception) 自定义异常类)
|
||||
EXCEPTION_MAX: t.CDefine = 64
|
||||
define EXCEPTION_MAX = 64
|
||||
# 异常类表槽内类名/父类名长度(含 NUL)
|
||||
EXCEPTION_NAME_LEN: t.CDefine = 128
|
||||
define EXCEPTION_NAME_LEN = 128
|
||||
# 内置异常编码(对齐 TPC HandlesBase.py EXCEPTION_CODE_MAP);
|
||||
# KeyError=6 IOError=7 OSError=8 AssertionError=9 Exception=99;用户类从 100 起
|
||||
BUILTIN_EH_VALUE_ERROR: t.CDefine = 1
|
||||
BUILTIN_EH_RUNTIME_ERROR: t.CDefine = 3
|
||||
BUILTIN_EH_EXCEPTION: t.CDefine = 99
|
||||
EH_USER_CODE_START: t.CDefine = 100
|
||||
define BUILTIN_EH_VALUE_ERROR = 1
|
||||
define BUILTIN_EH_RUNTIME_ERROR = 3
|
||||
define BUILTIN_EH_EXCEPTION = 99
|
||||
define EH_USER_CODE_START = 100
|
||||
# 方法元数据表容量(原 HandlesClassDef.META_MAX/META_KEY_LEN,阶段 D 拆分遗漏)
|
||||
META_MAX: t.CDefine = 512
|
||||
META_KEY_LEN: t.CDefine = 128
|
||||
define META_MAX = 512
|
||||
define META_KEY_LEN = 128
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ClassGenBase - ClassGenMixin 拆分(阶段 D):字段 + 方法元数据/异常/继承检测/装饰器(Meta)
|
||||
#
|
||||
# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenBase:
|
||||
novirtual class ClassGenBase:
|
||||
"""字段 + 方法元数据/异常/继承检测/装饰器(Meta)"""
|
||||
|
||||
# --- 方法元数据表(原 _g_method_meta_keys/_g_method_meta_flags/_g_method_meta_count) ---
|
||||
@@ -100,7 +95,7 @@ class ClassGenBase:
|
||||
DecoratorFuncNames: bytes
|
||||
DecoratorWrapNames: bytes
|
||||
# 装饰器首个常量参数(@repeat(3) 的 3),无参数为 0(每槽 8B,i64)
|
||||
DecoratorArgs: int64 | t.CPtr
|
||||
DecoratorArgs: int64*
|
||||
|
||||
# --- 异常类注册表(try-except,对齐 TPC HandlesClassDef.py L47-61) ---
|
||||
# perm_pool 分配(跨 mark/reset 存活):每槽类名(128B) + 父类名(128B) + 编码(4B)
|
||||
@@ -109,7 +104,7 @@ class ClassGenBase:
|
||||
ExceptionCount: int
|
||||
ExceptionNames: bytes
|
||||
ExceptionParents: bytes
|
||||
ExceptionCodes: int | t.CPtr
|
||||
ExceptionCodes: int*
|
||||
# 下一个待分配的异常编码(用户类,从 100 起)
|
||||
NextExceptionCode: int
|
||||
# 递归收集子孙编码用的临时计数(collect_descendant_codes 返回后无效)。
|
||||
@@ -125,7 +120,7 @@ class ClassGenBase:
|
||||
# --- 泛型模板表(原 HandlesClassDef._generic_class_names/
|
||||
# _generic_class_nodes/_generic_class_sha1s) ---
|
||||
GenericClassNames: list[str]*
|
||||
GenericClassNodes: list[ast.ClassDef*] | t.CPtr
|
||||
GenericClassNodes: list[ast.ClassDef*]*
|
||||
GenericClassSha1s: list[str]*
|
||||
# 泛型模板来源文件路径(与上面三表同序)。特化翻译模板方法体时 node.lineno 是模板
|
||||
# 文件行号,若 CurrentFile 仍是调用方文件,fatal_error 会把模板行号套到调用方文件上
|
||||
@@ -165,8 +160,7 @@ class ClassGenBase:
|
||||
# 别名形式: from t import CEnum as en; class Color(en)
|
||||
# 解析别名原始名(en → CEnum)再比较
|
||||
if trans is not None and trans._from_imports is not None:
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
|
||||
trans._from_imports, nm.id)
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id)
|
||||
if alias_orig is not None:
|
||||
og_len_ce: sizet = 0
|
||||
while alias_orig[og_len_ce] != ' ' and alias_orig[og_len_ce] != '\0':
|
||||
@@ -218,8 +212,7 @@ class ClassGenBase:
|
||||
return 1
|
||||
# 别名形式: from t import CUnion as un; class Data(un)
|
||||
if trans is not None and trans._from_imports is not None:
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
|
||||
trans._from_imports, nm.id)
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id)
|
||||
if alias_orig is not None:
|
||||
og_len_cu: sizet = 0
|
||||
while alias_orig[og_len_cu] != ' ' and alias_orig[og_len_cu] != '\0':
|
||||
@@ -271,8 +264,7 @@ class ClassGenBase:
|
||||
return 1
|
||||
# 别名形式: from t import REnum as ren; class Opt(ren)
|
||||
if trans is not None and trans._from_imports is not None:
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
|
||||
trans._from_imports, nm.id)
|
||||
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id)
|
||||
if alias_orig is not None:
|
||||
og_len_cr: sizet = 0
|
||||
while alias_orig[og_len_cr] != ' ' and alias_orig[og_len_cr] != '\0':
|
||||
@@ -556,14 +548,10 @@ class ClassGenBase:
|
||||
if pool is None or func_name is None or wrapper_name is None:
|
||||
return -1
|
||||
if self.DecoratorFuncNames is None:
|
||||
self.DecoratorFuncNames = CompilerFactory.factory.PermPool.alloc(
|
||||
DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
self.DecoratorWrapNames = CompilerFactory.factory.PermPool.alloc(
|
||||
DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
self.DecoratorArgs = CompilerFactory.factory.PermPool.alloc(
|
||||
DECOR_FUNC_MAX * 8)
|
||||
if self.DecoratorFuncNames is None or self.DecoratorWrapNames is None \
|
||||
or self.DecoratorArgs is None:
|
||||
self.DecoratorFuncNames = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
self.DecoratorWrapNames = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
self.DecoratorArgs = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * 8)
|
||||
if self.DecoratorFuncNames is None or self.DecoratorWrapNames is None or self.DecoratorArgs is None:
|
||||
return -1
|
||||
string.memset(self.DecoratorFuncNames, 0, DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
string.memset(self.DecoratorWrapNames, 0, DECOR_FUNC_MAX * DECOR_NAME_LEN)
|
||||
@@ -986,8 +974,7 @@ class ClassGenBase:
|
||||
"""
|
||||
if base_name is None or trans is None or trans._from_imports is None:
|
||||
return base_name
|
||||
orig: str = self.Gen.ImportsGen.lookup_from_import_original(
|
||||
trans._from_imports, base_name)
|
||||
orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, base_name)
|
||||
if orig is not None:
|
||||
# lookup_from_import_original 返回 from_imports 内部指针且未 NUL 结尾
|
||||
# (如 "CStruct myint:t:CInt CChar:t CPtr:t" 整串直到真正的 NUL)。
|
||||
@@ -1146,8 +1133,7 @@ class ClassGenBase:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
if trans is not None:
|
||||
p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1)
|
||||
if p_entry is None:
|
||||
# 跨模块父类回退全局查找(父类注册在父模块 SHA1 下,如 linkedlist.LinkedNode),
|
||||
# 与字段展平(1.5 节)的回退保持一致,否则父类 NoVTable 被误判为有虚表 → 子类插 vptr
|
||||
@@ -1171,8 +1157,7 @@ class ClassGenBase:
|
||||
def _detect_vtable_status(self, cd: ast.ClassDef*,
|
||||
trans: HT.Translator* = None) -> int:
|
||||
"""检测类是否应该启用虚表"""
|
||||
if cd is None:
|
||||
return 0
|
||||
if cd is None: return 0
|
||||
|
||||
# 检查类装饰器
|
||||
if cd.decorator_list is not None:
|
||||
@@ -1189,8 +1174,7 @@ class ClassGenBase:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
if trans is not None:
|
||||
p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1)
|
||||
if p_entry is None:
|
||||
# 跨模块父类回退全局查找(同 _detect_vtable_status 的回退)
|
||||
p_entry = self.Gen.StructGen.find_struct(parent_name)
|
||||
@@ -1204,10 +1188,8 @@ class ClassGenBase:
|
||||
# 继承链统一虚表:父类有虚表 → 子类启用;父类无虚表 → 子类静态。
|
||||
# 若父类无 vtable 而子类有,父类方法按无 vptr 布局(self.field@0)操作
|
||||
# 子类实例(有 vptr@0)会字段错位 → 运行时错误(父类方法读 vptr 当字段)。
|
||||
if p_entry is None:
|
||||
return 1 # 父类信息未知(跨模块/未注册),保守启用虚表
|
||||
if p_entry.HasVTable == 1:
|
||||
return 1
|
||||
if p_entry is None: return 1 # 父类信息未知(跨模块/未注册),保守启用虚表
|
||||
if p_entry.HasVTable == 1: return 1
|
||||
return 0
|
||||
|
||||
# 默认(无装饰器无继承),检查函数级 @t.CVTable
|
||||
|
||||
@@ -16,27 +16,20 @@ from . import ClassGenBase
|
||||
|
||||
# ============================================================
|
||||
# ClassGenDef - ClassGenMixin 拆分(阶段 D):translate_class_def 主入口
|
||||
#
|
||||
# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
"""translate_class_def 主入口"""
|
||||
|
||||
# ============================================================
|
||||
# ============================================================
|
||||
# translate_class_def — 翻译 class 定义(簇 D)
|
||||
# ============================================================
|
||||
def translate_class_def(self, trans: HT.Translator*,
|
||||
node: ast.AST*) -> int:
|
||||
"""翻译 class 定义,返回 0"""
|
||||
if node is None or trans is None:
|
||||
return 0
|
||||
if node is None or trans is None: return 0
|
||||
|
||||
cd: ast.ClassDef* = ast.ClassDef*(node)
|
||||
if cd is None or cd.name is None:
|
||||
return 0
|
||||
if cd is None or cd.name is None: return 0
|
||||
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
class_name: str = cd.name
|
||||
@@ -85,8 +78,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
return self.Gen.ClassGenBase._register_exception_class_def(trans, cd)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
# 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。
|
||||
# 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry
|
||||
# (置空 Name + Ty=None,使 find_struct_by_module 不再命中),走下方完整注册路径重建。
|
||||
@@ -112,8 +104,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# _ensure_field_types_in_module 遍历悬空字段 ParamNode 链表
|
||||
# 读悬空挂起(G3 LinkedNode.prepend 挂起根因)。DeepCopyType
|
||||
# 递归深拷贝字段链表/子类型/Name 到 stdlib(深度上限+链守卫)。
|
||||
ty_deep: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, existing.Ty)
|
||||
ty_deep: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, existing.Ty)
|
||||
if ty_deep is not None:
|
||||
existing.Ty = ty_deep
|
||||
old_name: str = llvmlite.get_struct_name(existing.Ty)
|
||||
@@ -122,10 +113,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
on_copy: str = CompilerFactory.factory.PermPool.alloc(on_len + 1)
|
||||
if on_copy is not None:
|
||||
string.strcpy(on_copy, old_name)
|
||||
c.DerefAs(existing.Ty, llvmlite.LLVMType.Struct(
|
||||
llvmlite.get_struct_fields(existing.Ty),
|
||||
llvmlite.get_struct_fcount(existing.Ty),
|
||||
on_copy))
|
||||
*existing.Ty = llvmlite.LLVMType.Struct(llvmlite.get_struct_fields(existing.Ty), llvmlite.get_struct_fcount(existing.Ty), on_copy)
|
||||
# Phase B: 将已存在的命名结构体注册到当前模块(输出类型定义行)
|
||||
llvmlite.module_add_named_type(trans.Module, pool, existing.Ty)
|
||||
# B5:existing 路径(Phase B 已注册类)同样需设置 packed/aligned——
|
||||
@@ -185,8 +173,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# Phase B(declare_only==0)不延迟,避免死锁。
|
||||
# ============================================================
|
||||
if trans._declare_only == 1 and parent_name is not None:
|
||||
parent_check: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
parent_check: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1)
|
||||
if parent_check is None:
|
||||
parent_check = self.Gen.StructGen.find_struct(parent_name)
|
||||
if parent_check is None:
|
||||
@@ -237,14 +224,11 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
if parents_count > 0 and parents_buf is not None:
|
||||
for pi in range(parents_count):
|
||||
pname_addr: sizet = parents_buf[pi]
|
||||
if pname_addr == 0:
|
||||
continue
|
||||
if pname_addr == 0: continue
|
||||
pname: str = (str | t.CPtr)(pname_addr)
|
||||
if pname is None:
|
||||
continue
|
||||
if pname is None: continue
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
pname, trans.ModuleSha1)
|
||||
parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pname, trans.ModuleSha1)
|
||||
if parent_entry is None:
|
||||
# 父类可能定义在另一个模块(不同 SHA1,如 HandlesBase.Mixin),
|
||||
# find_struct_by_module 不回退全局查找,此处手动回退到 find_struct,
|
||||
@@ -259,19 +243,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
return 0
|
||||
pfc: int = parent_entry.FieldCount
|
||||
for pfi in range(pfc):
|
||||
pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(
|
||||
parent_entry, pfi)
|
||||
if pfe is None:
|
||||
continue
|
||||
pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(parent_entry, pfi)
|
||||
if pfe is None: continue
|
||||
pfn: str = self.Gen.StructGen.get_field_name_ptr(pfe)
|
||||
if pfn is None:
|
||||
continue
|
||||
if pfn is None: continue
|
||||
# 跳过父类的 vtable 指针字段
|
||||
if string.strcmp(pfn, "__vtable__") == 0:
|
||||
continue
|
||||
if string.strcmp(pfn, "__vtable__") == 0: continue
|
||||
# 多继承去重:字段名已存在跳过(先声明父类优先)
|
||||
if self.Gen.ClassGenBase._field_name_exists(field_names_buf, field_count, pfn) != 0:
|
||||
continue
|
||||
if self.Gen.ClassGenBase._field_name_exists(field_names_buf, field_count, pfn) != 0: continue
|
||||
if field_count < GenTypes.FIELD_MAX:
|
||||
pft: llvmlite.LLVMType* = self.Gen.StructGen.get_field_type_ptr(pfe)
|
||||
pfd: ast.AST* = self.Gen.StructGen.get_field_default_ptr(pfe)
|
||||
@@ -302,23 +281,19 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
cn: sizet = len(children)
|
||||
for ci in range(cn):
|
||||
stmt: ast.AST* = children.get(ci)
|
||||
if stmt is None:
|
||||
continue
|
||||
if stmt is None: continue
|
||||
sk: int = stmt.kind()
|
||||
|
||||
if sk != ast.ASTKind.AnnAssign: continue
|
||||
|
||||
# AnnAssign(target=Name(id), annotation=type, value=...)
|
||||
aa: ast.AnnAssign* = ast.AnnAssign*(stmt)
|
||||
if aa is None or aa.target is None:
|
||||
continue
|
||||
if aa is None or aa.target is None: continue
|
||||
|
||||
# 获取字段名
|
||||
if aa.target.kind() != ast.ASTKind.Name:
|
||||
continue
|
||||
if aa.target.kind() != ast.ASTKind.Name: continue
|
||||
tgt: ast.Name* = ast.Name*(aa.target)
|
||||
if tgt.id is None:
|
||||
continue
|
||||
if tgt.id is None: continue
|
||||
|
||||
# 类体 CDefine 常量(任意位置,2026-08-10):注册到全局 CDefine 表。
|
||||
# 方法内裸名(如 ISINSTANCE_CLASS_MAX)经 translate_name_value 查
|
||||
@@ -359,16 +334,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
continue
|
||||
|
||||
# 解析字段类型
|
||||
field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
# 单参 t.CArray[elem] + 列表字面量 → 静态数组 [N x elem]
|
||||
# (与局部 AnnAssign 路径一致,对齐 TPC ParseListAnnotation 语义):
|
||||
# 否则字段保持 Ptr(elem)(如 t.CArray[str] → i8**),
|
||||
# for x in self.field 会误走指针迭代(元素非整数 → null 终止符
|
||||
# 检查失败报错)。推断为静态数组后走数组迭代(按长度 N)。
|
||||
if field_ty is not None:
|
||||
field_ty = self.Gen.AssignGen._infer_static_array_ty_from_literal(
|
||||
pool, aa.annotation, aa.value, field_ty)
|
||||
field_ty = self.Gen.AssignGen._infer_static_array_ty_from_literal(pool, aa.annotation, aa.value, field_ty)
|
||||
if field_ty is None:
|
||||
# BUG 5 方案1修改点1:消除 i32 静默回退
|
||||
# Phase A-pre(declare_only=1):依赖的类可能尚未注册,延迟到下一遍
|
||||
@@ -425,8 +398,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 提取原始类型注解的类名(联合类型简化为 Ptr(i8) 时回退查找结构体)
|
||||
# BUG 1 方案3:传 pool 使泛型 Subscript 返回 mangled name(如 "list[ast.AST|t.CPtr]")
|
||||
if aa.annotation is not None:
|
||||
annot_cn: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
|
||||
aa.annotation, trans._imported_modules, pool, trans._from_imports)
|
||||
annot_cn: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(aa.annotation, trans._imported_modules, pool, trans._from_imports)
|
||||
if annot_cn is not None:
|
||||
diag_cn_val: sizet = sizet(annot_cn)
|
||||
field_annot_buf[field_count] = diag_cn_val
|
||||
@@ -434,23 +406,20 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
field_annot_buf[field_count] = 0
|
||||
# t.CVolatile 存储类标记 → 该字段经对象访问的 load/store 带
|
||||
# volatile(如 Spinlock.locked: t.CVolatile | t.CInt)。
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(
|
||||
aa.annotation, "CVolatile", 0) != 0:
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(aa.annotation, "CVolatile", 0) != 0:
|
||||
field_volatile_buf[field_count] = 1
|
||||
else:
|
||||
field_volatile_buf[field_count] = 0
|
||||
# rawptr[t.CVolatile | T](volatile 指针指向物,等价 C 的
|
||||
# volatile T*)→ 经该字段解引用(self.ptr[i]/self.ptr.field)
|
||||
# 的 load/store 带 volatile。
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(
|
||||
aa.annotation) != 0:
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(aa.annotation) != 0:
|
||||
field_pointee_volatile_buf[field_count] = 1
|
||||
else:
|
||||
field_pointee_volatile_buf[field_count] = 0
|
||||
# const 对象字段(注解含 t.CConst 且字段类型非指针)→ 经对象给该
|
||||
# 字段赋值 fail-fast。判据与 TPC 的 Gen.field_const_flags 一致。
|
||||
if self.Gen.TypeGenErr.is_const_object_marker(
|
||||
aa.annotation, field_ty) != 0:
|
||||
if self.Gen.TypeGenErr.is_const_object_marker(aa.annotation, field_ty) != 0:
|
||||
field_const_buf[field_count] = 1
|
||||
else:
|
||||
field_const_buf[field_count] = 0
|
||||
@@ -544,8 +513,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 后续文件字段类型引用(resolve → Ptr(entry.Ty))→ opaque 扫描遍历悬空 fields
|
||||
# 崩溃(LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。
|
||||
if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0:
|
||||
st_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, struct_ty)
|
||||
st_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, struct_ty)
|
||||
if st_copy is not None:
|
||||
struct_ty = st_copy
|
||||
type_name = llvmlite.get_struct_name(struct_ty)
|
||||
@@ -556,8 +524,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# B5:@c.Attribute(t.attr.packed) 打包结构体 → 类型定义输出 <{...}>
|
||||
# (LLVM packed struct,无字段填充,GEP 按 packed 布局计算偏移)。
|
||||
# idt/gdt/elf/fat32 等二进制格式结构体依赖它读写硬件/磁盘布局。
|
||||
is_packed_cd: int = self.Gen.ClassGenBase._class_has_tattr(
|
||||
cd.decorator_list, "packed")
|
||||
is_packed_cd: int = self.Gen.ClassGenBase._class_has_tattr(cd.decorator_list, "packed")
|
||||
if is_packed_cd != 0:
|
||||
llvmlite.module_set_named_type_packed(trans.Module, pool, struct_ty, 1)
|
||||
|
||||
@@ -573,8 +540,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# ============================================================
|
||||
# 3. 注册到 HandlesStruct
|
||||
# ============================================================
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, struct_ty, trans.ModuleSha1)
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, struct_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "CLASS")
|
||||
return 0
|
||||
|
||||
@@ -18,20 +18,15 @@ from . import ClassGenBase
|
||||
# 未定义名在常量上下文被 TPV 折叠为 0,会导致枚举成员收集被静默跳过、
|
||||
# register_enum 永不调用 → 所有 CEnum 注册失败 → 裸名枚举访问 NameError)
|
||||
# ============================================================
|
||||
ENUM_MEMBER_MAX_LOCAL: t.CDefine = 128 # 与 StmtGenDeclMixin.ENUM_MEMBER_MAX 一致
|
||||
RENUM_CLASS_MAX: t.CDefine = 64
|
||||
RENUM_VARIANT_PER_CLASS: t.CDefine = 32
|
||||
RENUM_ALIAS_MAX: t.CDefine = 512
|
||||
define ENUM_MEMBER_MAX_LOCAL = 128
|
||||
define RENUM_ENUM_CLASS_MAX = 64
|
||||
define RENUM_ENUM_VARIANT_PER_CLASS = 32
|
||||
define RENUM_ENUM_ALIAS_MAX = 512
|
||||
|
||||
# ============================================================
|
||||
# ClassGenEnum - ClassGenMixin 拆分(阶段 D):enum/union/renum 定义与变体表
|
||||
#
|
||||
# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
novirtual class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
"""enum/union/renum 定义与变体表"""
|
||||
|
||||
def _resolve_enum_member_type(self, pool: memhub.MemBuddy*,
|
||||
@@ -49,8 +44,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
at: ast.Attribute* = ast.Attribute*(ann_node)
|
||||
if at.attr is None:
|
||||
# [S4 fail-fast] Attribute 缺失成员名(AST 损坏),不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, "枚举成员类型注解 Attribute 缺失成员名", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, "枚举成员类型注解 Attribute 缺失成员名", "TypeError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
# t.State → 默认 i32
|
||||
if string.strcmp(at.attr, "State") == 0:
|
||||
@@ -62,13 +56,10 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if string.strcmp(at.attr, "CBool") == 0:
|
||||
return llvmlite.Int8(pool)
|
||||
# 其他 t.CXxx 类型:统一口径(CTypedef 动态表优先,miss 回退 map_t_type)
|
||||
ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(
|
||||
pool, at.attr, imported_modules, from_imports)
|
||||
if ty is not None:
|
||||
return ty
|
||||
ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, imported_modules, from_imports)
|
||||
if ty is not None: return ty
|
||||
# [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, f"枚举成员类型注解解析失败: t.{at.attr}", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: t.{at.attr}", "NameError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
|
||||
# Name 节点: from-import 形式(State / CInt)
|
||||
@@ -76,8 +67,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
nm: ast.Name* = ast.Name*(ann_node)
|
||||
if nm.id is None:
|
||||
# [S4 fail-fast] Name 缺失标识符(AST 损坏),不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, "枚举成员类型注解 Name 缺失标识符", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, "枚举成员类型注解 Name 缺失标识符", "TypeError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
if string.strcmp(nm.id, "State") == 0:
|
||||
return llvmlite.Int32(pool)
|
||||
@@ -97,27 +87,23 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# map_t_type 的 CBool,用于普通变量/形参/字段)。
|
||||
# 两侧一致:TPC 侧枚举成员 bool 经 t.CBool.Size 亦为 8。
|
||||
return llvmlite.Int8(pool)
|
||||
ty2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(
|
||||
pool, nm.id, imported_modules, from_imports)
|
||||
ty2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, nm.id, imported_modules, from_imports)
|
||||
if ty2 is not None:
|
||||
return ty2
|
||||
# [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, f"枚举成员类型注解解析失败: {nm.id}", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {nm.id}", "NameError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
|
||||
# BinOp 节点: t.State | int8(递归查找实际类型)
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp* = ast.BinOp*(ann_node)
|
||||
if bop.op == ast.OpKind.BitOr:
|
||||
left_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(
|
||||
pool, bop.left, imported_modules, from_imports)
|
||||
left_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, bop.left, imported_modules, from_imports)
|
||||
# 跳过 t.State(i32 默认),优先返回具体类型
|
||||
left_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(left_ty)
|
||||
if left_bits != 0 and not self._is_state_annotation(bop.left):
|
||||
return left_ty
|
||||
right_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(
|
||||
pool, bop.right, imported_modules, from_imports)
|
||||
right_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, bop.right, imported_modules, from_imports)
|
||||
if right_ty is not None and not self._is_state_annotation(bop.right):
|
||||
return right_ty
|
||||
# 两边都是 State 或无法确定,返回较宽的
|
||||
@@ -126,13 +112,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
return left_ty
|
||||
return right_ty
|
||||
# fail-fast:BinOp 但非 BitOr(未知联合运算),不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
|
||||
# fail-fast:未知注解节点 kind,不再静默回退 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError")
|
||||
return llvmlite.Int32(pool) # 不可达(fatal_error 已退出)
|
||||
def _is_state_annotation(self, node: ast.AST*) -> int:
|
||||
"""检查注解节点是否为 t.State,返回 1=是 / 0=否"""
|
||||
@@ -385,25 +369,18 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# 具体整数类型、rawptr[...] 又是 Subscript(非 Name/Attribute/BinOp)
|
||||
# 会在解析里报笼统的"注解解析失败",两者都盖不住"指针成员"这个真因。
|
||||
if self._enum_member_annotation_is_ptr(aa.annotation) == 1:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
aa,
|
||||
f"枚举成员 '{tgt.id}' 不能是指针类型(枚举值只支持整数成员类型)",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(aa, f"枚举成员 '{tgt.id}' 不能是指针类型(枚举值只支持整数成员类型)", "TypeError")
|
||||
return 0 # 不可达(fatal_error 已退出)
|
||||
|
||||
# 解析成员类型
|
||||
member_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(
|
||||
pool, aa.annotation, trans._imported_modules, trans._from_imports)
|
||||
member_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, aa.annotation, trans._imported_modules, trans._from_imports)
|
||||
|
||||
# [枚举规格 fail-fast] 成员类型必须是整数类型:浮点/void/结构体/
|
||||
# 数组的位宽均为 0,无法参与"枚举宽度 = 最宽成员类型"的推导,
|
||||
# 静默接受会让寄存器宽度与访问侧常量类型不一致。禁止静默降级。
|
||||
member_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(member_ty)
|
||||
if member_bits <= 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
aa,
|
||||
f"枚举成员 '{tgt.id}' 的类型必须为整数类型(不允许指针/浮点/void/结构体/数组),无法推导枚举宽度",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(aa, f"枚举成员 '{tgt.id}' 的类型必须为整数类型(不允许指针/浮点/void/结构体/数组),无法推导枚举宽度", "TypeError")
|
||||
return 0 # 不可达(fatal_error 已退出)
|
||||
|
||||
# 解析成员值
|
||||
@@ -510,8 +487,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
base_ty = mty
|
||||
|
||||
# 注册枚举
|
||||
entry: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.register_enum(
|
||||
pool, class_name, base_ty)
|
||||
entry: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.register_enum(pool, class_name, base_ty)
|
||||
if entry is None:
|
||||
VLogger.error("failed to register {class_name}", "ENUM")
|
||||
return 0
|
||||
@@ -627,8 +603,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
def _translate_union_def(self, trans: HT.Translator*,
|
||||
cd: ast.ClassDef*) -> int:
|
||||
"""翻译联合体定义,返回 0"""
|
||||
if cd is None or cd.name is None or trans is None:
|
||||
return 0
|
||||
if cd is None or cd.name is None or trans is None: return 0
|
||||
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
class_name: str = cd.name
|
||||
@@ -637,8 +612,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
self.Gen.StructGen.add_visible_struct(pool, class_name)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
if existing is not None:
|
||||
# Phase B: 将已存在的命名结构体注册到当前模块
|
||||
if existing.Ty is not None:
|
||||
@@ -666,36 +640,27 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
|
||||
for ci in range(cn):
|
||||
stmt: ast.AST* = children.get(ci)
|
||||
if stmt is None:
|
||||
continue
|
||||
if stmt is None: continue
|
||||
sk: int = stmt.kind()
|
||||
|
||||
if sk == ast.ASTKind.AnnAssign:
|
||||
aa: ast.AnnAssign* = ast.AnnAssign*(stmt)
|
||||
if aa is None or aa.target is None:
|
||||
continue
|
||||
if aa is None or aa.target is None: continue
|
||||
|
||||
# 获取字段名
|
||||
if aa.target.kind() != ast.ASTKind.Name:
|
||||
continue
|
||||
if aa.target.kind() != ast.ASTKind.Name: continue
|
||||
tgt: ast.Name* = ast.Name*(aa.target)
|
||||
if tgt.id is None:
|
||||
continue
|
||||
if tgt.id is None: continue
|
||||
|
||||
# 解析字段类型
|
||||
field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if field_ty is None:
|
||||
# Phase A-pre(declare_only=1):依赖的类可能尚未注册,
|
||||
# 静默 return 1 让多遍收敛机制生效(renum 返回 1=跳过该类)
|
||||
if trans._declare_only == 1:
|
||||
return 1
|
||||
if trans._declare_only == 1: return 1
|
||||
# Phase B(declare_only=0):真正的类型解析错误,fast-fail 终止
|
||||
type_name: str = self.Gen.TypeGenResolve.annotation_to_str(aa.annotation)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
aa,
|
||||
f"'{type_name}' is not defined",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(aa, f"'{type_name}' is not defined", "NameError")
|
||||
field_ty = llvmlite.Int32(pool)
|
||||
|
||||
# 计算字段大小,更新 max_size
|
||||
@@ -747,8 +712,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# entry.Ty 悬空 → 后续文件 opaque 扫描跨模块引用遍历悬空 fields 崩溃
|
||||
# (LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。
|
||||
if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0:
|
||||
union_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, union_ty)
|
||||
union_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, union_ty)
|
||||
if union_copy is not None:
|
||||
union_ty = union_copy
|
||||
|
||||
@@ -756,8 +720,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
llvmlite.module_add_named_type(trans.Module, pool, union_ty)
|
||||
|
||||
# 注册到 HandlesStruct(传递 SHA1 在注册时直接设置,避免跨模块同名找错 entry)
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, union_ty, trans.ModuleSha1)
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, union_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "UNION")
|
||||
return 0
|
||||
@@ -810,35 +773,20 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if dyn_sz > 0:
|
||||
return dyn_sz
|
||||
# 内置类型
|
||||
if string.strcmp(type_name, "int") == 0:
|
||||
return 4
|
||||
if string.strcmp(type_name, "CInt") == 0:
|
||||
return 4
|
||||
if string.strcmp(type_name, "CInt8T") == 0:
|
||||
return 1
|
||||
if string.strcmp(type_name, "CInt16T") == 0:
|
||||
return 2
|
||||
if string.strcmp(type_name, "CInt32T") == 0:
|
||||
return 4
|
||||
if string.strcmp(type_name, "CInt64T") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "CChar") == 0:
|
||||
return 1
|
||||
if string.strcmp(type_name, "CDouble") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "CFloat") == 0:
|
||||
return 4
|
||||
if string.strcmp(type_name, "CPtr") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "CSizeT") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "str") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "bytes") == 0:
|
||||
return 8
|
||||
if string.strcmp(type_name, "bool") == 0:
|
||||
# bool = t.CBool = i8(1 字节)
|
||||
return 1
|
||||
if string.strcmp(type_name, "int") == 0: return 4
|
||||
if string.strcmp(type_name, "CInt") == 0: return 4
|
||||
if string.strcmp(type_name, "CInt8T") == 0: return 1
|
||||
if string.strcmp(type_name, "CInt16T") == 0: return 2
|
||||
if string.strcmp(type_name, "CInt32T") == 0: return 4
|
||||
if string.strcmp(type_name, "CInt64T") == 0: return 8
|
||||
if string.strcmp(type_name, "CChar") == 0: return 1
|
||||
if string.strcmp(type_name, "CDouble") == 0: return 8
|
||||
if string.strcmp(type_name, "CFloat") == 0: return 4
|
||||
if string.strcmp(type_name, "CPtr") == 0: return 8
|
||||
if string.strcmp(type_name, "CSizeT") == 0: return 8
|
||||
if string.strcmp(type_name, "str") == 0: return 8
|
||||
if string.strcmp(type_name, "bytes") == 0: return 8
|
||||
if string.strcmp(type_name, "bool") == 0: return 1
|
||||
# 已注册的结构体类型
|
||||
struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(type_name)
|
||||
if struct_ty is not None:
|
||||
@@ -850,8 +798,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
def _translate_renum_def(self, trans: HT.Translator*,
|
||||
cd: ast.ClassDef*) -> int:
|
||||
"""翻译 REnum 类定义,返回 0"""
|
||||
if cd is None or cd.name is None or trans is None:
|
||||
return 0
|
||||
if cd is None or cd.name is None or trans is None: return 0
|
||||
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
class_name: str = cd.name
|
||||
@@ -860,8 +807,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
self.Gen.StructGen.add_visible_struct(pool, class_name)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
if existing is not None:
|
||||
# existing 只保证 struct entry 在,不保证 REnum 语义(变体表)在:struct entry
|
||||
# 由 register_struct 写 StructTable,跨 Phase 存活(perm_pool);而变体表是 gen
|
||||
@@ -885,9 +831,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# [D32 fail-fast] 此前只 warning + return 0:变体表**静默不注册** →
|
||||
# _is_renum_class_name 恒 0、变体构造拿不到 tag(__types.vp L703
|
||||
# `LLVMType.Metadata()` 被当外部函数根因)。禁止静默跳过。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
cd, f"REnum 类 '{class_name}' 缺少类体(children 为 None),无法注册变体表",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(cd, f"REnum 类 '{class_name}' 缺少类体(children 为 None),无法注册变体表", "TypeError")
|
||||
return 0
|
||||
|
||||
cn: sizet = len(children)
|
||||
@@ -946,13 +890,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if vnm is not None and vnm.id is not None:
|
||||
mem_ty_l: llvmlite.LLVMType* = None
|
||||
if trans is not None:
|
||||
mem_ty_l = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, vaa.annotation,
|
||||
trans._imported_modules,
|
||||
trans._from_imports, trans, 0)
|
||||
self._register_renum_field_alias(
|
||||
pool, class_name, vnm.id, field_idx + 1,
|
||||
mem_ty_l, variant_cd.name)
|
||||
mem_ty_l = self.Gen.TypeGenResolve.resolve_annotation_type(pool, vaa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
self._register_renum_field_alias(pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name)
|
||||
field_idx += 1
|
||||
if field_idx > max_field_count:
|
||||
max_field_count = field_idx
|
||||
@@ -980,9 +919,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if variant_count == 0:
|
||||
# [D32 fail-fast] 同上:变体数为 0 时此前静默 return → 变体表不注册。
|
||||
# 对 `class X(t.REnum)` 而言变体数必 > 0,为 0 说明 AST 变体类丢失。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
cd, f"REnum 类 '{class_name}' 的变体数为 0(嵌套变体类丢失),无法注册变体表",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(cd, f"REnum 类 '{class_name}' 的变体数为 0(嵌套变体类丢失),无法注册变体表", "TypeError")
|
||||
return 0
|
||||
|
||||
# 计算每个位置的最大字段大小
|
||||
@@ -1046,8 +983,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
viperlib.snprintf(renum_name_buf, 64, "%s.%s", trans.ModuleSha1, class_name)
|
||||
renum_type_name = renum_name_buf
|
||||
|
||||
renum_ty: llvmlite.LLVMType* = llvmlite.Struct(
|
||||
pool, first_node, total_positions, renum_type_name)
|
||||
renum_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, total_positions, renum_type_name)
|
||||
if renum_ty is None:
|
||||
VLogger.error(f"failed to create type for {class_name}", "RENUM")
|
||||
return 0
|
||||
@@ -1056,8 +992,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# 与 entry.Ty 保持同一指针,find_struct_by_type 匹配不失效)
|
||||
# StdlibAlloc=1(Phase2 mark2 后)也必须深拷贝:同 union 的悬空根因。
|
||||
if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0:
|
||||
renum_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, renum_ty)
|
||||
renum_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, renum_ty)
|
||||
if renum_copy is not None:
|
||||
renum_ty = renum_copy
|
||||
|
||||
@@ -1065,8 +1000,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
llvmlite.module_add_named_type(trans.Module, pool, renum_ty)
|
||||
|
||||
# 注册到 HandlesStruct
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, renum_ty, trans.ModuleSha1)
|
||||
entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, renum_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "RENUM")
|
||||
return 0
|
||||
@@ -1152,29 +1086,20 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# 与第一遍同规则:有效 AnnAssign 仍占用 payload 槽位
|
||||
field_idx += 1
|
||||
continue
|
||||
mem_ty_l: llvmlite.LLVMType* = \
|
||||
self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, vaa.annotation,
|
||||
trans._imported_modules,
|
||||
trans._from_imports, trans, 0)
|
||||
mem_ty_l: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, vaa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
# 解析成功 → 触发别名表去重路径(类型槽为 0 时回填;非 0 跳过)
|
||||
if mem_ty_l is not None:
|
||||
self._register_renum_field_alias(
|
||||
pool, class_name, vnm.id, field_idx + 1,
|
||||
mem_ty_l, variant_cd.name)
|
||||
self._register_renum_field_alias(pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name)
|
||||
field_idx += 1
|
||||
def _register_renum_variants(self, pool: memhub.MemBuddy*,
|
||||
class_name: str,
|
||||
cd: ast.ClassDef*,
|
||||
variant_count: int):
|
||||
"""注册 REnum 类的变体名和 tag 值到全局变体表"""
|
||||
if pool is None or class_name is None or cd is None:
|
||||
return
|
||||
if variant_count == 0:
|
||||
return
|
||||
if pool is None or class_name is None or cd is None: return
|
||||
if variant_count == 0: return
|
||||
children: list[ast.AST*]* = cd.children
|
||||
if children is None:
|
||||
return
|
||||
if children is None: return
|
||||
|
||||
# 懒初始化表(首次注册时分配)
|
||||
# 注意: 必须用 stdlib 分配——这些表在 1b 阶段(mark1 之后)首次分配,
|
||||
@@ -1464,8 +1389,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# _refill_renum_field_types)类型槽为 0 时,本次解析成功则
|
||||
# 回填真实类型;非 0 槽保持原样(避免重复 DeepCopy 覆盖抖动)。
|
||||
if self.RenumAliasTy[i] == 0 and field_ty is not None:
|
||||
ty_copy_rf2: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, field_ty)
|
||||
ty_copy_rf2: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, field_ty)
|
||||
if ty_copy_rf2 is not None:
|
||||
self.RenumAliasTy[i] = sizet(ty_copy_rf2)
|
||||
return
|
||||
@@ -1492,8 +1416,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# 未解析成功(自引用等)存 0,绑定回退槽位类型)
|
||||
self.RenumAliasTy[idx] = 0
|
||||
if field_ty is not None:
|
||||
ty_copy_rfa: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, field_ty)
|
||||
ty_copy_rfa: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, field_ty)
|
||||
if ty_copy_rfa is not None:
|
||||
self.RenumAliasTy[idx] = sizet(ty_copy_rfa)
|
||||
# 变体名同样 strcpy 到 perm_pool(1a reset 后 variant_cd.name 悬空)
|
||||
|
||||
@@ -15,22 +15,16 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
# 泛型特化递归深度上限(泛型循环套用防护)
|
||||
# 正常嵌套特化深度 ≤ 3(如 list[list[str]]);64 远超合理值,命中即循环。
|
||||
# (原 HandlesClassDef/ClassGenMixin 顶层常量,阶段 D 拆分时遗漏,补回)
|
||||
GENERIC_SPEC_MAX_DEPTH: t.CDefine = 64
|
||||
define GENERIC_SPEC_MAX_DEPTH = 64
|
||||
# 泛型模板表容量上限(与 GenericClassNames 等 pool 表可容纳的模板数对齐;
|
||||
# 原 ClassGenMixin 顶层常量,阶段 D 拆分时遗漏,补回)
|
||||
GENERIC_TEMPLATE_MAX: t.CDefine = 512
|
||||
# 泛型特化缓存表容量(原 HandlesClassDef.SPEC_CACHE_MAX,阶段 D 拆分遗漏)
|
||||
SPEC_CACHE_MAX: t.CDefine = 512
|
||||
define GENERIC_TEMPLATE_MAX = 512
|
||||
# 泛型特化缓存表容量
|
||||
define SPEC_CACHE_MAX = 512
|
||||
|
||||
# ============================================================
|
||||
# ClassGenGeneric - 泛型模板注册/特化/克隆
|
||||
#
|
||||
# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesClassDef 委托。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
"""泛型模板注册/特化/克隆"""
|
||||
|
||||
# ============================================================
|
||||
@@ -49,20 +43,16 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
接收 type_params 而非 cd,避免 cd.type_params 属性访问
|
||||
因跨模块类型推断失败返回 None。
|
||||
"""
|
||||
if tp is None:
|
||||
return 0
|
||||
if tp is None: return 0
|
||||
return 1
|
||||
def _dup_perm_str(self, s: str) -> str:
|
||||
"""深拷贝字符串到永久池(无永久池/分配失败时原样返回入参)"""
|
||||
if s is None:
|
||||
return None
|
||||
if s is None: return None
|
||||
perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool
|
||||
if perm is None:
|
||||
return s
|
||||
if perm is None: return s
|
||||
n: sizet = string.strlen(s)
|
||||
b: str = perm.alloc(n + 1)
|
||||
if b is None:
|
||||
return s
|
||||
if b is None: return s
|
||||
string.strcpy(b, s)
|
||||
return b
|
||||
def _register_generic_template(self, pool: memhub.MemBuddy*,
|
||||
@@ -92,8 +82,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
(同样的类名/节点/ SHA1/文件路径,同样的插入顺序与查重),发射的 IR 与
|
||||
符号名不受池选择影响 ⇒ 逐字不变。
|
||||
"""
|
||||
if cd is None or cd.name is None:
|
||||
return
|
||||
if cd is None or cd.name is None: return
|
||||
perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool
|
||||
table_pool: memhub.MemBuddy* = perm
|
||||
if table_pool is None:
|
||||
@@ -104,11 +93,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
self.GenericClassSha1s = list[str](table_pool, 8)
|
||||
self.GenericClassFiles = list[str](table_pool, 8)
|
||||
if self.GenericClassTpParams is None:
|
||||
if perm is None:
|
||||
return
|
||||
if perm is None: return
|
||||
self.GenericClassTpParams = perm.alloc(GENERIC_TEMPLATE_MAX * 8)
|
||||
if self.GenericClassTpParams is None:
|
||||
return
|
||||
if self.GenericClassTpParams is None: return
|
||||
string.memset(self.GenericClassTpParams, 0, GENERIC_TEMPLATE_MAX * 8)
|
||||
# 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败)
|
||||
names_local: list[str]* = self.GenericClassNames
|
||||
@@ -116,16 +103,14 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
i: sizet
|
||||
for i in range(cn):
|
||||
nm: str = names_local.get(i)
|
||||
if nm is not None and string.strcmp(nm, cd.name) == 0:
|
||||
return
|
||||
if nm is not None and string.strcmp(nm, cd.name) == 0: return
|
||||
# type_params stdlib 深拷贝:模板节点的 type_params 是 pool 分配的
|
||||
tp_names_buf: str = self._copy_type_params_stdlib(cd.type_params)
|
||||
self.GenericClassNames.append(self._dup_perm_str(cd.name))
|
||||
self.GenericClassNodes.append(cd)
|
||||
self.GenericClassSha1s.append(self._dup_perm_str(module_sha1))
|
||||
# 同时保存模板来源文件路径(错误定位用,见字段注释)
|
||||
self.GenericClassFiles.append(
|
||||
self._dup_perm_str(self.Gen.TypeGenResolve.get_current_file()))
|
||||
self.GenericClassFiles.append(self._dup_perm_str(self.Gen.TypeGenResolve.get_current_file()))
|
||||
if tp_names_buf is not None and cn < GENERIC_TEMPLATE_MAX:
|
||||
self.GenericClassTpParams[cn] = sizet(tp_names_buf)
|
||||
def _copy_type_params_stdlib(self, tp: list[str]*) -> str:
|
||||
@@ -602,12 +587,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
# 方法体永不发射 → 特化方法只有 call 无 define → 链接 undefined symbol。
|
||||
pre_existing.MethodsEmitted = 1
|
||||
# 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效)
|
||||
tp_names_pre: list[str]* = self._find_generic_template_tp_params(
|
||||
pool, class_name)
|
||||
tp_names_pre: list[str]* = self._find_generic_template_tp_params(pool, class_name)
|
||||
if tp_names_pre is None:
|
||||
tp_names_pre = template_cd.type_params
|
||||
spec_cd_pre: ast.ClassDef* = self._clone_classdef_for_spec(
|
||||
pool, template_cd, spec_name, tp_names_pre, type_args)
|
||||
spec_cd_pre: ast.ClassDef* = self._clone_classdef_for_spec(pool, template_cd, spec_name, tp_names_pre, type_args)
|
||||
if spec_cd_pre is not None:
|
||||
trans.GenericTypeParamNames = tp_names_pre
|
||||
trans.GenericTypeArgs = type_args
|
||||
@@ -681,12 +664,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
|
||||
# 5. 拷贝 ClassDef 节点
|
||||
# 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效)
|
||||
tp_names: list[str]* = self._find_generic_template_tp_params(
|
||||
pool, class_name)
|
||||
tp_names: list[str]* = self._find_generic_template_tp_params(pool, class_name)
|
||||
if tp_names is None:
|
||||
tp_names = template_cd.type_params
|
||||
spec_cd: ast.ClassDef* = self._clone_classdef_for_spec(
|
||||
pool, template_cd, spec_name, tp_names, type_args)
|
||||
spec_cd: ast.ClassDef* = self._clone_classdef_for_spec(pool, template_cd, spec_name, tp_names, type_args)
|
||||
if spec_cd is None:
|
||||
self.GenericSpecDepth -= 1
|
||||
return None
|
||||
@@ -734,10 +715,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
result_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(spec_name)
|
||||
if result_entry is not None:
|
||||
ri: int
|
||||
for ri in range(result_entry.FieldCount):
|
||||
rfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(
|
||||
result_entry, ri)
|
||||
rfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(result_entry, ri)
|
||||
if rfe is not None:
|
||||
rfn: str = self.Gen.StructGen.get_field_name_ptr(rfe)
|
||||
if rfn is None:
|
||||
|
||||
@@ -4,10 +4,6 @@ from . import ClassGenBase
|
||||
|
||||
# ============================================================
|
||||
# ClassGenMixin - 类定义/继承/泛型/vtable/enum/union/renum
|
||||
#
|
||||
# 方法已全部拆至 ClassGenBase/Enum/Generic/VTable/Def,本文件保留类声明。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenMixin(ClassGenBase.ClassGenBase):
|
||||
novirtual class ClassGenMixin(ClassGenBase.ClassGenBase):
|
||||
"""类定义处理 Mixin(阶段 D 拆分后顶层,方法全部在子 Mixin)"""
|
||||
@@ -17,21 +17,15 @@ import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# 方法元数据 flag:TLS(@t.TLS 装饰器,对齐 ClassGenBase 本地常量;本地副本避免跨模块 CDefine 查找)
|
||||
META_TLS: t.CDefine = 32
|
||||
# 虚表方法数上限(原 HandlesClassDef.VTBL_METHOD_MAX,阶段 D 拆分遗漏)
|
||||
VTBL_METHOD_MAX: t.CDefine = 32
|
||||
|
||||
SCOPE_FUNCTION: t.CDefine = 1
|
||||
define META_TLS = 32
|
||||
# 虚表方法数上限
|
||||
define VTBL_METHOD_MAX = 32
|
||||
define SCOPE_FUNCTION = 1
|
||||
|
||||
# ============================================================
|
||||
# ClassGenVTable - ClassGenMixin 拆分(阶段 D):vtable 收集/生成/方法翻译
|
||||
#
|
||||
# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
"""vtable 收集/生成/方法翻译"""
|
||||
|
||||
# ============================================================
|
||||
@@ -45,8 +39,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
dlen: sizet = string.strlen(dst)
|
||||
slen: sizet = string.strlen(src)
|
||||
remain: sizet = dst_size - dlen
|
||||
if remain <= 0:
|
||||
return
|
||||
if remain <= 0: return
|
||||
i: sizet = 0
|
||||
while i < slen and i + 1 < remain:
|
||||
dst[dlen + i] = src[i]
|
||||
@@ -114,8 +107,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 如果子类覆盖了方法,full_name 用子类的;否则用父类的。
|
||||
# 用 SHA1 感知查找,规避跨模块同名 find_struct 找错
|
||||
# ============================================================
|
||||
vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
# 多继承:遍历所有父类(声明顺序),vtable 方法合并(短名去重,先声明父类优先)
|
||||
parent_count: int = self.Gen.StructGen.get_parent_count(class_name)
|
||||
if parent_count > 0:
|
||||
@@ -124,8 +116,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if pname is None:
|
||||
continue
|
||||
# 查找父类 entry(优先同模块 SHA1 匹配)
|
||||
vt_parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
pname, trans.ModuleSha1)
|
||||
vt_parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pname, trans.ModuleSha1)
|
||||
if vt_parent_entry is None:
|
||||
# 跨模块继承: 父类在不同模块定义(SHA1 不同),回退到按类名查找
|
||||
vt_parent_entry = self.Gen.StructGen.find_struct(pname)
|
||||
@@ -204,8 +195,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
method_parent_sha1s[method_count] = 0
|
||||
else:
|
||||
# 继承未覆盖: 用实际定义类的模块 SHA1(跨模块继承时 mangling 正确)
|
||||
def_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(
|
||||
def_class)
|
||||
def_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(def_class)
|
||||
if def_entry2 is not None and def_entry2.ModuleSha1 is not None:
|
||||
method_parent_sha1s[method_count] = sizet(def_entry2.ModuleSha1)
|
||||
else:
|
||||
@@ -308,8 +298,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
method_parent_sha1s: sizet* = self.VtParentSha1s
|
||||
method_count: int = self.VtMethodCount
|
||||
# 重新获取 entry(后续存储 VTableMethods 用)
|
||||
vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
|
||||
# 2. 构造 VTable 类型: { i8*, i8*, ..., i8* }
|
||||
i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool)
|
||||
@@ -370,8 +359,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
continue
|
||||
func_ty_buf[0] = '\0'
|
||||
if ge is None or ge.Spec is None or TSpec.SpecToLLVMText(ge.Spec, func_ty_buf, 1024) != 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError")
|
||||
continue
|
||||
|
||||
# 构造 bitcast 字符串: i8* bitcast (func_ty* @mangled to i8*)
|
||||
@@ -397,8 +385,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
vtable_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vtable_name_buf)
|
||||
|
||||
# 5. 创建全局变量
|
||||
gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(
|
||||
pool, vtable_mangled, vtable_ty)
|
||||
gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, vtable_mangled, vtable_ty)
|
||||
if gv is None:
|
||||
return 0
|
||||
gv.Initializer = init_buf
|
||||
@@ -636,8 +623,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 推断返回类型
|
||||
ret_ty: llvmlite.LLVMType* = None
|
||||
if fd.returns is not None:
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
if ret_ty is None and fd.returns is not None:
|
||||
# 存储类标记(t.State / t.CExport / t.CExtern)语义为 Void:这类注解
|
||||
# 不携带真实返回类型(extern/export 语法写成 "<原类型> | t.<标记>",
|
||||
@@ -649,8 +635,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
else:
|
||||
# [S4 fail-fast] 有返回注解但解析失败 → 不再退回 infer_return_type()
|
||||
# (推断可能给出与真实注解不符的类型,静默错到运行期才暴露)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fd, f"方法 '{class_name}.{method_name}' 返回类型注解解析失败", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(fd, f"方法 '{class_name}.{method_name}' 返回类型注解解析失败", "NameError")
|
||||
return 0
|
||||
if ret_ty is None:
|
||||
# __init__ 和 __before_init__ 返回 void
|
||||
@@ -661,12 +646,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
ret_ty = llvmlite.Ptr(pool, struct_ty)
|
||||
else:
|
||||
param_types_str: str = self.Gen.TypeGenErr.build_param_types_str(pool, fd.args)
|
||||
ret_ty = self.Gen.TypeGenErr.infer_return_type(
|
||||
pool, fd.children, param_types_str)
|
||||
ret_ty = self.Gen.TypeGenErr.infer_return_type(pool, fd.children, param_types_str)
|
||||
|
||||
# 创建 LLVM 函数
|
||||
func: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, mangled_name, ret_ty)
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_name, ret_ty)
|
||||
if func is None:
|
||||
return 0
|
||||
|
||||
@@ -728,14 +711,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if arg is not None and arg.arg is not None:
|
||||
param_ty: llvmlite.LLVMType* = i32_ty
|
||||
if arg.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved is None:
|
||||
# [S4 fail-fast] 有注解但解析失败:不再静默用 i32
|
||||
# (方法签名与调用点/实现体三方不一致)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg, f"方法 '{class_name}.{method_name}' 形参 '{arg.arg}' 类型注解解析失败",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg, f"方法 '{class_name}.{method_name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
return 0
|
||||
# 裸类形参 → Ptr(struct):按"对象即指针"引用传参。
|
||||
# 若按 struct 值传参,self.Head = node 会取局部拷贝地址
|
||||
@@ -783,8 +763,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
tls_m_flag_name: str = pool.alloc(128)
|
||||
if tls_m_flag_name is not None:
|
||||
viperlib.snprintf(tls_m_flag_name, 128, "__tls_init_done_%s", method_name)
|
||||
tls_m_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(
|
||||
pool, mod, tls_m_flag_name, 1, 0)
|
||||
tls_m_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(pool, mod, tls_m_flag_name, 1, 0)
|
||||
if tls_m_gv is not None:
|
||||
i1_ty_m: llvmlite.LLVMType* = llvmlite.Int1(pool)
|
||||
if i1_ty_m is not None:
|
||||
@@ -793,46 +772,37 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
tls_m_rn: str = pool.alloc(64)
|
||||
if tls_m_rn is not None:
|
||||
viperlib.snprintf(tls_m_rn, 64, "@%s", tls_m_flag_name)
|
||||
tls_m_ref: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, tls_m_ptr_ty, tls_m_rn)
|
||||
tls_m_ref: llvmlite.Value* = llvmlite.SSAValue(pool, tls_m_ptr_ty, tls_m_rn)
|
||||
if tls_m_ref is not None:
|
||||
tls_m_ld: llvmlite.Value* = llvmlite.build_load(
|
||||
func_builder, i1_ty_m, tls_m_ref)
|
||||
tls_m_ld: llvmlite.Value* = llvmlite.build_load(func_builder, i1_ty_m, tls_m_ref)
|
||||
lc_m: int = trans._label_counter
|
||||
trans._label_counter = lc_m + 1
|
||||
tls_m_buf: str = pool.alloc(64)
|
||||
if tls_m_buf is not None:
|
||||
viperlib.snprintf(tls_m_buf, 64, "tls.skip.%d", lc_m)
|
||||
tls_m_skip: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_m_buf)
|
||||
tls_m_skip: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_m_buf)
|
||||
viperlib.snprintf(tls_m_buf, 64, "tls.cont.%d", lc_m)
|
||||
tls_m_cont: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_m_buf)
|
||||
tls_m_cont: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_m_buf)
|
||||
if tls_m_skip is not None and tls_m_cont is not None:
|
||||
llvmlite.build_cond_br(
|
||||
func_builder, tls_m_ld, tls_m_skip, tls_m_cont)
|
||||
llvmlite.build_cond_br(func_builder, tls_m_ld, tls_m_skip, tls_m_cont)
|
||||
llvmlite.position_at_end(func_builder, tls_m_skip)
|
||||
match ret_ty:
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
tlm0: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, ret_ty, 0, "0")
|
||||
tlm0: llvmlite.Value* = llvmlite.ConstInt(pool, ret_ty, 0, "0")
|
||||
if tlm0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlm0)
|
||||
case llvmlite.LLVMType.Float(_):
|
||||
tlmf: llvmlite.Value* = llvmlite.ConstFloat(
|
||||
pool, ret_ty, 0.0)
|
||||
tlmf: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0)
|
||||
if tlmf is not None:
|
||||
llvmlite.build_ret(func_builder, tlmf)
|
||||
case _:
|
||||
tlmn: llvmlite.Value* = llvmlite.ConstNull(
|
||||
pool, ret_ty, "null")
|
||||
tlmn: llvmlite.Value* = llvmlite.ConstNull(pool, ret_ty, "null")
|
||||
if tlmn is not None:
|
||||
llvmlite.build_ret(func_builder, tlmn)
|
||||
llvmlite.position_at_end(func_builder, tls_m_cont)
|
||||
tlmo: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, i1_ty_m, 1, "1")
|
||||
tlmo: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_m, 1, "1")
|
||||
if tlmo is not None:
|
||||
llvmlite.build_store(func_builder, tlmo, tls_m_ref)
|
||||
|
||||
@@ -878,13 +848,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if arg2 is not None and arg2.arg is not None:
|
||||
param_ty2: llvmlite.LLVMType* = i32_ty
|
||||
if arg2.annotation is not None:
|
||||
resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg2.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg2.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved2 is None:
|
||||
# fail-fast:参数有注解但类型解析失败,不再静默保持 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg2, f"方法 '{class_name}.{method_name}' 参数 '{arg2.arg}' 类型解析失败",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg2, f"方法 '{class_name}.{method_name}' 参数 '{arg2.arg}' 类型解析失败", "NameError")
|
||||
resolved2 = i32_ty # 不可达(fatal_error 已退出)
|
||||
if resolved2 is not None:
|
||||
# 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针)
|
||||
@@ -902,16 +869,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 存储原始类型注解的类名(方法调用检测时,Ptr(i8) 回退到类名查找结构体)
|
||||
# 传 pool:泛型 Subscript 返回 mangled name(对齐 HandlesAnnAssign 修复)
|
||||
if arg2.annotation is not None:
|
||||
cls_nm_oc: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
|
||||
arg2.annotation, imported_modules, pool, trans._from_imports)
|
||||
cls_nm_oc: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg2.annotation, imported_modules, pool, trans._from_imports)
|
||||
if cls_nm_oc is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, arg2.arg, cls_nm_oc)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg2.arg, cls_nm_oc)
|
||||
pname2: str = pool.alloc(32)
|
||||
if pname2 is not None:
|
||||
viperlib.snprintf(pname2, 32, "%%%s", arg2.arg)
|
||||
param_val: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, param_ty2, pname2)
|
||||
param_val: llvmlite.Value* = llvmlite.SSAValue(pool, param_ty2, pname2)
|
||||
llvmlite.build_store(func_builder, param_val, alloca)
|
||||
|
||||
# OOP iter 协议:__next__ 的 stop-flag 参数初始化(store 0)并保存
|
||||
@@ -922,12 +886,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if i1_ty_sf is not None:
|
||||
i1_ptr_ty_sf: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_sf)
|
||||
if i1_ptr_ty_sf is not None:
|
||||
flag_ref_sf: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, i1_ptr_ty_sf, "%__stop_iter_flag__")
|
||||
flag_ref_sf: llvmlite.Value* = llvmlite.SSAValue(pool, i1_ptr_ty_sf, "%__stop_iter_flag__")
|
||||
if flag_ref_sf is not None:
|
||||
trans._stop_iter_flag_ptr = flag_ref_sf
|
||||
zero_i1_sf: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, i1_ty_sf, 0, "0")
|
||||
zero_i1_sf: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_sf, 0, "0")
|
||||
if zero_i1_sf is not None:
|
||||
llvmlite.build_store(func_builder, zero_i1_sf, flag_ref_sf)
|
||||
|
||||
@@ -1013,12 +975,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# TypeGenResolve._is_cvoid_marker(TypeGenResolve.vp:1484)
|
||||
# ③ -> None(CONST_NONE):解析即 Void(TypeGenResolve.vp:1996-1999)
|
||||
if _is_void == 0 and fd.returns is not None:
|
||||
if self.Gen.TypeGenResolve._is_cvoid_marker(
|
||||
fd.returns, imported_modules) != 0:
|
||||
if self.Gen.TypeGenResolve._is_cvoid_marker(fd.returns, imported_modules) != 0:
|
||||
_is_void = 1
|
||||
elif fd.returns.kind() == ast.ASTKind.Constant:
|
||||
ret_none_cn_m: ast.Constant* = (
|
||||
ast.Constant*)(fd.returns)
|
||||
ret_none_cn_m: ast.Constant* = (ast.Constant*)(fd.returns)
|
||||
if ret_none_cn_m.const_kind == ast.CONST_NONE:
|
||||
_is_void = 1
|
||||
if _is_void != 0:
|
||||
@@ -1049,10 +1009,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
rt_name_m = "?"
|
||||
err_fn_m: str = pool.alloc(256)
|
||||
if err_fn_m is not None:
|
||||
viperlib.snprintf(
|
||||
err_fn_m, 256,
|
||||
"方法 '%s' 流程掉出末尾但未显式 return(返回类型 %s),"
|
||||
"请补显式 return(如 return 0 / return null)", method_name, rt_name_m)
|
||||
viperlib.snprintf(err_fn_m, 256, "方法 '%s' 流程掉出末尾但未显式 return(返回类型 %s),请补显式 return(如 return 0 / return null)", method_name, rt_name_m)
|
||||
self.Gen.TypeGenErr.fatal_error(fd, err_fn_m, "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(fd, "方法流程掉出末尾但未显式 return", "TypeError")
|
||||
else:
|
||||
@@ -1096,18 +1053,15 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
|
||||
# 构建函数名: ClassName.__before_init__
|
||||
full_name_buf: str = pool.alloc(128)
|
||||
if full_name_buf is None:
|
||||
return 0
|
||||
if full_name_buf is None: return 0
|
||||
viperlib.snprintf(full_name_buf, 128, "%s.__before_init__", class_name)
|
||||
full_name: str = full_name_buf
|
||||
|
||||
mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name)
|
||||
|
||||
# 创建函数
|
||||
func: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, mangled_name, void_ty)
|
||||
if func is None:
|
||||
return 0
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_name, void_ty)
|
||||
if func is None: return 0
|
||||
|
||||
# 注册到函数表
|
||||
max_funcs: int = 1024
|
||||
@@ -1123,11 +1077,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
|
||||
# 创建 entry 块 + builder
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
if entry_blk is None: return 0
|
||||
func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
if func_builder is None: return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
|
||||
# 注册 self 为 SSA 值
|
||||
@@ -1181,8 +1133,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
vt_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vt_full_name)
|
||||
|
||||
# GEP 到 __vtable__ 字段(索引 0)
|
||||
vt_slot: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, vt_i8_ptr_ty, self_val, 0)
|
||||
vt_slot: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, vt_i8_ptr_ty, self_val, 0)
|
||||
if vt_slot is not None:
|
||||
# 创建全局变量引用 Value
|
||||
vt_ref: llvmlite.Value* = llvmlite.new_value(pool)
|
||||
@@ -1200,16 +1151,14 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
llvmlite.value_set_name(vt_ref, vt_ref_name)
|
||||
|
||||
# bitcast 到 i8*
|
||||
vt_as_i8: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
func_builder, vt_ref, vt_i8_ptr_ty)
|
||||
vt_as_i8: llvmlite.Value* = llvmlite.build_bitcast(func_builder, vt_ref, vt_i8_ptr_ty)
|
||||
if vt_as_i8 is not None:
|
||||
llvmlite.build_store(func_builder, vt_as_i8, vt_slot)
|
||||
|
||||
# 2. 逐字段 store 默认值(用 bi_entry 直接访问,规避跨模块同名 find_struct 找错)
|
||||
if bi_entry is not None:
|
||||
for fi in range(bi_entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(
|
||||
bi_entry, fi)
|
||||
fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(bi_entry, fi)
|
||||
if fe is None or fe.DefaultVal is None:
|
||||
continue
|
||||
# 静态数组字段 + 列表字面量默认值 → 整体置零 + 逐元素 GEP+store
|
||||
@@ -1219,8 +1168,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 推断为静态数组,此处保证 __before_init__ 填充真实字符串指针。
|
||||
if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 \
|
||||
and fe.DefaultVal.kind() == ast.ASTKind.List:
|
||||
field_ptr_arr: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
field_ptr_arr: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr_arr is not None:
|
||||
zero_arr_f: llvmlite.Value* = llvmlite.ConstZero(pool, fe.Ty)
|
||||
if zero_arr_f is not None:
|
||||
@@ -1232,22 +1180,16 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
arr_ctx: str = pool.alloc(192)
|
||||
if arr_ctx is not None:
|
||||
fname_dbg_v: str = fe.Name
|
||||
if fname_dbg_v is None:
|
||||
fname_dbg_v = "?"
|
||||
if fname_dbg_v is None: fname_dbg_v = "?"
|
||||
viperlib.snprintf(arr_ctx, 192, "类 %s 字段 %s:", class_name, fname_dbg_v)
|
||||
self.Gen.AssignGen._init_global_array_from_list(
|
||||
func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans, arr_ctx)
|
||||
self.Gen.AssignGen._init_global_array_from_list(func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans, arr_ctx)
|
||||
continue
|
||||
# 翻译默认值表达式
|
||||
default_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
func_builder, pool, mod, fe.DefaultVal, None, 0, trans)
|
||||
if default_val is None:
|
||||
continue
|
||||
default_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(func_builder, pool, mod, fe.DefaultVal, None, 0, trans)
|
||||
if default_val is None: continue
|
||||
# GEP 到字段
|
||||
field_ptr: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr is None:
|
||||
continue
|
||||
field_ptr: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr is None: continue
|
||||
# 类型转换并 store
|
||||
default_val = self.Gen.ExprGenBase.coerce_to_type(func_builder, default_val, fe.Ty, fe.DefaultVal)
|
||||
llvmlite.build_store(func_builder, default_val, field_ptr)
|
||||
|
||||
@@ -13,13 +13,8 @@ import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
|
||||
# ============================================================
|
||||
# ExprGenBase - ExprGenMixin 拆分(阶段 D):表达式基础工具(类型判断/指针层级/coerce)
|
||||
#
|
||||
# 最底层 Base(ExprGenMixin/Const/Fstr/Ops/Cdef/Name/Attr/Cls 均 1 级继承本类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenBase:
|
||||
novirtual class ExprGenBase:
|
||||
"""表达式基础工具(类型判断/指针层级/coerce)"""
|
||||
|
||||
# --- docstring 登记表字段(__doc__ 魔法属性支持)---
|
||||
@@ -44,8 +39,7 @@ class ExprGenBase:
|
||||
# ============================================================
|
||||
def get_func_name(self, func_node: ast.AST*) -> str:
|
||||
"""从函数节点提取函数名"""
|
||||
if func_node is None:
|
||||
return None
|
||||
if func_node is None: return None
|
||||
k: int = func_node.kind()
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(func_node)
|
||||
@@ -60,13 +54,11 @@ class ExprGenBase:
|
||||
def escape_llvm_string(self, pool: memhub.MemBuddy*,
|
||||
src: str) -> str:
|
||||
"""将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """
|
||||
if src is None:
|
||||
return None
|
||||
if src is None: return None
|
||||
slen: sizet = string.strlen(src)
|
||||
alloc_size: sizet = 4 * slen + 8
|
||||
buf: str = pool.alloc(alloc_size)
|
||||
if buf is None:
|
||||
return None
|
||||
if buf is None: return None
|
||||
pos: sizet = 0
|
||||
buf[pos] = 'c'
|
||||
pos += 1
|
||||
@@ -114,8 +106,7 @@ class ExprGenBase:
|
||||
# ============================================================
|
||||
def get_llvm_float_bits(self, ty: llvmlite.LLVMType*) -> int:
|
||||
"""获取 LLVM 浮点类型的位宽,非浮点类型返回 0"""
|
||||
if ty is None:
|
||||
return 0
|
||||
if ty is None: return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Float(bits):
|
||||
return bits
|
||||
@@ -128,8 +119,7 @@ class ExprGenBase:
|
||||
# ============================================================
|
||||
def is_ptr_type(self, ty: llvmlite.LLVMType*) -> int:
|
||||
"""检查 ty 是否是 Ptr 类型,返回 1=是, 0=否"""
|
||||
if ty is None:
|
||||
return 0
|
||||
if ty is None: return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Ptr(pointee):
|
||||
return 1
|
||||
@@ -166,15 +156,11 @@ class ExprGenBase:
|
||||
# ============================================================
|
||||
def _is_zero_int_literal(self, node: ast.AST*) -> int:
|
||||
"""判断节点是否为整数字面量 0,返回 1=是 / 0=否"""
|
||||
if node is None:
|
||||
return 0
|
||||
if node.kind() != ast.ASTKind.Constant:
|
||||
return 0
|
||||
if node is None: return 0
|
||||
if node.kind() != ast.ASTKind.Constant: return 0
|
||||
cn: ast.Constant* = ast.Constant*(node)
|
||||
if cn is None or cn.const_kind != ast.CONST_INT:
|
||||
return 0
|
||||
if cn.int_val == 0:
|
||||
return 1
|
||||
if cn is None or cn.const_kind != ast.CONST_INT: return 0
|
||||
if cn.int_val == 0: return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# is_array_type - 检查类型是否为 Array
|
||||
@@ -183,8 +169,7 @@ class ExprGenBase:
|
||||
# ============================================================
|
||||
def is_array_type(self, ty: llvmlite.LLVMType*) -> int:
|
||||
"""检查 ty 是否是 Array 类型,返回 1=是, 0=否"""
|
||||
if ty is None:
|
||||
return 0
|
||||
if ty is None: return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Array(_, _):
|
||||
return 1
|
||||
@@ -245,22 +230,16 @@ class ExprGenBase:
|
||||
trans: HT.Translator*,
|
||||
sub_node: ast.AST*) -> int:
|
||||
"""判断下标基座是否为 list[T] 变量(1=是)"""
|
||||
if sub_node is None or trans is None:
|
||||
return 0
|
||||
if sub_node is None or trans is None: return 0
|
||||
sub: ast.Subscript* = ast.Subscript*(sub_node)
|
||||
if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name:
|
||||
return 0
|
||||
if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return 0
|
||||
nm: ast.Name* = ast.Name*(sub.value)
|
||||
if nm.id is None:
|
||||
return 0
|
||||
if nm.id is None: return 0
|
||||
alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return 0
|
||||
if self.is_ptr_type(alloca.Ty) == 0:
|
||||
return 0
|
||||
if alloca is None or alloca.Ty is None: return 0
|
||||
if self.is_ptr_type(alloca.Ty) == 0: return 0
|
||||
pointee: llvmlite.LLVMType* = alloca.Ty.Pointee
|
||||
if pointee is None:
|
||||
return 0
|
||||
if pointee is None: return 0
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Ptr(inner_ty):
|
||||
lsn_ls: str = None
|
||||
@@ -281,22 +260,16 @@ class ExprGenBase:
|
||||
trans: HT.Translator*,
|
||||
sub_node: ast.AST*) -> str:
|
||||
"""解析下标基座变量的结构体类名(无则 None)"""
|
||||
if sub_node is None or trans is None:
|
||||
return None
|
||||
if sub_node is None or trans is None: return None
|
||||
sub: ast.Subscript* = ast.Subscript*(sub_node)
|
||||
if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name:
|
||||
return None
|
||||
if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return None
|
||||
nm: ast.Name* = ast.Name*(sub.value)
|
||||
if nm.id is None:
|
||||
return None
|
||||
if nm.id is None: return None
|
||||
alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return None
|
||||
if self.is_ptr_type(alloca.Ty) == 0:
|
||||
return None
|
||||
if alloca is None or alloca.Ty is None: return None
|
||||
if self.is_ptr_type(alloca.Ty) == 0: return None
|
||||
pointee: llvmlite.LLVMType* = alloca.Ty.Pointee
|
||||
if pointee is None:
|
||||
return None
|
||||
if pointee is None: return None
|
||||
if self.is_ptr_type(pointee) != 0:
|
||||
inner: llvmlite.LLVMType* = pointee.Pointee
|
||||
if inner is not None:
|
||||
@@ -316,17 +289,13 @@ class ExprGenBase:
|
||||
trans: HT.Translator*,
|
||||
sub_node: ast.AST*) -> int:
|
||||
"""下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)"""
|
||||
if self._is_list_subscript_base(pool, trans, sub_node) != 0:
|
||||
return 1
|
||||
if self._is_list_subscript_base(pool, trans, sub_node) != 0: return 1
|
||||
cls_ugi: str = self._sub_base_class_name(pool, trans, sub_node)
|
||||
if cls_ugi is None:
|
||||
return 0
|
||||
if cls_ugi is None: return 0
|
||||
lookup_ugi: str = pool.alloc(128)
|
||||
if lookup_ugi is None:
|
||||
return 0
|
||||
if lookup_ugi is None: return 0
|
||||
viperlib.snprintf(lookup_ugi, 128, "%s.__getitem__", cls_ugi)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_ugi) is not None:
|
||||
return 1
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_ugi) is not None: return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _deref_if_ptr_ptr - 如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用
|
||||
@@ -338,19 +307,14 @@ class ExprGenBase:
|
||||
def _deref_if_ptr_ptr(self, builder: llvmlite.IRBuilder*,
|
||||
obj_ptr: llvmlite.Value*) -> llvmlite.Value*:
|
||||
"""如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针"""
|
||||
if obj_ptr is None or obj_ptr.Ty is None:
|
||||
return obj_ptr
|
||||
if self.is_ptr_type(obj_ptr.Ty) == 0:
|
||||
return obj_ptr
|
||||
if obj_ptr is None or obj_ptr.Ty is None: return obj_ptr
|
||||
if self.is_ptr_type(obj_ptr.Ty) == 0: return obj_ptr
|
||||
pointee: llvmlite.LLVMType* = obj_ptr.Ty.Pointee
|
||||
if pointee is None:
|
||||
return obj_ptr
|
||||
if self.is_ptr_type(pointee) == 0:
|
||||
return obj_ptr
|
||||
if pointee is None: return obj_ptr
|
||||
if self.is_ptr_type(pointee) == 0: return obj_ptr
|
||||
# obj_ptr 是 Ptr(Ptr(...)),load 解引用
|
||||
loaded: llvmlite.Value* = llvmlite.build_load(builder, pointee, obj_ptr)
|
||||
if loaded is None:
|
||||
return obj_ptr
|
||||
if loaded is None: return obj_ptr
|
||||
return loaded
|
||||
# ============================================================
|
||||
# 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si
|
||||
@@ -369,8 +333,7 @@ class ExprGenBase:
|
||||
|
||||
node: AST 节点(用于错误定位),可为 None
|
||||
"""
|
||||
if val is None or target_ty is None:
|
||||
return val
|
||||
if val is None or target_ty is None: return val
|
||||
# 函数 → 指针: bitcast(如 CreateThread(..., _thread_alloc_free, ...) 传函数指针)
|
||||
# 函数 Value 的 Ty 是 Func,既不是整数也不是指针,需在整数/浮点转换之前处理
|
||||
match val.Ty:
|
||||
@@ -397,12 +360,8 @@ class ExprGenBase:
|
||||
# 属标准 C 空指针用法,须放行而非报 CastError。先拓宽到 i64
|
||||
# (inttoptr 要求同宽,对齐 MatchGenMixin 模式),再 inttoptr 成空指针。
|
||||
if val.IsConst == 1 and val.IntVal == 0:
|
||||
return llvmlite.build_inttoptr(
|
||||
builder, llvmlite.const_int64(builder.Pool, 0), target_ty)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
"整数隐式转指针已禁止:必须显式强转为指针(如 t.CPtr(x))才能把整数赋给指针类型",
|
||||
"CastError")
|
||||
return llvmlite.build_inttoptr(builder, llvmlite.const_int64(builder.Pool, 0), target_ty)
|
||||
self.Gen.TypeGenErr.fatal_error(node, "整数隐式转指针已禁止:必须显式强转为指针(如 t.CPtr(x))才能把整数赋给指针类型", "CastError")
|
||||
return val
|
||||
# 指针 → 整数: ptrtoint(当目标明确是整数而非指针时)
|
||||
# 注意: target_bits == 8 时跳过 ptrtoint,走后面的 build_load 解引用首字符
|
||||
@@ -434,10 +393,7 @@ class ExprGenBase:
|
||||
target_max_u: uint64 = (uint64(1) << target_bits) - 1
|
||||
if uint64(val.IntVal) > target_max_u:
|
||||
max_print: int64 = int64(target_max_u)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"窄化截断溢出:常量 {val.IntVal} 超出目标类型 {target_bits} 位范围 [0, {max_print}],赋值将被静默截断",
|
||||
"OverflowError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"窄化截断溢出:常量 {val.IntVal} 超出目标类型 {target_bits} 位范围 [0, {max_print}],赋值将被静默截断", "OverflowError")
|
||||
return llvmlite.build_trunc(builder, val, target_ty)
|
||||
# 浮点转换
|
||||
val_fbits: int = self.get_llvm_float_bits(val.Ty)
|
||||
@@ -463,19 +419,16 @@ class ExprGenBase:
|
||||
if self.is_ptr_type(val.Ty) == 0 and self.is_ptr_type(target_ty) != 0:
|
||||
vk_agg: int = val.Ty.kind()
|
||||
if vk_agg == llvmlite.LLVMType.Struct or vk_agg == llvmlite.LLVMType.Array:
|
||||
tmp_agg: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(
|
||||
builder, val.Ty)
|
||||
tmp_agg: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, val.Ty)
|
||||
if tmp_agg is not None:
|
||||
llvmlite.build_store(builder, val, tmp_agg)
|
||||
match target_ty:
|
||||
case llvmlite.LLVMType.Ptr(pointee_agg):
|
||||
if self.Gen.AssignGen._stg_ty_equal(
|
||||
builder.Pool, pointee_agg, val.Ty) != 0:
|
||||
if self.Gen.AssignGen._stg_ty_equal(builder.Pool, pointee_agg, val.Ty) != 0:
|
||||
return tmp_agg
|
||||
case _:
|
||||
pass
|
||||
bc_agg: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, tmp_agg, target_ty)
|
||||
bc_agg: llvmlite.Value* = llvmlite.build_bitcast(builder, tmp_agg, target_ty)
|
||||
if bc_agg is not None:
|
||||
return bc_agg
|
||||
return tmp_agg
|
||||
@@ -504,8 +457,7 @@ class ExprGenBase:
|
||||
trans 供 _node_type_unsigned 经 SymTab 解析变量注解的符号性(Name/
|
||||
Subscript 形态必需);省略则仅能识别显式 t.CUIntXXT 强转。
|
||||
"""
|
||||
if val is None or val.Ty is None:
|
||||
return 0
|
||||
if val is None or val.Ty is None: return 0
|
||||
return self.Gen.ExprGenOps.should_zext_widen(pool, val, None, node, trans)
|
||||
|
||||
# translate_ptr_arith:指针算术 ptr±int,用 getelementptr(按 pointee 元素大小缩放索引,对齐 TPC ExprGen.emit_binary_op / HandlesAugAssign.py);数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0),避免以整个数组为步长
|
||||
@@ -515,8 +467,7 @@ class ExprGenBase:
|
||||
int_val: llvmlite.Value*,
|
||||
op: int) -> llvmlite.Value*:
|
||||
"""指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)"""
|
||||
if ptr_val is None or int_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
if ptr_val is None or int_val is None or ptr_val.Ty is None: return None
|
||||
# 提取 pointee 类型(非指针 → 不处理返回 None)
|
||||
elem_ty: llvmlite.LLVMType* = None
|
||||
match ptr_val.Ty:
|
||||
@@ -524,19 +475,15 @@ class ExprGenBase:
|
||||
elem_ty = pointee
|
||||
case _:
|
||||
return None
|
||||
if elem_ty is None:
|
||||
return None
|
||||
if elem_ty is None: return None
|
||||
# 索引统一到 i64(对齐 TPC zext 到 i64)
|
||||
i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool)
|
||||
idx: llvmlite.Value* = self.coerce_to_type(builder, int_val, i64_ty, None)
|
||||
if idx is None:
|
||||
return None
|
||||
if idx is None: return None
|
||||
# ptr - int → 负索引(LLVM GEP 索引为加法语义)
|
||||
if op == ast.OpKind.Sub:
|
||||
neg_idx: llvmlite.Value* = llvmlite.build_sub(
|
||||
builder, llvmlite.const_int64(pool, 0), idx)
|
||||
if neg_idx is None:
|
||||
return None
|
||||
neg_idx: llvmlite.Value* = llvmlite.build_sub(builder, llvmlite.const_int64(pool, 0), idx)
|
||||
if neg_idx is None: return None
|
||||
idx = neg_idx
|
||||
# 数组 pointee → 先 decay 为元素指针(getelementptr [N x ty], [N x ty]* %p, i32 0, i32 0)
|
||||
if self.is_array_type(elem_ty) != 0:
|
||||
@@ -548,16 +495,13 @@ class ExprGenBase:
|
||||
return None
|
||||
if inner_ty is None:
|
||||
return None
|
||||
decayed: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0))
|
||||
if decayed is None:
|
||||
return None
|
||||
decayed: llvmlite.Value* = llvmlite.build_gep_array(builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0))
|
||||
if decayed is None: return None
|
||||
return llvmlite.build_gep(builder, inner_ty, decayed, idx)
|
||||
return llvmlite.build_gep(builder, elem_ty, ptr_val, idx)
|
||||
def InitExprGen(self) -> int:
|
||||
"""初始化 ExprGen 族字段(构造时由 Generator 调用)"""
|
||||
if self is None:
|
||||
return 1
|
||||
if self is None: return 1
|
||||
self.DocKeys = None
|
||||
self.DocValues = None
|
||||
self.DocCount = 0
|
||||
|
||||
@@ -19,37 +19,27 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
# ============================================================
|
||||
# ExprGenCdef - ExprGenMixin 拆分(阶段 D):跨模块 CDefine 查找
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
"""跨模块 CDefine 查找"""
|
||||
|
||||
# _build_source_path_from_sha1:通过 SHA1 从 StubMerger 全局存储器构建源 .vp/.py 文件路径(.vpi 未生成时回退读源 .py);rel_path 以 "lib/" 开头 → {Config.SourceDir}/{rel_path},其他 → {Config.IncludesDir}/{rel_path}。返回 stdlib.malloc 分配的路径字符串(调用者负责 free),失败返回 None
|
||||
def _build_source_path_from_sha1(self, sha1: str) -> str:
|
||||
"""通过 SHA1 从全局存储器构建源 .py 文件路径"""
|
||||
if sha1 is None:
|
||||
return None
|
||||
if Config.IncludesDir is None:
|
||||
return None
|
||||
if sha1 is None: return None
|
||||
if Config.IncludesDir is None: return None
|
||||
# 从 StubMerger 全局存储器获取相对路径数组
|
||||
rel_arr_ptr: bytes = StubMergerStore.GetSha1StoreRelArrPtr()
|
||||
count: int = StubMergerStore.GetSha1StoreCount()
|
||||
if rel_arr_ptr is None or count <= 0:
|
||||
return None
|
||||
if rel_arr_ptr is None or count <= 0: return None
|
||||
sha1_arr_ptr: bytes = StubMergerStore.GetSha1StoreArrPtr()
|
||||
if sha1_arr_ptr is None:
|
||||
return None
|
||||
if sha1_arr_ptr is None: return None
|
||||
# 遍历查找匹配的 SHA1
|
||||
idx_s: int = -1
|
||||
for i in range(count):
|
||||
sidx: sizet = sizet(i) * 17
|
||||
cur_sha1: str = sha1_arr_ptr + sidx
|
||||
if cur_sha1[0] == '\0':
|
||||
continue
|
||||
if cur_sha1[0] == '\0': continue
|
||||
if string.strcmp(cur_sha1, sha1) == 0:
|
||||
idx_s = i
|
||||
break
|
||||
|
||||
@@ -16,24 +16,17 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
|
||||
# ============================================================
|
||||
# docstring 登记表容量常量(与 ExprGenMixin 保持一致,本地副本避免
|
||||
# 跨模块 CDefine 查找 bug:ExprGenCls(C) 在 ExprGenMixin(M) 之前按
|
||||
# 文件序编译时,跨模块 CDefine 全局表未注册 → NameError 未定义)
|
||||
# docstring 登记表容量常量(与 ExprGenMixin 保持一致,存疑
|
||||
# ============================================================
|
||||
DOC_MAX: t.CDefine = 512
|
||||
DOC_KEY_SZ: t.CDefine = 192
|
||||
DOC_VAL_SZ: t.CDefine = 4096
|
||||
define DOC_MAX = 512
|
||||
define DOC_KEY_SZ = 192
|
||||
define DOC_VAL_SZ = 4096
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprGenCls - ExprGenMixin 拆分(阶段 D):类名推断/docstring 登记
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
"""类名推断/docstring 登记"""
|
||||
|
||||
# ============================================================
|
||||
@@ -48,40 +41,30 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
|
||||
def _extract_docstring_from_body(self, body: list[ast.AST*]*) -> str:
|
||||
"""从函数/类体提取 docstring:body[0] 为 Expr(Constant str) 时返回内容"""
|
||||
if body is None or len(body) == 0:
|
||||
return None
|
||||
if body is None or len(body) == 0: return None
|
||||
first: ast.AST* = body.get(0)
|
||||
if first is None or first.kind() != ast.ASTKind.Expr:
|
||||
return None
|
||||
if first is None or first.kind() != ast.ASTKind.Expr: return None
|
||||
ex: rawptr[ast.Expr] = rawptr[ast.Expr](first)
|
||||
if ex is None or ex.value is None or ex.value.kind() != ast.ASTKind.Constant:
|
||||
return None
|
||||
if ex is None or ex.value is None or ex.value.kind() != ast.ASTKind.Constant: return None
|
||||
cn: ast.Constant* = ast.Constant*(ex.value)
|
||||
if cn is None or cn.const_kind != ast.CONST_STR:
|
||||
return None
|
||||
if cn is None or cn.const_kind != ast.CONST_STR: return None
|
||||
return cn.str_val
|
||||
def register_docstring(self, module_sha1: str, symbol: str, doc: str) -> None:
|
||||
"""登记 docstring(key="{module_sha1}.{symbol}"),查重幂等"""
|
||||
if module_sha1 is None or symbol is None or doc is None:
|
||||
return
|
||||
if string.strlen(doc) == 0:
|
||||
return
|
||||
if module_sha1 is None or symbol is None or doc is None: return
|
||||
if string.strlen(doc) == 0: return
|
||||
if self.DocKeys is None:
|
||||
self.DocKeys = CompilerFactory.factory.PermPool.alloc(DOC_MAX * DOC_KEY_SZ)
|
||||
self.DocValues = CompilerFactory.factory.PermPool.alloc(DOC_MAX * DOC_VAL_SZ)
|
||||
if self.DocKeys is None or self.DocValues is None:
|
||||
return
|
||||
if self.DocKeys is None or self.DocValues is None: return
|
||||
string.memset(self.DocKeys, 0, DOC_MAX * DOC_KEY_SZ)
|
||||
string.memset(self.DocValues, 0, DOC_MAX * DOC_VAL_SZ)
|
||||
if self.DocCount >= DOC_MAX:
|
||||
return
|
||||
if self.DocCount >= DOC_MAX: return
|
||||
ml: sizet = string.strlen(module_sha1)
|
||||
sl: sizet = string.strlen(symbol)
|
||||
key_buf: bytes = stdlib.malloc(ml + sl + 2)
|
||||
if key_buf is None:
|
||||
return
|
||||
if key_buf is None: return
|
||||
viperlib.snprintf(key_buf, ml + sl + 2, "%s.%s", module_sha1, symbol)
|
||||
i: int
|
||||
for i in range(self.DocCount):
|
||||
if string.strcmp(self.DocKeys + i * DOC_KEY_SZ, key_buf) == 0:
|
||||
stdlib.free(key_buf)
|
||||
@@ -92,15 +75,12 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
stdlib.free(key_buf)
|
||||
def lookup_docstring(self, module_sha1: str, symbol: str) -> str:
|
||||
"""查找 docstring 内容(key="{module_sha1}.{symbol}"),未找到返回 None"""
|
||||
if self.DocKeys is None or module_sha1 is None or symbol is None:
|
||||
return None
|
||||
if self.DocKeys is None or module_sha1 is None or symbol is None: return None
|
||||
ml: sizet = string.strlen(module_sha1)
|
||||
sl: sizet = string.strlen(symbol)
|
||||
key_buf: bytes = stdlib.malloc(ml + sl + 2)
|
||||
if key_buf is None:
|
||||
return None
|
||||
if key_buf is None: return None
|
||||
viperlib.snprintf(key_buf, ml + sl + 2, "%s.%s", module_sha1, symbol)
|
||||
i: int
|
||||
for i in range(self.DocCount):
|
||||
if string.strcmp(self.DocKeys + i * DOC_KEY_SZ, key_buf) == 0:
|
||||
stdlib.free(key_buf)
|
||||
@@ -109,16 +89,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
def extract_module_docstrings(self, tree: ast.AST*, module_sha1: str) -> None:
|
||||
"""扫描模块 AST:登记模块级函数/类/方法的 docstring(幂等)"""
|
||||
if tree is None or module_sha1 is None:
|
||||
return
|
||||
if tree is None or module_sha1 is None: return
|
||||
ch: list[ast.AST*]* = tree.children
|
||||
if ch is None:
|
||||
return
|
||||
if ch is None: return
|
||||
cn: sizet = len(ch)
|
||||
for ci in range(cn):
|
||||
child: ast.AST* = ch.get(ci)
|
||||
if child is None:
|
||||
continue
|
||||
if child is None: continue
|
||||
kd: int = child.kind()
|
||||
if kd == ast.ASTKind.FunctionDef:
|
||||
fd: ast.FunctionDef* = ast.FunctionDef*(child)
|
||||
@@ -129,8 +106,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
self.register_docstring(module_sha1, fd.name, fdoc)
|
||||
elif kd == ast.ASTKind.ClassDef:
|
||||
cd: ast.ClassDef* = ast.ClassDef*(child)
|
||||
if cd is None or cd.name is None:
|
||||
continue
|
||||
if cd is None or cd.name is None: continue
|
||||
cd_body0: list[ast.AST*]* = cd.children
|
||||
cdoc: str = self._extract_docstring_from_body(cd_body0)
|
||||
if cdoc is not None:
|
||||
@@ -141,11 +117,9 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
cbn: sizet = len(cd_body)
|
||||
for mi in range(cbn):
|
||||
m: ast.AST* = cd_body.get(mi)
|
||||
if m is None or m.kind() != ast.ASTKind.FunctionDef:
|
||||
continue
|
||||
if m is None or m.kind() != ast.ASTKind.FunctionDef: continue
|
||||
mfd: ast.FunctionDef* = ast.FunctionDef*(m)
|
||||
if mfd is None or mfd.name is None:
|
||||
continue
|
||||
if mfd is None or mfd.name is None: continue
|
||||
mdoc: str = self._extract_docstring_from_body(mfd.children)
|
||||
if mdoc is not None:
|
||||
cl_nl: sizet = string.strlen(cd.name)
|
||||
@@ -161,10 +135,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
|
||||
判定顺序:本地变量(函数变量)→ 结构体类(含跨模块预注册)→ 模块名。
|
||||
"""
|
||||
if trans is None or name_id is None or out_mod is None or out_sym is None:
|
||||
return 0
|
||||
if trans.ModuleSha1 is None:
|
||||
return 0
|
||||
if trans is None or name_id is None or out_mod is None or out_sym is None: return 0
|
||||
if trans.ModuleSha1 is None: return 0
|
||||
# 1. 本地变量(函数变量/全局变量)
|
||||
if self.Gen.VarGen.lookup_var(trans.SymTab, name_id) is not None:
|
||||
string.strcpy(out_mod, trans.ModuleSha1)
|
||||
@@ -201,21 +173,17 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
remote.RemoteClass.remote_method / LocalClass.local_method 等。
|
||||
最左 Name 判定:模块名 → 该模块 sha1;变量/类 → 类所属模块 sha1。
|
||||
"""
|
||||
if trans is None or at is None or out_mod is None or out_sym is None:
|
||||
return 0
|
||||
if trans.ModuleSha1 is None:
|
||||
return 0
|
||||
if trans is None or at is None or out_mod is None or out_sym is None: return 0
|
||||
if trans.ModuleSha1 is None: return 0
|
||||
# 收集 Attribute 链(最外层 attr 在前)
|
||||
DOC_CHAIN_MAX: int = 8
|
||||
items: bytes = stdlib.malloc(DOC_CHAIN_MAX * 128)
|
||||
if items is None:
|
||||
return 0
|
||||
if items is None: return 0
|
||||
n_items: int = 0
|
||||
cur: ast.AST* = (ast.AST*)(at)
|
||||
while cur is not None and cur.kind() == ast.ASTKind.Attribute and n_items < DOC_CHAIN_MAX:
|
||||
cat: ast.Attribute* = ast.Attribute*(cur)
|
||||
if cat.attr is None:
|
||||
break
|
||||
if cat.attr is None: break
|
||||
string.strcpy(items + n_items * 128, cat.attr)
|
||||
n_items += 1
|
||||
cur = cat.value
|
||||
@@ -244,7 +212,6 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
stdlib.free(items)
|
||||
return 1
|
||||
total: sizet = 0
|
||||
j: int
|
||||
for j in range(n_items):
|
||||
total += string.strlen(items + j * 128) + 1
|
||||
sym_buf: bytes = stdlib.malloc(total + 1)
|
||||
@@ -304,27 +271,22 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
node: ast.AST*,
|
||||
trans: HT.Translator*) -> str:
|
||||
"""从表达式推断结构体类名,无法推断返回 None"""
|
||||
if node is None or trans is None:
|
||||
return None
|
||||
if node is None or trans is None: return None
|
||||
k: int = node.kind()
|
||||
# Call: 类实例化 / 方法调用
|
||||
if k == ast.ASTKind.Call:
|
||||
cl: ast.Call* = ast.Call*(node)
|
||||
if cl is None or cl.func is None:
|
||||
return None
|
||||
if cl is None or cl.func is None: return None
|
||||
if cl.func.kind() == ast.ASTKind.Name:
|
||||
cand: str = (ast.Name*(cl.func)).id
|
||||
if cand is None:
|
||||
return None
|
||||
if self.Gen.StructGen.find_struct(cand) is not None:
|
||||
return cand
|
||||
if cand is None: return None
|
||||
if self.Gen.StructGen.find_struct(cand) is not None: return cand
|
||||
return None
|
||||
if cl.func.kind() == ast.ASTKind.Attribute:
|
||||
# 方法调用 a.cross(b):vpi 返回注解缓存精确解析返回类名
|
||||
# (方法可返回非同类对象,如 Transform.world_position → 'Vec3')。
|
||||
ca: ast.Attribute* = ast.Attribute*(cl.func)
|
||||
if ca is None or ca.attr is None or ca.value is None:
|
||||
return None
|
||||
if ca is None or ca.attr is None or ca.value is None: return None
|
||||
# 模块级函数调用(Module.func()):接收者是已导入模块名而非类对象
|
||||
if ca.value.kind() == ast.ASTKind.Name:
|
||||
mod_nm2: str = (ast.Name*(ca.value)).id
|
||||
@@ -344,10 +306,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
if ret_cls2 is not None:
|
||||
return ret_cls2
|
||||
obj_cls: str = self.infer_expr_class(pool, mod, ca.value, trans)
|
||||
if obj_cls is None:
|
||||
return None
|
||||
if self._cls_has_dunder(pool, mod, obj_cls, ca.attr) == 0:
|
||||
return None
|
||||
if obj_cls is None: return None
|
||||
if self._cls_has_dunder(pool, mod, obj_cls, ca.attr) == 0: return None
|
||||
cls_sha1: str = self.Gen.StructGen.get_struct_sha1(obj_cls)
|
||||
if cls_sha1 is None and trans.ModuleSha1 is not None:
|
||||
cls_sha1 = trans.ModuleSha1
|
||||
@@ -359,8 +319,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
temp_dir = self.Gen.CallGenBase.TempDir
|
||||
if temp_dir is not None:
|
||||
VpiReader._ensure_vpi_ret_annot_loaded(cls_sha1, temp_dir)
|
||||
annot_ret: str = VpiReader._lookup_vpi_ret_annot(
|
||||
cls_sha1, obj_cls, ca.attr)
|
||||
annot_ret: str = VpiReader._lookup_vpi_ret_annot(cls_sha1, obj_cls, ca.attr)
|
||||
if annot_ret is not None:
|
||||
ret_cls = self._extract_annot_class_name(pool, annot_ret)
|
||||
return ret_cls
|
||||
@@ -368,15 +327,11 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
# Name: 源变量注解
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(node)
|
||||
if nm is None or nm.id is None:
|
||||
return None
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is None:
|
||||
return None
|
||||
if nm is None or nm.id is None: return None
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if ve is None: return None
|
||||
acn_n: str = self.Gen.VarGen.var_annot_class_name(ve)
|
||||
if acn_n is None:
|
||||
return None
|
||||
if acn_n is None: return None
|
||||
# 去模块前缀:json.JsonValue → JsonValue。AnnotClassName 可能带
|
||||
# 模块限定(extract_class_name_from_annotation 的 Attribute 分支返回
|
||||
# "memhub.MemBuddy" 形式),而 find_struct/_cls_has_dunder/
|
||||
@@ -389,25 +344,19 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
# BinOp/UnaryOp: 运算符重载返回同类对象
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp* = ast.BinOp*(node)
|
||||
if bop is None or bop.left is None:
|
||||
return None
|
||||
if bop is None or bop.left is None: return None
|
||||
dunder: str = self.Gen.ExprGenOps._binop_to_dunder(bop.op)
|
||||
if dunder is None:
|
||||
return None
|
||||
if dunder is None: return None
|
||||
lhs_cls: str = self.infer_expr_class(pool, mod, bop.left, trans)
|
||||
if lhs_cls is None or self._cls_has_dunder(pool, mod, lhs_cls, dunder) == 0:
|
||||
return None
|
||||
if lhs_cls is None or self._cls_has_dunder(pool, mod, lhs_cls, dunder) == 0: return None
|
||||
return lhs_cls
|
||||
if k == ast.ASTKind.UnaryOp:
|
||||
uop: ast.UnaryOp* = ast.UnaryOp*(node)
|
||||
if uop is None or uop.operand is None:
|
||||
return None
|
||||
if uop is None or uop.operand is None: return None
|
||||
dunder: str = self.Gen.ExprGenOps._unaryop_to_dunder(uop.op)
|
||||
if dunder is None:
|
||||
return None
|
||||
if dunder is None: return None
|
||||
opr_cls: str = self.infer_expr_class(pool, mod, uop.operand, trans)
|
||||
if opr_cls is None or self._cls_has_dunder(pool, mod, opr_cls, dunder) == 0:
|
||||
return None
|
||||
if opr_cls is None or self._cls_has_dunder(pool, mod, opr_cls, dunder) == 0: return None
|
||||
return opr_cls
|
||||
# Attribute: 字段注解类名(属性链递归,如 p = r.origin)
|
||||
if k == ast.ASTKind.Attribute:
|
||||
@@ -420,18 +369,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
# SHA1(stub 中声明)即视为存在。仅在确实存在时采用推断类名,
|
||||
# 避免把原生运算误标为类类型。
|
||||
# ============================================================
|
||||
def _cls_has_dunder(self, pool: memhub.MemBuddy*,
|
||||
mod: llvmlite.LLVMModule*,
|
||||
class_name: str, dunder: str) -> int:
|
||||
def _cls_has_dunder(self, pool: memhub.MemBuddy*, mod: llvmlite.LLVMModule*, class_name: str, dunder: str) -> int:
|
||||
"""类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1"""
|
||||
if class_name is None or dunder is None or mod is None:
|
||||
return 0
|
||||
if class_name is None or dunder is None or mod is None: return 0
|
||||
lookup_name: str = pool.alloc(128)
|
||||
if lookup_name is None:
|
||||
return 0
|
||||
if lookup_name is None: return 0
|
||||
viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None:
|
||||
return 1
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None: return 1
|
||||
# 继承链祖先查找
|
||||
mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name)
|
||||
mi: int = 1
|
||||
@@ -445,8 +389,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
return 1
|
||||
mi += 1
|
||||
# 跨模块:类有 SHA1(stub 中声明该方法)视为存在
|
||||
if self.Gen.StructGen.get_struct_sha1(class_name) is not None:
|
||||
return 1
|
||||
if self.Gen.StructGen.get_struct_sha1(class_name) is not None: return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _extract_annot_class_name - 从返回注解文本提取结构体类名
|
||||
@@ -456,17 +399,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
# CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合
|
||||
# 多候选时取首个命中段。
|
||||
# ============================================================
|
||||
def _extract_annot_class_name(self, pool: memhub.MemBuddy*,
|
||||
annot: str) -> str:
|
||||
def _extract_annot_class_name(self, pool: memhub.MemBuddy*, annot: str) -> str:
|
||||
"""从返回注解文本提取已注册结构体类名,无命中返回 None"""
|
||||
if pool is None or annot is None:
|
||||
return None
|
||||
if pool is None or annot is None: return None
|
||||
alen: sizet = string.strlen(annot)
|
||||
if alen == 0:
|
||||
return None
|
||||
if alen == 0: return None
|
||||
seg: str = pool.alloc(256)
|
||||
if seg is None:
|
||||
return None
|
||||
if seg is None: return None
|
||||
start: sizet = 0
|
||||
i: sizet
|
||||
for i in range(alen):
|
||||
|
||||
@@ -15,13 +15,8 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
|
||||
# ============================================================
|
||||
# ExprGenConst - ExprGenMixin 拆分(阶段 D):常量/全局字符串/list 字面量翻译
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
"""常量/全局字符串/list 字面量翻译"""
|
||||
|
||||
# ============================================================
|
||||
@@ -34,8 +29,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
trans: HT.Translator*) -> llvmlite.Value*:
|
||||
"""创建全局字符串常量并返回 i8* bitcast"""
|
||||
escaped: str = self.escape_llvm_string(pool, str_val)
|
||||
if escaped is None:
|
||||
return None
|
||||
if escaped is None: return None
|
||||
|
||||
slen: sizet = string.strlen(str_val)
|
||||
count: int = slen + 1
|
||||
@@ -276,13 +270,11 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
first_elem_val = self.Gen.ExprGen.translate_value(builder, pool, mod, first_elem_node, None, 0, trans)
|
||||
if first_elem_val is None or first_elem_val.Ty is None:
|
||||
# fail-fast:首元素翻译失败/Value 类型缺失,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError")
|
||||
inferred_type_name = self._infer_elem_type_from_value(pool, first_elem_val)
|
||||
if inferred_type_name is None:
|
||||
# fail-fast:首元素 Value 类型无法映射为 list 元素类型,立即终止编译
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError")
|
||||
else:
|
||||
# 空 list 无元素可推断,保持默认 str(list[str])
|
||||
inferred_type_name = "str"
|
||||
@@ -338,25 +330,21 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
string.memset(new_args, 0, 8 * 32)
|
||||
new_args[0] = sizet(pool_val)
|
||||
new_ptr: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans)
|
||||
new_ptr: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans)
|
||||
if new_ptr is not None:
|
||||
storage_ptr = new_ptr
|
||||
|
||||
# 调用 __before_init__(storage_ptr)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans)
|
||||
|
||||
# 调用 __init__(storage_ptr, pool_val, elem_size=0)
|
||||
init_args: sizet* = pool.alloc(8 * 32)
|
||||
if init_args is None:
|
||||
return None
|
||||
if init_args is None: return None
|
||||
string.memset(init_args, 0, 8 * 32)
|
||||
init_args[0] = sizet(pool_val)
|
||||
elem_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 0)
|
||||
init_args[1] = sizet(elem_size_val)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans)
|
||||
|
||||
# 对每个元素调用 append(storage_ptr, elem_val)
|
||||
if elts_count > 0:
|
||||
@@ -366,12 +354,10 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
if append_args is not None:
|
||||
string.memset(append_args, 0, 8 * 32)
|
||||
append_args[0] = sizet(first_elem_val)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans)
|
||||
|
||||
# 翻译剩余元素
|
||||
i: sizet = 1
|
||||
while i < elts_count:
|
||||
for i in range(1, elts_count):
|
||||
elem_node_i: ast.AST* = elts.get(i)
|
||||
elem_val_i: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans)
|
||||
if elem_val_i is not None:
|
||||
@@ -379,8 +365,6 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
if ap_args is not None:
|
||||
string.memset(ap_args, 0, 8 * 32)
|
||||
ap_args[0] = sizet(elem_val_i)
|
||||
self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans)
|
||||
i += 1
|
||||
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans)
|
||||
|
||||
return storage_ptr
|
||||
@@ -13,19 +13,14 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
# CDefine 查找 bug:ExprGenFstr(F) 在 ExprGenMixin(M) 之前按文件序
|
||||
# 编译时,跨模块 CDefine 全局表未注册 → NameError 未定义)
|
||||
# ============================================================
|
||||
FSTR_BUF_SIZE: t.CDefine = 1024
|
||||
FSTR_SPEC_MAX: t.CDefine = 64
|
||||
FSTR_FMT_MAX: t.CDefine = 64
|
||||
define FSTR_BUF_SIZE = 1024
|
||||
define FSTR_SPEC_MAX = 64
|
||||
define FSTR_FMT_MAX = 64
|
||||
|
||||
# ============================================================
|
||||
# ExprGenFstr - ExprGenMixin 拆分(阶段 D):f-string/格式化值翻译
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
"""f-string/格式化值翻译"""
|
||||
|
||||
# ============================================================
|
||||
@@ -41,16 +36,13 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
node: ast.AST*,
|
||||
trans: HT.Translator* = None) -> llvmlite.Value*:
|
||||
"""f-string → snprintf 生成 i8* 栈缓冲"""
|
||||
if node is None or builder is None or trans is None:
|
||||
return None
|
||||
if node is None or builder is None or trans is None: return None
|
||||
js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](node)
|
||||
if js is None or js.values is None:
|
||||
return None
|
||||
if js is None or js.values is None: return None
|
||||
|
||||
# 编译期格式串缓冲(pool 分配)
|
||||
fmt_buf: str = pool.alloc(FSTR_BUF_SIZE)
|
||||
if fmt_buf is None:
|
||||
return None
|
||||
if fmt_buf is None: return None
|
||||
fmt_buf[0] = '\0'
|
||||
|
||||
# 运行时参数链表(Value.Next 链接,与 printf 调用一致)
|
||||
@@ -62,24 +54,19 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
pn: sizet = len(parts)
|
||||
for pi in range(pn):
|
||||
part: ast.AST* = parts.get(pi)
|
||||
if part is None:
|
||||
continue
|
||||
if part is None: continue
|
||||
if part.kind() == ast.ASTKind.Constant:
|
||||
pcn: ast.Constant* = ast.Constant*(part)
|
||||
if pcn.const_kind == ast.CONST_STR and pcn.str_val is not None:
|
||||
self._fstr_append_literal(fmt_buf, pcn.str_val)
|
||||
continue
|
||||
if part.kind() != ast.ASTKind.FormattedValue:
|
||||
continue
|
||||
continue
|
||||
if part.kind() != ast.ASTKind.FormattedValue: continue
|
||||
fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part)
|
||||
if fv.value is None:
|
||||
continue
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fv.value, None, 0, trans)
|
||||
if fv.value is None: continue
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fv.value, None, 0, trans)
|
||||
if val is None:
|
||||
# fail-fast:f-string 格式化值翻译失败必须终止编译,绝不在
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError")
|
||||
continue
|
||||
# 确定 C 格式说明符(format_spec 优先,否则按值类型推断)
|
||||
c_fmt: str = None
|
||||
@@ -94,8 +81,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1:
|
||||
string.strcat(fmt_buf, c_fmt)
|
||||
# 转换参数类型(i8/i16→i32、bool→i32、f32→f64)
|
||||
cast_val: llvmlite.Value* = self._fstr_cast_value(
|
||||
builder, pool, val, c_fmt, fv.value, trans)
|
||||
cast_val: llvmlite.Value* = self._fstr_cast_value(builder, pool, val, c_fmt, fv.value, trans)
|
||||
if cast_val is None:
|
||||
cast_val = val
|
||||
cast_val.Next = None
|
||||
@@ -125,12 +111,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
arg_head: llvmlite.Value* = None
|
||||
arg_tail: llvmlite.Value* = None
|
||||
arg_count: int = 0
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fv.value, None, 0, trans)
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fv.value, None, 0, trans)
|
||||
if val is None:
|
||||
# fail-fast:裸 FormattedValue 翻译失败必须终止编译,绝不在
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError")
|
||||
else:
|
||||
c_fmt: str = None
|
||||
if fv.format_spec is not None:
|
||||
@@ -142,8 +126,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式无法推断(值类型缺失)", "TypeError")
|
||||
if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1:
|
||||
string.strcat(fmt_buf, c_fmt)
|
||||
cast_val: llvmlite.Value* = self._fstr_cast_value(
|
||||
builder, pool, val, c_fmt, fv.value, trans)
|
||||
cast_val: llvmlite.Value* = self._fstr_cast_value(builder, pool, val, c_fmt, fv.value, trans)
|
||||
if cast_val is None:
|
||||
cast_val = val
|
||||
cast_val.Next = None
|
||||
@@ -166,20 +149,15 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
# 空 f-string(f"")→ 空字符串常量
|
||||
return self.Gen.ExprGenConst.create_global_string(builder, pool, mod, "", trans)
|
||||
# 格式串 → 全局字符串常量(i8*)
|
||||
fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fmt_buf, trans)
|
||||
if fmt_ptr is None:
|
||||
return None
|
||||
fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(builder, pool, mod, fmt_buf, trans)
|
||||
if fmt_ptr is None: return None
|
||||
# 固定栈缓冲 [FSTR_BUF_SIZE x i8],GEP(0,0) 取 i8*
|
||||
buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, FSTR_BUF_SIZE)
|
||||
buf_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, buf_ty)
|
||||
if buf_alloca is None:
|
||||
return None
|
||||
if buf_alloca is None: return None
|
||||
zero_i32: llvmlite.Value* = llvmlite.const_int32(pool, 0)
|
||||
buf_ptr: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, buf_ty, i8_ty, buf_alloca, zero_i32)
|
||||
if buf_ptr is None:
|
||||
return None
|
||||
buf_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, buf_ty, i8_ty, buf_alloca, zero_i32)
|
||||
if buf_ptr is None: return None
|
||||
# snprintf(buf, FSTR_BUF_SIZE, fmt, args...)
|
||||
size_val: llvmlite.Value* = llvmlite.const_int64(pool, FSTR_BUF_SIZE)
|
||||
buf_ptr.Next = size_val
|
||||
@@ -192,12 +170,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
def _fstr_append_literal(self, fmt_buf: str,
|
||||
lit: str) -> None:
|
||||
"""追加字面量到格式串(% 转义为 %%)"""
|
||||
if fmt_buf is None or lit is None:
|
||||
return
|
||||
if fmt_buf is None or lit is None: return
|
||||
cur_len: sizet = string.strlen(fmt_buf)
|
||||
rem: sizet = FSTR_BUF_SIZE - 1 - cur_len
|
||||
if rem == 0:
|
||||
return
|
||||
if rem == 0: return
|
||||
src_len: sizet = string.strlen(lit)
|
||||
si: sizet = 0
|
||||
while si < src_len and rem > 0:
|
||||
@@ -238,18 +214,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
sk: int = spec_node.kind()
|
||||
if sk == ast.ASTKind.JoinedStr:
|
||||
jss: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](spec_node)
|
||||
if jss.values is None:
|
||||
return None
|
||||
if jss.values is None: return None
|
||||
vn: sizet = len(jss.values)
|
||||
for vi in range(vn):
|
||||
vpart: ast.AST* = jss.values.get(vi)
|
||||
if vpart is None:
|
||||
continue
|
||||
if vpart.kind() != ast.ASTKind.Constant:
|
||||
return None
|
||||
if vpart is None: continue
|
||||
if vpart.kind() != ast.ASTKind.Constant: return None
|
||||
vcn: ast.Constant* = ast.Constant*(vpart)
|
||||
if vcn.const_kind != ast.CONST_STR or vcn.str_val is None:
|
||||
return None
|
||||
if vcn.const_kind != ast.CONST_STR or vcn.str_val is None: return None
|
||||
if string.strlen(spec) + string.strlen(vcn.str_val) < FSTR_SPEC_MAX - 1:
|
||||
string.strcat(spec, vcn.str_val)
|
||||
elif sk == ast.ASTKind.Constant:
|
||||
@@ -257,11 +229,9 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
if cn.const_kind != ast.CONST_STR or cn.str_val is None:
|
||||
return None
|
||||
string.strncpy(spec, cn.str_val, FSTR_SPEC_MAX - 1)
|
||||
else:
|
||||
return None
|
||||
else: return None
|
||||
slen: sizet = string.strlen(spec)
|
||||
if slen == 0:
|
||||
return None
|
||||
if slen == 0: return None
|
||||
|
||||
# 2. 逐段解析: [fill]align / sign / # / 0 / width / , / .precision / type
|
||||
pos: sizet = 0
|
||||
@@ -279,8 +249,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
c_flags: str = pool.alloc(FSTR_FMT_MAX)
|
||||
c_width: str = pool.alloc(32)
|
||||
c_prec: str = pool.alloc(32)
|
||||
if c_flags is None or c_width is None or c_prec is None:
|
||||
return None
|
||||
if c_flags is None or c_width is None or c_prec is None: return None
|
||||
c_flags[0] = '\0'
|
||||
c_width[0] = '\0'
|
||||
c_prec[0] = '\0'
|
||||
@@ -329,30 +298,24 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
if pos < slen:
|
||||
fmt_type = spec[pos]
|
||||
pos += 1
|
||||
if pos != slen:
|
||||
return None # 多余字符无法解析
|
||||
if pos != slen: return None # 多余字符无法解析
|
||||
|
||||
# 3. 长度修饰(按值类型位宽)
|
||||
len_mod: str = pool.alloc(4)
|
||||
if len_mod is None:
|
||||
return None
|
||||
if len_mod is None: return None
|
||||
len_mod[0] = '\0'
|
||||
ibits: int = self.Gen.ExprGenBase.get_llvm_type_bits(val.Ty)
|
||||
# 32 位**不写**长度修饰符(N14):`{x:08X}` 的实参是 i32,此前推导出
|
||||
# `l` → 格式串 `%08lX`(long)与实参宽度不符(LP64 下 printf 按 64 位
|
||||
# 读参 → 变参错位)。与同文件无 spec 路径 `_fstr_infer_c_fmt`(32 位用
|
||||
# `%u/%d`)以及 TPC 侧 HandlesExprFormat.py 保持一致。
|
||||
if ibits == 64:
|
||||
string.strcpy(len_mod, "ll")
|
||||
elif ibits == 16:
|
||||
string.strcpy(len_mod, "h")
|
||||
elif ibits == 8:
|
||||
string.strcpy(len_mod, "hh")
|
||||
if ibits == 64: string.strcpy(len_mod, "ll")
|
||||
elif ibits == 16: string.strcpy(len_mod, "h")
|
||||
elif ibits == 8: string.strcpy(len_mod, "hh")
|
||||
|
||||
# 4. 组装 C 格式串
|
||||
out: str = pool.alloc(FSTR_FMT_MAX)
|
||||
if out is None:
|
||||
return None
|
||||
if out is None: return None
|
||||
out[0] = '\0'
|
||||
string.strcat(out, "%")
|
||||
string.strcat(out, c_flags)
|
||||
@@ -411,18 +374,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
arg_node: ast.AST*,
|
||||
trans: HT.Translator*) -> str:
|
||||
"""无 format_spec 时按值类型推断 C printf 格式(对齐 TPC 无 spec 分支,带 % 前缀)"""
|
||||
if val is None or pool is None:
|
||||
return None
|
||||
if val is None or pool is None: return None
|
||||
out: str = pool.alloc(16)
|
||||
if out is None:
|
||||
return None
|
||||
if out is None: return None
|
||||
out[0] = '\0'
|
||||
ibits: int = self.Gen.ExprGenBase.get_llvm_type_bits(val.Ty)
|
||||
fbits: int = self.Gen.ExprGenBase.get_llvm_float_bits(val.Ty)
|
||||
if ibits == 1:
|
||||
return "%d" # bool
|
||||
if ibits == 8:
|
||||
return "%c" # 字符
|
||||
if ibits == 1: return "%d" # bool
|
||||
if ibits == 8: return "%c" # 字符
|
||||
if ibits != 0:
|
||||
if self.Gen.ExprGenOps._node_type_unsigned(pool, arg_node, trans) != 0:
|
||||
if ibits == 64:
|
||||
|
||||
@@ -15,9 +15,9 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
# DOC_KEY_SZ: key "{module_sha1}.{symbol}" 缓冲宽度
|
||||
# DOC_VAL_SZ: docstring 内容缓冲宽度
|
||||
# ============================================================
|
||||
DOC_MAX: t.CDefine = 512
|
||||
DOC_KEY_SZ: t.CDefine = 192
|
||||
DOC_VAL_SZ: t.CDefine = 4096
|
||||
define DOC_MAX = 512
|
||||
define DOC_KEY_SZ = 192
|
||||
define DOC_VAL_SZ = 4096
|
||||
|
||||
# ============================================================
|
||||
# f-string 翻译常量(对齐 TPC HandlesExprFormat)
|
||||
@@ -26,37 +26,22 @@ DOC_VAL_SZ: t.CDefine = 4096
|
||||
# FSTR_SPEC_MAX: 编译期 format_spec 解析缓冲宽度
|
||||
# FSTR_FMT_MAX: 编译期 C printf 格式串缓冲宽度
|
||||
# ============================================================
|
||||
FSTR_BUF_SIZE: t.CDefine = 1024
|
||||
FSTR_SPEC_MAX: t.CDefine = 64
|
||||
FSTR_FMT_MAX: t.CDefine = 64
|
||||
define FSTR_BUF_SIZE = 1024
|
||||
define FSTR_SPEC_MAX = 64
|
||||
define FSTR_FMT_MAX = 64
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprGenMixin - 表达式处理 Mixin(对象化 P3,wiki/14-oo-refactor.md)
|
||||
#
|
||||
# 从 HandlesExpr.vp(48 函数,无全局状态)与 HandlesExprOps.vp
|
||||
# 迁移:模块级纯函数 → 类方法(self 替代,参数保留含 builder/pool)。
|
||||
#
|
||||
# 迁移原则(与 P2 一致,行为零变化):
|
||||
# 1. 方法保留原函数签名(含 builder/pool 首参),仅函数体内
|
||||
# 本模块函数调用改为 self.xxx(...)
|
||||
# 2. 外部模块调用(HandlesExprCall.xxx / HandlesType.xxx 等)保留模块前缀
|
||||
# 3. HandlesExpr.vp / HandlesExprOps.vp 原函数保留为"委托":本地
|
||||
# 模块级单例 _g_gen(BuildPipeline/main 注入)cast 成 Generator 类型
|
||||
# 4. ExprHandle 类保留在 HandlesExpr.vp(translator handler 模式)
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprGenMixin - 表达式/常量/下标/属性访问/运算符
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
"""表达式处理 Mixin(纯方法化迁移,无状态字段)"""
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译值表达式(RHS 分派)— 模块级版本
|
||||
# ============================================================
|
||||
@@ -78,11 +63,9 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
"""
|
||||
if trans is not None:
|
||||
if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
trans.TranslateDepth += 1
|
||||
rv: llvmlite.Value* = self._translate_value_impl(
|
||||
builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx)
|
||||
rv: llvmlite.Value* = self._translate_value_impl(builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx)
|
||||
if trans is not None:
|
||||
trans.TranslateDepth -= 1
|
||||
return rv
|
||||
@@ -103,40 +86,19 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
if k == ast.ASTKind.Constant:
|
||||
rv: llvmlite.Value* = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty)
|
||||
return rv
|
||||
elif k == ast.ASTKind.Name:
|
||||
# target_ty(使用处类型:赋值目标 / 形参 / 返回)与 use_ctx(真实站点
|
||||
# 种类,仅供报文)下传给裸名翻译,供 CDefine 常量按使用处宽度物化;
|
||||
# 非常量名不受影响(见 translate_name_value)。
|
||||
return self.Gen.ExprGenName.translate_name_value(
|
||||
builder, pool, node, trans, target_ty, use_ctx)
|
||||
elif k == ast.ASTKind.BinOp:
|
||||
return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans)
|
||||
elif k == ast.ASTKind.Call:
|
||||
return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
|
||||
elif k == ast.ASTKind.Compare:
|
||||
return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.UnaryOp:
|
||||
return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.BoolOp:
|
||||
return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans)
|
||||
elif k == ast.ASTKind.Subscript:
|
||||
return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Attribute:
|
||||
return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.List:
|
||||
return self.Gen.ExprGenConst.translate_list_literal(builder, pool, mod, node, None, trans)
|
||||
elif k == ast.ASTKind.IfExp:
|
||||
return self.Gen.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Lambda:
|
||||
# 模块级委托:translate_lambda 定义在 FuncGenMixin(跨 Mixin
|
||||
# 方法不能 self. 直接调用,见 HandlesExpr.translate_lambda)
|
||||
return self.Gen.FuncGen.translate_lambda(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.JoinedStr:
|
||||
return self.Gen.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.FormattedValue:
|
||||
# 解析器对 f"{expr:spec}"(单 FormattedValue 无字面量)返回裸 FormattedValue
|
||||
# 而非 JoinedStr(见 ast/parser.vp _parse_fstring),需单独翻译
|
||||
return self.Gen.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Name: return self.Gen.ExprGenName.translate_name_value(builder, pool, node, trans, target_ty, use_ctx)
|
||||
elif k == ast.ASTKind.BinOp: return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans)
|
||||
elif k == ast.ASTKind.Call: return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
|
||||
elif k == ast.ASTKind.Compare: return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.BoolOp: return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans)
|
||||
elif k == ast.ASTKind.Subscript: return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Attribute: return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.List: return self.Gen.ExprGenConst.translate_list_literal(builder, pool, mod, node, None, trans)
|
||||
elif k == ast.ASTKind.IfExp: return self.Gen.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Lambda: return self.Gen.FuncGen.translate_lambda(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.JoinedStr: return self.Gen.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.FormattedValue: return self.Gen.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans)
|
||||
elif k == ast.ASTKind.Await:
|
||||
# 协程 await(TPV-M1):await 目标是 async 函数调用时内联翻译
|
||||
# (子帧创建 + resume 到 DONE + 取子帧 ret 存父帧 await 槽 + 父挂起),
|
||||
@@ -158,10 +120,8 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
# 全代码库无调用点使用;按 C 语义视为单目解引用(*ptr → load pointee,
|
||||
# 对齐 UnaryOp(Deref))。构造 Deref UnaryOp 复用既有翻译/错误路径。
|
||||
st: rawptr[ast.Starred] = rawptr[ast.Starred](node)
|
||||
if st is None or st.value is None:
|
||||
return None
|
||||
if st is None or st.value is None: return None
|
||||
deref_node: ast.AST* = ast.UnaryOp(pool, ast.OpKind.Deref, st.value)
|
||||
if deref_node is None:
|
||||
return None
|
||||
if deref_node is None: return None
|
||||
return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, deref_node, trans)
|
||||
return None
|
||||
@@ -10,19 +10,14 @@ import viperlib
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
|
||||
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprGenName - ExprGenMixin 拆分(阶段 D):Name/Subscript/下标访问
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
"""Name/Subscript/下标访问"""
|
||||
|
||||
def _cut_from_import_mod(self, pool: memhub.MemBuddy*,
|
||||
@@ -36,16 +31,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
对齐 ExprGenCdef._lookup_cross_module_cdefine 的截断逻辑)。
|
||||
截断到空格/冒号/NUL;raw 无效返回 None。
|
||||
"""
|
||||
if raw is None:
|
||||
return None
|
||||
if raw is None: return None
|
||||
mbl_c: sizet = 0
|
||||
while raw[mbl_c] != ' ' and raw[mbl_c] != '\0' and raw[mbl_c] != ':':
|
||||
mbl_c += 1
|
||||
if mbl_c == 0:
|
||||
return None
|
||||
if mbl_c == 0: return None
|
||||
buf_c: str = pool.alloc(mbl_c + 1)
|
||||
if buf_c is None:
|
||||
return None
|
||||
if buf_c is None: return None
|
||||
string.strncpy(buf_c, raw, mbl_c)
|
||||
buf_c[mbl_c] = '\0'
|
||||
return buf_c
|
||||
@@ -71,11 +63,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# "use of undefined value '@.str.{sha1}.N'(SysLibTest _cleanup 根因)"
|
||||
mod: llvmlite.LLVMModule* = trans.Module
|
||||
nm: ast.Name* = ast.Name*(node)
|
||||
if nm is None:
|
||||
return None
|
||||
if nm is None: return None
|
||||
nm_id: str = nm.id
|
||||
if nm_id is None:
|
||||
return None
|
||||
if nm_id is None: return None
|
||||
# CDefine 编译期常量:返回常量值(浮点 CDefine → double 常量,整数 → i32;否则 double 函数里 return 会生成 ret i32 0 报错)。注意同名变量优先——当前作用域已存在变量时不得被 CDefine 表条目遮蔽(vpi stub 注入会把依赖模块的 CDefine 注册进导入方表,可能误解析局部变量为常量),守卫与下方跨模块 CDefine 查找的 lookup_var 检查一致
|
||||
cdef_val_d: double = self.Gen.TypeGenCDef.lookup_cdefine_double(nm_id)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
@@ -95,8 +85,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 使用处宽度(经 translate_value 的 target_ty 下传;站点种类由
|
||||
# use_ctx 携带,仅供报文使用):
|
||||
# 更宽 ⇒ 就地升宽物化;更窄 ⇒ fail-fast;取不到 ⇒ 既有默认 32/64。
|
||||
uw_val: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(
|
||||
pool, node, nm_id, cdef_val_c, target_ty, use_ctx)
|
||||
uw_val: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(pool, node, nm_id, cdef_val_c, target_ty, use_ctx)
|
||||
if uw_val is not None:
|
||||
return uw_val
|
||||
return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val_c)
|
||||
@@ -114,8 +103,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 文件,且多 includes 目录下还可能触发 XMOD-CD 误报
|
||||
# (ExprGenCdef._build_source_path_from_sha1 拼错路径)。
|
||||
if self.Gen.VarGen.lookup_var(trans.SymTab, nm_id) is None:
|
||||
cdef_val: int64 = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, nm_id, trans._from_imports, trans._imported_modules, 0, node)
|
||||
cdef_val: int64 = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, nm_id, trans._from_imports, trans._imported_modules, 0, node)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
if self.Gen.TypeGenCDef.is_cdefine_str() != 0:
|
||||
cdef_sv2: str = self.Gen.TypeGenCDef.lookup_cdefine_string(nm_id)
|
||||
@@ -128,8 +116,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if self.Gen.TypeGenCDef.is_cdefine_double() != 0:
|
||||
return llvmlite.ConstFloat(pool, llvmlite.Double(pool), dchk_nm)
|
||||
# 使用处宽度同口径(跨模块 CDefine)
|
||||
uw_x: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(
|
||||
pool, node, nm_id, cdef_val, target_ty, use_ctx)
|
||||
uw_x: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(pool, node, nm_id, cdef_val, target_ty, use_ctx)
|
||||
if uw_x is not None:
|
||||
return uw_x
|
||||
return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val)
|
||||
@@ -139,21 +126,17 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# i64 全局、非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)。from-import
|
||||
# 确认名称确实来自某模块后,按后缀匹配查找该全局并加载。
|
||||
if trans is not None and trans._from_imports is not None:
|
||||
fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import(
|
||||
trans._from_imports, nm_id, 0)
|
||||
fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, nm_id, 0)
|
||||
if fi_mod_raw is not None:
|
||||
# 带源模块 SHA1 前缀精确查找,避免多模块同名全局后缀匹配串扰。
|
||||
# fi_mod_raw 非 NUL 结尾,先截断再查 SHA1(否则整串查不到退化裸名)
|
||||
fi_mod_cut: str = self._cut_from_import_mod(pool, fi_mod_raw)
|
||||
if fi_mod_cut is None:
|
||||
fi_mod_cut = fi_mod_raw
|
||||
fi_gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id)
|
||||
fi_gv: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
trans.Module, fi_gv_q)
|
||||
fi_gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id)
|
||||
fi_gv: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(trans.Module, fi_gv_q)
|
||||
if fi_gv is not None and fi_gv.Ty is not None:
|
||||
fi_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(
|
||||
pool, fi_gv.Name, fi_gv.Ty)
|
||||
fi_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(pool, fi_gv.Name, fi_gv.Ty)
|
||||
if fi_ref is not None and fi_ref.Ty is not None:
|
||||
fi_pty: llvmlite.LLVMType* = fi_ref.Ty.Pointee
|
||||
if fi_pty is not None:
|
||||
@@ -168,16 +151,14 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# global 变量:从模块作用域查找(global 声明优先级最高)
|
||||
if trans is not None:
|
||||
if GenApi.is_global_name(trans, nm_id) != 0:
|
||||
mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm_id)
|
||||
mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm_id)
|
||||
if mod_alloca is not None:
|
||||
load_ty: llvmlite.LLVMType* = None
|
||||
if mod_alloca.Ty is not None:
|
||||
load_ty = mod_alloca.Ty.Pointee
|
||||
if load_ty is None:
|
||||
# fail-fast:global 变量存储类型缺失,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"变量 '{nm_id}' 存储类型缺失", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"变量 '{nm_id}' 存储类型缺失", "TypeError")
|
||||
# 全局数组(如 pyzlib.pyzlib_error_msg: CArray[char, 512]):
|
||||
# 按 C 语义衰减为基址返回(对齐下方局部数组分支 L3383-3388)。
|
||||
# 否则 load [512 x i8] 数组值当 i8* 传 → set_error 的 strncpy
|
||||
@@ -191,8 +172,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# t.CVolatile 全局:load 带 volatile 限定符(禁优化器消除重复读)
|
||||
vol_g: int = 0
|
||||
if trans is not None:
|
||||
ve_g: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_id)
|
||||
ve_g: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_id)
|
||||
vol_g = self.Gen.VarGen.var_is_volatile(ve_g)
|
||||
return llvmlite.build_load(builder, load_ty, mod_alloca, vol_g)
|
||||
|
||||
@@ -218,8 +198,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
load_ty = alloca.Ty.Pointee
|
||||
if load_ty is None:
|
||||
# fail-fast:局部变量存储类型缺失,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"变量 '{nm_id}' 存储类型缺失", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"变量 '{nm_id}' 存储类型缺失", "TypeError")
|
||||
# 结构体值变量(alloca 类型为 Struct,如 `x: Cls | t.CPtr`):
|
||||
# 按"对象即指针"语义返回其地址(alloca 指针),而非加载结构体值。
|
||||
# 结构体值无法参与 ptrtoint/方法调用等地址相关操作,加载值会导致
|
||||
@@ -236,8 +215,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# t.CVolatile 局部变量:load 带 volatile 限定符
|
||||
vol_l: int = 0
|
||||
if trans is not None:
|
||||
ve_l: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_id)
|
||||
ve_l: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_id)
|
||||
vol_l = self.Gen.VarGen.var_is_volatile(ve_l)
|
||||
return llvmlite.build_load(builder, load_ty, alloca, vol_l)
|
||||
|
||||
@@ -246,8 +224,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# ② 模块别名/模块函数引用之前(会话名不得被 printf 等本模块 declare 抢走)。
|
||||
# 非 REPL(trans.ReplCtx is None)时 repl_try_read 立即返回 None ⇒ 原路径逐字不变。
|
||||
if trans is not None and trans.ReplCtx is not None:
|
||||
sess_val: llvmlite.Value* = self.Gen.VarGen.repl_try_read(
|
||||
trans, nm_id, node)
|
||||
sess_val: llvmlite.Value* = self.Gen.VarGen.repl_try_read(trans, nm_id, node)
|
||||
if sess_val is not None:
|
||||
return sess_val
|
||||
|
||||
@@ -268,8 +245,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 最终打印出 `declare void @()` 空名函数。正确做法:按 Function 的
|
||||
# RetTy/Params 构造真实函数类型,用 new_value 包装成普通 Value 再 bitcast。
|
||||
if trans is not None and trans.Module is not None:
|
||||
fn_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
trans.Module, nm_id)
|
||||
fn_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, nm_id)
|
||||
if fn_ref is not None:
|
||||
fn_name: str = llvmlite.function_get_name(fn_ref)
|
||||
if fn_name is None:
|
||||
@@ -278,8 +254,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fn_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(fn_ref)
|
||||
if fn_ret_ty is None:
|
||||
# fail-fast:函数返回类型缺失,无法构造函数指针(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError")
|
||||
fn_pp: llvmlite.Param* = llvmlite.function_get_param_head(fn_ref)
|
||||
fn_first_node: llvmlite.Function* = None
|
||||
fn_prev_node: llvmlite.Function* = None
|
||||
@@ -295,8 +270,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fn_prev_node = fn_pn
|
||||
fn_pcount += 1
|
||||
fn_pp = llvmlite.param_get_next(fn_pp)
|
||||
fn_ty: llvmlite.LLVMType* = llvmlite.Func(
|
||||
pool, fn_ret_ty, fn_first_node, fn_pcount)
|
||||
fn_ty: llvmlite.LLVMType* = llvmlite.Func(pool, fn_ret_ty, fn_first_node, fn_pcount)
|
||||
if fn_ty is None:
|
||||
return None
|
||||
# 构造函数指针 Value(new_value 包装,避免触碰 Function.Next)
|
||||
@@ -313,8 +287,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
else:
|
||||
viperlib.snprintf(fn_ref_name, 256, "@%s", fn_name)
|
||||
llvmlite.value_set_name(fn_ref_v, fn_ref_name)
|
||||
fn_i8ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
fn_i8ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
return llvmlite.build_bitcast(builder, fn_ref_v, fn_i8ptr_ty)
|
||||
|
||||
# ============================================================
|
||||
@@ -329,8 +302,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if trans is not None and trans._from_imports is not None:
|
||||
if trans.Module is not None:
|
||||
# 是 from-import 名称(禁用 star 回退,避免误归 star 模块)
|
||||
fi_mod: str = self.Gen.ImportsGen.lookup_from_import(
|
||||
trans._from_imports, nm_id, 0)
|
||||
fi_mod: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, nm_id, 0)
|
||||
if fi_mod is not None:
|
||||
# 排除已注册类名/枚举名:这些是类型,不作为全局变量值读取
|
||||
fi_is_class: int = 0
|
||||
@@ -341,8 +313,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fi_is_class = 1
|
||||
if fi_is_class == 0:
|
||||
fi_gname: str = nm_id
|
||||
fi_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
|
||||
trans._from_imports, nm_id)
|
||||
fi_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm_id)
|
||||
if fi_orig is not None:
|
||||
og_len_fi: sizet = 0
|
||||
while fi_orig[og_len_fi] != ' ' and fi_orig[og_len_fi] != '\0':
|
||||
@@ -361,10 +332,8 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fi_mod_cut2: str = self._cut_from_import_mod(pool, fi_mod)
|
||||
if fi_mod_cut2 is None:
|
||||
fi_mod_cut2 = fi_mod
|
||||
gv_fi_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname)
|
||||
gv_fi: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
trans.Module, gv_fi_q)
|
||||
gv_fi_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname)
|
||||
gv_fi: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(trans.Module, gv_fi_q)
|
||||
ref_fi: llvmlite.Value* = None
|
||||
if gv_fi is not None and gv_fi.Ty is not None:
|
||||
ref_fi = self.Gen.ExprGenAttr.make_global_ref(pool, gv_fi.Name, gv_fi.Ty)
|
||||
@@ -624,8 +593,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
s_val_ptr: llvmlite.Value* = self.coerce_to_type(builder, rhs_val, s_elem_ty, node)
|
||||
if s_val_ptr is None:
|
||||
return 0
|
||||
s_ep: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, s_addr, llvmlite.Ptr(pool, s_elem_ty))
|
||||
s_ep: llvmlite.Value* = llvmlite.build_bitcast(builder, s_addr, llvmlite.Ptr(pool, s_elem_ty))
|
||||
if s_ep is not None:
|
||||
llvmlite.build_store(builder, s_val_ptr, s_ep)
|
||||
return 0
|
||||
@@ -695,24 +663,17 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
match nl_ty:
|
||||
case llvmlite.LLVMType.Array(elem_ty_nl, _cnt_nl):
|
||||
arr_ptr_nl: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
arr_ptr_nl: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl is None:
|
||||
return None
|
||||
return llvmlite.build_gep_array(
|
||||
builder, nl_ty, elem_ty_nl, arr_ptr_nl,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
return llvmlite.build_gep_array(builder, nl_ty, elem_ty_nl, arr_ptr_nl, self._zext_index_to_i32(builder, idx_val))
|
||||
case llvmlite.LLVMType.Ptr(inner_nl):
|
||||
arr_ptr_nl2: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl2 is None:
|
||||
return None
|
||||
arr_ptr_nl2: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl2 is None: return None
|
||||
return llvmlite.build_gep(builder, inner_nl, arr_ptr_nl2, idx_val)
|
||||
case _:
|
||||
arr_ptr_nl3: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl3 is None:
|
||||
return None
|
||||
arr_ptr_nl3: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl3 is None: return None
|
||||
return llvmlite.build_gep(builder, nl_ty, arr_ptr_nl3, idx_val)
|
||||
return None
|
||||
# ============================================================
|
||||
@@ -741,16 +702,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# p.entry 垃圾 → 用户进程 iretq 到垃圾地址 → PF)。
|
||||
if sub.slice is not None and sub.slice.kind() == ast.ASTKind.Slice:
|
||||
slc: rawptr[ast.Slice] = rawptr[ast.Slice](sub.slice)
|
||||
base_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
if base_v is None:
|
||||
return None
|
||||
if slc.lower is None:
|
||||
return base_v
|
||||
start_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, slc.lower, None, 0, trans)
|
||||
if start_v is None:
|
||||
return None
|
||||
base_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans)
|
||||
if base_v is None: return None
|
||||
if slc.lower is None: return base_v
|
||||
start_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, slc.lower, None, 0, trans)
|
||||
if start_v is None: return None
|
||||
i64_sc: llvmlite.LLVMType* = llvmlite.Int64(pool)
|
||||
start_w: llvmlite.Value* = start_v
|
||||
if start_v.Ty is not None:
|
||||
@@ -763,34 +719,26 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.build_gep(builder, i8_sc, base_v, start_w)
|
||||
|
||||
# 翻译索引
|
||||
idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None:
|
||||
return None
|
||||
idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None: return None
|
||||
|
||||
# 嵌套下标读取: a[i][j] —— 递归取内层指针后 load
|
||||
# (与 get_subscript_ptr 嵌套分支对称;如 gfx.vp 的
|
||||
# a.m[i][k] * b.m[k][j],内层 translate_value 会把行加载为
|
||||
# Array 值(非指针)→ 通用路径失败 → "rhs 翻译失败")
|
||||
if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript:
|
||||
inner_ptr_r: llvmlite.Value* = self.get_subscript_ptr(
|
||||
builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr_r is None or inner_ptr_r.Ty is None:
|
||||
return None
|
||||
inner_ptr_r: llvmlite.Value* = self.get_subscript_ptr(builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr_r is None or inner_ptr_r.Ty is None: return None
|
||||
inner_elem_r: llvmlite.LLVMType* = inner_ptr_r.Ty.Pointee
|
||||
if inner_elem_r is None:
|
||||
return None
|
||||
if inner_elem_r is None: return None
|
||||
match inner_elem_r:
|
||||
case llvmlite.LLVMType.Array(arr_ie_r, _):
|
||||
elem_ptr_r: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, inner_elem_r, arr_ie_r, inner_ptr_r,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
elem_ptr_r: llvmlite.Value* = llvmlite.build_gep_array(builder, inner_elem_r, arr_ie_r, inner_ptr_r, self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr_r is not None:
|
||||
return llvmlite.build_load(builder, arr_ie_r, elem_ptr_r)
|
||||
return None
|
||||
case _:
|
||||
elem_ptr_r2: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, inner_elem_r, inner_ptr_r, idx_val)
|
||||
elem_ptr_r2: llvmlite.Value* = llvmlite.build_gep(builder, inner_elem_r, inner_ptr_r, idx_val)
|
||||
if elem_ptr_r2 is not None:
|
||||
return llvmlite.build_load(builder, inner_elem_r, elem_ptr_r2)
|
||||
return None
|
||||
@@ -802,14 +750,12 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# rawptr[t.CVolatile | T] 变量(volatile 指针指向物):本分支内
|
||||
# 的**元素 load**(p[i] 解引用)带 volatile;仅读取指针值自身的
|
||||
# load(alloca → 指针值)不带(那是指针变量而非所指物)。
|
||||
vol_sub_rd: int = self.Gen.VarGen.var_pointee_is_volatile(
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id))
|
||||
vol_sub_rd: int = self.Gen.VarGen.var_pointee_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id))
|
||||
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
|
||||
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
|
||||
# 读路径:元素指针 load 出元素值
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_ptr_r: llvmlite.Value* = self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
nl_ptr_r: llvmlite.Value* = self._nonlocal_subscript_ptr(builder, pool, trans, nm.id, idx_val)
|
||||
if nl_ptr_r is not None and nl_ptr_r.Ty is not None:
|
||||
nl_elem_ty: llvmlite.LLVMType* = nl_ptr_r.Ty.Pointee
|
||||
if nl_elem_ty is not None:
|
||||
@@ -825,9 +771,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Array(elem_ty, count):
|
||||
# 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, pointee, elem_ty, alloca,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, pointee, elem_ty, alloca, self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr is not None:
|
||||
return llvmlite.build_load(builder, elem_ty, elem_ptr)
|
||||
return None
|
||||
@@ -839,21 +783,15 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
#(对齐 Ptr(Ptr(list)) 变量路径,修复 parts[0] 崩溃)
|
||||
if lsn_v is not None:
|
||||
if string.strstr(lsn_v, "list[") is not None:
|
||||
elem_addr_v: llvmlite.Value* = \
|
||||
self.list_getitem_inline(
|
||||
builder, pool, alloca, idx_val, node)
|
||||
elem_addr_v: llvmlite.Value* = self.list_getitem_inline(builder, pool, alloca, idx_val, node)
|
||||
if elem_addr_v is not None:
|
||||
elem_ty_v: llvmlite.LLVMType* = \
|
||||
self._list_elem_type_from_name(pool, lsn_v)
|
||||
elem_ty_v: llvmlite.LLVMType* = self._list_elem_type_from_name(pool, lsn_v)
|
||||
if elem_ty_v is not None:
|
||||
elem_ptr_ty_v: llvmlite.LLVMType* = \
|
||||
llvmlite.Ptr(pool, elem_ty_v)
|
||||
elem_ptr_ty_v: llvmlite.LLVMType* = llvmlite.Ptr(pool, elem_ty_v)
|
||||
casted_v: llvmlite.Value* = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, elem_addr_v, elem_ptr_ty_v)
|
||||
llvmlite.build_bitcast(builder, elem_addr_v, elem_ptr_ty_v)
|
||||
if casted_v is not None:
|
||||
return llvmlite.build_load(
|
||||
builder, elem_ty_v, casted_v)
|
||||
return llvmlite.build_load(builder, elem_ty_v, casted_v)
|
||||
return None
|
||||
case llvmlite.LLVMType.Ptr(inner_ty):
|
||||
# 检查 inner_ty 是否是 list[T] 类型(泛型类不注册 struct)
|
||||
@@ -867,23 +805,17 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if list_struct_name is not None:
|
||||
if string.strstr(list_struct_name, "list[") is not None:
|
||||
# list[T] 类型: 内联生成 __getitem__ 逻辑
|
||||
ptr_val_list: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_list: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_list is not None:
|
||||
elem_addr_list: llvmlite.Value* = self.list_getitem_inline(
|
||||
builder, pool, ptr_val_list, idx_val, node)
|
||||
elem_addr_list: llvmlite.Value* = self.list_getitem_inline(builder, pool, ptr_val_list, idx_val, node)
|
||||
if elem_addr_list is not None:
|
||||
# 根据类型名提取元素类型,bitcast 后 load
|
||||
elem_ty_list: llvmlite.LLVMType* = self._list_elem_type_from_name(
|
||||
pool, list_struct_name)
|
||||
elem_ty_list: llvmlite.LLVMType* = self._list_elem_type_from_name(pool, list_struct_name)
|
||||
if elem_ty_list is not None:
|
||||
elem_ptr_ty_list: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, elem_ty_list)
|
||||
casted_addr_list: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, elem_addr_list, elem_ptr_ty_list)
|
||||
elem_ptr_ty_list: llvmlite.LLVMType* = llvmlite.Ptr(pool, elem_ty_list)
|
||||
casted_addr_list: llvmlite.Value* = llvmlite.build_bitcast(builder, elem_addr_list, elem_ptr_ty_list)
|
||||
if casted_addr_list is not None:
|
||||
return llvmlite.build_load(
|
||||
builder, elem_ty_list, casted_addr_list)
|
||||
return llvmlite.build_load(builder, elem_ty_list, casted_addr_list)
|
||||
return None
|
||||
# inner_ty 是 Ptr 说明 alloca.Ty 是三重指针 Ptr(Ptr(Ptr(...))),
|
||||
# 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。
|
||||
@@ -892,11 +824,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 对比 HashTable|t.CPtr: alloca.Ty=HashTable**, inner_ty=Struct(HashTable)
|
||||
# (非 Ptr), 仍走下面的方法调用转发路径。
|
||||
if self.is_ptr_type(inner_ty) != 0:
|
||||
ptr_val_pp: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_pp: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_pp is not None:
|
||||
elem_ptr_pp: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val_pp, idx_val)
|
||||
elem_ptr_pp: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val_pp, idx_val)
|
||||
if elem_ptr_pp is not None:
|
||||
# volatile 指针指向物:解引用 load 带 volatile
|
||||
return llvmlite.build_load(builder, inner_ty, elem_ptr_pp, vol_sub_rd)
|
||||
@@ -911,23 +841,18 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if gi_lookup_rd is not None:
|
||||
viperlib.snprintf(gi_lookup_rd, 128, "%s.__getitem__", cls_nm_rd_ptr)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_rd) is not None:
|
||||
obj_ptr_rd: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
obj_ptr_rd: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if not (obj_ptr_rd is None):
|
||||
arg_vals_rd_p: sizet* = pool.alloc(8)
|
||||
if not (arg_vals_rd_p is None):
|
||||
arg_vals_rd_p[0] = sizet(idx_val)
|
||||
ret_rd_p: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_rd_ptr, "__getitem__",
|
||||
obj_ptr_rd, arg_vals_rd_p, 1, trans, sub)
|
||||
ret_rd_p: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_rd_ptr, "__getitem__", obj_ptr_rd, arg_vals_rd_p, 1, trans, sub)
|
||||
if not (ret_rd_p is None):
|
||||
return ret_rd_p
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
ptr_val_rd_g: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_rd_g: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_rd_g is not None:
|
||||
elem_rd_g: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val_rd_g, idx_val)
|
||||
elem_rd_g: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val_rd_g, idx_val)
|
||||
if elem_rd_g is not None:
|
||||
# volatile 指针指向物:解引用 load 带 volatile
|
||||
return llvmlite.build_load(builder, inner_ty, elem_rd_g, vol_sub_rd)
|
||||
@@ -944,21 +869,17 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 必须先 load alloca 得指针值,再 GEP i8*(步长 8)——
|
||||
# 否则 GEP base 用 alloca(&elem_ptr)读到栈变量而非数据区,
|
||||
# list.get 返回"元素地址"而非"元素值"(dump 虚调用读错 vtable)。
|
||||
ptr_val_pe_ts: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_pe_ts: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_pe_ts is not None:
|
||||
elem_ptr_ts: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_pe_ts, idx_val)
|
||||
elem_ptr_ts: llvmlite.Value* = llvmlite.build_gep(builder, pointee, ptr_val_pe_ts, idx_val)
|
||||
if elem_ptr_ts is not None:
|
||||
# volatile 指针指向物:解引用 load 带 volatile
|
||||
return llvmlite.build_load(builder, pointee, elem_ptr_ts, vol_sub_rd)
|
||||
return None
|
||||
# 普通指针遍历: 先 load 指针值,再 GEP
|
||||
ptr_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val is not None:
|
||||
elem_ptr2: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val, idx_val)
|
||||
elem_ptr2: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val, idx_val)
|
||||
if elem_ptr2 is not None:
|
||||
# volatile 指针指向物:解引用 load 带 volatile
|
||||
return llvmlite.build_load(builder, inner_ty, elem_ptr2, vol_sub_rd)
|
||||
@@ -975,13 +896,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Int(bits_rd):
|
||||
if bits_rd == 8:
|
||||
i8_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
elem_ptr_rd: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i8_ptr_rd, alloca, idx_val)
|
||||
i8_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
elem_ptr_rd: llvmlite.Value* = llvmlite.build_gep(builder, i8_ptr_rd, alloca, idx_val)
|
||||
if elem_ptr_rd is not None:
|
||||
return llvmlite.build_load(
|
||||
builder, i8_ptr_rd, elem_ptr_rd)
|
||||
return llvmlite.build_load(builder, i8_ptr_rd, elem_ptr_rd)
|
||||
case _:
|
||||
pass
|
||||
# 自定义类(结构体类型): 仅当类定义了 __getitem__
|
||||
@@ -993,23 +911,18 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if gi_lookup_sub is not None:
|
||||
viperlib.snprintf(gi_lookup_sub, 128, "%s.__getitem__", cls_nm_sub)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_sub) is not None:
|
||||
obj_val_sub: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
obj_val_sub: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if not (obj_val_sub is None):
|
||||
arg_vals_sub: sizet* = pool.alloc(8)
|
||||
if not (arg_vals_sub is None):
|
||||
arg_vals_sub[0] = sizet(idx_val)
|
||||
ret_sub: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_sub, "__getitem__",
|
||||
obj_val_sub, arg_vals_sub, 1, trans, sub)
|
||||
ret_sub: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_sub, "__getitem__", obj_val_sub, arg_vals_sub, 1, trans, sub)
|
||||
if not (ret_sub is None):
|
||||
return ret_sub
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
ptr_val_sub_g: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_sub_g: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_sub_g is not None:
|
||||
elem_sub_g: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_sub_g, idx_val)
|
||||
elem_sub_g: llvmlite.Value* = llvmlite.build_gep(builder, pointee, ptr_val_sub_g, idx_val)
|
||||
if elem_sub_g is not None:
|
||||
# volatile 指针指向物:解引用 load 带 volatile
|
||||
return llvmlite.build_load(builder, pointee, elem_sub_g, vol_sub_rd)
|
||||
@@ -1017,8 +930,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
pass
|
||||
|
||||
# 通用路径:翻译 value 获取指针
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans)
|
||||
if ptr_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
|
||||
@@ -1027,16 +939,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 通用路径基址(如 self.ptr / 复杂表达式):仅当基址可解析到
|
||||
# VarEntry/FieldEntry 且其为 rawptr[t.CVolatile|T] 时,元素 load 带 volatile;
|
||||
# 其余基址解析返回 0(明确不支持,见限制清单)。守卫为 0 时文本不变。
|
||||
vol_sub_gen: int = self.Gen.ExprGenAttr.base_pointee_is_volatile(
|
||||
pool, trans, sub.value)
|
||||
vol_sub_gen: int = self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, sub.value)
|
||||
elem_ty2: llvmlite.LLVMType* = ptr_val.Ty.Pointee
|
||||
if elem_ty2 is not None:
|
||||
# 数组类型: 双索引 GEP + load 元素
|
||||
match elem_ty2:
|
||||
case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2):
|
||||
elem_ptr3: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, elem_ty2, arr_elem_ty2, ptr_val,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
elem_ptr3: llvmlite.Value* = llvmlite.build_gep_array(builder, elem_ty2, arr_elem_ty2, ptr_val, self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr3 is not None:
|
||||
return llvmlite.build_load(builder, arr_elem_ty2, elem_ptr3, vol_sub_gen)
|
||||
return None
|
||||
@@ -1050,29 +959,20 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 存指针",合法 C 联合读回应按指针读回。统一按 i8* load(同宽 8 字节,
|
||||
# 位模式不变):指针目标直接 bitcast;整数目标隐式 ptrtoint 同样
|
||||
# 保持位模式(对齐 MatchGenMixin 的 REnum 槽位按声明类型读机制)。
|
||||
if trans is not None and sub.value is not None \
|
||||
and sub.value.kind() == ast.ASTKind.Attribute:
|
||||
fa_u64: str = self.Gen.ExprGenAttr._resolve_attr_field_class(
|
||||
pool, trans, sub.value)
|
||||
if trans is not None and sub.value is not None and sub.value.kind() == ast.ASTKind.Attribute:
|
||||
fa_u64: str = self.Gen.ExprGenAttr._resolve_attr_field_class(pool, trans, sub.value)
|
||||
if fa_u64 is not None and self._annot_is_64bit_scalar(fa_u64) != 0:
|
||||
match elem_ty2:
|
||||
case llvmlite.LLVMType.Int(eb_u64):
|
||||
if eb_u64 == 64:
|
||||
cell_p_u64: llvmlite.Value* = \
|
||||
llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val)
|
||||
cell_p_u64: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val)
|
||||
if cell_p_u64 is not None:
|
||||
i8_ty_u64: llvmlite.LLVMType* = \
|
||||
llvmlite.Int8(pool)
|
||||
i8p_ty_u64: llvmlite.LLVMType* = \
|
||||
llvmlite.Ptr(pool, i8_ty_u64)
|
||||
i8pp_ty_u64: llvmlite.LLVMType* = \
|
||||
llvmlite.Ptr(pool, i8p_ty_u64)
|
||||
cast_cell_u64: llvmlite.Value* = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, cell_p_u64, i8pp_ty_u64)
|
||||
i8_ty_u64: llvmlite.LLVMType* = llvmlite.Int8(pool)
|
||||
i8p_ty_u64: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_u64)
|
||||
i8pp_ty_u64: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8p_ty_u64)
|
||||
cast_cell_u64: llvmlite.Value* = llvmlite.build_bitcast(builder, cell_p_u64, i8pp_ty_u64)
|
||||
if cast_cell_u64 is not None:
|
||||
return llvmlite.build_load(
|
||||
builder, i8p_ty_u64, cast_cell_u64, vol_sub_gen)
|
||||
return llvmlite.build_load(builder, i8p_ty_u64, cast_cell_u64, vol_sub_gen)
|
||||
case _:
|
||||
pass
|
||||
# 自定义结构体 (如 self._ht[key]): 仅当类定义了 __getitem__ 才转发方法调用;
|
||||
@@ -1086,20 +986,16 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
arg_vals_rd_g: sizet* = pool.alloc(8)
|
||||
if not (arg_vals_rd_g is None):
|
||||
arg_vals_rd_g[0] = sizet(idx_val)
|
||||
ret_rd_g: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_rd_gen, "__getitem__",
|
||||
ptr_val, arg_vals_rd_g, 1, trans, sub)
|
||||
ret_rd_g: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_rd_gen, "__getitem__", ptr_val, arg_vals_rd_g, 1, trans, sub)
|
||||
if not (ret_rd_g is None):
|
||||
return ret_rd_g
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
elem_ptr_gen: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, elem_ty2, ptr_val, idx_val)
|
||||
elem_ptr_gen: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val)
|
||||
if elem_ptr_gen is not None:
|
||||
return llvmlite.build_load(builder, elem_ty2, elem_ptr_gen, vol_sub_gen)
|
||||
return None
|
||||
# 指针类型: 单索引 GEP + load
|
||||
elem_ptr4: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, elem_ty2, ptr_val, idx_val)
|
||||
elem_ptr4: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val)
|
||||
if elem_ptr4 is not None:
|
||||
return llvmlite.build_load(builder, elem_ty2, elem_ptr4, vol_sub_gen)
|
||||
return None
|
||||
@@ -1110,14 +1006,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
"""注解是否为 64 位标量 | t.CPtr 联合(AnnotClassName 为提取出的
|
||||
非 CPtr 侧类型名,如 int64|t.CPtr → "CInt64T")。此类联合的
|
||||
8 字节单元格存 i64 标量,下标元素类型应为 Int64 而非指针。"""
|
||||
if annot is None:
|
||||
return 0
|
||||
if string.strstr(annot, "CInt64T") is not None:
|
||||
return 1
|
||||
if string.strstr(annot, "CUInt64T") is not None:
|
||||
return 1
|
||||
if string.strstr(annot, "CSizeT") is not None:
|
||||
return 1
|
||||
if annot is None: return 0
|
||||
if string.strstr(annot, "CInt64T") is not None: return 1
|
||||
if string.strstr(annot, "CUInt64T") is not None: return 1
|
||||
if string.strstr(annot, "CSizeT") is not None: return 1
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -1140,49 +1032,36 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
trans: HT.Translator*,
|
||||
node: ast.AST*) -> int:
|
||||
"""下标基座存储形态:1=数组 / 0=指针 / -1=无法判定"""
|
||||
if node is None or trans is None:
|
||||
return -1
|
||||
if node is None or trans is None: return -1
|
||||
sub_bk: ast.Subscript* = ast.Subscript*(node)
|
||||
if sub_bk is None or sub_bk.value is None:
|
||||
return -1
|
||||
if sub_bk is None or sub_bk.value is None: return -1
|
||||
base_ty_bk: llvmlite.LLVMType* = None
|
||||
if sub_bk.value.kind() == ast.ASTKind.Name:
|
||||
nm_bk: ast.Name* = ast.Name*(sub_bk.value)
|
||||
if nm_bk.id is None:
|
||||
return -1
|
||||
alloca_bk: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm_bk.id)
|
||||
if nm_bk.id is None: return -1
|
||||
alloca_bk: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm_bk.id)
|
||||
if alloca_bk is None:
|
||||
alloca_bk = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm_bk.id)
|
||||
if alloca_bk is None or alloca_bk.Ty is None:
|
||||
return -1
|
||||
if self.is_ptr_type(alloca_bk.Ty) == 0:
|
||||
return -1
|
||||
if alloca_bk is None or alloca_bk.Ty is None: return -1
|
||||
if self.is_ptr_type(alloca_bk.Ty) == 0: return -1
|
||||
base_ty_bk = alloca_bk.Ty.Pointee
|
||||
elif sub_bk.value.kind() == ast.ASTKind.Attribute:
|
||||
# 单层 obj.field(如 self.arr):非 fatal 只读解析字段类型
|
||||
fe_bk: GenTypes.FieldEntry* = \
|
||||
self.Gen.ExprGenAttr._resolve_attr_field_entry(pool, trans, sub_bk.value)
|
||||
if fe_bk is None or fe_bk.Ty is None:
|
||||
return -1
|
||||
fe_bk: GenTypes.FieldEntry* = self.Gen.ExprGenAttr._resolve_attr_field_entry(pool, trans, sub_bk.value)
|
||||
if fe_bk is None or fe_bk.Ty is None: return -1
|
||||
base_ty_bk = fe_bk.Ty
|
||||
else:
|
||||
return -1
|
||||
if base_ty_bk is None:
|
||||
return -1
|
||||
if base_ty_bk is None: return -1
|
||||
# 基座自身是数组值 → 数组存储
|
||||
if self.is_array_type(base_ty_bk) != 0:
|
||||
return 1
|
||||
if self.is_array_type(base_ty_bk) != 0: return 1
|
||||
if self.is_ptr_type(base_ty_bk) != 0:
|
||||
inner_bk: llvmlite.LLVMType* = base_ty_bk.Pointee
|
||||
if inner_bk is None:
|
||||
return -1
|
||||
if inner_bk is None: return -1
|
||||
# Ptr(Array) → t.CArray[T,N] 局部/字段(数组存储)
|
||||
if self.is_array_type(inner_bk) != 0:
|
||||
return 1
|
||||
if self.is_array_type(inner_bk) != 0: return 1
|
||||
# Ptr(Struct) → rawptr[T](指针存储)
|
||||
if inner_bk.kind() == llvmlite.LLVMType.Struct:
|
||||
return 0
|
||||
if inner_bk.kind() == llvmlite.LLVMType.Struct: return 0
|
||||
return -1
|
||||
|
||||
def get_subscript_ptr(self, builder: llvmlite.IRBuilder*,
|
||||
@@ -1191,17 +1070,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
node: ast.AST*,
|
||||
trans: HT.Translator* = None) -> llvmlite.Value*:
|
||||
"""获取下标表达式的元素指针(用于赋值 lhs)"""
|
||||
if node is None or builder is None:
|
||||
return None
|
||||
if node is None or builder is None: return None
|
||||
sub: ast.Subscript* = ast.Subscript*(node)
|
||||
if sub is None:
|
||||
return None
|
||||
if sub is None: return None
|
||||
|
||||
# 翻译索引
|
||||
idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None:
|
||||
return None
|
||||
idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None: return None
|
||||
|
||||
# 嵌套下标: a[i][j] = v —— 递归解析内层下标指针后 GEP
|
||||
# (如 gfx.vp Mat4.m: t.CArray[t.CArray[float, 4], 4] 的 m.m[0][0] = 1;
|
||||
@@ -1209,18 +1084,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 会把内层元素加载为值(Array 类型)→ is_ptr_type 失败 → 返回 None →
|
||||
# "subscript ptr is None" fail-fast。递归取内层指针再 GEP 根治。)
|
||||
if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript:
|
||||
inner_ptr: llvmlite.Value* = self.get_subscript_ptr(
|
||||
builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr is None or inner_ptr.Ty is None:
|
||||
return None
|
||||
inner_ptr: llvmlite.Value* = self.get_subscript_ptr(builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr is None or inner_ptr.Ty is None: return None
|
||||
inner_elem: llvmlite.LLVMType* = inner_ptr.Ty.Pointee
|
||||
if inner_elem is None:
|
||||
return None
|
||||
if inner_elem is None: return None
|
||||
match inner_elem:
|
||||
case llvmlite.LLVMType.Array(arr_ie, _):
|
||||
return llvmlite.build_gep_array(
|
||||
builder, inner_elem, arr_ie, inner_ptr,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
return llvmlite.build_gep_array(builder, inner_elem, arr_ie, inner_ptr, self._zext_index_to_i32(builder, idx_val))
|
||||
case _:
|
||||
return llvmlite.build_gep(builder, inner_elem, inner_ptr, idx_val)
|
||||
|
||||
@@ -1231,8 +1101,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
|
||||
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
return self._nonlocal_subscript_ptr(builder, pool, trans, nm.id, idx_val)
|
||||
alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is not None and alloca.Ty is not None:
|
||||
if self.is_ptr_type(alloca.Ty) != 0:
|
||||
@@ -1242,19 +1111,15 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Array(elem_ty, count):
|
||||
# 数组遍历
|
||||
return llvmlite.build_gep_array(
|
||||
builder, pointee, elem_ty, alloca,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
return llvmlite.build_gep_array(builder, pointee, elem_ty, alloca, self._zext_index_to_i32(builder, idx_val))
|
||||
case llvmlite.LLVMType.Ptr(inner_ty):
|
||||
# inner_ty 是 Ptr 说明 alloca.Ty 是三重指针,
|
||||
# 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。
|
||||
# 此时 [i]=val 应该是指针解引用赋值, 而非调用 __setitem__。
|
||||
if self.is_ptr_type(inner_ty) != 0:
|
||||
ptr_val_gsp: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_gsp: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_gsp is not None:
|
||||
return llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val_gsp, idx_val)
|
||||
return llvmlite.build_gep(builder, inner_ty, ptr_val_gsp, idx_val)
|
||||
return None
|
||||
# 自定义结构体 (如 HashTable|t.CPtr, JsonValue|t.CPtr):
|
||||
# 仅当类定义了 __setitem__(当前模块定义或跨模块 stub declare 注入)
|
||||
@@ -1279,8 +1144,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# alloca 得指针值,再 GEP——否则 GEP base 用 alloca(&elem_ptr)
|
||||
# 读到栈变量而非数据区,赋值写不进 list 数据
|
||||
# (data 全 0xbaadf00d,dump 虚调用读错 vtable 崩溃)。
|
||||
ptr_val_pe: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_pe: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_pe is not None:
|
||||
# [FIX 2026-08-30] 64 位标量联合(int64|t.CPtr /
|
||||
# uint64|t.CPtr / sizet|t.CPtr):8 字节单元格存
|
||||
@@ -1289,29 +1153,22 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 否则元素类型为指针 → i64 存储触发整数隐式转指针
|
||||
# fail-fast(把解引用写入误判为 int→ptr)。
|
||||
pe_annot: str = self.Gen.VarGen.var_annot_class_name(ve_pe)
|
||||
if pe_annot is not None \
|
||||
and self._annot_is_64bit_scalar(pe_annot) != 0:
|
||||
return llvmlite.build_gep(
|
||||
builder, llvmlite.Int64(pool), ptr_val_pe, idx_val)
|
||||
if pe_annot is not None and self._annot_is_64bit_scalar(pe_annot) != 0:
|
||||
return llvmlite.build_gep(builder, llvmlite.Int64(pool), ptr_val_pe, idx_val)
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Int(bits_pe):
|
||||
if bits_pe == 8:
|
||||
i8_ptr_pe: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
return llvmlite.build_gep(
|
||||
builder, i8_ptr_pe, ptr_val_pe, idx_val)
|
||||
i8_ptr_pe: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
return llvmlite.build_gep(builder, i8_ptr_pe, ptr_val_pe, idx_val)
|
||||
case _:
|
||||
pass
|
||||
return llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_pe, idx_val)
|
||||
return llvmlite.build_gep(builder, pointee, ptr_val_pe, idx_val)
|
||||
return None
|
||||
# 普通指针遍历: 先 load 指针值,再 GEP
|
||||
ptr_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val is None:
|
||||
return None
|
||||
gep_r: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val, idx_val)
|
||||
gep_r: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val, idx_val)
|
||||
return gep_r
|
||||
case _:
|
||||
# pointee 是普通标量类型 (如 i64, i32, i8):
|
||||
@@ -1329,26 +1186,21 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 得指针值,再按 i8* 步长 GEP——否则 GEP base 用 alloca
|
||||
# (&elem_ptr)算到栈地址,赋值写不进 list 数据区
|
||||
# (append 只增 count、data 全 0xbaadf00d)。
|
||||
ptr_val_cs: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
ptr_val_cs: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca)
|
||||
if ptr_val_cs is not None:
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Int(bits_cs):
|
||||
if bits_cs == 8:
|
||||
i8_ptr_cs: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
return llvmlite.build_gep(
|
||||
builder, i8_ptr_cs, ptr_val_cs, idx_val)
|
||||
i8_ptr_cs: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
return llvmlite.build_gep(builder, i8_ptr_cs, ptr_val_cs, idx_val)
|
||||
case _:
|
||||
pass
|
||||
return llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_cs, idx_val)
|
||||
return llvmlite.build_gep(builder, pointee, ptr_val_cs, idx_val)
|
||||
return None
|
||||
return llvmlite.build_gep(builder, pointee, alloca, idx_val)
|
||||
|
||||
# 通用路径
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans)
|
||||
if ptr_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
if self.is_ptr_type(ptr_val.Ty) != 0:
|
||||
@@ -1357,9 +1209,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 数组类型: 双索引 GEP (getelementptr [N x ty], ptr, i32 0, i32 idx)
|
||||
match elem_ty2:
|
||||
case llvmlite.LLVMType.Array(arr_elem_ty, arr_count):
|
||||
return llvmlite.build_gep_array(
|
||||
builder, elem_ty2, arr_elem_ty, ptr_val,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
return llvmlite.build_gep_array(builder, elem_ty2, arr_elem_ty, ptr_val, self._zext_index_to_i32(builder, idx_val))
|
||||
case _:
|
||||
pass
|
||||
# 自定义结构体 (如 self._ht[key]): 仅当类定义了 __setitem__
|
||||
|
||||
@@ -14,13 +14,8 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
|
||||
# ============================================================
|
||||
# ExprGenOps - ExprGenMixin 拆分(阶段 D):比较/一元/布尔/binop 运算
|
||||
#
|
||||
# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
"""比较/一元/布尔/binop 运算"""
|
||||
|
||||
# ============================================================
|
||||
@@ -37,21 +32,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
node: ast.AST*,
|
||||
trans: HT.Translator* = None) -> llvmlite.Value*:
|
||||
"""翻译三元表达式 (body if test else orelse),返回 phi 结果 Value"""
|
||||
if node is None or builder is None or trans is None:
|
||||
return None
|
||||
if node is None or builder is None or trans is None: return None
|
||||
ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node)
|
||||
if ie is None:
|
||||
return None
|
||||
if ie is None: return None
|
||||
|
||||
func: llvmlite.Function* = trans._cur_func
|
||||
if func is None:
|
||||
return None
|
||||
if func is None: return None
|
||||
|
||||
# 1. 求值条件
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.test, None, 0, trans)
|
||||
if cond_val is None:
|
||||
return None
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.test, None, 0, trans)
|
||||
if cond_val is None: return None
|
||||
# 转换为 i1
|
||||
cond_bits: int = self.get_llvm_type_bits(cond_val.Ty)
|
||||
if cond_bits == 1:
|
||||
@@ -78,16 +68,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
viperlib.snprintf(name_buf, 32, "ifexp.merge.%d", cnt)
|
||||
merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
if then_bb is None or else_bb is None or merge_bb is None:
|
||||
return None
|
||||
if then_bb is None or else_bb is None or merge_bb is None: return None
|
||||
|
||||
# 3. 条件跳转
|
||||
llvmlite.build_cond_br(builder, cond_i1, then_bb, else_bb)
|
||||
|
||||
# 4. then 分支
|
||||
llvmlite.position_at_end(builder, then_bb)
|
||||
body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.body, None, 0, trans)
|
||||
body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.body, None, 0, trans)
|
||||
then_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock
|
||||
if body_val is None:
|
||||
# fail-fast:三元表达式 then 分支翻译失败,立即终止编译(暴露上游根因)
|
||||
@@ -106,8 +94,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if self.is_ptr_type(body_val.Ty) != 0:
|
||||
orelse_target_ty = body_val.Ty
|
||||
llvmlite.position_at_end(builder, else_bb)
|
||||
orelse_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty)
|
||||
orelse_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty)
|
||||
else_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock
|
||||
if orelse_val is None:
|
||||
# fail-fast:三元表达式 else 分支翻译失败,立即终止编译(暴露上游根因)
|
||||
@@ -157,10 +144,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# fail-fast:三元表达式分支类型缺失,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(node, "三元表达式分支类型缺失", "TypeError")
|
||||
|
||||
inc1: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(
|
||||
pool, body_val, then_blk_for_phi)
|
||||
inc2: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(
|
||||
pool, orelse_val, else_blk_for_phi)
|
||||
inc1: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, body_val, then_blk_for_phi)
|
||||
inc2: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, orelse_val, else_blk_for_phi)
|
||||
if inc1 is None or inc2 is None:
|
||||
return None
|
||||
# 链表顺序: inc1 (head) -> inc2 (tail)
|
||||
@@ -272,8 +257,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return 1
|
||||
# 2) 变量注解类型为无符号类型(trans 可用时查 SymTab)
|
||||
if trans is not None:
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if ve is not None:
|
||||
# [S4 切读] Spec 明确无符号(TS_UINT)优先于字符串判定
|
||||
if self._entry_spec_unsigned(ve.Spec) != 0:
|
||||
@@ -302,8 +286,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if sub_su.value is not None and sub_su.value.kind() == ast.ASTKind.Name:
|
||||
snm_su: ast.Name* = ast.Name*(sub_su.value)
|
||||
if snm_su.id is not None and trans is not None:
|
||||
ve_su: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, snm_su.id)
|
||||
ve_su: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, snm_su.id)
|
||||
if ve_su is not None:
|
||||
# [S4 切读] Spec 明确无符号优先(数组元素为无符号的联合注解场景
|
||||
# 时 Spec 仍是 Ptr/Array ⇒ 返回 0,自动回退字符串路径)
|
||||
@@ -322,8 +305,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if at_u.value.kind() == ast.ASTKind.Name:
|
||||
vn_u: ast.Name* = ast.Name*(at_u.value)
|
||||
if vn_u.id is not None:
|
||||
ve_u: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, vn_u.id)
|
||||
ve_u: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, vn_u.id)
|
||||
if ve_u is not None:
|
||||
cls_nm_u = self.Gen.VarGen.var_annot_class_name(ve_u)
|
||||
if cls_nm_u is not None:
|
||||
@@ -383,8 +365,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if self._spec_sign_from_annot(nm.id) == TSpec.TS_SIGN_SIGNED:
|
||||
return 1
|
||||
if trans is not None:
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if ve is not None:
|
||||
ncn_s: str = self.Gen.VarGen.var_annot_class_name(ve)
|
||||
if ncn_s is not None:
|
||||
@@ -396,8 +377,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if sub_s.value is not None and sub_s.value.kind() == ast.ASTKind.Name:
|
||||
snm: ast.Name* = ast.Name*(sub_s.value)
|
||||
if snm.id is not None and trans is not None:
|
||||
ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, snm.id)
|
||||
ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, snm.id)
|
||||
if ve_s is not None:
|
||||
scn_s: str = self.Gen.VarGen.var_annot_class_name(ve_s)
|
||||
if scn_s is not None:
|
||||
@@ -483,8 +463,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if comparators is None or len(comparators) == 0:
|
||||
return None
|
||||
rhs_node: ast.AST* = comparators.get(0)
|
||||
rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rhs_node, None, 0, trans)
|
||||
rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rhs_node, None, 0, trans)
|
||||
if rhs is None:
|
||||
return None
|
||||
|
||||
@@ -523,27 +502,22 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if cmp_with_none == 0 and lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: ast.Name* = ast.Name*(lhs_node)
|
||||
if nm is not None and nm.id is not None:
|
||||
lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if lhs_alloca is not None:
|
||||
if cmp_zero == 0 or self.get_ptr_level(lhs_alloca.Ty) == 0:
|
||||
ovl_self1: llvmlite.Value* = lhs_alloca
|
||||
# Ptr(Ptr(Struct)) 对象存储槽:load 出对象指针作 self
|
||||
# (与 translate_binop 路径 1 一致,避免槽地址当对象地址)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value* = llvmlite.build_load(builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if load_self1 is not None:
|
||||
ovl_self1 = load_self1
|
||||
ovl_result: llvmlite.Value* = self.try_operator_overload(
|
||||
pool, builder, mod, ovl_self1, rhs, op, trans, 1)
|
||||
ovl_result: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, ovl_self1, rhs, op, trans, 1)
|
||||
if ovl_result is not None:
|
||||
return ovl_result
|
||||
|
||||
# 正常翻译 lhs
|
||||
lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cmp.left, None, 0, trans)
|
||||
lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cmp.left, None, 0, trans)
|
||||
if lhs is None:
|
||||
return None
|
||||
|
||||
@@ -559,8 +533,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
cn_lookup: str = pool.alloc(128)
|
||||
if cn_lookup is not None:
|
||||
viperlib.snprintf(cn_lookup, 128, "%s.__contains__", cn_cls)
|
||||
cn_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
mod, cn_lookup)
|
||||
cn_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, cn_lookup)
|
||||
if cn_fn is not None:
|
||||
cn_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(cn_fn)
|
||||
cn_fn_name: str = llvmlite.function_get_name(cn_fn)
|
||||
@@ -576,26 +549,22 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 参数链表: self → key(独立 null 结尾)
|
||||
cn_self.Next = lhs
|
||||
lhs.Next = None
|
||||
cn_res: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, cn_fn_name, cn_self, 2, cn_ret, 0)
|
||||
cn_res: llvmlite.Value* = llvmlite.build_call(builder, cn_fn_name, cn_self, 2, cn_ret, 0)
|
||||
if cn_res is not None:
|
||||
# 归一化到 i1(__contains__ 返回 int/i32 等)
|
||||
cn_i1: llvmlite.Value* = cn_res
|
||||
match cn_ret:
|
||||
case llvmlite.LLVMType.Int(cn_bits):
|
||||
if cn_bits > 1:
|
||||
cn_zero: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, cn_ret, 0, "0")
|
||||
cn_zero: llvmlite.Value* = llvmlite.ConstInt(pool, cn_ret, 0, "0")
|
||||
if cn_zero is not None:
|
||||
cn_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cn_res, cn_zero)
|
||||
cn_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cn_res, cn_zero)
|
||||
case _:
|
||||
pass
|
||||
if op == ast.OpKind.NotIn:
|
||||
i1_ty_ni: llvmlite.LLVMType* = llvmlite.Int1(pool)
|
||||
if i1_ty_ni is not None and cn_i1 is not None:
|
||||
one_i1_ni: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, i1_ty_ni, 1, "1")
|
||||
one_i1_ni: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_ni, 1, "1")
|
||||
if one_i1_ni is not None:
|
||||
cn_i1 = llvmlite.build_xor(builder, cn_i1, one_i1_ni)
|
||||
if cn_i1 is not None:
|
||||
@@ -610,8 +579,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# Is/IsNot 不在 _cmpop_to_dunder 映射中,会自动返回 None 回退原生比较
|
||||
# None 比较跳过重载(走身份比较);指针判空(cmp_zero + 指针)同样跳过
|
||||
if cmp_with_none == 0 and (cmp_zero == 0 or self.get_ptr_level(lhs.Ty) == 0):
|
||||
ovl_result2: llvmlite.Value* = self.try_operator_overload(
|
||||
pool, builder, mod, lhs, rhs, op, trans, 1)
|
||||
ovl_result2: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, lhs, rhs, op, trans, 1)
|
||||
if ovl_result2 is not None:
|
||||
return ovl_result2
|
||||
|
||||
@@ -677,10 +645,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
rhs = llvmlite.build_ptrtoint(builder, rhs, lhs.Ty)
|
||||
else:
|
||||
# 不同级指针(1 vs 2 等)→ 禁止(fast-fail)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
cmp,
|
||||
f"比较类型不匹配: 不同级指针比较 (lhs 层级={lhs_ptr_level}, rhs 层级={rhs_ptr_level})",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(cmp, f"比较类型不匹配: 不同级指针比较 (lhs 层级={lhs_ptr_level}, rhs 层级={rhs_ptr_level})", "TypeError")
|
||||
else:
|
||||
# None 比较: None 被翻译为 i8* null(一级指针)
|
||||
# 如果 lhs 是指针,将 rhs (i8* null) bitcast 为 lhs 的指针类型
|
||||
@@ -786,21 +751,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
trans: HT.Translator* = None) -> llvmlite.Value*:
|
||||
"""翻译一元运算(-x, +x, not x, ~x)"""
|
||||
uo: ast.UnaryOp* = ast.UnaryOp*(node)
|
||||
if uo is None:
|
||||
return None
|
||||
if uo is None: return None
|
||||
|
||||
operand: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, uo.operand, None, 0, trans)
|
||||
if operand is None:
|
||||
return None
|
||||
operand: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo.operand, None, 0, trans)
|
||||
if operand is None: return None
|
||||
|
||||
# === 一元运算符重载: -obj/+obj/~obj 调用 __neg__/__pos__/__invert__ ===
|
||||
# 仅 USub/UAdd/Invert 有重载语义(not 无 dunder 方法)
|
||||
if uo.op == ast.OpKind.USub or uo.op == ast.OpKind.UAdd or uo.op == ast.OpKind.Invert:
|
||||
ovl_u: llvmlite.Value* = self.try_unary_operator_overload(
|
||||
pool, builder, mod, operand, uo.op, trans)
|
||||
if ovl_u is not None:
|
||||
return ovl_u
|
||||
ovl_u: llvmlite.Value* = self.try_unary_operator_overload(pool, builder, mod, operand, uo.op, trans)
|
||||
if ovl_u is not None: return ovl_u
|
||||
|
||||
if uo.op == ast.OpKind.USub:
|
||||
# -x
|
||||
@@ -854,8 +814,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if d_pointee is not None:
|
||||
return llvmlite.build_load(builder, d_pointee, operand)
|
||||
# 非指针即类型推断退化:fail-fast,绝不按 i8 兜底读取
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "单目 '*' 解引用的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "单目 '*' 解引用的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
return None
|
||||
elif uo.op == ast.OpKind.AddrOf:
|
||||
# &x → 左值地址(不 load):Name 变量 alloca / 模块全局 / 模块函数 /
|
||||
@@ -868,8 +827,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# self/cls 对象引用:返回对象指针本身(Ptr(Struct))而非
|
||||
# 指针变量的地址(Ptr(Ptr(Struct)))
|
||||
if string.strcmp(nm_ao.id, "self") == 0 or string.strcmp(nm_ao.id, "cls") == 0:
|
||||
se_ao: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_ao.id)
|
||||
se_ao: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ao.id)
|
||||
if se_ao is not None and se_ao.Alloca is not None and se_ao.Alloca.Ty is not None:
|
||||
match se_ao.Alloca.Ty:
|
||||
case llvmlite.LLVMType.Ptr(sa1):
|
||||
@@ -930,18 +888,15 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.SSAValue(pool, llvmlite.Ptr(pool, fn_ty_ao), fbuf_ao)
|
||||
elif uo.operand.kind() == ast.ASTKind.Attribute:
|
||||
# 字段地址(GEP,不 load)
|
||||
fptr_ao: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, uo.operand, trans)
|
||||
fptr_ao: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, uo.operand, trans)
|
||||
if fptr_ao is not None:
|
||||
return fptr_ao
|
||||
elif uo.operand.kind() == ast.ASTKind.Subscript:
|
||||
# 元素地址(GEP,不 load)
|
||||
sptr_ao: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
builder, pool, mod, uo.operand, trans)
|
||||
sptr_ao: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, uo.operand, trans)
|
||||
if sptr_ao is not None:
|
||||
return sptr_ao
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "单目 '&' 取地址的操作数必须是左值(Name/Attribute/Subscript)", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "单目 '&' 取地址的操作数必须是左值(Name/Attribute/Subscript)", "TypeError")
|
||||
return None
|
||||
return operand
|
||||
# ============================================================
|
||||
@@ -991,16 +946,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# phi 入边链表头/尾
|
||||
phi_head: rawptr[llvmlite.PhiIncoming] = None
|
||||
phi_tail: rawptr[llvmlite.PhiIncoming] = None
|
||||
phi_head: llvmlite.PhiIncoming* = None
|
||||
phi_tail: llvmlite.PhiIncoming* = None
|
||||
phi_count: int = count - 1 # 循环次数
|
||||
|
||||
# 对每个值(除最后一个)求值并短路
|
||||
for i in range(count - 1):
|
||||
val_node: ast.AST* = values.get(i)
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, val_node,
|
||||
funcs_ptr, func_count, trans)
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, val_node, funcs_ptr, func_count, trans)
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
@@ -1030,7 +983,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 添加 phi 入边:(val_i1, cond_br 所在 BB)
|
||||
cur_bb: rawptr[llvmlite.BasicBlock] = builder.CurBlock
|
||||
inc: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(pool, val_i1, cur_bb)
|
||||
inc: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, val_i1, cur_bb)
|
||||
if phi_head is None:
|
||||
phi_head = inc
|
||||
phi_tail = inc
|
||||
@@ -1043,9 +996,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 最后一个值:求值后直接跳 merge
|
||||
last_node: ast.AST* = values.get(count - 1)
|
||||
last_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, last_node,
|
||||
funcs_ptr, func_count, trans)
|
||||
last_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, last_node, funcs_ptr, func_count, trans)
|
||||
if last_val is None:
|
||||
return None
|
||||
last_bits: int = self.get_llvm_type_bits(last_val.Ty)
|
||||
@@ -1194,35 +1145,28 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
mj += 1
|
||||
|
||||
# 既无函数定义也无 SHA1 → 该类没有此 dunder 方法,返回 None 回退原生运算
|
||||
if found_func is None and cls_sha1 is None:
|
||||
return None
|
||||
if found_func is None and cls_sha1 is None: return None
|
||||
|
||||
# 方法在"定义它的模块"中确实不存在(同模块类但模块内无此 dunder):
|
||||
# 返回 None 回退原生运算,绝不发出幽灵 call——否则 IR 残留
|
||||
# `call void @...__div__`(副作用)且调用方回退原生 sdiv 双重发射,
|
||||
# llc 报 invalid operand type for instruction(CPythonTest PyFloatObj 根因)
|
||||
if found_func is None and trans is not None and trans.ModuleSha1 is not None:
|
||||
if cls_sha1 is not None and string.strcmp(cls_sha1, trans.ModuleSha1) == 0:
|
||||
return None
|
||||
if cls_sha1 is not None and string.strcmp(cls_sha1, trans.ModuleSha1) == 0: return None
|
||||
# 跨模块类:stub 可能未注入,方法存在性以依赖模块 vpi stub 为准。
|
||||
# vpi 未命中(依赖模块确实无此 dunder)→ 回退原生比较(icmp),
|
||||
# 绝不发幽灵 call——`call @{cls_sha1}.{Class}.{dunder}` 链接 undefined
|
||||
# (MemBuddy 无 __eq__ 时 os._mbuddy == sys._mbuddy,SysLibTest 根因)。
|
||||
vpi_dup: llvmlite.LLVMType* = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi(
|
||||
pool, cls_sha1, search_class, dunder)
|
||||
if vpi_dup is None:
|
||||
return None
|
||||
vpi_dup: llvmlite.LLVMType* = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi(pool, cls_sha1, search_class, dunder)
|
||||
if vpi_dup is None: return None
|
||||
|
||||
# 构建 extra_args 数组(仅含 rhs 一个参数)
|
||||
extra_args: sizet* = pool.alloc(8)
|
||||
if extra_args is None:
|
||||
return None
|
||||
if extra_args is None: return None
|
||||
extra_args[0] = sizet(rhs)
|
||||
|
||||
# 调用方法: lhs.__dunder__(rhs)
|
||||
return self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, search_class, dunder,
|
||||
lhs, extra_args, 1, trans)
|
||||
return self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, search_class, dunder, lhs, extra_args, 1, trans)
|
||||
# ============================================================
|
||||
# try_unary_operator_overload - 尝试一元运算符重载
|
||||
#
|
||||
@@ -1305,9 +1249,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
|
||||
# 一元方法无额外参数(extra_args 为空)
|
||||
return self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, search_class, dunder,
|
||||
operand, None, 0, trans)
|
||||
return self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, search_class, dunder, operand, None, 0, trans)
|
||||
# ============================================================
|
||||
# fail_if_double_ptr_binop - 双指针算术 fail-fast(**唯一实现**)
|
||||
#
|
||||
@@ -1404,8 +1346,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
op: int = binop.op
|
||||
|
||||
# 先翻译 rhs(只翻译一次,避免副作用重复)
|
||||
rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rhs_node, None, 0, trans)
|
||||
rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rhs_node, None, 0, trans)
|
||||
if rhs is None:
|
||||
return None
|
||||
|
||||
@@ -1415,8 +1356,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: ast.Name* = ast.Name*(lhs_node)
|
||||
if nm is not None and nm.id is not None:
|
||||
lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if lhs_alloca is not None:
|
||||
ovl_self1: llvmlite.Value* = lhs_alloca
|
||||
# alloca 是 Ptr(Ptr(Struct))(X|t.CPtr 对象存储槽)时,
|
||||
@@ -1424,32 +1364,27 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# load 槽内容(对象指针值)当字段读 → 垃圾(MultiInheritTest
|
||||
# Vec2Both __add__ 输出 (1.0,2.0) 根因;get_struct_type_from_value
|
||||
# 递归解指针后路径 1 能识别 alloca,需同步修正 self 语义)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value* = llvmlite.build_load(builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if load_self1 is not None:
|
||||
ovl_self1 = load_self1
|
||||
ovl_result: llvmlite.Value* = self.try_operator_overload(
|
||||
pool, builder, mod, ovl_self1, rhs, op, trans, 0)
|
||||
ovl_result: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, ovl_self1, rhs, op, trans, 0)
|
||||
if ovl_result is not None:
|
||||
return ovl_result
|
||||
|
||||
# 正常翻译 lhs
|
||||
lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, lhs_node, None, 0, trans)
|
||||
lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, lhs_node, None, 0, trans)
|
||||
if lhs is None:
|
||||
return None
|
||||
|
||||
# === 运算符重载路径 2: lhs 是 Ptr(Struct)(如 Counter|t.CPtr 变量 load 后)===
|
||||
ovl_result2: llvmlite.Value* = self.try_operator_overload(
|
||||
pool, builder, mod, lhs, rhs, op, trans, 0)
|
||||
ovl_result2: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, lhs, rhs, op, trans, 0)
|
||||
if ovl_result2 is not None:
|
||||
return ovl_result2
|
||||
|
||||
# 获取操作数类型信息
|
||||
lhs_bits: int = self.get_llvm_type_bits(lhs.Ty)
|
||||
rhs_bits: int = self.get_llvm_type_bits(rhs.Ty)
|
||||
lhs_bits: int = self.get_llvm_type_bits(lhs.Ty)
|
||||
rhs_bits: int = self.get_llvm_type_bits(rhs.Ty)
|
||||
lhs_fbits: int = self.get_llvm_float_bits(lhs.Ty)
|
||||
rhs_fbits: int = self.get_llvm_float_bits(rhs.Ty)
|
||||
|
||||
@@ -1523,17 +1458,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if lhs_bits == 0 and rhs_bits == 0:
|
||||
if op == ast.OpKind.BitOr or op == ast.OpKind.BitAnd or op == ast.OpKind.BitXor or op == ast.OpKind.LShift or op == ast.OpKind.RShift:
|
||||
# fail-fast:位运算操作数类型非法,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
"位运算操作数类型非法: lhs/rhs 均为非整数类型(指针或结构体),无法执行位运算",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "位运算操作数类型非法: lhs/rhs 均为非整数类型(指针或结构体),无法执行位运算", "TypeError")
|
||||
|
||||
if op == ast.OpKind.Add:
|
||||
return llvmlite.build_add(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.Sub:
|
||||
return llvmlite.build_sub(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.Mult:
|
||||
return llvmlite.build_mul(builder, lhs, rhs)
|
||||
if op == ast.OpKind.Add: return llvmlite.build_add(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.Sub: return llvmlite.build_sub(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.Mult: return llvmlite.build_mul(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.Div:
|
||||
# 无符号操作数 → udiv(binop_unsigned 经 _node_type_unsigned 判定,
|
||||
# 覆盖 sizet/uint64 及变量/数组元素的注解无符号性)。
|
||||
@@ -1550,14 +1479,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if binop_unsigned != 0:
|
||||
return llvmlite.build_urem(builder, lhs, rhs)
|
||||
return llvmlite.build_srem(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitAnd:
|
||||
return llvmlite.build_and(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitOr:
|
||||
return llvmlite.build_or(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitXor:
|
||||
return llvmlite.build_xor(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.LShift:
|
||||
return llvmlite.build_shl(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitAnd: return llvmlite.build_and(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitOr: return llvmlite.build_or(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.BitXor: return llvmlite.build_xor(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.LShift: return llvmlite.build_shl(builder, lhs, rhs)
|
||||
elif op == ast.OpKind.RShift:
|
||||
# 无符号 >> → lshr(逻辑右移),有符号 >> → ashr(算术右移)
|
||||
# 对齐 TPC ExprGen.emit_binary_op:i8/i16 默认无符号;其余查操作数无符号性
|
||||
|
||||
@@ -14,16 +14,11 @@ import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
# ============================================================
|
||||
# FuncGenBase - FuncGenMixin 拆分(阶段 D):函数属性 / 命名 / mangle / create_function 基础工具
|
||||
#
|
||||
# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class FuncGenBase(CallGenBase.CallGenBase):
|
||||
novirtual class FuncGenBase(CallGenBase.CallGenBase):
|
||||
"""函数属性 / 命名 / mangle / create_function 基础工具"""
|
||||
|
||||
# ============================================================
|
||||
# ============================================================
|
||||
# extract_func_attrs - 从 decorator_list 提取 c.Attribute 属性
|
||||
#
|
||||
# 支持 @c.Attribute(t.attr.xxx()) 和 @c.Attribute(t.attr.xxx) 形式
|
||||
@@ -35,77 +30,58 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
decorator_list: list[ast.AST*]*,
|
||||
imported_modules: str) -> str:
|
||||
"""从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串"""
|
||||
if decorator_list is None:
|
||||
return None
|
||||
if decorator_list is None: return None
|
||||
dn: sizet = len(decorator_list)
|
||||
if dn == 0:
|
||||
return None
|
||||
if dn == 0: return None
|
||||
|
||||
attrs_buf: str = pool.alloc(256)
|
||||
if attrs_buf is None:
|
||||
return None
|
||||
if attrs_buf is None: return None
|
||||
attrs_buf[0] = '\0'
|
||||
found_any: int = 0
|
||||
|
||||
for di in range(dn):
|
||||
deco: ast.AST* = decorator_list.get(di)
|
||||
if deco is None:
|
||||
continue
|
||||
if deco is None: continue
|
||||
dk: int = deco.kind()
|
||||
if dk != ast.ASTKind.Call:
|
||||
continue
|
||||
if dk != ast.ASTKind.Call: continue
|
||||
call_node: ast.Call* = ast.Call*(deco)
|
||||
if call_node.func is None:
|
||||
continue
|
||||
if call_node.func is None: continue
|
||||
cfk: int = call_node.func.kind()
|
||||
if cfk != ast.ASTKind.Attribute:
|
||||
continue
|
||||
if cfk != ast.ASTKind.Attribute: continue
|
||||
|
||||
# 检测 c.Attribute
|
||||
func_attr: ast.Attribute* = ast.Attribute*(call_node.func)
|
||||
if func_attr.attr is None:
|
||||
continue
|
||||
if string.strcmp(func_attr.attr, "Attribute") != 0:
|
||||
continue
|
||||
if func_attr.value is None:
|
||||
continue
|
||||
if func_attr.attr is None: continue
|
||||
if string.strcmp(func_attr.attr, "Attribute") != 0: continue
|
||||
if func_attr.value is None: continue
|
||||
fvk: int = func_attr.value.kind()
|
||||
if fvk != ast.ASTKind.Name:
|
||||
continue
|
||||
if fvk != ast.ASTKind.Name: continue
|
||||
c_name: ast.Name* = ast.Name*(func_attr.value)
|
||||
if c_name.id is None:
|
||||
continue
|
||||
if string.strcmp(c_name.id, "c") != 0:
|
||||
continue
|
||||
if c_name.id is None: continue
|
||||
if string.strcmp(c_name.id, "c") != 0: continue
|
||||
imp_c: int = self.Gen.ImportsGen.is_module_imported(imported_modules, "c")
|
||||
if imp_c == 0:
|
||||
continue
|
||||
if imp_c == 0: continue
|
||||
|
||||
# 遍历参数提取属性
|
||||
if call_node.args is None:
|
||||
continue
|
||||
if call_node.args is None: continue
|
||||
args_list: list[ast.AST*]* = call_node.args
|
||||
an: sizet = len(args_list)
|
||||
for ai in range(an):
|
||||
arg_node: ast.AST* = args_list.get(ai)
|
||||
if arg_node is None:
|
||||
continue
|
||||
if arg_node is None: continue
|
||||
# 提取属性名(t.attr.xxx / t.attr.xxx() / t.attr.llvm.xxx)
|
||||
attr_name: str = self._get_attr_name_from_node(arg_node)
|
||||
if attr_name is None:
|
||||
continue
|
||||
if attr_name is None: continue
|
||||
# B5:section 字符串属性(t.attr.section(".text.startup"))不能内联
|
||||
# 在函数签名行(llc: expected string constant),必须走属性组
|
||||
# #N(function_set_attr_group)→ 由 FuncGenDef 单独提取处理。
|
||||
if string.strcmp(attr_name, "section") == 0:
|
||||
continue
|
||||
if string.strcmp(attr_name, "section") == 0: continue
|
||||
# 映射到 LLVM 属性名并追加
|
||||
ar: int = self._append_llvm_attr(attrs_buf, attr_name)
|
||||
if ar != 0:
|
||||
found_any = 1
|
||||
|
||||
if found_any == 0:
|
||||
return None
|
||||
if found_any == 0: return None
|
||||
return attrs_buf
|
||||
def extract_func_section(self, pool: memhub.MemBuddy*,
|
||||
decorator_list: list[ast.AST*]*,
|
||||
@@ -116,38 +92,28 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
attributes #N = { ... }),不能内联(llc: expected string constant)。
|
||||
main.vp boot 函数 t.attr.section(".text.startup") 供链接器按段放置。
|
||||
"""
|
||||
if pool is None or decorator_list is None:
|
||||
return None
|
||||
if pool is None or decorator_list is None: return None
|
||||
dn: sizet = len(decorator_list)
|
||||
if dn == 0:
|
||||
return None
|
||||
if dn == 0: return None
|
||||
for di in range(dn):
|
||||
deco: ast.AST* = decorator_list.get(di)
|
||||
if deco is None or deco.kind() != ast.ASTKind.Call:
|
||||
continue
|
||||
if deco is None or deco.kind() != ast.ASTKind.Call: continue
|
||||
call_node: ast.Call* = ast.Call*(deco)
|
||||
if call_node.func is None or call_node.func.kind() != ast.ASTKind.Attribute:
|
||||
continue
|
||||
if call_node.func is None or call_node.func.kind() != ast.ASTKind.Attribute: continue
|
||||
func_attr: ast.Attribute* = ast.Attribute*(call_node.func)
|
||||
if func_attr.attr is None or string.strcmp(func_attr.attr, "Attribute") != 0:
|
||||
continue
|
||||
if call_node.args is None:
|
||||
continue
|
||||
if func_attr.attr is None or string.strcmp(func_attr.attr, "Attribute") != 0: continue
|
||||
if call_node.args is None: continue
|
||||
args_list: list[ast.AST*]* = call_node.args
|
||||
an: sizet = len(args_list)
|
||||
for ai in range(an):
|
||||
arg_node: ast.AST* = args_list.get(ai)
|
||||
if arg_node is None:
|
||||
continue
|
||||
if arg_node is None: continue
|
||||
attr_name: str = self._get_attr_name_from_node(arg_node)
|
||||
if attr_name is None or string.strcmp(attr_name, "section") != 0:
|
||||
continue
|
||||
if attr_name is None or string.strcmp(attr_name, "section") != 0: continue
|
||||
sec_val: str = self._get_attr_call_arg_str(arg_node)
|
||||
if sec_val is None:
|
||||
continue
|
||||
if sec_val is None: continue
|
||||
sec_buf: str = pool.alloc(128)
|
||||
if sec_buf is None:
|
||||
return None
|
||||
if sec_buf is None: return None
|
||||
viperlib.snprintf(sec_buf, 128, "\"section\"=\"%s\"", sec_val)
|
||||
return sec_buf
|
||||
return None
|
||||
@@ -159,15 +125,13 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
- Attribute: t.attr.packed -> "packed"
|
||||
- Attribute(t.attr.llvm.xxx): t.attr.llvm.nounwind -> "nounwind"
|
||||
"""
|
||||
if node is None:
|
||||
return None
|
||||
if node is None: return None
|
||||
k: int = node.kind()
|
||||
|
||||
# Call 节点: t.attr.always_inline()
|
||||
if k == ast.ASTKind.Call:
|
||||
call: ast.Call* = ast.Call*(node)
|
||||
if call.func is None or call.func.kind() != ast.ASTKind.Attribute:
|
||||
return None
|
||||
if call.func is None or call.func.kind() != ast.ASTKind.Attribute: return None
|
||||
at: ast.Attribute* = ast.Attribute*(call.func)
|
||||
return at.attr
|
||||
|
||||
@@ -179,55 +143,33 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
return None
|
||||
def _get_attr_call_arg_str(self, node: ast.AST*) -> str:
|
||||
"""取 t.attr.xxx("val") 调用的首参字符串常量(如 section(".text.startup"))"""
|
||||
if node is None or node.kind() != ast.ASTKind.Call:
|
||||
return None
|
||||
if node is None or node.kind() != ast.ASTKind.Call: return None
|
||||
cl: ast.Call* = ast.Call*(node)
|
||||
if cl.args is None or len(cl.args) == 0:
|
||||
return None
|
||||
if cl.args is None or len(cl.args) == 0: return None
|
||||
a0: ast.AST* = cl.args.get(0)
|
||||
if a0 is None or a0.kind() != ast.ASTKind.Constant:
|
||||
return None
|
||||
if a0 is None or a0.kind() != ast.ASTKind.Constant: return None
|
||||
cn: ast.Constant* = ast.Constant*(a0)
|
||||
if cn.const_kind != ast.CONST_STR:
|
||||
return None
|
||||
if cn.const_kind != ast.CONST_STR: return None
|
||||
return cn.str_val
|
||||
def _append_llvm_attr(self, attrs_buf: str, attr_name: str) -> int:
|
||||
"""将属性名映射到 LLVM 属性名并追加到缓冲区
|
||||
|
||||
返回 1 表示已追加,0 表示不支持该属性
|
||||
"""
|
||||
if attrs_buf is None or attr_name is None:
|
||||
return 0
|
||||
if attrs_buf is None or attr_name is None: return 0
|
||||
|
||||
# 先确定映射的 LLVM 属性名
|
||||
llvm_name: str = None
|
||||
if string.strcmp(attr_name, "always_inline") == 0:
|
||||
llvm_name = "alwaysinline"
|
||||
elif string.strcmp(attr_name, "noinline") == 0:
|
||||
llvm_name = "noinline"
|
||||
elif string.strcmp(attr_name, "noreturn") == 0:
|
||||
llvm_name = "noreturn"
|
||||
elif string.strcmp(attr_name, "pure") == 0:
|
||||
llvm_name = "readonly"
|
||||
elif string.strcmp(attr_name, "const") == 0:
|
||||
llvm_name = "readnone"
|
||||
elif string.strcmp(attr_name, "nounwind") == 0:
|
||||
llvm_name = "nounwind"
|
||||
elif string.strcmp(attr_name, "noredzone") == 0:
|
||||
llvm_name = "noredzone"
|
||||
elif string.strcmp(attr_name, "stackrealign") == 0:
|
||||
# 动态重对齐栈(LLVM 序言 and rsp,-16)。入口函数(_start)由 bootloader
|
||||
# jmp 进入(rsp≡0 mod 16),而 llc 按 call 约定假设入口 rsp≡8 → 帧整体
|
||||
# 偏 8 → 所有调用 rsp≡8 → 变参函数保存 xmm 的 movaps #GP。stackrealign
|
||||
# 使序言动态对齐,与入口约定无关(sched started 后 movaps #GP 根因)。
|
||||
# 注意:stackrealign 是 LLVM 字符串属性,必须带引号("stackrealign"),
|
||||
# 与 noinline/nounwind 等枚举属性(无引号)区分,否则 llc 报
|
||||
# "expected '{' in function body"。
|
||||
llvm_name = '"stackrealign"'
|
||||
elif string.strcmp(attr_name, "willreturn") == 0:
|
||||
llvm_name = "willreturn"
|
||||
elif string.strcmp(attr_name, "mustprogress") == 0:
|
||||
llvm_name = "mustprogress"
|
||||
if string.strcmp(attr_name, "always_inline") == 0: llvm_name = "alwaysinline"
|
||||
elif string.strcmp(attr_name, "noinline") == 0: llvm_name = "noinline"
|
||||
elif string.strcmp(attr_name, "noreturn") == 0: llvm_name = "noreturn"
|
||||
elif string.strcmp(attr_name, "pure") == 0: llvm_name = "readonly"
|
||||
elif string.strcmp(attr_name, "const") == 0: llvm_name = "readnone"
|
||||
elif string.strcmp(attr_name, "nounwind") == 0: llvm_name = "nounwind"
|
||||
elif string.strcmp(attr_name, "noredzone") == 0: llvm_name = "noredzone"
|
||||
elif string.strcmp(attr_name, "stackrealign") == 0: llvm_name = '"stackrealign"'
|
||||
elif string.strcmp(attr_name, "willreturn") == 0: llvm_name = "willreturn"
|
||||
elif string.strcmp(attr_name, "mustprogress") == 0: llvm_name = "mustprogress"
|
||||
else:
|
||||
# packed/aligned/section/visibility/weak 等不支持作为函数内联属性
|
||||
return 0
|
||||
@@ -240,16 +182,14 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
def _append_str(self, buf: str, s: str,
|
||||
max_len: sizet = 256) -> None:
|
||||
"""将字符串追加到 buf 末尾(有界,防 strcpy 越界写穿定长缓冲)"""
|
||||
if buf is None or s is None:
|
||||
return
|
||||
if buf is None or s is None: return
|
||||
# 防御:TPV 方法默认参数注册存在缺陷(缺参调用 max_len 落到 0),
|
||||
# 显式兜底为 256,避免有界写入检查误判丢弃全部属性文本。
|
||||
if max_len == 0:
|
||||
max_len = 256
|
||||
cur_len: sizet = string.strlen(buf)
|
||||
s_len: sizet = string.strlen(s)
|
||||
if cur_len + s_len + 1 > max_len:
|
||||
return # 无剩余容量:丢弃本次追加,避免越界写
|
||||
if cur_len + s_len + 1 > max_len: return # 无剩余容量:丢弃本次追加,避免越界写 存疑
|
||||
string.strcpy(buf + cur_len, s)
|
||||
# ============================================================
|
||||
# _mangle_name - 为名称添加 SHA1 前缀
|
||||
@@ -259,21 +199,17 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
def _mangle_name(self, trans: HT.Translator*, name: str) -> str:
|
||||
"""为任意名称添加 SHA1 前缀(不做 main/export 检查)"""
|
||||
if trans is None or name is None:
|
||||
return name
|
||||
if trans.ModuleSha1 is None:
|
||||
return name
|
||||
if trans is None or name is None: return name
|
||||
if trans.ModuleSha1 is None: return name
|
||||
name_len: sizet = string.strlen(name)
|
||||
# 已带 SHA1 前缀("{16hex}.")则跳过
|
||||
# [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`。旧判据是 `name_len > 17`,
|
||||
# 与真源的 `>= 17` 只差"前缀之后为空串"这一退化形态(无实际意义),一并对齐。
|
||||
if GenApi.sha1_prefix_len(name) != 0:
|
||||
return name
|
||||
if GenApi.sha1_prefix_len(name) != 0: return name
|
||||
sha1: str = trans.ModuleSha1
|
||||
sha1_len: sizet = string.strlen(sha1)
|
||||
mangled: str = stdlib.malloc(sha1_len + name_len + 2)
|
||||
if mangled is None:
|
||||
return name
|
||||
if mangled is None: return name
|
||||
string.strcpy(mangled, sha1)
|
||||
mangled[sha1_len] = '.'
|
||||
string.strcpy(mangled + sha1_len + 1, name)
|
||||
@@ -286,17 +222,14 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
def _mangle_name_with_sha1(self, sha1: str, name: str) -> str:
|
||||
"""用指定 SHA1 为名称添加前缀(不做 main/export 检查)"""
|
||||
if sha1 is None or name is None:
|
||||
return name
|
||||
if sha1 is None or name is None: return name
|
||||
name_len: sizet = string.strlen(name)
|
||||
# 已带 SHA1 前缀("{16hex}.")则跳过
|
||||
# [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`(口径对齐同 _mangle_name)。
|
||||
if GenApi.sha1_prefix_len(name) != 0:
|
||||
return name
|
||||
if GenApi.sha1_prefix_len(name) != 0: return name
|
||||
sha1_len: sizet = string.strlen(sha1)
|
||||
mangled: str = stdlib.malloc(sha1_len + name_len + 2)
|
||||
if mangled is None:
|
||||
return name
|
||||
if mangled is None: return name
|
||||
string.strcpy(mangled, sha1)
|
||||
mangled[sha1_len] = '.'
|
||||
string.strcpy(mangled + sha1_len + 1, name)
|
||||
@@ -313,12 +246,9 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
def _mangle_func_name(self, trans: HT.Translator*, name: str,
|
||||
has_export: int) -> str:
|
||||
"""为函数名添加 SHA1 前缀(检查 main/export)"""
|
||||
if trans is None or name is None:
|
||||
return name
|
||||
if has_export != 0:
|
||||
return name
|
||||
if string.strcmp(name, "main") == 0:
|
||||
return name
|
||||
if trans is None or name is None: return name
|
||||
if has_export != 0: return name
|
||||
if string.strcmp(name, "main") == 0: return name
|
||||
return self._mangle_name(trans, name)
|
||||
# ============================================================
|
||||
# _body_has_raise - 函数体是否含 raise(非 StopIteration)
|
||||
@@ -335,13 +265,10 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
bn_f: sizet = len(body_f)
|
||||
for bi_f in range(bn_f):
|
||||
stmt_f: ast.AST* = body_f.get(bi_f)
|
||||
if stmt_f is None:
|
||||
continue
|
||||
if stmt_f.kind() != ast.ASTKind.Raise:
|
||||
continue
|
||||
if stmt_f is None: continue
|
||||
if stmt_f.kind() != ast.ASTKind.Raise: continue
|
||||
rn_f: rawptr[ast.Raise] = rawptr[ast.Raise](stmt_f)
|
||||
if rn_f is None or rn_f.exc is None:
|
||||
continue
|
||||
if rn_f is None or rn_f.exc is None: continue
|
||||
ek_f: int = rn_f.exc.kind()
|
||||
is_stop_f: int = 0
|
||||
if ek_f == ast.ASTKind.Name:
|
||||
@@ -372,31 +299,24 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
from_imports: str,
|
||||
trans: HT.Translator*) -> llvmlite.LLVMType*:
|
||||
"""解析 @c.CReturn 装饰器为 struct 返回类型;无 CReturn 返回 None"""
|
||||
if fd is None or fd.decorator_list is None:
|
||||
return None
|
||||
if fd is None or fd.decorator_list is None: return None
|
||||
cr_head: llvmlite.Function* = None
|
||||
cr_last: llvmlite.Function* = None
|
||||
cr_count: int = 0
|
||||
cr_dn: sizet = len(fd.decorator_list)
|
||||
for cdi in range(cr_dn):
|
||||
deco_cr: ast.AST* = fd.decorator_list.get(cdi)
|
||||
if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call:
|
||||
continue
|
||||
if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call: continue
|
||||
deco_call_cr: ast.Call* = ast.Call*(deco_cr)
|
||||
if deco_call_cr.func is None or deco_call_cr.func.kind() != ast.ASTKind.Attribute:
|
||||
continue
|
||||
if deco_call_cr.func is None or deco_call_cr.func.kind() != ast.ASTKind.Attribute: continue
|
||||
deco_fa_cr: ast.Attribute* = ast.Attribute*(deco_call_cr.func)
|
||||
if deco_fa_cr.attr is None or string.strcmp(deco_fa_cr.attr, "CReturn") != 0:
|
||||
continue
|
||||
if deco_fa_cr.attr is None or string.strcmp(deco_fa_cr.attr, "CReturn") != 0: continue
|
||||
cr_args: list[ast.AST*]* = deco_call_cr.args
|
||||
if cr_args is None:
|
||||
continue
|
||||
if cr_args is None: continue
|
||||
cr_an: sizet = len(cr_args)
|
||||
for cai in range(cr_an):
|
||||
cr_aty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, cr_args.get(cai), imported_modules, from_imports, trans, 0)
|
||||
if cr_aty is None:
|
||||
continue
|
||||
cr_aty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, cr_args.get(cai), imported_modules, from_imports, trans, 0)
|
||||
if cr_aty is None: continue
|
||||
cr_pn: llvmlite.Function* = llvmlite.new_param_node(pool, cr_aty)
|
||||
if cr_pn is not None:
|
||||
if cr_head is None:
|
||||
@@ -417,12 +337,10 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
args_node: ast.AST*,
|
||||
ret_ty: llvmlite.LLVMType*) -> llvmlite.Function*:
|
||||
"""创建 LLVM 函数并添加参数"""
|
||||
if name is None or mod is None:
|
||||
return None
|
||||
if name is None or mod is None: return None
|
||||
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, name, ret_ty)
|
||||
if func is None:
|
||||
return None
|
||||
if func is None: return None
|
||||
|
||||
if args_node is not None:
|
||||
ags: ast.Arguments* = ast.Arguments*(args_node)
|
||||
@@ -437,18 +355,15 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
if arg.annotation is not None:
|
||||
if arg.annotation.kind() == ast.ASTKind.Attribute:
|
||||
at_cf: ast.Attribute* = ast.Attribute*(arg.annotation)
|
||||
if at_cf.attr is not None and string.strcmp(at_cf.attr, "CVoid") == 0:
|
||||
continue
|
||||
if at_cf.attr is not None and string.strcmp(at_cf.attr, "CVoid") == 0: continue
|
||||
param_ty: llvmlite.LLVMType* = i32_ty
|
||||
if arg.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg.annotation, None, None, None, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, None, None, None, 0)
|
||||
if resolved is None:
|
||||
# [S4 fail-fast] 有注解但解析失败:不再静默用 i32。
|
||||
# 本函数不传 trans/imports 上下文,解析失败即调用方未补齐
|
||||
# 上下文(暴露上游,不由本函数兜底)。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg, f"函数 '{name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg, f"函数 '{name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
return None
|
||||
param_ty = resolved
|
||||
pname: str = pool.alloc(32)
|
||||
|
||||
@@ -17,12 +17,8 @@ import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
# ============================================================
|
||||
# FuncGenDef - 函数声明 / translate_function_def / decorator wrapper
|
||||
#
|
||||
# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesExprCall 委托。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class FuncGenDef(CallGenBase.CallGenBase):
|
||||
novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
"""函数声明 / translate_function_def / decorator wrapper"""
|
||||
|
||||
# forward_declare_functions - 预扫描所有顶层 FunctionDef,创建前向声明
|
||||
@@ -34,12 +30,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
def forward_declare_functions(self, trans: HT.Translator*,
|
||||
tree: ast.AST*) -> int:
|
||||
"""预扫描所有顶层 FunctionDef,创建前向声明"""
|
||||
if trans is None or tree is None:
|
||||
return 0
|
||||
if trans is None or tree is None: return 0
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
mod: llvmlite.LLVMModule* = trans.Module
|
||||
if pool is None or mod is None:
|
||||
return 0
|
||||
if pool is None or mod is None: return 0
|
||||
|
||||
imported_modules: str = trans._imported_modules
|
||||
from_imports: str = trans._from_imports
|
||||
@@ -50,8 +44,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
ch: list[ast.AST*]* = tree.children
|
||||
if ch is None:
|
||||
return 0
|
||||
if ch is None: return 0
|
||||
|
||||
# 解析函数签名期间临时切换到"仅声明"模式:
|
||||
# 签名里的泛型类注解(如 _empty_like(a: ndarray[t.CDouble]))会触发泛型特化,
|
||||
@@ -78,28 +71,20 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
pre_i: sizet
|
||||
for pre_i in range(cn_count):
|
||||
pre_child: ast.AST* = ch.get(pre_i)
|
||||
if pre_child is None:
|
||||
continue
|
||||
if pre_child.kind() != ast.ASTKind.ClassDef:
|
||||
continue
|
||||
if pre_child is None: continue
|
||||
if pre_child.kind() != ast.ASTKind.ClassDef: continue
|
||||
pre_cd: ast.ClassDef* = ast.ClassDef*(pre_child)
|
||||
if pre_cd is None or pre_cd.name is None:
|
||||
continue
|
||||
pre_ex: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
pre_cd.name, trans.ModuleSha1)
|
||||
if pre_ex is not None and pre_ex.FieldCount > 0:
|
||||
continue
|
||||
if pre_cd is None or pre_cd.name is None: continue
|
||||
pre_ex: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pre_cd.name, trans.ModuleSha1)
|
||||
if pre_ex is not None and pre_ex.FieldCount > 0: continue
|
||||
self.Gen.ClassGenDef.translate_class_def(trans, pre_child)
|
||||
|
||||
for ci in range(cn_count):
|
||||
child: ast.AST* = ch.get(ci)
|
||||
if child is None:
|
||||
continue
|
||||
if child.kind() != ast.ASTKind.FunctionDef:
|
||||
continue
|
||||
if child is None: continue
|
||||
if child.kind() != ast.ASTKind.FunctionDef: continue
|
||||
fd: ast.FunctionDef* = ast.FunctionDef*(child)
|
||||
if fd is None or fd.name is None:
|
||||
continue
|
||||
if fd is None or fd.name is None: continue
|
||||
|
||||
# PEP 695 泛型函数(def f[T](...) -> T)按普通函数编译(TPV 无泛型
|
||||
# 函数特化机制,与 translate_function_def L678-691 一致):此处先设置
|
||||
@@ -121,8 +106,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 推断返回类型
|
||||
ret_ty: llvmlite.LLVMType* = None
|
||||
if fd.returns is not None:
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
# 单独 t.CExport 返回注解(def free(...) -> t.CExport:)=
|
||||
# 导出修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type
|
||||
# 回退为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。
|
||||
@@ -141,15 +125,13 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 否则 declare i32 + define {i64,i64,i64} → llc "value doesn't
|
||||
# match function result type"——GetMemoryStats 根因)
|
||||
if ret_ty is None:
|
||||
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(
|
||||
pool, fd, imported_modules, from_imports, trans)
|
||||
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans)
|
||||
if ret_ty is None and fd.returns is not None:
|
||||
# 有返回注解但解析失败:编译期报错,不静默回退 i32。
|
||||
# (i32 回退曾导致掉尾检查强制 return i32 / 跨模块调用返回类型错位,
|
||||
# mm.vp free / GetMemoryStats 根因。)无返回注解函数(def foo():)
|
||||
# 保留 i32 默认,不在此报错。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fd, "函数返回类型解析失败:注解不可解析", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(fd, "函数返回类型解析失败:注解不可解析", "TypeError")
|
||||
return 0
|
||||
if ret_ty is None:
|
||||
ret_ty = i32_ty
|
||||
@@ -193,8 +175,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
continue
|
||||
|
||||
# 创建 declare
|
||||
func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, mangled_name, ret_ty)
|
||||
func: llvmlite.Function* = llvmlite.create_declare(pool, mod, mangled_name, ret_ty)
|
||||
if func is None:
|
||||
if tp_names_fd is not None:
|
||||
self.Gen.TypeGenBase.clear_generic_context()
|
||||
@@ -238,21 +219,17 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
an: sizet = len(alist)
|
||||
for ai in range(an):
|
||||
arg: ast.Arg* = ast.Arg*(alist.get(ai))
|
||||
if arg is None or arg.arg is None:
|
||||
continue
|
||||
if arg is None or arg.arg is None: continue
|
||||
# CVoid 表示空参:跳过
|
||||
if arg.annotation is not None:
|
||||
if self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0:
|
||||
continue
|
||||
if self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0: continue
|
||||
param_ty: llvmlite.LLVMType* = i32_ty
|
||||
if arg.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved is None:
|
||||
# [S4 fail-fast] 有注解但解析失败:不再静默用 i32
|
||||
# (declare 与 define 签名不一致 → ABI 错位,运行期读栈垃圾)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg, f"前向声明形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg, f"前向声明形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
return 0
|
||||
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||
# CArray 形参 → 元素指针 ty*(C 数组衰减,与 add_param 一致)
|
||||
@@ -331,8 +308,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 推断返回类型:优先使用返回类型注解
|
||||
ret_ty: llvmlite.LLVMType* = None
|
||||
if fd.returns is not None:
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0)
|
||||
# 单独 t.CExport 返回注解(def free(...) -> t.CExport:)= 导出
|
||||
# 修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type 回退
|
||||
# 为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。
|
||||
@@ -357,8 +333,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# declare 成 i32 → 定义阶段 ret {i64,i64,i64} 与 i32 不匹配。
|
||||
# 公共方法 _resolve_creturn_ret_ty 保证声明/定义两阶段一致)
|
||||
if ret_ty is None:
|
||||
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(
|
||||
pool, fd, imported_modules, from_imports, trans)
|
||||
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans)
|
||||
|
||||
# 如果仍然为 None,扫描 return 语句推断(至少返回 i32)
|
||||
if ret_ty is None:
|
||||
@@ -371,18 +346,13 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if self.Gen.TypeGenErr.body_has_value_return(pool, fd.children) != 0:
|
||||
rtn_err: str = pool.alloc(256)
|
||||
if rtn_err is not None:
|
||||
viperlib.snprintf(
|
||||
rtn_err, 256,
|
||||
"函数 '%s' 无返回类型注解却返回了非 None 值,"
|
||||
"请添加显式返回类型注解(如 -> int)", fd.name)
|
||||
viperlib.snprintf(rtn_err, 256, "函数 '%s' 无返回类型注解却返回了非 None 值,请添加显式返回类型注解(如 -> int)", fd.name)
|
||||
self.Gen.TypeGenErr.fatal_error(fd, rtn_err, "TypeError")
|
||||
return 0
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fd, "函数无返回类型注解却返回了非 None 值", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(fd, "函数无返回类型注解却返回了非 None 值", "TypeError")
|
||||
return 0
|
||||
param_types_str: str = self.Gen.TypeGenErr.build_param_types_str(pool, fd.args)
|
||||
ret_ty = self.Gen.TypeGenErr.infer_return_type(
|
||||
pool, fd.children, param_types_str)
|
||||
ret_ty = self.Gen.TypeGenErr.infer_return_type(pool, fd.children, param_types_str)
|
||||
# 检测是否为外部声明函数(t.CExtern 或 t.State)
|
||||
# 语义:t.CExtern 忽略 body 体,仅生成 declare(由链接器解析符号)
|
||||
# t.State = t.CExtern + t.CExport(既是声明又是导出)
|
||||
@@ -493,14 +463,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 外部声明函数:生成 declare(仅声明,不定义)
|
||||
# 先检查是否已由 forward_declare_functions 创建,避免重复 declare
|
||||
existing_extern: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name)
|
||||
if existing_extern is not None:
|
||||
# 已存在前向声明,复用之,不再重复创建
|
||||
return 0
|
||||
if existing_extern is not None: return 0
|
||||
|
||||
func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, mangled_name, ret_ty)
|
||||
if func is None:
|
||||
return 0
|
||||
func: llvmlite.Function* = llvmlite.create_declare(pool, mod, mangled_name, ret_ty)
|
||||
if func is None: return 0
|
||||
|
||||
# 注册到函数表
|
||||
max_funcs_extern: int = 256
|
||||
@@ -523,14 +489,11 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
continue
|
||||
param_ty_e: llvmlite.LLVMType* = i32_ty
|
||||
if arg_e.annotation is not None:
|
||||
resolved_e: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg_e.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved_e: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_e.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved_e is None:
|
||||
# fail-fast:外部声明函数参数有注解但类型解析失败,
|
||||
# 不再静默保持 i32(声明签名错误会在 ABI 层暴露)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg_e, f"参数 '{arg_e.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_e.annotation)}",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg_e, f"参数 '{arg_e.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_e.annotation)}", "NameError")
|
||||
resolved_e = i32_ty # 不可达(fatal_error 已退出)
|
||||
if resolved_e is not None:
|
||||
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||
@@ -560,8 +523,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if func_attrs_e is not None:
|
||||
llvmlite.function_set_attrs(func, func_attrs_e)
|
||||
# B5:section 字符串属性走属性组 #N
|
||||
func_section_e: str = self.Gen.FuncGenBase.extract_func_section(
|
||||
pool, fd.decorator_list, imported_modules)
|
||||
func_section_e: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules)
|
||||
if func_section_e is not None:
|
||||
llvmlite.function_set_attr_group(func, func_section_e)
|
||||
|
||||
@@ -583,8 +545,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if func_attrs_reuse is not None:
|
||||
llvmlite.function_set_attrs(func, func_attrs_reuse)
|
||||
# B5:section 字符串属性走属性组 #N
|
||||
func_section_reuse: str = self.Gen.FuncGenBase.extract_func_section(
|
||||
pool, fd.decorator_list, imported_modules)
|
||||
func_section_reuse: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules)
|
||||
if func_section_reuse is not None:
|
||||
llvmlite.function_set_attr_group(func, func_section_reuse)
|
||||
else:
|
||||
@@ -599,8 +560,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if func_attrs is not None:
|
||||
llvmlite.function_set_attrs(func, func_attrs)
|
||||
# B5:section 字符串属性走属性组 #N(LLVM 不接受内联 section="...")
|
||||
func_section: str = self.Gen.FuncGenBase.extract_func_section(
|
||||
pool, fd.decorator_list, imported_modules)
|
||||
func_section: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules)
|
||||
if func_section is not None:
|
||||
llvmlite.function_set_attr_group(func, func_section)
|
||||
|
||||
@@ -640,13 +600,11 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
continue
|
||||
param_ty: llvmlite.LLVMType* = i32_ty
|
||||
if arg.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved is None:
|
||||
# [S4 fail-fast] 有注解但解析失败:不再静默用 i32
|
||||
# (形参类型错 → ABI 错位/字段访问错)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg, f"形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg, f"形参 '{arg.arg}' 类型注解解析失败", "NameError")
|
||||
return 0
|
||||
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||
# CArray 形参 → 元素指针 ty*(C 数组衰减:final(out: t.CArray[..., N])
|
||||
@@ -707,8 +665,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
tls_flag_name: str = pool.alloc(128)
|
||||
if tls_flag_name is not None:
|
||||
viperlib.snprintf(tls_flag_name, 128, "__tls_init_done_%s", fd.name)
|
||||
tls_flag_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(
|
||||
pool, mod, tls_flag_name, 1, 0)
|
||||
tls_flag_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(pool, mod, tls_flag_name, 1, 0)
|
||||
if tls_flag_gv is not None:
|
||||
i1_ty_t: llvmlite.LLVMType* = llvmlite.Int1(pool)
|
||||
if i1_ty_t is not None:
|
||||
@@ -719,49 +676,40 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
tls_ref_name: str = pool.alloc(64)
|
||||
if tls_ref_name is not None:
|
||||
viperlib.snprintf(tls_ref_name, 64, "@%s", tls_flag_name)
|
||||
tls_flag_ref: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, tls_gv_ptr_ty, tls_ref_name)
|
||||
tls_flag_ref: llvmlite.Value* = llvmlite.SSAValue(pool, tls_gv_ptr_ty, tls_ref_name)
|
||||
if tls_flag_ref is not None:
|
||||
tls_flag_ld: llvmlite.Value* = llvmlite.build_load(
|
||||
func_builder, i1_ty_t, tls_flag_ref)
|
||||
tls_flag_ld: llvmlite.Value* = llvmlite.build_load(func_builder, i1_ty_t, tls_flag_ref)
|
||||
# 块名唯一化(create_block 不自动编号,同函数同名 label 冲突)
|
||||
lc_t: int = trans._label_counter
|
||||
trans._label_counter = lc_t + 1
|
||||
tls_bb_buf: str = pool.alloc(64)
|
||||
if tls_bb_buf is not None:
|
||||
viperlib.snprintf(tls_bb_buf, 64, "tls.skip.%d", lc_t)
|
||||
tls_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_bb_buf)
|
||||
tls_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_bb_buf)
|
||||
viperlib.snprintf(tls_bb_buf, 64, "tls.cont.%d", lc_t)
|
||||
tls_cont_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_bb_buf)
|
||||
tls_cont_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_bb_buf)
|
||||
if tls_skip_bb is not None and tls_cont_bb is not None:
|
||||
llvmlite.build_cond_br(
|
||||
func_builder, tls_flag_ld, tls_skip_bb, tls_cont_bb)
|
||||
llvmlite.build_cond_br(func_builder, tls_flag_ld, tls_skip_bb, tls_cont_bb)
|
||||
# skip 块:按返回类型生成默认值直接返回
|
||||
llvmlite.position_at_end(func_builder, tls_skip_bb)
|
||||
match ret_ty:
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
tlz0: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, ret_ty, 0, "0")
|
||||
tlz0: llvmlite.Value* = llvmlite.ConstInt(pool, ret_ty, 0, "0")
|
||||
if tlz0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlz0)
|
||||
case llvmlite.LLVMType.Float(_):
|
||||
tlf0: llvmlite.Value* = llvmlite.ConstFloat(
|
||||
pool, ret_ty, 0.0)
|
||||
tlf0: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0)
|
||||
if tlf0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlf0)
|
||||
case _:
|
||||
tln0: llvmlite.Value* = llvmlite.ConstNull(
|
||||
pool, ret_ty, "null")
|
||||
tln0: llvmlite.Value* = llvmlite.ConstNull(pool, ret_ty, "null")
|
||||
if tln0 is not None:
|
||||
llvmlite.build_ret(func_builder, tln0)
|
||||
# cont 块:置标志=1,继续函数体
|
||||
llvmlite.position_at_end(func_builder, tls_cont_bb)
|
||||
tlone: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, i1_ty_t, 1, "1")
|
||||
tlone: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_t, 1, "1")
|
||||
if tlone is not None:
|
||||
llvmlite.build_store(func_builder, tlone, tls_flag_ref)
|
||||
|
||||
@@ -798,13 +746,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
continue
|
||||
param_ty2: llvmlite.LLVMType* = i32_ty
|
||||
if arg2.annotation is not None:
|
||||
resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg2.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg2.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved2 is None:
|
||||
# fail-fast:参数有注解但类型解析失败,不再静默保持 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg2, f"参数 '{arg2.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg2.annotation)}",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg2, f"参数 '{arg2.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg2.annotation)}", "NameError")
|
||||
resolved2 = i32_ty # 不可达(fatal_error 已退出)
|
||||
if resolved2 is not None:
|
||||
# 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针);
|
||||
@@ -824,11 +769,9 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 传 pool:泛型 Subscript 返回 mangled name(对齐 HandlesAnnAssign 修复)
|
||||
cls_nm: str = None
|
||||
if arg2.annotation is not None:
|
||||
cls_nm = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
|
||||
arg2.annotation, imported_modules, pool, trans._from_imports)
|
||||
cls_nm = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg2.annotation, imported_modules, pool, trans._from_imports)
|
||||
if cls_nm is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, arg2.arg, cls_nm)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg2.arg, cls_nm)
|
||||
# t.CVolatile 形参:声明期标记,函数体内该参数名的
|
||||
# load/store 带 volatile(volatile 参数对象的读改写不得
|
||||
# 被优化器提升/合并,如自旋等待入参)。
|
||||
@@ -837,28 +780,19 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 是否含 t.CConst,不看指针层数)——TPC 形参登记点
|
||||
# HandlesFunctions 的 IsParam=True 用同一条件,两侧逐条
|
||||
# 对齐(见 Debugger/type-descriptors.md 已知差异)。
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(
|
||||
arg2.annotation, "CConst", 0) != 0:
|
||||
self.Gen.VarGen.set_var_const(
|
||||
trans.SymTab, arg2.arg)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(
|
||||
arg2.annotation, "CVolatile", 0) != 0:
|
||||
self.Gen.VarGen.set_var_volatile(
|
||||
trans.SymTab, arg2.arg)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(arg2.annotation, "CConst", 0) != 0:
|
||||
self.Gen.VarGen.set_var_const(trans.SymTab, arg2.arg)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(arg2.annotation, "CVolatile", 0) != 0:
|
||||
self.Gen.VarGen.set_var_volatile(trans.SymTab, arg2.arg)
|
||||
# rawptr[t.CVolatile | T] 形参(volatile 指针指向物):
|
||||
# 函数体内该参数解引用(p[i]/p.field/c.Deref(p))带 volatile。
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(
|
||||
arg2.annotation) != 0:
|
||||
self.Gen.VarGen.set_var_pointee_volatile(
|
||||
trans.SymTab, arg2.arg)
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(arg2.annotation) != 0:
|
||||
self.Gen.VarGen.set_var_pointee_volatile(trans.SymTab, arg2.arg)
|
||||
pname2: str = pool.alloc(32)
|
||||
if pname2 is not None:
|
||||
viperlib.snprintf(pname2, 32, "%%%s", arg2.arg)
|
||||
param_val: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, param_ty2, pname2)
|
||||
vol_p2: int = self.Gen.VarGen.var_is_volatile(
|
||||
self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, arg2.arg))
|
||||
param_val: llvmlite.Value* = llvmlite.SSAValue(pool, param_ty2, pname2)
|
||||
vol_p2: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg2.arg))
|
||||
llvmlite.build_store(func_builder, param_val, alloca, vol_p2)
|
||||
|
||||
# *args 变长参数:创建 va_list 缓冲区 + 调用 va_start + 注册到符号表
|
||||
@@ -879,12 +813,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i8_ty_va: llvmlite.LLVMType* = llvmlite.Int8(pool)
|
||||
i8_ptr_ty_va: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_va)
|
||||
va_buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty_va, 24)
|
||||
va_list_alloca: llvmlite.Value* = llvmlite.build_alloca_aligned(
|
||||
func_builder, va_buf_ty, 16)
|
||||
va_list_alloca: llvmlite.Value* = llvmlite.build_alloca_aligned(func_builder, va_buf_ty, 16)
|
||||
if va_list_alloca is not None:
|
||||
# i8* 地址(指向 24 字节 va_list 缓冲区)——vararg 名的值语义
|
||||
va_list_addr: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
func_builder, va_list_alloca, i8_ptr_ty_va)
|
||||
va_list_addr: llvmlite.Value* = llvmlite.build_bitcast(func_builder, va_list_alloca, i8_ptr_ty_va)
|
||||
if va_list_addr is not None:
|
||||
# 注册到符号表(translate_name_value 对 vararg 名特殊处理返回地址)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, vararg_name_str, va_list_alloca)
|
||||
@@ -916,10 +848,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i32_ty_eh2: llvmlite.LLVMType* = llvmlite.Int32(pool)
|
||||
i32_ptr_ty_eh2: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty_eh2)
|
||||
if i8_ptr_ptr_ty_eh2 is not None and i32_ptr_ty_eh2 is not None:
|
||||
msg_out_ref: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__")
|
||||
code_out_ref: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, i32_ptr_ty_eh2, "%__eh_code_out__")
|
||||
msg_out_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__")
|
||||
code_out_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i32_ptr_ty_eh2, "%__eh_code_out__")
|
||||
trans._eh_msg_out_param = msg_out_ref
|
||||
trans._eh_code_out_param = code_out_ref
|
||||
trans._cur_func_has_eh = 1
|
||||
@@ -970,9 +900,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 嵌套函数定义前:预扫描其链内 nonlocal 并建堆
|
||||
# (不同层捕获不同变量的场景,见 _prepare_chain_nonlocals)
|
||||
if stmt2.kind() == ast.ASTKind.FunctionDef:
|
||||
self.Gen.FuncGen._prepare_chain_nonlocals(
|
||||
trans, stmt2, pool, func_builder, mod,
|
||||
llvmlite.Int8(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool)))
|
||||
self.Gen.FuncGen._prepare_chain_nonlocals(trans, stmt2, pool, func_builder, mod, llvmlite.Int8(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool)))
|
||||
self.Gen.StmtGen.translate_stmt(trans, stmt2)
|
||||
|
||||
# 如果函数体最后一条语句不是 Return,添加隐式 ret
|
||||
@@ -1026,12 +954,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# ② 裸名 CVoid(from t import CVoid)③ -> None(CONST_NONE);
|
||||
# ①②统一经既有判据 TypeGenResolve._is_cvoid_marker 判定(不新增名字白名单)。
|
||||
if _is_void == 0 and fd.returns is not None:
|
||||
if self.Gen.TypeGenResolve._is_cvoid_marker(
|
||||
fd.returns, imported_modules) != 0:
|
||||
if self.Gen.TypeGenResolve._is_cvoid_marker(fd.returns, imported_modules) != 0:
|
||||
_is_void = 1
|
||||
elif fd.returns.kind() == ast.ASTKind.Constant:
|
||||
ret_none_cn: ast.Constant* = (
|
||||
ast.Constant*)(fd.returns)
|
||||
ret_none_cn: ast.Constant* = (ast.Constant*)(fd.returns)
|
||||
if ret_none_cn.const_kind == ast.CONST_NONE:
|
||||
_is_void = 1
|
||||
if _is_void != 0:
|
||||
@@ -1068,10 +994,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
rt_name = "?"
|
||||
err_fn: str = pool.alloc(256)
|
||||
if err_fn is not None:
|
||||
viperlib.snprintf(
|
||||
err_fn, 256,
|
||||
"函数 '%s' 流程掉出函数末尾但未显式 return(返回类型 %s),"
|
||||
"请补显式 return(如 return 0 / return null)", fd.name, rt_name)
|
||||
viperlib.snprintf(err_fn, 256, "函数 '%s' 流程掉出函数末尾但未显式 return(返回类型 %s),请补显式 return(如 return 0 / return null)", fd.name, rt_name)
|
||||
self.Gen.TypeGenErr.fatal_error(node, err_fn, "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "函数流程掉出末尾但未显式 return", "TypeError")
|
||||
else:
|
||||
@@ -1105,9 +1028,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if wb_name is not None:
|
||||
viperlib.snprintf(wb_name, 128, "__decor_wrap_%s", fd.name)
|
||||
self.Gen.ClassGenBase.register_decorator(pool, fd.name, wb_name, decor_arg0)
|
||||
self._gen_decor_wrapper(
|
||||
trans, pool, mod, func, fd.name, wb_name,
|
||||
decor_handler, decor_arg0)
|
||||
self._gen_decor_wrapper(trans, pool, mod, func, fd.name, wb_name, decor_handler, decor_arg0)
|
||||
|
||||
return 0
|
||||
# ============================================================
|
||||
@@ -1165,10 +1086,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
pp = llvmlite.param_get_next(pp)
|
||||
|
||||
# ---- 创建 wrapper 函数并添加参数(名字 %a0..%aN)----
|
||||
wrapper: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, wrapper_name, ret_ty)
|
||||
if wrapper is None:
|
||||
return None
|
||||
wrapper: llvmlite.Function* = llvmlite.create_function(pool, mod, wrapper_name, ret_ty)
|
||||
if wrapper is None: return None
|
||||
pi: int = 0
|
||||
for pi in range(n_params):
|
||||
pname_w: str = pool.alloc(16)
|
||||
@@ -1217,8 +1136,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
return None
|
||||
rec_val: llvmlite.Value* = llvmlite.build_load(wb, i8_ty, rec_flag_ref)
|
||||
rec_zero: llvmlite.Value* = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
rec_is: llvmlite.Value* = llvmlite.build_icmp(
|
||||
wb, llvmlite.ICMP_NE, rec_val, rec_zero)
|
||||
rec_is: llvmlite.Value* = llvmlite.build_icmp(wb, llvmlite.ICMP_NE, rec_val, rec_zero)
|
||||
llvmlite.build_cond_br(wb, rec_is, rec_bb, dec_bb)
|
||||
# recursive_call:直接调用原函数返回(跳过所有装饰逻辑)
|
||||
llvmlite.position_at_end(wb, rec_bb)
|
||||
@@ -1229,8 +1147,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if an_r is None:
|
||||
continue
|
||||
viperlib.snprintf(an_r, 16, "%%a%d", ri)
|
||||
av_r: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, (llvmlite.LLVMType*)(param_tys[ri]), an_r)
|
||||
av_r: llvmlite.Value* = llvmlite.SSAValue(pool, (llvmlite.LLVMType*)(param_tys[ri]), an_r)
|
||||
if av_r is not None:
|
||||
llvmlite.value_set_next(av_r, None)
|
||||
if rec_args is None:
|
||||
@@ -1245,8 +1162,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.build_call(wb, orig_call_name, rec_args, n_params, ret_ty, 0)
|
||||
llvmlite.build_ret_void(wb)
|
||||
else:
|
||||
rc_res: llvmlite.Value* = llvmlite.build_call(
|
||||
wb, orig_call_name, rec_args, n_params, ret_ty, 0)
|
||||
rc_res: llvmlite.Value* = llvmlite.build_call(wb, orig_call_name, rec_args, n_params, ret_ty, 0)
|
||||
if rc_res is not None:
|
||||
llvmlite.build_ret(wb, rc_res)
|
||||
else:
|
||||
@@ -1271,26 +1187,22 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
fields_head: llvmlite.Function* = None
|
||||
fk: int = 0
|
||||
for fk in range(n_params - 1, -1, -1):
|
||||
pn_n: llvmlite.Function* = llvmlite.new_param_node(
|
||||
pool, (llvmlite.LLVMType*)(param_tys[fk]))
|
||||
pn_n: llvmlite.Function* = llvmlite.new_param_node(pool, (llvmlite.LLVMType*)(param_tys[fk]))
|
||||
if pn_n is not None:
|
||||
pn_n.Next = fields_head
|
||||
fields_head = pn_n
|
||||
args_ty: llvmlite.LLVMType* = llvmlite.Struct(
|
||||
pool, fields_head, n_params, None)
|
||||
args_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, fields_head, n_params, None)
|
||||
if args_ty is not None:
|
||||
args_alloca = llvmlite.build_alloca(wb, args_ty)
|
||||
fi2: int = 0
|
||||
for fi2 in range(n_params):
|
||||
fld_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[fi2])
|
||||
fld_ptr: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
wb, args_ty, fld_ty, args_alloca, fi2)
|
||||
fld_ptr: llvmlite.Value* = llvmlite.build_gep_struct(wb, args_ty, fld_ty, args_alloca, fi2)
|
||||
if fld_ptr is not None:
|
||||
fld_nm: str = pool.alloc(16)
|
||||
if fld_nm is not None:
|
||||
viperlib.snprintf(fld_nm, 16, "%%a%d", fi2)
|
||||
fld_v: llvmlite.Value* = llvmlite.SSAValue(
|
||||
pool, fld_ty, fld_nm)
|
||||
fld_v: llvmlite.Value* = llvmlite.SSAValue(pool, fld_ty, fld_nm)
|
||||
if fld_v is not None:
|
||||
llvmlite.build_store(wb, fld_v, fld_ptr)
|
||||
args_ptr = llvmlite.build_bitcast(wb, args_alloca, i8_ptr_ty)
|
||||
@@ -1313,15 +1225,13 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.build_store(wb, ret_zero, ret_alloca)
|
||||
|
||||
# 4. 函数名字符串常量
|
||||
fn_str: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(
|
||||
wb, pool, mod, func_name, trans)
|
||||
fn_str: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(wb, pool, mod, func_name, trans)
|
||||
if fn_str is None:
|
||||
fn_str = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
|
||||
# 5. handler 声明(未翻译时 declare,固定签名 i32 (i8*,i8*,i32,i8*,i8*,i8*))
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, handler_name) is None:
|
||||
handler_d: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, handler_name, i32_ty)
|
||||
handler_d: llvmlite.Function* = llvmlite.create_declare(pool, mod, handler_name, i32_ty)
|
||||
if handler_d is not None:
|
||||
llvmlite.add_param(pool, handler_d, i8_ptr_ty, "ctx")
|
||||
llvmlite.add_param(pool, handler_d, i8_ptr_ty, "func_name")
|
||||
@@ -1336,18 +1246,12 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
null_dec: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
# 参数链表(6 个独立值):ctx_ptr → fn_str → 0 → args_ptr → null → null
|
||||
# 注意:不能 self 链接(null.Next = null 会让 build_call 遍历死循环)
|
||||
if ctx_ptr is not None:
|
||||
llvmlite.value_set_next(ctx_ptr, fn_str)
|
||||
if fn_str is not None:
|
||||
llvmlite.value_set_next(fn_str, ph0)
|
||||
if ph0 is not None:
|
||||
llvmlite.value_set_next(ph0, args_ptr)
|
||||
if args_ptr is not None:
|
||||
llvmlite.value_set_next(args_ptr, null_ret)
|
||||
if null_ret is not None:
|
||||
llvmlite.value_set_next(null_ret, null_dec)
|
||||
n_calls: llvmlite.Value* = llvmlite.build_call(
|
||||
wb, handler_name, ctx_ptr, 6, i32_ty, 0)
|
||||
if ctx_ptr is not None: llvmlite.value_set_next(ctx_ptr, fn_str)
|
||||
if fn_str is not None: llvmlite.value_set_next(fn_str, ph0)
|
||||
if ph0 is not None: llvmlite.value_set_next(ph0, args_ptr)
|
||||
if args_ptr is not None: llvmlite.value_set_next(args_ptr, null_ret)
|
||||
if null_ret is not None: llvmlite.value_set_next(null_ret, null_dec)
|
||||
n_calls: llvmlite.Value* = llvmlite.build_call(wb, handler_name, ctx_ptr, 6, i32_ty, 0)
|
||||
|
||||
# 7. 计数器 alloca(TPV 用 alloca 计数器替代 phi)
|
||||
cnt_alloca: llvmlite.Value* = llvmlite.build_alloca(wb, i32_ty)
|
||||
@@ -1359,8 +1263,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 8. loop.header:cur = load cnt; cur < n_calls → body / post
|
||||
llvmlite.position_at_end(wb, loop_h_bb)
|
||||
cur_i: llvmlite.Value* = llvmlite.build_load(wb, i32_ty, cnt_alloca)
|
||||
loop_cond: llvmlite.Value* = llvmlite.build_icmp(
|
||||
wb, llvmlite.ICMP_SLT, cur_i, n_calls)
|
||||
loop_cond: llvmlite.Value* = llvmlite.build_icmp(wb, llvmlite.ICMP_SLT, cur_i, n_calls)
|
||||
llvmlite.build_cond_br(wb, loop_cond, loop_b_bb, post_bb)
|
||||
|
||||
# 9. loop.body:读回参数(装饰器可能已修改)→ 调用原函数 → store ret
|
||||
@@ -1370,10 +1273,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
k: int = 0
|
||||
for k in range(n_params):
|
||||
fld_ty_k: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[k])
|
||||
fld_pk: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
wb, args_ty, fld_ty_k, args_alloca, k)
|
||||
if fld_pk is None:
|
||||
continue
|
||||
fld_pk: llvmlite.Value* = llvmlite.build_gep_struct(wb, args_ty, fld_ty_k, args_alloca, k)
|
||||
if fld_pk is None: continue
|
||||
fld_vk: llvmlite.Value* = llvmlite.build_load(wb, fld_ty_k, fld_pk)
|
||||
if fld_vk is not None:
|
||||
llvmlite.value_set_next(fld_vk, None)
|
||||
@@ -1384,12 +1285,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
while ct.Next is not None:
|
||||
ct = ct.Next
|
||||
llvmlite.value_set_next(ct, fld_vk)
|
||||
res_v: llvmlite.Value* = llvmlite.build_call(
|
||||
wb, orig_call_name, call_args, n_params, ret_ty, 0)
|
||||
res_v: llvmlite.Value* = llvmlite.build_call(wb, orig_call_name, call_args, n_params, ret_ty, 0)
|
||||
if ret_alloca is not None and res_v is not None:
|
||||
llvmlite.build_store(wb, res_v, ret_alloca)
|
||||
nxt_i: llvmlite.Value* = llvmlite.build_add(
|
||||
wb, cur_i, llvmlite.ConstInt(pool, i32_ty, 1, "1"))
|
||||
nxt_i: llvmlite.Value* = llvmlite.build_add(wb, cur_i, llvmlite.ConstInt(pool, i32_ty, 1, "1"))
|
||||
if nxt_i is not None and cnt_alloca is not None:
|
||||
llvmlite.build_store(wb, nxt_i, cnt_alloca)
|
||||
llvmlite.build_br(wb, loop_h_bb)
|
||||
@@ -1401,16 +1300,11 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
ret_ptr = llvmlite.build_bitcast(wb, ret_alloca, i8_ptr_ty)
|
||||
ph1: llvmlite.Value* = llvmlite.ConstInt(pool, i32_ty, 1, "1")
|
||||
# 后置参数链:ctx_ptr → fn_str → 1 → args_ptr → ret_ptr → null
|
||||
if ctx_ptr is not None:
|
||||
llvmlite.value_set_next(ctx_ptr, fn_str)
|
||||
if fn_str is not None:
|
||||
llvmlite.value_set_next(fn_str, ph1)
|
||||
if ph1 is not None:
|
||||
llvmlite.value_set_next(ph1, args_ptr)
|
||||
if args_ptr is not None:
|
||||
llvmlite.value_set_next(args_ptr, ret_ptr)
|
||||
if ret_ptr is not None:
|
||||
llvmlite.value_set_next(ret_ptr, null_dec)
|
||||
if ctx_ptr is not None: llvmlite.value_set_next(ctx_ptr, fn_str)
|
||||
if fn_str is not None: llvmlite.value_set_next(fn_str, ph1)
|
||||
if ph1 is not None: llvmlite.value_set_next(ph1, args_ptr)
|
||||
if args_ptr is not None: llvmlite.value_set_next(args_ptr, ret_ptr)
|
||||
if ret_ptr is not None: llvmlite.value_set_next(ret_ptr, null_dec)
|
||||
llvmlite.build_call(wb, handler_name, ctx_ptr, 6, i32_ty, 0)
|
||||
if rec_flag_ref is not None:
|
||||
rec_zero2: llvmlite.Value* = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
|
||||
@@ -15,55 +15,19 @@ import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FuncGenMixin - 函数/方法声明与翻译 Mixin(对象化 P5-1,wiki/14-oo-refactor.md)
|
||||
#
|
||||
# 从 HandlesFunctions.vp 迁移:模块级纯函数(trans 首参,无全局状态)
|
||||
# → 类方法(self 替代,trans 参数保留)。
|
||||
#
|
||||
# 迁移原则(与 P2/P3/P4 一致,行为零变化):
|
||||
# 1. 方法保留原函数签名(含 trans 首参),仅函数体内的
|
||||
# 本模块函数调用改为 self.xxx(...)
|
||||
# 2. 外部模块调用(HandlesExprCall.xxx/HandlesType.xxx 等)保留模块前缀
|
||||
# 3. HandlesFunctions.vp 原函数保留为"委托":本地模块级单例 _g_gen
|
||||
# (BuildPipeline/main 注入)cast 成 Generator 类型
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。
|
||||
# FuncGenMixin - 函数/方法声明与翻译 Mixin
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# HandlesFunctions - 函数定义处理(trans 单参模式)
|
||||
#
|
||||
# 参考 Python 版 TransPyC FunctionHandle
|
||||
#
|
||||
# 函数有自己的局部作用域,通过 HandlesVar.enter_scope/exit_scope
|
||||
# 管理嵌套作用域链,翻译函数体前进入函数作用域,翻译完退出。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# 作用域类型常量(本地副本,与 HandlesFunctions.vp 保持一致)
|
||||
SCOPE_FUNCTION: t.CDefine = 1
|
||||
# 作用域类型常量 存疑
|
||||
define SCOPE_FUNCTION = 1
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FuncGenMixin - 函数属性/命名/声明/翻译
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
"""函数/方法翻译 Mixin(纯方法化迁移,无状态字段)"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ============================================================
|
||||
# translate_nested_function_def - 嵌套函数提升 + 闭包创建
|
||||
#
|
||||
@@ -74,12 +38,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节, malloc 分配)
|
||||
# Env 结构: {i8* ptr0, i8* ptr1, ...} (每个 nonlocal 变量 8 字节,指向父函数 alloca)
|
||||
# ============================================================
|
||||
def translate_nested_function_def(self, trans: HT.Translator*,
|
||||
node: ast.AST*) -> int:
|
||||
def translate_nested_function_def(self, trans: HT.Translator*, node: ast.AST*) -> int:
|
||||
"""翻译嵌套函数定义:提升为顶层函数 + 创建闭包"""
|
||||
fd: ast.FunctionDef* = ast.FunctionDef*(node)
|
||||
if fd is None or fd.name is None:
|
||||
return 0
|
||||
if fd is None or fd.name is None: return 0
|
||||
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
mod: llvmlite.LLVMModule* = trans.Module
|
||||
@@ -96,10 +58,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
mangled_promoted: str = self.Gen.FuncGenBase._mangle_name(trans, promoted_name)
|
||||
|
||||
# 2. 创建提升后的函数: define i32 @__closure_{name}(i8* %env, args...)
|
||||
func: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, mangled_promoted, i32_ty)
|
||||
if func is None:
|
||||
return 0
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_promoted, i32_ty)
|
||||
if func is None: return 0
|
||||
llvmlite.add_param(pool, func, i8_ptr_ty, "%env")
|
||||
|
||||
# 2a. 嵌套函数参数:加入提升函数签名(i8* %env, 参数...),
|
||||
@@ -117,15 +77,12 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
an_n: sizet = len(alist_n)
|
||||
for ai_n in range(an_n):
|
||||
arg_n: ast.Arg* = ast.Arg*(alist_n.get(ai_n))
|
||||
if arg_n is None or arg_n.arg is None:
|
||||
continue
|
||||
if arg_n is None or arg_n.arg is None: continue
|
||||
if arg_n.annotation is not None:
|
||||
if self.Gen.TypeGenResolve._is_t_attr(arg_n.annotation, "CVoid", imported_modules) != 0:
|
||||
continue
|
||||
if self.Gen.TypeGenResolve._is_t_attr(arg_n.annotation, "CVoid", imported_modules) != 0: continue
|
||||
pty_n: llvmlite.LLVMType* = i32_ty
|
||||
if arg_n.annotation is not None:
|
||||
resolved_n: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg_n.annotation, imported_modules, from_imports, trans, 0)
|
||||
resolved_n: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_n.annotation, imported_modules, from_imports, trans, 0)
|
||||
if resolved_n is not None:
|
||||
match resolved_n:
|
||||
case llvmlite.LLVMType.Struct(_, _, _):
|
||||
@@ -135,8 +92,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
pty_n = resolved_n
|
||||
if param_count < 64 and param_tys is not None:
|
||||
pty_slot_n: str | t.CPtr = (t.CPtr)(
|
||||
uint64(param_tys) + param_count * 8)
|
||||
pty_slot_n: str | t.CPtr = (t.CPtr)(uint64(param_tys) + param_count * 8)
|
||||
pty_slot_n[0] = pty_n
|
||||
pname_n: str = pool.alloc(32)
|
||||
if pname_n is not None:
|
||||
@@ -146,11 +102,9 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
|
||||
# 3. 创建 entry 块 + builder
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
if entry_blk is None: return 0
|
||||
func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
if func_builder is None: return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
|
||||
# 4. 进入嵌套函数作用域(嵌套符号表)
|
||||
@@ -191,36 +145,27 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if p_alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, arg_p.arg, p_alloca)
|
||||
if arg_p.annotation is not None:
|
||||
cls_nm_p: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
|
||||
arg_p.annotation, imported_modules, pool, trans._from_imports)
|
||||
cls_nm_p: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg_p.annotation, imported_modules, pool, trans._from_imports)
|
||||
if cls_nm_p is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, arg_p.arg, cls_nm_p)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg_p.arg, cls_nm_p)
|
||||
# const 形参:沿用 TPC 形参的历史判据(只看注解是否含
|
||||
# t.CConst,不看指针层数),两侧逐条对齐(见
|
||||
# Debugger/type-descriptors.md 已知差异)。
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(
|
||||
arg_p.annotation, "CConst", 0) != 0:
|
||||
self.Gen.VarGen.set_var_const(
|
||||
trans.SymTab, arg_p.arg)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(arg_p.annotation, "CConst", 0) != 0:
|
||||
self.Gen.VarGen.set_var_const(trans.SymTab, arg_p.arg)
|
||||
# t.CVolatile 形参:声明期标记(与 FuncGenDef 主路径同款),
|
||||
# 函数体内该参数名的 load/store 带 volatile。
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(
|
||||
arg_p.annotation, "CVolatile", 0) != 0:
|
||||
self.Gen.VarGen.set_var_volatile(
|
||||
trans.SymTab, arg_p.arg)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(arg_p.annotation, "CVolatile", 0) != 0:
|
||||
self.Gen.VarGen.set_var_volatile(trans.SymTab, arg_p.arg)
|
||||
# rawptr[t.CVolatile | T] 形参(volatile 指针指向物):
|
||||
# 函数体内该参数解引用带 volatile(与 FuncGenDef 主路径同款)。
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(
|
||||
arg_p.annotation) != 0:
|
||||
self.Gen.VarGen.set_var_pointee_volatile(
|
||||
trans.SymTab, arg_p.arg)
|
||||
if self.Gen.TypeGenErr.has_pointee_volatile_marker(arg_p.annotation) != 0:
|
||||
self.Gen.VarGen.set_var_pointee_volatile(trans.SymTab, arg_p.arg)
|
||||
pname2_n: str = pool.alloc(32)
|
||||
if pname2_n is not None:
|
||||
viperlib.snprintf(pname2_n, 32, "%%%s", arg_p.arg)
|
||||
p_val: llvmlite.Value* = llvmlite.SSAValue(pool, pty2_n, pname2_n)
|
||||
vol_pn: int = self.Gen.VarGen.var_is_volatile(
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg_p.arg))
|
||||
vol_pn: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg_p.arg))
|
||||
llvmlite.build_store(func_builder, p_val, p_alloca, vol_pn)
|
||||
idx_p += 1
|
||||
|
||||
@@ -326,8 +271,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
env_size_val: llvmlite.Value* = llvmlite.const_int64(pool, env_size)
|
||||
if env_size_val is not None:
|
||||
env_size_val.Next = None
|
||||
env_ptr = llvmlite.build_call(
|
||||
parent_builder, "malloc", env_size_val, 1, i8_ptr_ty, 0)
|
||||
env_ptr = llvmlite.build_call(parent_builder, "malloc", env_size_val, 1, i8_ptr_ty, 0)
|
||||
|
||||
# 为每个 nonlocal 变量建立堆存储并注册到 env:
|
||||
# 运行时 env 链式共享(无需编译期映射——映射存编译期 Value 对象
|
||||
@@ -352,44 +296,33 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 1. 优先查全局堆地址映射(_prepare_chain_nonlocals 已为
|
||||
# 链内 nonlocal 建堆并 store 到 @nlheap.*;不同层捕获
|
||||
# 不同变量时(ClosureTest2 Test 7)level2 的 b 经此共享)
|
||||
gname_ck: str = self._nl_heap_global_name(
|
||||
pool, trans, nl_name)
|
||||
if gname_ck is not None \
|
||||
and self._nl_heap_global_exists(mod, gname_ck) != 0:
|
||||
gv_ref0: llvmlite.Value* = self._nl_heap_global_ref(
|
||||
pool, trans, nl_name)
|
||||
gname_ck: str = self._nl_heap_global_name(pool, trans, nl_name)
|
||||
if gname_ck is not None and self._nl_heap_global_exists(mod, gname_ck) != 0:
|
||||
gv_ref0: llvmlite.Value* = self._nl_heap_global_ref(pool, trans, nl_name)
|
||||
if gv_ref0 is not None:
|
||||
heap_store = llvmlite.build_load(
|
||||
parent_builder, i8_ptr_ty, gv_ref0)
|
||||
heap_store = llvmlite.build_load(parent_builder, i8_ptr_ty, gv_ref0)
|
||||
if heap_store is None:
|
||||
local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nl_name)
|
||||
local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nl_name)
|
||||
if local_alloca is not None and local_alloca.Ty is not None:
|
||||
# 父函数局部变量:新建堆存储 + 拷贝当前值 + 重定向
|
||||
nl_load_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee
|
||||
if nl_load_ty is not None:
|
||||
cur_val_nl: llvmlite.Value* = llvmlite.build_load(
|
||||
parent_builder, nl_load_ty, local_alloca)
|
||||
cur_val_nl: llvmlite.Value* = llvmlite.build_load(parent_builder, nl_load_ty, local_alloca)
|
||||
# 堆存储大小按类型字节数:数组(如 [4 x i32]=16 字节)
|
||||
# 不能固定 8 字节(越界写崩溃);指针/标量 ≥ 8 字节
|
||||
st_size: int = self._type_byte_size(pool, nl_load_ty)
|
||||
st_size_val: llvmlite.Value* = llvmlite.const_int64(
|
||||
pool, st_size)
|
||||
st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(
|
||||
parent_builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(parent_builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is not None:
|
||||
# 拷贝当前值到堆存储
|
||||
st_slot_nl: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
st_slot_nl: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
if st_slot_nl is not None and cur_val_nl is not None:
|
||||
llvmlite.build_store(parent_builder, cur_val_nl, st_slot_nl)
|
||||
# 父函数 VarEntry.Alloca 重定向到堆(父函数读写走共享堆)
|
||||
ve_nl: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nl_name)
|
||||
heap_typed: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
ve_nl: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nl_name)
|
||||
heap_typed: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
if ve_nl is not None and heap_typed is not None:
|
||||
ve_nl.Alloca = heap_typed
|
||||
# 记录到全局映射(后续层/父函数可见)
|
||||
@@ -405,8 +338,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
llvmlite.module_add_global(mod, gv_new)
|
||||
gv_ref_new = self._nl_heap_global_ref(pool, trans, nl_name)
|
||||
if gv_ref_new is not None:
|
||||
llvmlite.build_store(
|
||||
parent_builder, var_storage, gv_ref_new)
|
||||
llvmlite.build_store(parent_builder, var_storage, gv_ref_new)
|
||||
heap_store = var_storage
|
||||
else:
|
||||
# 父函数中该变量是 nonlocal(多层嵌套):从父函数 env
|
||||
@@ -416,11 +348,9 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
continue
|
||||
# env[ni] = 堆存储地址(共享)
|
||||
offset_val: llvmlite.Value* = llvmlite.const_int32(pool, ni * 8)
|
||||
slot: llvmlite.Value* = llvmlite.build_gep(
|
||||
parent_builder, i8_ty, env_ptr, offset_val)
|
||||
slot: llvmlite.Value* = llvmlite.build_gep(parent_builder, i8_ty, env_ptr, offset_val)
|
||||
if slot is not None:
|
||||
slot_typed: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, slot, i8_ptr_ptr_ty)
|
||||
slot_typed: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, slot, i8_ptr_ptr_ty)
|
||||
if slot_typed is not None:
|
||||
llvmlite.build_store(parent_builder, heap_store, slot_typed)
|
||||
|
||||
@@ -428,8 +358,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16)
|
||||
if closure_size_val is not None:
|
||||
closure_size_val.Next = None
|
||||
closure_ptr: llvmlite.Value* = llvmlite.build_call(
|
||||
parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
closure_ptr: llvmlite.Value* = llvmlite.build_call(parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
if closure_ptr is None:
|
||||
# malloc 失败,恢复状态
|
||||
trans._cur_func_name = old_func_name
|
||||
@@ -457,20 +386,16 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
|
||||
# bitcast 函数指针到 i8*(闭包存储 i8* 类型)
|
||||
fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if fn_slot is not None and fn_as_i8ptr is not None:
|
||||
llvmlite.build_store(parent_builder, fn_as_i8ptr, fn_slot)
|
||||
|
||||
# 13d. 存储 env_ptr 到 offset 8
|
||||
eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: llvmlite.Value* = llvmlite.build_gep(
|
||||
parent_builder, i8_ty, closure_ptr, eight_val)
|
||||
env_slot_addr: llvmlite.Value* = llvmlite.build_gep(parent_builder, i8_ty, closure_ptr, eight_val)
|
||||
if env_slot_addr is not None:
|
||||
env_slot: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
parent_builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
env_slot: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if env_slot is not None:
|
||||
if env_ptr is not None:
|
||||
llvmlite.build_store(parent_builder, env_ptr, env_slot)
|
||||
@@ -512,27 +437,19 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
k: int = node.kind()
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(node)
|
||||
if nm.id is None:
|
||||
return 1
|
||||
if nm.id is None: return 1
|
||||
# 当前作用域已定义(参数 / AnnAssign 局部,含分支内)→ 非捕获
|
||||
if self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) is not None:
|
||||
return 1
|
||||
if self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) is not None: return 1
|
||||
# 已注册 nonlocal(显式 nonlocal 语句 / 已捕获)→ 跳过
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return 1
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is None or ve.Alloca is None or ve.Alloca.Ty is None:
|
||||
return 1
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0: return 1
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if ve is None or ve.Alloca is None or ve.Alloca.Ty is None: return 1
|
||||
nl_ty: llvmlite.LLVMType* = ve.Alloca.Ty.Pointee
|
||||
if nl_ty is None:
|
||||
return 1
|
||||
if nl_ty is None: return 1
|
||||
# 模块级全局直接解析,无需 env 捕获
|
||||
mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id)
|
||||
if mod_gv is not None:
|
||||
if uint64(mod_gv) == uint64(ve.Alloca):
|
||||
return 1
|
||||
if uint64(mod_gv) == uint64(ve.Alloca): return 1
|
||||
# 外层函数局部变量 → 隐式捕获(注册为 nonlocal)
|
||||
GenApi.add_nonlocal_name(trans, nm.id, nl_ty)
|
||||
return 1
|
||||
@@ -569,7 +486,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, ifn.orelse.get(bi_el))
|
||||
return 1
|
||||
if k == ast.ASTKind.For:
|
||||
for_n: rawptr[ast.For] = rawptr[ast.For](node)
|
||||
for_n: ast.For* = ast.For*(node)
|
||||
# 循环目标是新局部变量,不参与捕获
|
||||
if for_n.iter is not None:
|
||||
self._closure_scan_captures(trans, for_n.iter)
|
||||
@@ -880,22 +797,18 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
"""计算 LLVM 类型占用的字节大小(递归)"""
|
||||
if ty is None:
|
||||
# [S4 fail-fast] 类型缺失 → 不再保守 8 字节(分配不足会越界写邻块)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "nonlocal 共享存储:类型缺失,无法计算尺寸", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "nonlocal 共享存储:类型缺失,无法计算尺寸", "TypeError")
|
||||
return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Int(bits):
|
||||
sz_i: int = (bits + 7) // 8
|
||||
if sz_i < 8:
|
||||
sz_i = 8
|
||||
if sz_i < 8: sz_i = 8
|
||||
return sz_i
|
||||
case llvmlite.LLVMType.Ptr(_pe):
|
||||
return 8
|
||||
case llvmlite.LLVMType.Float(fb):
|
||||
if fb == 64:
|
||||
return 8
|
||||
if fb >= 128:
|
||||
return 16
|
||||
if fb == 64: return 8
|
||||
if fb >= 128: return 16
|
||||
return 4
|
||||
case llvmlite.LLVMType.Array(et, cnt):
|
||||
esz: int = self._type_byte_size(pool, et)
|
||||
@@ -995,13 +908,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
continue
|
||||
dup: int = 0
|
||||
for di in range(count):
|
||||
if string.strcmp((str)(
|
||||
uint64(names) + di * 8), nm_x.id) == 0:
|
||||
if string.strcmp((str)(uint64(names) + di * 8), nm_x.id) == 0:
|
||||
dup = 1
|
||||
break
|
||||
if dup == 0 and count < 64:
|
||||
nm_slot: str | t.CPtr = (t.CPtr)(
|
||||
uint64(names) + count * 8)
|
||||
nm_slot: str* = (t.CPtr)(uint64(names) + count * 8)
|
||||
nm_slot[0] = nm_x.id
|
||||
count += 1
|
||||
return count
|
||||
@@ -1024,38 +935,28 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
i8_ty: llvmlite.LLVMType*,
|
||||
i8_ptr_ty: llvmlite.LLVMType*) -> int:
|
||||
"""预收集嵌套函数链内 nonlocal 并建堆,1 成功"""
|
||||
if node is None or trans is None or builder is None or mod is None:
|
||||
return 0
|
||||
if node is None or trans is None or builder is None or mod is None: return 0
|
||||
# 每函数只预建一次:多个嵌套函数定义共享同一堆(防重复 malloc +
|
||||
# 二次重定向 VarEntry.Alloca 导致兄弟闭包各持一堆,计数不同步)
|
||||
if trans._nl_chain_done != 0:
|
||||
return 1
|
||||
if trans._nl_chain_done != 0: return 1
|
||||
if trans._nl_chain_names is None:
|
||||
trans._nl_chain_names = pool.alloc(8 * 64)
|
||||
if trans._nl_chain_names is not None:
|
||||
string.memset(trans._nl_chain_names, 0, 8 * 64)
|
||||
if trans._nl_chain_names is None:
|
||||
return 0
|
||||
trans._nl_chain_count = self._collect_chain_nonlocals(
|
||||
trans, node, trans._nl_chain_names, 0)
|
||||
if trans._nl_chain_names is None: return 0
|
||||
trans._nl_chain_count = self._collect_chain_nonlocals(trans, node, trans._nl_chain_names, 0)
|
||||
trans._nl_chain_done = 1
|
||||
for ci in range(trans._nl_chain_count):
|
||||
nm_slot: str | t.CPtr = (t.CPtr)(
|
||||
uint64(trans._nl_chain_names) + ci * 8)
|
||||
nm_slot: str* = (t.CPtr)(uint64(trans._nl_chain_names) + ci * 8)
|
||||
nl_name: str = nm_slot[0]
|
||||
if nl_name is None:
|
||||
continue
|
||||
if nl_name is None: continue
|
||||
# 只在"定义它的函数"(当前顶层作用域有 alloca)中建堆
|
||||
local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nl_name)
|
||||
if local_alloca is None or local_alloca.Ty is None:
|
||||
continue
|
||||
local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nl_name)
|
||||
if local_alloca is None or local_alloca.Ty is None: continue
|
||||
nl_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee
|
||||
if nl_ty is None:
|
||||
continue
|
||||
if nl_ty is None: continue
|
||||
gname: str = self._nl_heap_global_name(pool, trans, nl_name)
|
||||
if gname is None:
|
||||
continue
|
||||
if gname is None: continue
|
||||
# 建堆(按类型字节大小)并拷贝当前值——每次本函数执行都新建共享堆,并 store 到
|
||||
# 模块级映射(跨函数可见)。不能因映射变量已存在就跳过:跳过会让本函数运行时
|
||||
# @nlheap.* 保持上一函数的堆地址,env 读到错堆。映射变量仅首次 add(模块去重),
|
||||
@@ -1064,22 +965,17 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is None:
|
||||
continue
|
||||
cur_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, nl_ty, local_alloca)
|
||||
st_slot: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
cur_val: llvmlite.Value* = llvmlite.build_load(builder, nl_ty, local_alloca)
|
||||
st_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
if st_slot is not None and cur_val is not None:
|
||||
llvmlite.build_store(builder, cur_val, st_slot)
|
||||
# 重定向 VarEntry(父函数读写走共享堆)
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nl_name)
|
||||
ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nl_name)
|
||||
if ve is not None:
|
||||
heap_typed: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
heap_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
if heap_typed is not None:
|
||||
ve.Alloca = heap_typed
|
||||
# 创建/复用全局映射变量并 store 堆地址(跨函数可见)
|
||||
@@ -1099,8 +995,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
gv_found.Initializer = "null"
|
||||
llvmlite.module_add_global(mod, gv_found)
|
||||
if gv_found is not None:
|
||||
gv_ref: llvmlite.Value* = self._nl_heap_global_ref(
|
||||
pool, trans, nl_name)
|
||||
gv_ref: llvmlite.Value* = self._nl_heap_global_ref(pool, trans, nl_name)
|
||||
if gv_ref is not None:
|
||||
llvmlite.build_store(builder, var_storage, gv_ref)
|
||||
return 1
|
||||
@@ -1169,13 +1064,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
string.strncpy(param_names + param_count * 32, arg_n.arg, 31)
|
||||
p_ty: llvmlite.LLVMType* = i32_ty
|
||||
if arg_n.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, arg_n.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_n.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if resolved is None:
|
||||
# fail-fast:lambda 参数有注解但类型解析失败,不再静默保持 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg_n, f"参数 '{arg_n.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_n.annotation)}",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(arg_n, f"参数 '{arg_n.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_n.annotation)}", "NameError")
|
||||
resolved = i32_ty # 不可达(fatal_error 已退出)
|
||||
if resolved is not None:
|
||||
match resolved:
|
||||
@@ -1185,8 +1077,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
p_ty = llvmlite.Ptr(pool, aelem_ty_l)
|
||||
case _:
|
||||
p_ty = resolved
|
||||
ty_slot_p: str | t.CPtr = (t.CPtr)(
|
||||
uint64(param_tys) + param_count * 8)
|
||||
ty_slot_p: str* = (t.CPtr)(uint64(param_tys) + param_count * 8)
|
||||
ty_slot_p[0] = p_ty
|
||||
param_count += 1
|
||||
|
||||
@@ -1203,19 +1094,15 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if cap_tys is None:
|
||||
return None
|
||||
string.memset(cap_tys, 0, 8 * 64)
|
||||
cap_count: int = self._lambda_scan_body(
|
||||
trans, lam.body, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, 0)
|
||||
cap_count: int = self._lambda_scan_body(trans, lam.body, param_names, param_count, cap_names, cap_allocas, cap_tys, 0)
|
||||
|
||||
# 4. 创建提升函数 __lambda_{id}(i8* %env, [args...])
|
||||
func: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, mangled_promoted, i32_ty)
|
||||
if func is None:
|
||||
return None
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_promoted, i32_ty)
|
||||
if func is None: return None
|
||||
llvmlite.add_param(pool, func, i8_ptr_ty, "%env")
|
||||
for pi2 in range(param_count):
|
||||
ty_addr2: uint64 = uint64(param_tys) + pi2 * 8
|
||||
ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2)
|
||||
ty_slot2: str* = (t.CPtr)(ty_addr2)
|
||||
p_ty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot2[0])
|
||||
if p_ty2 is None:
|
||||
p_ty2 = i32_ty
|
||||
@@ -1261,30 +1148,20 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 注意:不能用 (str)(cap_addr) 整数转换——TPV 将其编译为 itoa(整数转字符串),
|
||||
# 会把 cap_slot 变成数字串,define_var 键名错乱,lambda body lookup 无法命中。
|
||||
cap_slot: str = cap_names + ci * 64
|
||||
if cap_slot[0] == '\0':
|
||||
continue
|
||||
if cap_slot[0] == '\0': continue
|
||||
ty_addr3: uint64 = uint64(cap_tys) + ci * 8
|
||||
ty_slot3: str | t.CPtr = (t.CPtr)(ty_addr3)
|
||||
cap_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot3[0])
|
||||
if cap_ty is None:
|
||||
continue
|
||||
if cap_ty is None: continue
|
||||
off_val: llvmlite.Value* = llvmlite.const_int32(pool, ci * 8)
|
||||
slot_addr: llvmlite.Value* = llvmlite.build_gep(
|
||||
func_builder, i8_ty, env_param_val, off_val)
|
||||
if slot_addr is None:
|
||||
continue
|
||||
storage_addr: llvmlite.Value* = llvmlite.build_load(
|
||||
func_builder, i8_ptr_ty, slot_addr)
|
||||
if storage_addr is None:
|
||||
continue
|
||||
st_typed: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty))
|
||||
if st_typed is None:
|
||||
continue
|
||||
cap_val: llvmlite.Value* = llvmlite.build_load(
|
||||
func_builder, cap_ty, st_typed)
|
||||
if cap_val is None:
|
||||
continue
|
||||
slot_addr: llvmlite.Value* = llvmlite.build_gep(func_builder, i8_ty, env_param_val, off_val)
|
||||
if slot_addr is None: continue
|
||||
storage_addr: llvmlite.Value* = llvmlite.build_load(func_builder, i8_ptr_ty, slot_addr)
|
||||
if storage_addr is None: continue
|
||||
st_typed: llvmlite.Value* = llvmlite.build_bitcast(func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty))
|
||||
if st_typed is None: continue
|
||||
cap_val: llvmlite.Value* = llvmlite.build_load(func_builder, cap_ty, st_typed)
|
||||
if cap_val is None: continue
|
||||
var_alloca: llvmlite.Value* = llvmlite.build_alloca(func_builder, cap_ty)
|
||||
if var_alloca is not None:
|
||||
llvmlite.build_store(func_builder, cap_val, var_alloca)
|
||||
@@ -1297,8 +1174,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
p_ty3: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot4[0])
|
||||
if p_ty3 is None:
|
||||
# fail-fast:lambda 参数类型槽缺失(内部状态不一致),不再静默保持 i32
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
lam, f"lambda 参数 '{param_names + pi3 * 32}' 类型信息缺失", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(lam, f"lambda 参数 '{param_names + pi3 * 32}' 类型信息缺失", "InternalCompilerError")
|
||||
p_ty3 = i32_ty # 不可达(fatal_error 已退出)
|
||||
pname_ref: str = pool.alloc(32)
|
||||
if pname_ref is not None:
|
||||
@@ -1310,15 +1186,12 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.define_var(trans.SymTab, param_names + pi3 * 32, arg_alloca)
|
||||
|
||||
# 11. 翻译 body 表达式,coerce 到 i32 后 ret
|
||||
body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
func_builder, pool, mod, lam.body, None, 0, trans)
|
||||
body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(func_builder, pool, mod, lam.body, None, 0, trans)
|
||||
if body_val is not None and body_val.Ty is not None:
|
||||
if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0:
|
||||
if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0:
|
||||
llvmlite.build_ret(func_builder, body_val)
|
||||
else:
|
||||
ret_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
func_builder, body_val, i32_ty, lam.body)
|
||||
ret_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(func_builder, body_val, i32_ty, lam.body)
|
||||
if ret_val is not None:
|
||||
llvmlite.build_ret(func_builder, ret_val)
|
||||
else:
|
||||
@@ -1344,8 +1217,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
env_size_val: llvmlite.Value* = llvmlite.const_int64(pool, env_size)
|
||||
if env_size_val is not None:
|
||||
env_size_val.Next = None
|
||||
env_ptr = llvmlite.build_call(
|
||||
builder, "malloc", env_size_val, 1, i8_ptr_ty, 0)
|
||||
env_ptr = llvmlite.build_call(builder, "malloc", env_size_val, 1, i8_ptr_ty, 0)
|
||||
if env_ptr is not None:
|
||||
for ci3 in range(cap_count):
|
||||
# 与步骤 9 一致:str 指针偏移判空,避免整数转换 itoa 语义
|
||||
@@ -1354,16 +1226,12 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
continue
|
||||
al_addr: uint64 = uint64(cap_allocas) + ci3 * 8
|
||||
al_slot: str | t.CPtr = (t.CPtr)(al_addr)
|
||||
var_alloca2: llvmlite.Value* = (
|
||||
llvmlite.Value*)(al_slot[0])
|
||||
if var_alloca2 is None:
|
||||
continue
|
||||
var_alloca2: llvmlite.Value* = (llvmlite.Value*)(al_slot[0])
|
||||
if var_alloca2 is None: continue
|
||||
ty_addr5: uint64 = uint64(cap_tys) + ci3 * 8
|
||||
ty_slot5: str | t.CPtr = (t.CPtr)(ty_addr5)
|
||||
cap_ty2: llvmlite.LLVMType* = (
|
||||
llvmlite.LLVMType*)(ty_slot5[0])
|
||||
if cap_ty2 is None:
|
||||
continue
|
||||
cap_ty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot5[0])
|
||||
if cap_ty2 is None: continue
|
||||
# 堆存储大小:位宽/8,至少 8 字节(容纳指针/标量)
|
||||
ty_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cap_ty2)
|
||||
st_size: int = 8
|
||||
@@ -1372,22 +1240,17 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
var_storage: llvmlite.Value* = llvmlite.build_call(builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is not None:
|
||||
cur_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, cap_ty2, var_alloca2)
|
||||
cur_val: llvmlite.Value* = llvmlite.build_load(builder, cap_ty2, var_alloca2)
|
||||
if cur_val is not None:
|
||||
st_slot5: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, cap_ty2))
|
||||
st_slot5: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, cap_ty2))
|
||||
if st_slot5 is not None:
|
||||
llvmlite.build_store(builder, cur_val, st_slot5)
|
||||
off_val2: llvmlite.Value* = llvmlite.const_int32(pool, ci3 * 8)
|
||||
slot2: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i8_ty, env_ptr, off_val2)
|
||||
slot2: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, env_ptr, off_val2)
|
||||
if slot2 is not None:
|
||||
slot_typed2: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, slot2, i8_ptr_ptr_ty)
|
||||
slot_typed2: llvmlite.Value* = llvmlite.build_bitcast(builder, slot2, i8_ptr_ptr_ty)
|
||||
if slot_typed2 is not None:
|
||||
llvmlite.build_store(builder, var_storage, slot_typed2)
|
||||
|
||||
@@ -1395,8 +1258,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16)
|
||||
if closure_size_val is not None:
|
||||
closure_size_val.Next = None
|
||||
closure_ptr: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
closure_ptr: llvmlite.Value* = llvmlite.build_call(builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
if closure_ptr is None:
|
||||
return None
|
||||
|
||||
@@ -1411,20 +1273,16 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
else:
|
||||
viperlib.snprintf(fn_ptr_name, 64, "@%s", mangled_promoted)
|
||||
fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if fn_slot is not None and fn_as_i8ptr is not None:
|
||||
llvmlite.build_store(builder, fn_as_i8ptr, fn_slot)
|
||||
|
||||
# 16. [8] = env_ptr(无捕获存 null)
|
||||
eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i8_ty, closure_ptr, eight_val)
|
||||
env_slot_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val)
|
||||
if env_slot_addr is not None:
|
||||
env_slot: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
env_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if env_slot is not None:
|
||||
if env_ptr is not None:
|
||||
llvmlite.build_store(builder, env_ptr, env_slot)
|
||||
@@ -1481,11 +1339,9 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if cap_count >= 64:
|
||||
return cap_count
|
||||
string.strncpy(cap_names + cap_count * 64, nm.id, 63)
|
||||
al_slot: str | t.CPtr = (t.CPtr)(
|
||||
uint64(cap_allocas) + cap_count * 8)
|
||||
al_slot: str | t.CPtr = (t.CPtr)(uint64(cap_allocas) + cap_count * 8)
|
||||
al_slot[0] = alloca
|
||||
ty_slot: str | t.CPtr = (t.CPtr)(
|
||||
uint64(cap_tys) + cap_count * 8)
|
||||
ty_slot: str | t.CPtr = (t.CPtr)(uint64(cap_tys) + cap_count * 8)
|
||||
ty_slot[0] = pointee
|
||||
return cap_count + 1
|
||||
# 递归遍历常见表达式子节点
|
||||
|
||||
@@ -834,17 +834,14 @@ novirtual class ImportsGenMixin:
|
||||
self._check_import_sha1(node, alias.name)
|
||||
pool_val: memhub.MemBuddy* = trans.Pool
|
||||
im_val: str = trans._imported_modules
|
||||
trans._imported_modules = self.add_imported_module(
|
||||
pool_val, im_val, alias.name)
|
||||
trans._imported_modules = self.add_imported_module(pool_val, im_val, alias.name)
|
||||
# 别名也加入导入模块列表(用于模块限定构造器检查 Module.Class())
|
||||
if alias.asname is not None:
|
||||
trans._imported_modules = self.add_imported_module(
|
||||
pool_val, trans._imported_modules, alias.asname)
|
||||
trans._imported_modules = self.add_imported_module(pool_val, trans._imported_modules, alias.asname)
|
||||
# 别名也加入 from_imports(asname:fullname),
|
||||
# 使 HT.func() 跨模块调用能通过 from_imports 查找别名→完整模块名→SHA1
|
||||
# 否则 _lookup_module_sha1("HT") 找不到(mod_arr 只存文件名 HandlesTranslator)
|
||||
trans._from_imports = self.add_from_import(
|
||||
pool_val, trans._from_imports, alias.asname, alias.name)
|
||||
trans._from_imports = self.add_from_import(pool_val, trans._from_imports, alias.asname, alias.name)
|
||||
else:
|
||||
# 无别名时(import a.b.c),将顶层包名 "a" 也加入 _imported_modules,
|
||||
# 使 a.b.c 作为属性访问的 base 被翻译时能通过 is_module_imported("a") 检查
|
||||
@@ -856,8 +853,7 @@ novirtual class ImportsGenMixin:
|
||||
if pkg_buf is not None:
|
||||
string.strncpy(pkg_buf, alias.name, pkg_len)
|
||||
pkg_buf[pkg_len] = '\0'
|
||||
trans._imported_modules = self.add_imported_module(
|
||||
pool_val, trans._imported_modules, pkg_buf)
|
||||
trans._imported_modules = self.add_imported_module(pool_val, trans._imported_modules, pkg_buf)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -875,8 +871,7 @@ novirtual class ImportsGenMixin:
|
||||
if impf is None:
|
||||
return 0
|
||||
# 解析模块名:相对导入需补充包前缀
|
||||
resolved: str = self._resolve_relative_module(
|
||||
trans.Pool, trans.CurrentPackage,
|
||||
resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage,
|
||||
impf.level, impf.module)
|
||||
if resolved is not None:
|
||||
# 导入时立即校验模块 SHA1 是否注册(fast-fail,仅全量翻译时检查)
|
||||
@@ -887,8 +882,7 @@ novirtual class ImportsGenMixin:
|
||||
# 下方 L759-762 逐个校验(LookupSha1ByModName / 本地兄弟文件)。
|
||||
if trans._declare_only == 0 and impf.module is not None:
|
||||
self._check_import_sha1(node, resolved)
|
||||
trans._imported_modules = self.add_imported_module(
|
||||
trans.Pool, trans._imported_modules, resolved)
|
||||
trans._imported_modules = self.add_imported_module(trans.Pool, trans._imported_modules, resolved)
|
||||
# from . import Y(impf.module is None):resolved 是包名(vpsdk),
|
||||
# 各 name 是包的子模块 vpsdk.Y。须把完整子模块名也加入 _imported_modules,
|
||||
# 否则别名 "syscall" 精确匹配不到包名 "vpsdk" → is_module_imported 返回 0
|
||||
@@ -916,8 +910,7 @@ novirtual class ImportsGenMixin:
|
||||
or self._is_local_module_file(alias_m.name) != 0):
|
||||
if trans._declare_only == 0:
|
||||
self._check_import_sha1(node, jb_m)
|
||||
trans._imported_modules = self.add_imported_module(
|
||||
trans.Pool, trans._imported_modules, jb_m)
|
||||
trans._imported_modules = self.add_imported_module(trans.Pool, trans._imported_modules, jb_m)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -934,8 +927,7 @@ novirtual class ImportsGenMixin:
|
||||
if impf is None:
|
||||
return 0
|
||||
# 解析模块名:相对导入需补充包前缀
|
||||
resolved: str = self._resolve_relative_module(
|
||||
trans.Pool, trans.CurrentPackage,
|
||||
resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage,
|
||||
impf.level, impf.module)
|
||||
if resolved is not None:
|
||||
names: list[ast.AST*]* = impf.names
|
||||
@@ -963,8 +955,7 @@ novirtual class ImportsGenMixin:
|
||||
jb_t[fl_t] = '.'
|
||||
string.strcpy(jb_t + fl_t + 1, alias.name)
|
||||
fi_target = jb_t
|
||||
trans._from_imports = self.add_from_import(
|
||||
trans.Pool, trans._from_imports,
|
||||
trans._from_imports = self.add_from_import(trans.Pool, trans._from_imports,
|
||||
local_name, fi_target, orig_name)
|
||||
# 命名空间隔离:from-import 的名称标记为可见结构体
|
||||
self.Gen.StructGen.add_visible_struct(trans.Pool, local_name)
|
||||
|
||||
@@ -16,14 +16,14 @@ import lib.core.Gen.Generator as Generator
|
||||
|
||||
|
||||
# match case 数量上限(原 HandlesMatch.MAX_MATCH_CASES)
|
||||
MAX_MATCH_CASES: t.CDefine = 32
|
||||
define MAX_MATCH_CASES = 32
|
||||
|
||||
# 作用域种类常量(与 HandlesVar 的 Scope.Kind 区分,原 HandlesMatch.SCOPE_MATCH)
|
||||
SCOPE_MATCH: t.CDefine = 6
|
||||
define SCOPE_MATCH = 6
|
||||
|
||||
# match 翻译最大递归深度(match → case body → translate_value → 嵌套 match)。
|
||||
# 入口计数出口递减,超限即 fail-fast:AST 自引用环可致无限递归 → 栈溢出。
|
||||
MATCH_TRANSLATE_MAX_DEPTH: t.CDefine = 64
|
||||
define MATCH_TRANSLATE_MAX_DEPTH = 64
|
||||
|
||||
|
||||
novirtual class MatchGenMixin:
|
||||
@@ -66,8 +66,7 @@ novirtual class MatchGenMixin:
|
||||
"""match 语句翻译主入口(深度守卫包装器,原逻辑见 _translate_match_impl)"""
|
||||
if trans is not None:
|
||||
if trans.MatchTranslateDepth >= MATCH_TRANSLATE_MAX_DEPTH:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "match 翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "match 翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
trans.MatchTranslateDepth += 1
|
||||
mret: int = self._translate_match_impl(trans, node)
|
||||
if trans is not None:
|
||||
@@ -101,8 +100,7 @@ novirtual class MatchGenMixin:
|
||||
sk_seq: int = subject_node.kind()
|
||||
if sk_seq == ast.ASTKind.Tuple or sk_seq == ast.ASTKind.List:
|
||||
return self._handle_sequence_match(trans, m_node, subject_node)
|
||||
subject_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, subject_node,
|
||||
subject_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, subject_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if subject_val is None:
|
||||
# fail-fast: match subject 翻译失败
|
||||
@@ -117,14 +115,11 @@ novirtual class MatchGenMixin:
|
||||
if subject_node.kind() == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(subject_node)
|
||||
if nm.id is not None:
|
||||
entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry)
|
||||
if entry_annot is not None \
|
||||
and (self.Gen.ClassGenEnum._is_renum_class_name(
|
||||
entry_annot) != 0
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(
|
||||
entry_annot) != 0):
|
||||
and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(entry_annot) != 0):
|
||||
is_renum = 1
|
||||
renum_name = entry_annot
|
||||
subject_ptr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
@@ -139,8 +134,7 @@ novirtual class MatchGenMixin:
|
||||
case_node: ast.AST* = cases_list.get(ci)
|
||||
if case_node is not None \
|
||||
and case_node.kind() == ast.ASTKind.MatchCase:
|
||||
mc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(case_node)
|
||||
mc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(case_node)
|
||||
pat: ast.AST* = mc.pattern
|
||||
if pat is not None \
|
||||
and pat.kind() == ast.ASTKind.MatchClass:
|
||||
@@ -182,8 +176,7 @@ novirtual class MatchGenMixin:
|
||||
inner_nm: ast.Name* = ast.Name*(at.value)
|
||||
return inner_nm.id
|
||||
if at.value.kind() == ast.ASTKind.Attribute:
|
||||
inner_at: ast.Attribute* = (
|
||||
ast.Attribute*)(at.value)
|
||||
inner_at: ast.Attribute* = (ast.Attribute*)(at.value)
|
||||
return inner_at.attr
|
||||
# Name 形式:遍历所有 REnum 类反查
|
||||
if cls_node.kind() == ast.ASTKind.Name:
|
||||
@@ -240,12 +233,10 @@ novirtual class MatchGenMixin:
|
||||
call_node: ast.Call* = ast.Call*(val)
|
||||
fn: ast.AST* = call_node.func
|
||||
if fn is not None and fn.kind() == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute* = (
|
||||
ast.Attribute*)(fn)
|
||||
at: ast.Attribute* = (ast.Attribute*)(fn)
|
||||
if at.value is not None \
|
||||
and at.value.kind() == ast.ASTKind.Name:
|
||||
base_nm: ast.Name* = (
|
||||
ast.Name*)(at.value)
|
||||
base_nm: ast.Name* = (ast.Name*)(at.value)
|
||||
if base_nm.id is not None \
|
||||
and string.strcmp(base_nm.id, "c") == 0 \
|
||||
and at.attr is not None \
|
||||
@@ -287,25 +278,20 @@ novirtual class MatchGenMixin:
|
||||
and subj_ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0:
|
||||
# 情况1: T** → load 一次得 T*
|
||||
loaded_sub: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, subj_ty.Pointee, subject_ptr)
|
||||
loaded_sub: llvmlite.Value* = llvmlite.build_load(builder, subj_ty.Pointee, subject_ptr)
|
||||
if loaded_sub is not None:
|
||||
subject_ptr = loaded_sub
|
||||
# 情况2: 值型 subject(非指针)→ inttoptr 转回指针
|
||||
# 值型 subject 来自 REnum payload 槽位 load(槽位类型 i64,存的是指针),
|
||||
# 所以直接 inttoptr 到 renum_sty* 即可,无需 alloca+store
|
||||
if subject_ptr.Ty is None or self.Gen.ExprGenBase.is_ptr_type(subject_ptr.Ty) == 0:
|
||||
renum_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(
|
||||
renum_name)
|
||||
renum_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(renum_name)
|
||||
renum_sty: llvmlite.LLVMType* = None
|
||||
if renum_se is not None:
|
||||
renum_sty = renum_se.Ty
|
||||
if renum_sty is None:
|
||||
# fail-fast: REnum 结构体未注册,无法构造
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REnum 结构体 '{renum_name}' 未注册",
|
||||
"NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REnum 结构体 '{renum_name}' 未注册", "NameError")
|
||||
i64_ty0: llvmlite.LLVMType* = llvmlite.Int64(pool)
|
||||
int_val: llvmlite.Value* = subject_ptr
|
||||
# 非 i64 整数值先扩展/截断到 i64(inttoptr 要求同宽)
|
||||
@@ -317,21 +303,18 @@ novirtual class MatchGenMixin:
|
||||
else:
|
||||
int_val = llvmlite.build_zext(builder, subject_ptr, i64_ty0)
|
||||
renum_ptr_ty0: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_sty)
|
||||
subj_ptr0: llvmlite.Value* = llvmlite.build_inttoptr(
|
||||
builder, int_val, renum_ptr_ty0)
|
||||
subj_ptr0: llvmlite.Value* = llvmlite.build_inttoptr(builder, int_val, renum_ptr_ty0)
|
||||
if subj_ptr0 is not None:
|
||||
subject_ptr = subj_ptr0
|
||||
|
||||
# 1. bitcast subject 到 i32* 读 __tag
|
||||
i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool)
|
||||
i32_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty)
|
||||
tag_ptr: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, subject_ptr, i32_ptr_ty)
|
||||
tag_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, subject_ptr, i32_ptr_ty)
|
||||
if tag_ptr is None:
|
||||
# fail-fast: REnum tag 指针转换失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REnum tag 指针转换失败", "TypeError")
|
||||
tag_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, i32_ty, tag_ptr)
|
||||
tag_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, tag_ptr)
|
||||
if tag_val is None:
|
||||
# fail-fast: REnum tag 读取失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REnum tag 读取失败", "TypeError")
|
||||
@@ -344,11 +327,9 @@ novirtual class MatchGenMixin:
|
||||
# fail-fast: 标签缓冲区分配失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError")
|
||||
viperlib.snprintf(name_buf, 32, "match.default.%d", cnt)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.end.%d", cnt)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# 3. 准备收集数组(用 CSizeT 数组存指针)
|
||||
cases_list: list[ast.AST*]* = node.cases
|
||||
@@ -427,11 +408,9 @@ novirtual class MatchGenMixin:
|
||||
# 先用裸类名查表(变体表按裸类名注册,与模式侧 2b 路径同口径);
|
||||
# 失败再用注解书写形态重试(泛型特化 mangled 名确需带点)。
|
||||
# 两者都失败 → tag=-1 → step 5 前的硬校验 fail-fast。
|
||||
tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(
|
||||
tag_cls_bare, vnm)
|
||||
tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(tag_cls_bare, vnm)
|
||||
if tag < 0 and string.strcmp(tag_cls_bare, renum_name) != 0:
|
||||
tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(
|
||||
renum_name, vnm)
|
||||
tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(renum_name, vnm)
|
||||
if tag >= 0:
|
||||
tag_buf: str = pool.alloc(32)
|
||||
if tag_buf is not None:
|
||||
@@ -445,9 +424,7 @@ novirtual class MatchGenMixin:
|
||||
has_default = 1
|
||||
elif pk == ast.ASTKind.MatchValue:
|
||||
mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans)
|
||||
elif pk == ast.ASTKind.MatchOr:
|
||||
# MatchOr: 多个值共享一个 BB(取第一个值做 case)
|
||||
mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat)
|
||||
@@ -456,19 +433,15 @@ novirtual class MatchGenMixin:
|
||||
first_pat: ast.AST* = pats.get(0)
|
||||
if first_pat is not None \
|
||||
and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
mv2: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv2.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv2.value, trans._funcs, trans._func_count, trans)
|
||||
|
||||
# 创建 case BB
|
||||
if is_def == 0:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i)
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
else:
|
||||
bb = default_bb
|
||||
|
||||
@@ -495,8 +468,7 @@ novirtual class MatchGenMixin:
|
||||
|
||||
# 构建 SwitchCase 链表(非 default case 且有值)
|
||||
if is_def == 0 and cv is not None:
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(
|
||||
pool, cv, bb)
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(pool, cv, bb)
|
||||
if sc is not None:
|
||||
if sw_head is None:
|
||||
sw_head = sc
|
||||
@@ -525,8 +497,7 @@ novirtual class MatchGenMixin:
|
||||
# 结构性不可达。故不等即 fail-fast,打印类名/查表名/应提交数/实际数/
|
||||
# 各未取到值臂的 序号(变体名,tag),便于定位变体表失配。
|
||||
if need_case != sw_count:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REnum match 分派丢失 case:class='{renum_name}'(查表名='{tag_cls_bare}')应提交 {need_case} 个 case,实际提交 {sw_count} 个;未取到值的臂:{miss_buf}",
|
||||
"InternalCompilerError")
|
||||
llvmlite.build_switch(builder, tag_val, default_bb, sw_head, sw_count)
|
||||
@@ -551,8 +522,7 @@ novirtual class MatchGenMixin:
|
||||
|
||||
# 取 BB
|
||||
bb_addr: sizet = bb_arr[i]
|
||||
case_bb: rawptr[llvmlite.BasicBlock] = (
|
||||
rawptr[llvmlite.BasicBlock])(bb_addr)
|
||||
case_bb: rawptr[llvmlite.BasicBlock] = (rawptr[llvmlite.BasicBlock])(bb_addr)
|
||||
is_def: int = def_arr[i]
|
||||
nb: int = nb_arr[i]
|
||||
|
||||
@@ -570,9 +540,7 @@ novirtual class MatchGenMixin:
|
||||
# 变体字段绑定(MatchClass)
|
||||
if pat is not None and pat.kind() == ast.ASTKind.MatchClass \
|
||||
and renum_entry is not None and renum_ty is not None:
|
||||
self._bind_variant_fields(
|
||||
pat, renum_name, renum_entry, renum_ty,
|
||||
subject_ptr, trans, pool, builder)
|
||||
self._bind_variant_fields(pat, renum_name, renum_entry, renum_ty, subject_ptr, trans, pool, builder)
|
||||
|
||||
# 翻译 case body
|
||||
body_list: list[ast.AST*]* = mc.children
|
||||
@@ -619,8 +587,7 @@ novirtual class MatchGenMixin:
|
||||
if def_arr[di] == 1:
|
||||
dcase: ast.AST* = cases_list.get(di)
|
||||
if dcase is not None:
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dcase)
|
||||
dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dcase)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
@@ -674,13 +641,11 @@ novirtual class MatchGenMixin:
|
||||
return
|
||||
# bitcast subject_ptr 到 renum_ptr_ty(确保 GEP 类型匹配)
|
||||
renum_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_ty)
|
||||
casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, subject_ptr, renum_ptr_ty)
|
||||
casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, subject_ptr, renum_ptr_ty)
|
||||
if casted_ptr is None:
|
||||
casted_ptr = subject_ptr
|
||||
pn: sizet = len(pats)
|
||||
j: int = 0
|
||||
while j < pn:
|
||||
for j in range(pn):
|
||||
sub_pat: ast.AST* = pats.get(j)
|
||||
if sub_pat is not None and sub_pat.kind() == ast.ASTKind.MatchAs:
|
||||
ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](sub_pat)
|
||||
@@ -694,8 +659,7 @@ novirtual class MatchGenMixin:
|
||||
# class_name 用 CSizeT 指针值比较:必须传 renum_entry.Name
|
||||
# (注册时 _update_renum_alias_class_ptr 统一后的 perm_pool 指针);
|
||||
# renum_name(AnnotClassName 等)是不同指针,恒不匹配 → 误报 fail-fast。
|
||||
alt_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
renum_entry.Name, bind_name)
|
||||
alt_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(renum_entry.Name, bind_name)
|
||||
if alt_idx >= 1:
|
||||
payload_idx = alt_idx
|
||||
else:
|
||||
@@ -703,34 +667,20 @@ novirtual class MatchGenMixin:
|
||||
# (node 在本函数不存在——参数是 pat/sub_pat,用 sub_pat
|
||||
# 定位到具体 MatchAs 模式;TPC Python 语义下未定义名只在
|
||||
# 运行时求值才报错,TPV 惰性编译方法体时即 NameError)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
sub_pat,
|
||||
f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败", "TypeError")
|
||||
# 获取字段类型
|
||||
fe: GenTypes.FieldEntry* = (
|
||||
self.Gen.StructGen._get_field_entry(
|
||||
renum_entry, payload_idx))
|
||||
fe: GenTypes.FieldEntry* = (self.Gen.StructGen._get_field_entry(renum_entry, payload_idx))
|
||||
field_ty: llvmlite.LLVMType* = None
|
||||
if fe is not None:
|
||||
field_ty = fe.Ty
|
||||
if field_ty is None:
|
||||
# fail-fast: 变体字段类型缺失,禁止兜底 i8
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
sub_pat,
|
||||
f"REnum 变体字段类型缺失: {bind_name}",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段类型缺失: {bind_name}", "TypeError")
|
||||
# GEP 取字段地址
|
||||
elem_ptr: llvmlite.Value* = (
|
||||
llvmlite.build_gep_struct(
|
||||
builder, renum_ty, field_ty,
|
||||
casted_ptr, payload_idx))
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, renum_ty, field_ty,casted_ptr, payload_idx)
|
||||
if elem_ptr is None:
|
||||
# fail-fast: 变体字段地址计算失败
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
sub_pat,
|
||||
f"REnum 变体字段 '{bind_name}' 地址计算失败",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段 '{bind_name}' 地址计算失败", "TypeError")
|
||||
# 变体成员实际类型(对齐 TPC class_members):注册时别名表存了成员
|
||||
# 注解解析出的类型(perm_pool 深拷贝),用它把槽位地址 bitcast 成
|
||||
# Ptr(成员类型),使绑定变量按成员类型读 payload(否则按槽位 i64 读 →
|
||||
@@ -742,19 +692,14 @@ novirtual class MatchGenMixin:
|
||||
vnt_m: str = self._extract_variant_name_from_cls(pat)
|
||||
if vnt_m is not None and renum_entry is not None \
|
||||
and renum_entry.Name is not None:
|
||||
mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty(
|
||||
renum_entry.Name, vnt_m, payload_idx)
|
||||
mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty(renum_entry.Name, vnt_m, payload_idx)
|
||||
if mem_ty_m is not None:
|
||||
mem_ptr_m: llvmlite.LLVMType* = llvmlite.Ptr(
|
||||
pool, mem_ty_m)
|
||||
mem_ptr_m: llvmlite.LLVMType* = llvmlite.Ptr(pool, mem_ty_m)
|
||||
if mem_ptr_m is not None:
|
||||
cast_m: llvmlite.Value* = llvmlite.build_bitcast(
|
||||
builder, elem_ptr, mem_ptr_m)
|
||||
cast_m: llvmlite.Value* = llvmlite.build_bitcast(builder, elem_ptr, mem_ptr_m)
|
||||
if cast_m is not None:
|
||||
elem_ptr = cast_m
|
||||
self.Gen.VarGen.define_var(
|
||||
trans.SymTab, bind_name, elem_ptr)
|
||||
j = j + 1
|
||||
self.Gen.VarGen.define_var(trans.SymTab, bind_name, elem_ptr)
|
||||
|
||||
# ============================================================
|
||||
# _seq_cmp_eq - 序列匹配元素相等比较
|
||||
@@ -842,12 +787,10 @@ novirtual class MatchGenMixin:
|
||||
# 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式)
|
||||
elts_inl: list[ast.AST*]* = elts
|
||||
elt: ast.AST* = elts_inl.get(ei)
|
||||
sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, elt,
|
||||
sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, elt,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if sv is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
elt, f"match 序列元素 {ei} 翻译失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(elt, f"match 序列元素 {ei} 翻译失败", "TypeError")
|
||||
subj_vals[ei] = sizet(sv)
|
||||
|
||||
# 2. 创建 default/end BB
|
||||
@@ -857,11 +800,9 @@ novirtual class MatchGenMixin:
|
||||
if name_buf is None:
|
||||
return 0
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.default.%d", cnt)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.end.%d", cnt)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# 3. 第一遍:收集 case 信息(check/body BB、default 标记、nobreak、guard)
|
||||
cases_list: list[ast.AST*]* = node.cases
|
||||
@@ -887,10 +828,7 @@ novirtual class MatchGenMixin:
|
||||
# 否则 case 数超 MAX_MATCH_CASES 会越界写穿 pool 相邻块。超限直接
|
||||
# fail-fast,不静默丢弃 case。
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"match case 数量超过上限 MAX_MATCH_CASES={MAX_MATCH_CASES}",
|
||||
"OverflowError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"match case 数量超过上限 MAX_MATCH_CASES={MAX_MATCH_CASES}", "OverflowError")
|
||||
break
|
||||
case_node: ast.AST* = cases_list.get(i)
|
||||
if case_node is None or case_node.kind() != ast.ASTKind.MatchCase:
|
||||
@@ -907,8 +845,7 @@ novirtual class MatchGenMixin:
|
||||
is_def = 1
|
||||
elif pk != ast.ASTKind.MatchSequence:
|
||||
# fail-fast:序列匹配只接受 MatchSequence / 顶层 _ 通配
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat, "序列匹配 case 只支持 (元素) 或 _ 模式", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(pat, "序列匹配 case 只支持 (元素) 或 _ 模式", "TypeError")
|
||||
if is_def == 1:
|
||||
has_default = 1
|
||||
check_arr[collected] = 0
|
||||
@@ -917,11 +854,9 @@ novirtual class MatchGenMixin:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.check.%d.%d", cnt, i)
|
||||
cbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
cbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.body.%d.%d", cnt, i)
|
||||
bbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
bbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
check_arr[collected] = sizet(cbb)
|
||||
body_arr[collected] = sizet(bbb)
|
||||
if first_check < 0:
|
||||
@@ -957,8 +892,7 @@ novirtual class MatchGenMixin:
|
||||
cond: llvmlite.Value* = None
|
||||
cnode: ast.AST* = cases_list.get(ci)
|
||||
mc2: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](cnode)
|
||||
ms: rawptr[ast.MatchSequence] = (
|
||||
rawptr[ast.MatchSequence])(mc2.pattern)
|
||||
ms: rawptr[ast.MatchSequence] = (rawptr[ast.MatchSequence])(mc2.pattern)
|
||||
pats: list[ast.AST*]* = None
|
||||
if ms is not None:
|
||||
pats = ms.patterns
|
||||
@@ -978,14 +912,10 @@ novirtual class MatchGenMixin:
|
||||
continue
|
||||
pk1: int = pat1.kind()
|
||||
if pk1 == ast.ASTKind.MatchValue:
|
||||
mv: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(pat1)
|
||||
pv: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
mv: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(pat1)
|
||||
pv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans)
|
||||
if pv is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat1, f"序列模式元素 {pi} 翻译失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(pat1, f"序列模式元素 {pi} 翻译失败", "TypeError")
|
||||
sv1: llvmlite.Value* = llvmlite.Value*(subj_vals[pi])
|
||||
c1: llvmlite.Value* = self._seq_cmp_eq(trans, builder, sv1, pv)
|
||||
if c1 is None:
|
||||
@@ -1000,31 +930,25 @@ novirtual class MatchGenMixin:
|
||||
continue # _ 通配:恒真
|
||||
if ma2.name is not None:
|
||||
# fail-fast:序列模式变量绑定暂不支持
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat1, "序列模式变量绑定暂不支持", "NotImplementedError")
|
||||
self.Gen.TypeGenErr.fatal_error(pat1, "序列模式变量绑定暂不支持", "NotImplementedError")
|
||||
elif pk1 == ast.ASTKind.MatchStar:
|
||||
continue # 剩余元素通配:恒真
|
||||
else:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat1, "序列模式不支持的 pattern 类型", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(pat1, "序列模式不支持的 pattern 类型", "TypeError")
|
||||
# guard(若有):匹配成立且 guard 非零
|
||||
g_addr: sizet = guard_arr[ci]
|
||||
if g_addr != 0:
|
||||
gnode: ast.AST* = (ast.AST*)(g_addr)
|
||||
gv: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, gnode,
|
||||
gv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if gv is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
gnode, "match guard 翻译失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(gnode, "match guard 翻译失败", "TypeError")
|
||||
gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty)
|
||||
if gbits == 1:
|
||||
g1: llvmlite.Value* = gv
|
||||
else:
|
||||
gzero: llvmlite.Value* = llvmlite.const_int(
|
||||
pool, gbits if gbits > 0 else 32, 0)
|
||||
g1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, gv, gzero)
|
||||
gzero: llvmlite.Value* = llvmlite.const_int(pool, gbits if gbits > 0 else 32, 0)
|
||||
g1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, gv, gzero)
|
||||
if cond is None:
|
||||
cond = g1
|
||||
else:
|
||||
@@ -1055,8 +979,7 @@ novirtual class MatchGenMixin:
|
||||
bbb3: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[ci])
|
||||
llvmlite.position_at_end(builder, bbb3)
|
||||
cnode2: ast.AST* = cases_list.get(ci)
|
||||
mc3: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(cnode2)
|
||||
mc3: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(cnode2)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
body_list2: list[ast.AST*]* = mc3.children
|
||||
if body_list2 is not None:
|
||||
@@ -1098,8 +1021,7 @@ novirtual class MatchGenMixin:
|
||||
if def_arr[di] == 1:
|
||||
dnode: ast.AST* = cases_list.get(di)
|
||||
if dnode is not None:
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dnode)
|
||||
dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dnode)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
@@ -1170,11 +1092,9 @@ novirtual class MatchGenMixin:
|
||||
# fail-fast: 标签缓冲区分配失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError")
|
||||
viperlib.snprintf(name_buf, 32, "match.default.%d", cnt)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.end.%d", cnt)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# 3. 收集 case 信息
|
||||
cases_list: list[ast.AST*]* = node.cases
|
||||
@@ -1217,12 +1137,10 @@ novirtual class MatchGenMixin:
|
||||
pk: int = pat.kind()
|
||||
if pk == ast.ASTKind.MatchValue:
|
||||
mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
elif pk == ast.ASTKind.MatchSingleton:
|
||||
ms: rawptr[ast.MatchSingleton] = (
|
||||
rawptr[ast.MatchSingleton])(pat)
|
||||
ms: rawptr[ast.MatchSingleton] = (rawptr[ast.MatchSingleton])(pat)
|
||||
# None -> 0
|
||||
cv = llvmlite.const_int32(pool, 0)
|
||||
elif pk == ast.ASTKind.MatchAs:
|
||||
@@ -1237,22 +1155,16 @@ novirtual class MatchGenMixin:
|
||||
first_pat: ast.AST* = pats.get(0)
|
||||
if first_pat is not None \
|
||||
and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
mv2: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv2.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv2.value, trans._funcs, trans._func_count, trans)
|
||||
elif pk == ast.ASTKind.MatchClass:
|
||||
# 本路径(非 REnum 分派)不为 class-pattern 臂产出 case 值 → 该臂被
|
||||
# 静默丢弃、臂体不可达。若该 class-pattern 确实指向已注册 REnum
|
||||
# (_is_renum_class_name / _is_renum_by_entry 命中),说明是 REnum
|
||||
# 分派失配,必须 fail-fast 暴露,不得静默丢 case(禁止兜底掩盖)。
|
||||
rnm_nr: str = self._extract_renum_name_from_cls(pat)
|
||||
if rnm_nr is not None and (
|
||||
self.Gen.ClassGenEnum._is_renum_class_name(rnm_nr) != 0
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(rnm_nr) != 0):
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat,
|
||||
if rnm_nr is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm_nr) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(rnm_nr) != 0):
|
||||
self.Gen.TypeGenErr.fatal_error(pat,
|
||||
f"非 REnum 路径收到 REnum 变体模式 'case {rnm_nr}.*':case 值无法产出,该臂会被静默丢弃(REnum 分派失配)",
|
||||
"InternalCompilerError")
|
||||
|
||||
@@ -1260,8 +1172,7 @@ novirtual class MatchGenMixin:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i)
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
else:
|
||||
bb = default_bb
|
||||
|
||||
@@ -1276,8 +1187,7 @@ novirtual class MatchGenMixin:
|
||||
collected = collected + 1
|
||||
|
||||
if is_def == 0 and cv is not None:
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(
|
||||
pool, cv, bb)
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(pool, cv, bb)
|
||||
if sc is not None:
|
||||
if sw_head is None:
|
||||
sw_head = sc
|
||||
@@ -1351,8 +1261,7 @@ novirtual class MatchGenMixin:
|
||||
if def_arr[di] == 1:
|
||||
dcase: ast.AST* = cases_list.get(di)
|
||||
if dcase is not None:
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dcase)
|
||||
dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dcase)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
|
||||
@@ -14,24 +14,17 @@ import lib.core.Gen.Translator as HT
|
||||
import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StmtGenCifMixin - StmtGen 拆分 1/3:CIf 编译期求值 + NewXxxHandle 工厂
|
||||
#
|
||||
# 按功能域从 StmtGenMixin.vp 拆出(500~1500 行/文件架构重构,试点):
|
||||
# 簇 B(CIf 宏求值)+ NewIfHandle/NewWhileHandle/NewForHandle/
|
||||
# NewReturnHandle/NewMatchHandle 工厂。
|
||||
# 全部字段保留在本最底层父类(顺序 CifEvalOk->EnumTable->EnumCount->
|
||||
# DiagStmtCount 与 Generator 组合布局一致,见下方字段注释)。
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。
|
||||
# StmtGenCifMixin - CIf 编译期求值 + NewXxxHandle 工厂
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StmtGenCifMixin - CIf 求值 + 工厂(最底层父类)
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class StmtGenCifMixin:
|
||||
novirtual class StmtGenCifMixin:
|
||||
"""CIf 编译期求值 + NewXxxHandle 工厂(StmtGen 拆分 1/3,最底层)"""
|
||||
|
||||
# --- 编译期 CIf 求值状态(原 HandlesIf._g_cif_eval_ok) ---
|
||||
@@ -135,8 +128,7 @@ class StmtGenCifMixin:
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
self.CifEvalOk = 1
|
||||
return v
|
||||
v2: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, name, trans._from_imports, trans._imported_modules)
|
||||
v2: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, name, trans._from_imports, trans._imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
self.CifEvalOk = 1
|
||||
return v2
|
||||
@@ -167,8 +159,7 @@ class StmtGenCifMixin:
|
||||
# 跨模块: 确定真实模块名(解析 from_imports 别名)
|
||||
real_mod: str = vn.id
|
||||
if trans._from_imports is not None:
|
||||
resolved: str = self.Gen.ImportsGen.lookup_from_import(
|
||||
trans._from_imports, vn.id, 0)
|
||||
resolved: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, vn.id, 0)
|
||||
if resolved is not None:
|
||||
rm_len: sizet = 0
|
||||
while resolved[rm_len] != ' ' and resolved[rm_len] != '\0' and resolved[rm_len] != ':':
|
||||
@@ -485,8 +476,7 @@ class StmtGenCifMixin:
|
||||
rt_tail: llvmlite.Function* = None
|
||||
rvi: sizet
|
||||
for rvi in range(rt_n):
|
||||
ev_i: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rtp_elts.get(rvi),
|
||||
ev_i: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rtp_elts.get(rvi),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if ev_i is None:
|
||||
rt_val_ok = 0
|
||||
@@ -519,8 +509,7 @@ class StmtGenCifMixin:
|
||||
rvi3: sizet
|
||||
for rvi3 in range(rt_n):
|
||||
rv3: llvmlite.Value* = llvmlite.Value*(rt_vals[rvi3])
|
||||
rfp: llvmlite.Value* = llvmlite.build_gep_struct(
|
||||
builder, rt_struct_ty, rv3.Ty, rt_tmp, rvi3)
|
||||
rfp: llvmlite.Value* = llvmlite.build_gep_struct(builder, rt_struct_ty, rv3.Ty, rt_tmp, rvi3)
|
||||
if rfp is None:
|
||||
rt_val_ok = 0
|
||||
break
|
||||
@@ -535,8 +524,7 @@ class StmtGenCifMixin:
|
||||
ret_nm: ast.Name* = ast.Name*(rt.value)
|
||||
if ret_nm is not None and ret_nm.id is not None \
|
||||
and string.strcmp(ret_nm.id, "self") == 0:
|
||||
self_ptr: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, "self")
|
||||
self_ptr: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "self")
|
||||
if self_ptr is not None:
|
||||
# 检查 self_ptr 是否是 Ptr(Ptr(...))(alloca 存储指针)
|
||||
self_pointee_ty: llvmlite.LLVMType* = None
|
||||
@@ -560,8 +548,7 @@ class StmtGenCifMixin:
|
||||
# 构造(`-> Stack[int]` 里 `return Stack()`)用 CurFuncRetAnnot
|
||||
# 里的类型实参特化;仅该直接值生效(identity 判定在 CallGenCtor)。
|
||||
trans.CurRetNode = rt.value
|
||||
val = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rt.value,
|
||||
val = self.Gen.ExprGen.translate_value(builder, pool, mod, rt.value,
|
||||
trans._funcs, trans._func_count, trans, ret_val_ty, "返回注解")
|
||||
trans.CurRetNode = None
|
||||
|
||||
@@ -741,8 +728,7 @@ class StmtGenCifMixin:
|
||||
return 0
|
||||
|
||||
# 1. 求值条件表达式
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, if_node.test,
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, if_node.test,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
|
||||
# 2. 转换为 i1 条件
|
||||
@@ -756,12 +742,10 @@ class StmtGenCifMixin:
|
||||
elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0:
|
||||
# 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type")
|
||||
null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null")
|
||||
cond_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cond_val, null_cond)
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond)
|
||||
else:
|
||||
zero: llvmlite.Value* = llvmlite.const_int32(pool, 0)
|
||||
cond_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cond_val, zero)
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero)
|
||||
|
||||
# 3. 创建基本块(使用 trans._label_counter 生成唯一标签名,不与 SSA 名共享)
|
||||
cnt: int = trans._label_counter
|
||||
@@ -898,8 +882,7 @@ class StmtGenCifMixin:
|
||||
|
||||
# 3. cond 块: 求值条件,条件分支
|
||||
llvmlite.position_at_end(builder, cond_bb)
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, while_node.test,
|
||||
cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, while_node.test,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if cond_val is None:
|
||||
# fail-fast: while 条件表达式翻译失败
|
||||
@@ -912,12 +895,10 @@ class StmtGenCifMixin:
|
||||
elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0:
|
||||
# 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type")
|
||||
null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null")
|
||||
cond_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cond_val, null_cond)
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond)
|
||||
else:
|
||||
zero: llvmlite.Value* = llvmlite.const_int32(pool, 0)
|
||||
cond_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cond_val, zero)
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero)
|
||||
llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb)
|
||||
|
||||
# 4. body 块: 翻译循环体,跳回 cond
|
||||
@@ -1048,7 +1029,7 @@ class StmtGenCifMixin:
|
||||
if builder is None or func is None:
|
||||
return 0
|
||||
|
||||
for_node: rawptr[ast.For] = rawptr[ast.For](node)
|
||||
for_node: ast.For* = ast.For*(node)
|
||||
|
||||
# 1. 获取循环变量(Name 单变量 / Tuple 多变量)
|
||||
target: ast.AST* = for_node.target
|
||||
@@ -1125,16 +1106,14 @@ class StmtGenCifMixin:
|
||||
if iter_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm_lst: ast.Name* = ast.Name*(iter_node)
|
||||
if nm_lst.id is not None:
|
||||
ve_lst: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_lst.id)
|
||||
ve_lst: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_lst.id)
|
||||
lst_annot: str = self.Gen.VarGen.var_annot_class_name(ve_lst)
|
||||
if lst_annot is not None:
|
||||
# dict 容器变量:按 __count__/__keys__ 布局迭代(__iter__ 协议内联)
|
||||
# [S4] 容器基名精确比较(SpecTypeNameBaseIs):原 strstr("dict") 子串匹配
|
||||
# 会误命中任何含 "dict" 的类名(如 MyDictHelper)。
|
||||
if TSpec.SpecTypeNameBaseIs(lst_annot, "dict") != 0:
|
||||
lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, iter_node,
|
||||
lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if lst_val is not None and lst_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
@@ -1142,53 +1121,42 @@ class StmtGenCifMixin:
|
||||
# [S4] 同上:原 strstr("list") 会误命中 playlist / GSList 等;
|
||||
# 非 list 基名的用户类改由下方 OOP __iter__/__next__ 路径处理(更正确)。
|
||||
if TSpec.SpecTypeNameBaseIs(lst_annot, "list") != 0:
|
||||
lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, iter_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans)
|
||||
if lst_val is not None and lst_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
return self._handle_list_iter(trans, for_node, var_name, lst_val)
|
||||
# OOP iter 协议:迭代源是类对象且类有 __iter__/__next__ 方法 →
|
||||
# 走 __iter__/__next__ 调用迭代(对齐 TPC HandlesFor.py L142-166
|
||||
# _HandleForIterLlvm)。dict/list 是内置泛型容器已在上方内联处理。
|
||||
ov_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, iter_node,
|
||||
ov_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if ov_val is not None and ov_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0:
|
||||
ov_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(
|
||||
ov_val)
|
||||
ov_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(ov_val)
|
||||
if ov_st is not None:
|
||||
ov_cn: str = self.Gen.StructGen.get_class_name_by_type(pool, ov_st)
|
||||
if ov_cn is not None:
|
||||
oi_lookup: str = pool.alloc(128)
|
||||
if oi_lookup is not None:
|
||||
viperlib.snprintf(oi_lookup, 128, "%s.__iter__", ov_cn)
|
||||
oi_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
trans.Module, oi_lookup)
|
||||
oi_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, oi_lookup)
|
||||
if oi_fn is not None:
|
||||
on_lookup: str = pool.alloc(128)
|
||||
if on_lookup is not None:
|
||||
viperlib.snprintf(on_lookup, 128, "%s.__next__", ov_cn)
|
||||
on_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
trans.Module, on_lookup)
|
||||
on_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, on_lookup)
|
||||
if on_fn is not None:
|
||||
return self._handle_oop_iter(
|
||||
trans, for_node, var_name, ov_cn, ov_val)
|
||||
return self._handle_oop_iter(trans, for_node, var_name, ov_cn, ov_val)
|
||||
# 其它不支持的字面量:fast-fail 显式报错,
|
||||
# 避免 translate_value 触发 list[T] 特化崩溃或语义歧义。
|
||||
ik: int = iter_node.kind()
|
||||
if ik == ast.ASTKind.Constant:
|
||||
cn_ik: ast.Constant* = ast.Constant*(iter_node)
|
||||
if cn_ik.const_kind != ast.CONST_STR:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
iter_node,
|
||||
"for 迭代不支持该常量(仅支持字符串、数组、列表字面量、range())")
|
||||
self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持该常量(仅支持字符串、数组、列表字面量、range())")
|
||||
elif ik == ast.ASTKind.Dict or ik == ast.ASTKind.Set or ik == ast.ASTKind.Tuple \
|
||||
or ik == ast.ASTKind.SetComp or ik == ast.ASTKind.DictComp:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
iter_node,
|
||||
"for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量")
|
||||
self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量")
|
||||
return self._handle_ptr_iter(trans, for_node, var_name)
|
||||
|
||||
call: ast.Call* = ast.Call*(iter_node)
|
||||
@@ -1208,29 +1176,21 @@ class StmtGenCifMixin:
|
||||
# fail-fast: range 无参数,立即终止
|
||||
self.Gen.TypeGenErr.fatal_error(call, "range 需要至少一个参数", "SyntaxError")
|
||||
elif arg_count == 1:
|
||||
stop_val = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, args.get(0),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
stop_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(0), trans._funcs, trans._func_count, trans)
|
||||
if stop_val is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(args.get(0), "range 参数翻译失败", "TypeError")
|
||||
elif arg_count >= 2:
|
||||
start_val = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, args.get(0),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
start_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(0), trans._funcs, trans._func_count, trans)
|
||||
if start_val is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(args.get(0), "range 参数翻译失败", "TypeError")
|
||||
stop_val = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, args.get(1),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
stop_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(1), trans._funcs, trans._func_count, trans)
|
||||
if stop_val is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(args.get(1), "range 参数翻译失败", "TypeError")
|
||||
if arg_count >= 3:
|
||||
step_val = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, args.get(2),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
step_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(2), trans._funcs, trans._func_count, trans)
|
||||
if step_val is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(args.get(2), "range 参数翻译失败", "TypeError")
|
||||
@@ -1330,8 +1290,7 @@ class StmtGenCifMixin:
|
||||
# 命中父函数同名变量(如父函数自己的循环计数器 i)→ 循环计数写到
|
||||
# 父函数存储 → 跨函数 SSA 错乱(llc "instruction expected to be
|
||||
# numbered",Terminal _cmd_cd 的 for i in range(1,64) 根因)。
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
# 用 _alloca_at_entry:alloca 放函数入口块,保证支配性
|
||||
@@ -1343,8 +1302,7 @@ class StmtGenCifMixin:
|
||||
# 位宽随 range 参数类型(loop_store_ty),不再固定 i32:
|
||||
# uint64 上界 → i64 alloca,避免 trunc i64→i32 丢失高位。
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, loop_store_ty)
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 获取循环变量的实际元素类型(alloca 是指针类型,需解引用 Pointee)
|
||||
@@ -1416,8 +1374,7 @@ class StmtGenCifMixin:
|
||||
range_cmp_op = llvmlite.ICMP_UGT
|
||||
else:
|
||||
range_cmp_op = llvmlite.ICMP_ULT
|
||||
cond_i1: llvmlite.Value* = llvmlite.build_icmp(
|
||||
builder, range_cmp_op, cmp_lhs, cmp_rhs)
|
||||
cond_i1: llvmlite.Value* = llvmlite.build_icmp(builder, range_cmp_op, cmp_lhs, cmp_rhs)
|
||||
llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb)
|
||||
|
||||
# 9. body 块: 翻译循环体,跳到 incr
|
||||
@@ -1517,8 +1474,7 @@ class StmtGenCifMixin:
|
||||
if k == ast.ASTKind.Name:
|
||||
nm_s: ast.Name* = ast.Name*(src)
|
||||
if nm_s.id is not None and trans is not None:
|
||||
ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_s.id)
|
||||
ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_s.id)
|
||||
sq_annot: str = self.Gen.VarGen.var_annot_class_name(ve_s)
|
||||
if sq_annot is not None:
|
||||
# [S4] 容器基名精确比较(原 strstr("list") 子串匹配会误命中 playlist 等)
|
||||
@@ -1528,7 +1484,7 @@ class StmtGenCifMixin:
|
||||
return 0
|
||||
|
||||
def _build_seq_loop(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
t1: str, t2: str,
|
||||
src1: ast.AST*,
|
||||
src2: ast.AST*,
|
||||
@@ -1570,50 +1526,37 @@ class StmtGenCifMixin:
|
||||
if cargs1 is not None:
|
||||
n1: sizet = len(cargs1)
|
||||
if n1 >= 1:
|
||||
sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs1.get(0),
|
||||
sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(0),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if sv is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs1.get(0), "range 参数翻译失败", "TypeError")
|
||||
r1_stop = self.Gen.ExprGenBase.coerce_to_type(builder, sv, i64_ty, cargs1.get(0))
|
||||
if n1 >= 2:
|
||||
sv2: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs1.get(1),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
sv2: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(1), trans._funcs, trans._func_count, trans)
|
||||
if sv2 is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs1.get(1), "range 参数翻译失败", "TypeError")
|
||||
r1_start = self.Gen.ExprGenBase.coerce_to_type(builder, sv2, i64_ty, cargs1.get(1))
|
||||
if n1 >= 3:
|
||||
sv3: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs1.get(2),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
sv3: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(2), trans._funcs, trans._func_count, trans)
|
||||
if sv3 is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs1.get(2), "range 参数翻译失败", "TypeError")
|
||||
r1_step = self.Gen.ExprGenBase.coerce_to_type(builder, sv3, i64_ty, cargs1.get(2))
|
||||
elif kind1 == GenTypes.SEQ_KIND_STR:
|
||||
elem1_ty = i8_ty
|
||||
s1_ptr = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, src1,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
s1_ptr = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src1, trans._funcs, trans._func_count, trans)
|
||||
if s1_ptr is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源翻译失败")
|
||||
elif kind1 == GenTypes.SEQ_KIND_LIST:
|
||||
elem1_ty = i8_ptr_ty
|
||||
l1_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, src1,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if l1_obj is None or l1_obj.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(l1_obj.Ty) == 0:
|
||||
l1_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src1, trans._funcs, trans._func_count, trans)
|
||||
if l1_obj is None or l1_obj.Ty is None or self.Gen.ExprGenBase.is_ptr_type(l1_obj.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: list 源不是指针类型")
|
||||
l1_count = llvmlite.build_load(builder, i64_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 1)))
|
||||
l1_data = llvmlite.build_load(builder, i8_ptr_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 0)))
|
||||
l1_esize = llvmlite.build_load(builder, i64_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 4)))
|
||||
l1_count = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 1)))
|
||||
l1_data = llvmlite.build_load(builder, i8_ptr_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 0)))
|
||||
l1_esize = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 4)))
|
||||
|
||||
# ---- 源 2 准备(zip)----
|
||||
kind2: int = 0
|
||||
@@ -1640,50 +1583,36 @@ class StmtGenCifMixin:
|
||||
if cargs2 is not None:
|
||||
n2: sizet = len(cargs2)
|
||||
if n2 >= 1:
|
||||
svz: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs2.get(0),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
svz: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(0), trans._funcs, trans._func_count, trans)
|
||||
if svz is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs2.get(0), "range 参数翻译失败", "TypeError")
|
||||
r2_stop = self.Gen.ExprGenBase.coerce_to_type(builder, svz, i64_ty, cargs2.get(0))
|
||||
if n2 >= 2:
|
||||
svz2: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs2.get(1),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
svz2: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(1), trans._funcs, trans._func_count, trans)
|
||||
if svz2 is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs2.get(1), "range 参数翻译失败", "TypeError")
|
||||
r2_start = self.Gen.ExprGenBase.coerce_to_type(builder, svz2, i64_ty, cargs2.get(1))
|
||||
if n2 >= 3:
|
||||
svz3: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, cargs2.get(2),
|
||||
trans._funcs, trans._func_count, trans)
|
||||
svz3: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(2), trans._funcs, trans._func_count, trans)
|
||||
if svz3 is None:
|
||||
# fail-fast: range 参数翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(cargs2.get(2), "range 参数翻译失败", "TypeError")
|
||||
r2_step = self.Gen.ExprGenBase.coerce_to_type(builder, svz3, i64_ty, cargs2.get(2))
|
||||
elif kind2 == GenTypes.SEQ_KIND_STR:
|
||||
elem2_ty = i8_ty
|
||||
s2_ptr = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, src2,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
s2_ptr = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src2, trans._funcs, trans._func_count, trans)
|
||||
if s2_ptr is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源 2 翻译失败")
|
||||
elif kind2 == GenTypes.SEQ_KIND_LIST:
|
||||
elem2_ty = i8_ptr_ty
|
||||
l2_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, src2,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if l2_obj is None or l2_obj.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(l2_obj.Ty) == 0:
|
||||
l2_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src2, trans._funcs, trans._func_count, trans)
|
||||
if l2_obj is None or l2_obj.Ty is None or self.Gen.ExprGenBase.is_ptr_type(l2_obj.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: list 源 2 不是指针类型")
|
||||
l2_count = llvmlite.build_load(builder, i64_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 1)))
|
||||
l2_data = llvmlite.build_load(builder, i8_ptr_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 0)))
|
||||
l2_esize = llvmlite.build_load(builder, i64_ty,
|
||||
llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 4)))
|
||||
l2_count = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 1)))
|
||||
l2_data = llvmlite.build_load(builder, i8_ptr_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 0)))
|
||||
l2_esize = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 4)))
|
||||
|
||||
# ---- 循环变量 alloca ----
|
||||
# t1: enumerate → 序号 (i32);zip → 源 1 元素
|
||||
@@ -1860,7 +1789,7 @@ class StmtGenCifMixin:
|
||||
# end:
|
||||
# ============================================================
|
||||
def _handle_ptr_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str) -> int:
|
||||
"""指针迭代: for x in ptr: 直到解引用为空"""
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
@@ -1868,9 +1797,7 @@ class StmtGenCifMixin:
|
||||
func: llvmlite.Function* = trans._cur_func
|
||||
|
||||
# 翻译迭代器表达式,获取指针值
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, for_node.iter,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, for_node.iter, trans._funcs, trans._func_count, trans)
|
||||
if ptr_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "指针迭代: 无法翻译迭代器表达式")
|
||||
|
||||
@@ -1904,13 +1831,11 @@ class StmtGenCifMixin:
|
||||
i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool)
|
||||
|
||||
# 创建循环变量 alloca(存储元素值)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty)
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 创建隐式 index 变量,初始为 0
|
||||
@@ -1940,8 +1865,7 @@ class StmtGenCifMixin:
|
||||
# cond 块: load index, GEP, load elem, 空值判定(整数==0 / 指针==null / 浮点==0.0)
|
||||
llvmlite.position_at_end(builder, cond_bb)
|
||||
cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca)
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, elem_ty, ptr_val, cur_idx)
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty, ptr_val, cur_idx)
|
||||
cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr)
|
||||
is_null: llvmlite.Value* = None
|
||||
if elem_is_ptr2 != 0:
|
||||
@@ -2024,7 +1948,7 @@ class StmtGenCifMixin:
|
||||
# end:
|
||||
# ============================================================
|
||||
def _handle_array_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str,
|
||||
array_val: llvmlite.Value*) -> int:
|
||||
"""数组迭代: for x in arr: 按数组长度迭代"""
|
||||
@@ -2054,13 +1978,11 @@ class StmtGenCifMixin:
|
||||
i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool)
|
||||
|
||||
# 循环变量 alloca(存储元素值)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty)
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 隐式 index 变量,初始为 0
|
||||
@@ -2093,16 +2015,14 @@ class StmtGenCifMixin:
|
||||
llvmlite.position_at_end(builder, cond_bb)
|
||||
cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca)
|
||||
count_val: llvmlite.Value* = llvmlite.const_int32(pool, elem_count)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
llvmlite.build_cond_br(builder, in_bounds, elem_check_bb, end_bb)
|
||||
|
||||
# elem_check 块: GEP(0, idx) → load elem → 空值判定(NULL 终止)
|
||||
# 用户语义:整数/指针/浮点元素按"解引用为空"提前终止(如 split 尾哨兵
|
||||
# 的 str 数组),同时保留长度上限防越界读;聚合元素只按长度迭代。
|
||||
llvmlite.position_at_end(builder, elem_check_bb)
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, arr_ty, elem_ty, arr_tmp, cur_idx)
|
||||
elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, arr_tmp, cur_idx)
|
||||
cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr)
|
||||
elem_bits_a: int = self.Gen.ExprGenBase.get_llvm_type_bits(elem_ty)
|
||||
elem_ptr_a: int = self.Gen.ExprGenBase.is_ptr_type(elem_ty)
|
||||
@@ -2170,7 +2090,7 @@ class StmtGenCifMixin:
|
||||
# 元素类型取第一个元素的值类型,其余元素 coerce 到该类型。
|
||||
# ============================================================
|
||||
def _handle_list_literal_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str,
|
||||
list_node: ast.AST*) -> int:
|
||||
"""列表字面量迭代: for x in [a, b, c]: 按元素顺序迭代"""
|
||||
@@ -2193,8 +2113,7 @@ class StmtGenCifMixin:
|
||||
# 列表元素计数 > 实际填充 ⇒ 该槽为裸 0 ⇒ 上层某处产生了空 AST 元素。
|
||||
# 不给下游 translate_value 的守卫吞掉(那会静默跳过 store、产出错值),此处响亮失败。
|
||||
if first_el is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node,
|
||||
self.Gen.TypeGenErr.fatal_error(for_node,
|
||||
f"列表字面量迭代遇到空 AST 元素:第 0 个元素为裸空指针(0),"
|
||||
f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。",
|
||||
"ValueError")
|
||||
@@ -2202,14 +2121,12 @@ class StmtGenCifMixin:
|
||||
# @t.CVTable 类对象首字即 vptr,为 0 时下游任意虚调用(kind()/dump())都会
|
||||
# `load [0+slot]` ⇒ ASan READ at 0x0。读首字的唯一可用写法是 c.Deref((uint64*)(p))。
|
||||
if c.Deref((uint64*)(first_el)) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node,
|
||||
self.Gen.TypeGenErr.fatal_error(for_node,
|
||||
f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 0 个元素指针非 0"
|
||||
f"(地址 {uint64(first_el)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};"
|
||||
f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。",
|
||||
"ValueError")
|
||||
first_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, first_el,
|
||||
first_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, first_el,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if first_val is None or first_val.Ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(first_el, "列表字面量迭代: 无法确定元素类型")
|
||||
@@ -2221,8 +2138,7 @@ class StmtGenCifMixin:
|
||||
tmp_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, arr_ty)
|
||||
if tmp_alloca is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 临时数组分配失败")
|
||||
first_ptr: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, 0))
|
||||
first_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, 0))
|
||||
if first_ptr is not None:
|
||||
llvmlite.build_store(builder, first_val, first_ptr)
|
||||
# 写其余元素(coerce 到 elem_ty)
|
||||
@@ -2231,27 +2147,21 @@ class StmtGenCifMixin:
|
||||
el_node: ast.AST* = elts.get(i)
|
||||
# 显式判空(同上,用 `is None`):不得让空元素被 translate_value 的 None 守卫静默吞掉。
|
||||
if el_node is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node,
|
||||
self.Gen.TypeGenErr.fatal_error(for_node,
|
||||
f"列表字面量迭代遇到空 AST 元素:第 {i} 个元素为裸空指针(0),"
|
||||
f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。",
|
||||
"ValueError")
|
||||
# 对象有效性校验(vptr 非 0),同第 0 元素处:同族"取元素后即用"路径。
|
||||
if c.Deref((uint64*)(el_node)) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node,
|
||||
self.Gen.TypeGenErr.fatal_error(for_node,
|
||||
f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 {i} 个元素指针非 0"
|
||||
f"(地址 {uint64(el_node)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};"
|
||||
f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。",
|
||||
"ValueError")
|
||||
el_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, el_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
el_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, el_node, trans._funcs, trans._func_count, trans)
|
||||
if el_val is not None:
|
||||
el_val = self.Gen.ExprGenBase.coerce_to_type(builder, el_val, elem_ty, el_node)
|
||||
el_ptr: llvmlite.Value* = llvmlite.build_gep_array(
|
||||
builder, arr_ty, elem_ty, tmp_alloca,
|
||||
llvmlite.const_int32(pool, i))
|
||||
el_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, i))
|
||||
if el_ptr is not None:
|
||||
llvmlite.build_store(builder, el_val, el_ptr)
|
||||
i += 1
|
||||
@@ -2291,7 +2201,7 @@ class StmtGenCifMixin:
|
||||
# end:
|
||||
# ============================================================
|
||||
def _handle_list_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str,
|
||||
list_val: llvmlite.Value*) -> int:
|
||||
"""list[T] 容器迭代: for v in lst: 按 __count__ 动态长度迭代"""
|
||||
@@ -2304,20 +2214,17 @@ class StmtGenCifMixin:
|
||||
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
# 读取 __count__ (偏移 8, GEP index 1)
|
||||
cnt_ptr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i64_ty, list_val, llvmlite.const_int64(pool, 1))
|
||||
cnt_ptr: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 1))
|
||||
if cnt_ptr is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "list 迭代: 无法定位 __count__")
|
||||
count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr)
|
||||
|
||||
# 循环变量 alloca(元素类型 i8*,与 list.get 内联一致)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty)
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 隐式 index 变量 (i64,与 __count__ 类型对齐)
|
||||
@@ -2346,21 +2253,17 @@ class StmtGenCifMixin:
|
||||
# cond 块: load index, icmp slt idx, count
|
||||
llvmlite.position_at_end(builder, cond_bb)
|
||||
cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb)
|
||||
|
||||
# body 块: __data__ + idx*__elem_size__ → load 元素 → store to var
|
||||
llvmlite.position_at_end(builder, body_bb)
|
||||
dpp: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i64_ty, list_val, llvmlite.const_int64(pool, 0))
|
||||
dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 0))
|
||||
data_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, dpp)
|
||||
epp: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i64_ty, list_val, llvmlite.const_int64(pool, 4))
|
||||
epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 4))
|
||||
esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, epp)
|
||||
offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, esize)
|
||||
elem_addr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i8_ty, data_ptr, offset)
|
||||
elem_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, data_ptr, offset)
|
||||
cur_elem: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, elem_addr)
|
||||
llvmlite.build_store(builder, cur_elem, var_alloca)
|
||||
|
||||
@@ -2398,7 +2301,7 @@ class StmtGenCifMixin:
|
||||
return new_vars
|
||||
|
||||
def _handle_dict_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str,
|
||||
dict_val: llvmlite.Value*) -> int:
|
||||
"""dict 容器迭代: for key in d: 按 __count__/__keys__ 布局迭代
|
||||
@@ -2417,20 +2320,17 @@ class StmtGenCifMixin:
|
||||
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
# 读取 __count__(槽 2,字节偏移 16)
|
||||
cnt_ptr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i64_ty, dict_val, llvmlite.const_int64(pool, 2))
|
||||
cnt_ptr: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, dict_val, llvmlite.const_int64(pool, 2))
|
||||
if cnt_ptr is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "dict 迭代: 无法定位 __count__")
|
||||
count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr)
|
||||
|
||||
# 循环变量 alloca(元素类型 i8*,与 dict.__next__ 返回 str 一致)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty)
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 隐式 index 变量 (i64,与 __count__ 类型对齐)
|
||||
@@ -2459,19 +2359,16 @@ class StmtGenCifMixin:
|
||||
# cond 块: load index, icmp slt idx, count
|
||||
llvmlite.position_at_end(builder, cond_bb)
|
||||
cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val)
|
||||
llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb)
|
||||
|
||||
# body 块: __keys__ + idx*8 → load key (i8*) → store to var
|
||||
llvmlite.position_at_end(builder, body_bb)
|
||||
kpp: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i64_ty, dict_val, llvmlite.const_int64(pool, 0))
|
||||
kpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, dict_val, llvmlite.const_int64(pool, 0))
|
||||
keys_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, kpp)
|
||||
eight_val: llvmlite.Value* = llvmlite.const_int64(pool, 8)
|
||||
key_offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, eight_val)
|
||||
key_addr: llvmlite.Value* = llvmlite.build_gep(
|
||||
builder, i8_ty, keys_ptr, key_offset)
|
||||
key_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, keys_ptr, key_offset)
|
||||
cur_key: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, key_addr)
|
||||
llvmlite.build_store(builder, cur_key, var_alloca)
|
||||
|
||||
@@ -2535,7 +2432,7 @@ class StmtGenCifMixin:
|
||||
# VpiReader stub 声明同步该参数(_inject_method_declare)。
|
||||
# ============================================================
|
||||
def _handle_oop_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
var_name: str,
|
||||
class_name: str,
|
||||
obj_val: llvmlite.Value*) -> int:
|
||||
@@ -2557,11 +2454,9 @@ class StmtGenCifMixin:
|
||||
if iter_lookup is None:
|
||||
return 0
|
||||
viperlib.snprintf(iter_lookup, 128, "%s.__iter__", class_name)
|
||||
iter_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
mod, iter_lookup)
|
||||
iter_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, iter_lookup)
|
||||
if iter_fn is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node, f"OOP 迭代: 类 '{class_name}' 没有 __iter__ 方法")
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, f"OOP 迭代: 类 '{class_name}' 没有 __iter__ 方法")
|
||||
iter_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(iter_fn)
|
||||
iter_fn_name: str = llvmlite.function_get_name(iter_fn)
|
||||
if iter_ret_ty is None or iter_fn_name is None:
|
||||
@@ -2576,8 +2471,7 @@ class StmtGenCifMixin:
|
||||
if iter_self is None:
|
||||
return 0
|
||||
iter_self.Next = None
|
||||
iter_result: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, iter_fn_name, iter_self, 1, iter_ret_ty, 0)
|
||||
iter_result: llvmlite.Value* = llvmlite.build_call(builder, iter_fn_name, iter_self, 1, iter_ret_ty, 0)
|
||||
if iter_result is None:
|
||||
return 0
|
||||
|
||||
@@ -2586,25 +2480,21 @@ class StmtGenCifMixin:
|
||||
if next_lookup is None:
|
||||
return 0
|
||||
viperlib.snprintf(next_lookup, 128, "%s.__next__", class_name)
|
||||
next_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
mod, next_lookup)
|
||||
next_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, next_lookup)
|
||||
if next_fn is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
for_node, f"OOP 迭代: 类 '{class_name}' 没有 __next__ 方法")
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, f"OOP 迭代: 类 '{class_name}' 没有 __next__ 方法")
|
||||
next_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(next_fn)
|
||||
next_fn_name: str = llvmlite.function_get_name(next_fn)
|
||||
if next_ret_ty is None or next_fn_name is None:
|
||||
return 0
|
||||
|
||||
# 3. 循环变量 alloca(元素类型 = __next__ 返回类型)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, var_name)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, next_ret_ty)
|
||||
if var_alloca is not None:
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, var_name, var_alloca) == 0:
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0:
|
||||
new_vars = 1
|
||||
|
||||
# 4. stop flag alloca(i1,初始 0)
|
||||
@@ -2649,8 +2539,7 @@ class StmtGenCifMixin:
|
||||
# 参数链表: arg1(iter).Next = arg2(flag);flag 独立 null 结尾防自链接
|
||||
next_self.Next = flag_alloca
|
||||
flag_alloca.Next = None
|
||||
next_val: llvmlite.Value* = llvmlite.build_call(
|
||||
builder, next_fn_name, next_self, 2, next_ret_ty, 0)
|
||||
next_val: llvmlite.Value* = llvmlite.build_call(builder, next_fn_name, next_self, 2, next_ret_ty, 0)
|
||||
if next_val is None:
|
||||
return 0
|
||||
stop_val: llvmlite.Value* = llvmlite.build_load(builder, i1_ty, flag_alloca)
|
||||
@@ -2659,8 +2548,7 @@ class StmtGenCifMixin:
|
||||
flag_zero2: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty, 0, "0")
|
||||
continue_i1: llvmlite.Value* = None
|
||||
if flag_zero2 is not None:
|
||||
continue_i1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_EQ, stop_val, flag_zero2)
|
||||
continue_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, stop_val, flag_zero2)
|
||||
if continue_i1 is None:
|
||||
return 0
|
||||
llvmlite.build_cond_br(builder, continue_i1, body_bb, end_bb)
|
||||
@@ -2694,7 +2582,7 @@ class StmtGenCifMixin:
|
||||
return new_vars
|
||||
|
||||
def _handle_enumerate_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
t1: str, t2: str,
|
||||
call: ast.Call*) -> int:
|
||||
"""enumerate 迭代: for i, v in enumerate(x)"""
|
||||
@@ -2706,7 +2594,7 @@ class StmtGenCifMixin:
|
||||
return self._build_seq_loop(trans, for_node, t1, t2, cargs.get(0), None, 1)
|
||||
|
||||
def _handle_zip_iter(self, trans: HT.Translator*,
|
||||
for_node: rawptr[ast.For],
|
||||
for_node: ast.For*,
|
||||
t1: str, t2: str,
|
||||
call: ast.Call*) -> int:
|
||||
"""zip 迭代: for a, b in zip(x, y)"""
|
||||
|
||||
@@ -18,26 +18,19 @@ import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
# ============================================================
|
||||
# StmtGenDeclMixin - StmtGen 拆分 2/3:声明/枚举/nonlocal 访问
|
||||
#
|
||||
# 按功能域从 StmtGenMixin.vp 拆出(500~1500 行/文件架构重构,试点):
|
||||
# translate_global/nonlocal/expr_stmt/pre_scan、break/continue、
|
||||
# nonlocal 闭包 env 访问、枚举注册表。继承 StmtGenCifMixin。
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 常量(与 HandlesEnum 保持一致,本地副本避免跨模块 CDefine 查找 bug)
|
||||
# 常量
|
||||
# ============================================================
|
||||
ENUM_MAX: t.CDefine = 64
|
||||
ENUM_MEMBER_MAX: t.CDefine = 128
|
||||
define ENUM_MAX = 64
|
||||
define ENUM_MEMBER_MAX = 128
|
||||
|
||||
# ============================================================
|
||||
# StmtGenDeclMixin - 声明/枚举/nonlocal(中层级)
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
"""声明/枚举/nonlocal 访问(StmtGen 拆分 2/3,继承 Cif)"""
|
||||
|
||||
def translate_global(self, trans: HT.Translator*,
|
||||
@@ -78,8 +71,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
if nm.id is not None:
|
||||
# 查找父作用域中的变量 alloca,获取类型信息
|
||||
var_ty: llvmlite.LLVMType* = None
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if var_alloca is not None and var_alloca.Ty is not None:
|
||||
var_ty = var_alloca.Ty.Pointee
|
||||
# Void 类型视为无效(Pointee 访问异常时可能返回 Void),
|
||||
@@ -127,11 +119,9 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
# printf / print 走特殊路径(print 是类型感知格式化,不映射到 printf)
|
||||
if string.strcmp(func_name, "printf") == 0:
|
||||
self.Gen.CallGenLeafKit.translate_printf_call(
|
||||
trans.Pool, trans._cur_builder, trans.Module, cl, trans)
|
||||
self.Gen.CallGenLeafKit.translate_printf_call(trans.Pool, trans._cur_builder, trans.Module, cl, trans)
|
||||
elif string.strcmp(func_name, "print") == 0:
|
||||
self.Gen.CallGenLeafKit.translate_print_call(
|
||||
trans.Pool, trans._cur_builder, trans.Module, cl, trans)
|
||||
self.Gen.CallGenLeafKit.translate_print_call(trans.Pool, trans._cur_builder, trans.Module, cl, trans)
|
||||
else:
|
||||
# 通用函数调用(返回值丢弃)
|
||||
# M3:裸名调用**会话函数**(跨片段)时额外把返回值写进 ctx 结果区回显
|
||||
@@ -147,20 +137,15 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
sfn_ent: rawptr[GenTypes.ReplFuncEntry] = \
|
||||
self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name)
|
||||
if sfn_ent is not None and sfn_ent.RetTag != GenTypes.REPL_TY_VOID:
|
||||
sfn_v: llvmlite.Value* = self.Gen.CallGen.translate_call(
|
||||
trans.Pool, trans._cur_builder, trans.Module, call_node,
|
||||
sfn_v: llvmlite.Value* = self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if sfn_v is not None:
|
||||
ctx_v: llvmlite.Value* = self.Gen.VarGen.repl_ctx_ptr(
|
||||
trans, trans.ReplCtx, call_node)
|
||||
ctx_v: llvmlite.Value* = self.Gen.VarGen.repl_ctx_ptr(trans, trans.ReplCtx, call_node)
|
||||
if ctx_v is not None:
|
||||
self.Gen.VarGen.repl_emit_result(
|
||||
trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits,
|
||||
self.Gen.VarGen.repl_emit_result(trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits,
|
||||
call_node)
|
||||
return 0
|
||||
self.Gen.CallGen.translate_call(
|
||||
trans.Pool, trans._cur_builder, trans.Module, call_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans)
|
||||
return 0
|
||||
|
||||
def pre_scan_allocas(self, trans: HT.Translator*,
|
||||
@@ -192,7 +177,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
self.pre_scan_allocas(trans, ifn.orelse.get(bi_pre_e))
|
||||
return 0
|
||||
if k == ast.ASTKind.For:
|
||||
for_n: rawptr[ast.For] = rawptr[ast.For](node)
|
||||
for_n: ast.For* = ast.For*(node)
|
||||
if for_n.children is not None:
|
||||
bn_pre_f: sizet = len(for_n.children)
|
||||
for bi_pre_f in range(bn_pre_f):
|
||||
@@ -340,8 +325,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
def get_env_ptr_var(self, trans: HT.Translator*) -> llvmlite.Value*:
|
||||
"""获取或创建 _env_ptr 变量(存储闭包 env 指针)"""
|
||||
env_var: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, "_env_ptr")
|
||||
env_var: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "_env_ptr")
|
||||
if env_var is not None:
|
||||
return env_var
|
||||
# 创建 alloca 存储 env
|
||||
@@ -519,8 +503,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
# 注意:StdlibAlloc 是 StructGenMixin 字段,本 Mixin 方法体不能直接 self.StdlibAlloc
|
||||
# (NoVTable 按本 Mixin 字段布局编译),走模块级委托。
|
||||
if self.Gen.StructGen.get_stdlib_alloc() != 0:
|
||||
base_ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(
|
||||
CompilerFactory.factory.PermPool, base_ty)
|
||||
base_ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, base_ty)
|
||||
if base_ty_copy is not None:
|
||||
entry.BaseTy = base_ty_copy
|
||||
else:
|
||||
@@ -544,8 +527,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
# 去重:同名成员已存在则跳过(跨模块同名枚举合并注册 / 同模块
|
||||
# 重复处理幂等——如 w32.fileio 与 fat32_types 都有 FRESULT)
|
||||
for ei_d in range(enum_entry.MemberCount):
|
||||
ex_d: rawptr[GenTypes.EnumMember] = self._get_enum_member(
|
||||
enum_entry, ei_d)
|
||||
ex_d: rawptr[GenTypes.EnumMember] = self._get_enum_member(enum_entry, ei_d)
|
||||
if ex_d is not None and ex_d.Name is not None:
|
||||
if string.strcmp(ex_d.Name, member_name) == 0:
|
||||
return ei_d
|
||||
|
||||
@@ -19,22 +19,13 @@ import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin
|
||||
|
||||
# ============================================================
|
||||
# StmtGenMixin - 语句/流程翻译 Mixin(P6 对象化重构 A 组,拆分后顶层)
|
||||
#
|
||||
# 按功能域拆分(500~1500 行/文件架构重构,试点):
|
||||
# 顶层保留语句分派中枢簇 A(translate_stmt/try/raise/with/delete/
|
||||
# _eh_ret_default/_with_ctx_call);global/nonlocal/枚举/CIf 已拆至
|
||||
# StmtGenDeclMixin / StmtGenCifMixin(本类继承链 1/3、2/3)。
|
||||
# 外部引用(Generator.vp import + HandlesBody 委托)零改动。
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StmtGenMixin - 语句分派中枢(顶层)
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
"""语句/流程翻译 Mixin(拆分后顶层,继承 Decl)"""
|
||||
|
||||
def translate_stmt(self, trans: HT.Translator*,
|
||||
@@ -42,8 +33,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
"""翻译单条语句,返回新增的变量数(深度守卫包装器,原逻辑见 _translate_stmt_impl)"""
|
||||
if trans is not None:
|
||||
if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "语句翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "语句翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
trans.TranslateDepth += 1
|
||||
mret: int = self._translate_stmt_impl(trans, node)
|
||||
if trans is not None:
|
||||
@@ -129,28 +119,23 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if tgt.kind() == ast.ASTKind.Attribute:
|
||||
del_at: ast.Attribute* = ast.Attribute*(tgt)
|
||||
if del_at is not None:
|
||||
self.Gen.CallGenProp._try_property_deleter(
|
||||
pool, builder, mod, del_at, trans)
|
||||
self.Gen.CallGenProp._try_property_deleter(pool, builder, mod, del_at, trans)
|
||||
# del obj[key] → __delitem__(obj, key)(对齐 TPC HandlesDelete.py)。
|
||||
# 不能静默忽略 Subscript 目标——否则 del 不生效(len 不变)。
|
||||
elif tgt.kind() == ast.ASTKind.Subscript:
|
||||
dl_sub: ast.Subscript* = ast.Subscript*(tgt)
|
||||
if dl_sub is not None and dl_sub.value is not None and dl_sub.slice is not None:
|
||||
dl_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, dl_sub.value, None, 0, trans)
|
||||
dl_idx: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, dl_sub.slice, None, 0, trans)
|
||||
dl_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, dl_sub.value, None, 0, trans)
|
||||
dl_idx: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, dl_sub.slice, None, 0, trans)
|
||||
if dl_obj is not None and dl_idx is not None:
|
||||
dl_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(
|
||||
dl_obj)
|
||||
dl_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(dl_obj)
|
||||
if dl_st is not None:
|
||||
dl_cls: str = self.Gen.StructGen.get_class_name_by_type(pool, dl_st)
|
||||
if dl_cls is not None:
|
||||
dl_lookup: str = pool.alloc(128)
|
||||
if dl_lookup is not None:
|
||||
viperlib.snprintf(dl_lookup, 128, "%s.__delitem__", dl_cls)
|
||||
dl_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(
|
||||
mod, dl_lookup)
|
||||
dl_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, dl_lookup)
|
||||
if dl_fn is not None:
|
||||
dl_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(dl_fn)
|
||||
dl_fn_name: str = llvmlite.function_get_name(dl_fn)
|
||||
@@ -166,8 +151,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 参数链表: self → key(独立 null 结尾)
|
||||
dl_self.Next = dl_idx
|
||||
dl_idx.Next = None
|
||||
llvmlite.build_call(
|
||||
builder, dl_fn_name, dl_self, 2, dl_ret, 0)
|
||||
llvmlite.build_call(builder, dl_fn_name, dl_self, 2, dl_ret, 0)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -290,17 +274,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 无 except(非法 try,防御):直接吞掉
|
||||
llvmlite.build_br(builder, unhandled_bb)
|
||||
else:
|
||||
eh_code_val: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, i32_ty_t, exception_code)
|
||||
eh_code_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty_t, exception_code)
|
||||
next_check_t: rawptr[llvmlite.BasicBlock] = None
|
||||
for i_t in range(n_handlers_t):
|
||||
hdr_t: ast.ExceptHandler* = ast.ExceptHandler*(
|
||||
tr.handlers.get(i_t))
|
||||
hdr_t: ast.ExceptHandler* = ast.ExceptHandler*(tr.handlers.get(i_t))
|
||||
match_bb_t: rawptr[llvmlite.BasicBlock] = match_bbs.get(i_t)
|
||||
if i_t > 0 and next_check_t is not None:
|
||||
llvmlite.position_at_end(builder, next_check_t)
|
||||
eh_code_val = llvmlite.build_load(
|
||||
builder, i32_ty_t, exception_code)
|
||||
eh_code_val = llvmlite.build_load(builder, i32_ty_t, exception_code)
|
||||
if hdr_t is None or hdr_t.type is None:
|
||||
# 裸 except:无条件匹配
|
||||
llvmlite.build_br(builder, match_bb_t)
|
||||
@@ -320,8 +301,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
return 0
|
||||
n_codes_t: int = 0
|
||||
if hname_t is not None and self.Gen.ClassGenBase.is_exception_name(hname_t) != 0:
|
||||
n_codes_t = self.Gen.ClassGenBase.collect_descendant_codes(
|
||||
hname_t, codes_buf_t, 64)
|
||||
n_codes_t = self.Gen.ClassGenBase.collect_descendant_codes(hname_t, codes_buf_t, 64)
|
||||
else:
|
||||
c0_t: int = 1
|
||||
if hname_t is not None:
|
||||
@@ -332,22 +312,18 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
n_codes_t = 1
|
||||
match_cond_t: llvmlite.Value* = None
|
||||
for ci_t in range(n_codes_t):
|
||||
code_val_t: llvmlite.Value* = llvmlite.const_int32(
|
||||
pool, codes_buf_t[ci_t])
|
||||
is_match_t: llvmlite.Value* = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_EQ, eh_code_val, code_val_t)
|
||||
code_val_t: llvmlite.Value* = llvmlite.const_int32(pool, codes_buf_t[ci_t])
|
||||
is_match_t: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, eh_code_val, code_val_t)
|
||||
if match_cond_t is None:
|
||||
match_cond_t = is_match_t
|
||||
elif is_match_t is not None:
|
||||
match_cond_t = llvmlite.build_or(
|
||||
builder, match_cond_t, is_match_t)
|
||||
match_cond_t = llvmlite.build_or(builder, match_cond_t, is_match_t)
|
||||
if i_t < n_handlers_t - 1:
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.check.%d.%d", lc_t, i_t)
|
||||
next_check_t = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
else:
|
||||
next_check_t = unhandled_bb
|
||||
llvmlite.build_cond_br(
|
||||
builder, match_cond_t, match_bb_t, next_check_t)
|
||||
llvmlite.build_cond_br(builder, match_cond_t, match_bb_t, next_check_t)
|
||||
# MatchBB:绑定 handler 变量(e = 消息指针),跳 ExceptBB
|
||||
llvmlite.position_at_end(builder, match_bb_t)
|
||||
if hdr_t is not None and hdr_t.name is not None and hdr_t.name[0] != '\0':
|
||||
@@ -355,8 +331,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 重复 define_var 不 shadow——多 try 共用 `as e` 时各 MatchBB
|
||||
# 各自 store 消息,各 ExceptBB 读同一入口 alloca,避免
|
||||
# 非支配 alloca 触发 "does not dominate all uses")。
|
||||
h_ent_t: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, hdr_t.name)
|
||||
h_ent_t: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, hdr_t.name)
|
||||
if h_ent_t is not None and h_ent_t.Alloca is not None:
|
||||
h_alloca_t: llvmlite.Value* = h_ent_t.Alloca
|
||||
else:
|
||||
@@ -364,8 +339,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if h_alloca_t is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, hdr_t.name, h_alloca_t)
|
||||
if h_alloca_t is not None:
|
||||
h_msg_t: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, i8_ptr_ty_t, eh_message)
|
||||
h_msg_t: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty_t, eh_message)
|
||||
if h_msg_t is not None:
|
||||
llvmlite.build_store(builder, h_msg_t, h_alloca_t)
|
||||
except_bb_t: rawptr[llvmlite.BasicBlock] = except_bbs.get(i_t)
|
||||
@@ -375,10 +349,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
llvmlite.position_at_end(builder, unhandled_bb)
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \
|
||||
and trans._eh_code_out_param is not None:
|
||||
un_msg_t: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, i8_ptr_ty_t, eh_message)
|
||||
un_code_t: llvmlite.Value* = llvmlite.build_load(
|
||||
builder, i32_ty_t, exception_code)
|
||||
un_msg_t: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty_t, eh_message)
|
||||
un_code_t: llvmlite.Value* = llvmlite.build_load(builder, i32_ty_t, exception_code)
|
||||
if un_msg_t is not None:
|
||||
llvmlite.build_store(builder, un_msg_t, trans._eh_msg_out_param)
|
||||
if un_code_t is not None:
|
||||
@@ -391,8 +363,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
|
||||
# ---- 7. Except 体 ----
|
||||
for i_t in range(n_handlers_t):
|
||||
hdr2_t: ast.ExceptHandler* = ast.ExceptHandler*(
|
||||
tr.handlers.get(i_t))
|
||||
hdr2_t: ast.ExceptHandler* = ast.ExceptHandler*(tr.handlers.get(i_t))
|
||||
except_bb2_t: rawptr[llvmlite.BasicBlock] = except_bbs.get(i_t)
|
||||
llvmlite.position_at_end(builder, except_bb2_t)
|
||||
if hdr2_t is not None and hdr2_t.children is not None:
|
||||
@@ -467,11 +438,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if trans._stop_iter_flag_ptr is not None:
|
||||
i1_ty_r: llvmlite.LLVMType* = llvmlite.Int1(pool)
|
||||
if i1_ty_r is not None:
|
||||
one_i1_r: llvmlite.Value* = llvmlite.ConstInt(
|
||||
pool, i1_ty_r, 1, "1")
|
||||
one_i1_r: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_r, 1, "1")
|
||||
if one_i1_r is not None:
|
||||
llvmlite.build_store(
|
||||
builder, one_i1_r, trans._stop_iter_flag_ptr)
|
||||
llvmlite.build_store(builder, one_i1_r, trans._stop_iter_flag_ptr)
|
||||
self._eh_ret_default(trans, pool, builder)
|
||||
return 0
|
||||
|
||||
@@ -497,8 +466,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if exc_code == 0:
|
||||
exc_code = 1
|
||||
if ecl2.args is not None and len(ecl2.args) > 0:
|
||||
exc_msg = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ecl2.args.get(0), None, 0, trans)
|
||||
exc_msg = self.Gen.ExprGen.translate_value(builder, pool, mod, ecl2.args.get(0), None, 0, trans)
|
||||
|
||||
# ---- 异常分发 ----
|
||||
# 1. try 内:写入 try 的 eh_code/eh_message alloca,分支 DispatchBB
|
||||
@@ -507,8 +475,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if code_val_r is not None:
|
||||
llvmlite.build_store(builder, code_val_r, trans._eh_code_ptr)
|
||||
if exc_msg is None:
|
||||
exc_msg = llvmlite.ConstNull(
|
||||
pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null")
|
||||
exc_msg = llvmlite.ConstNull(pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null")
|
||||
if exc_msg is not None and trans._eh_msg_ptr is not None:
|
||||
llvmlite.build_store(builder, exc_msg, trans._eh_msg_ptr)
|
||||
llvmlite.build_br(builder, trans._eh_dispatch_bb)
|
||||
@@ -520,8 +487,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if code_val_r2 is not None:
|
||||
llvmlite.build_store(builder, code_val_r2, trans._eh_code_out_param)
|
||||
if exc_msg is None:
|
||||
exc_msg = llvmlite.ConstNull(
|
||||
pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null")
|
||||
exc_msg = llvmlite.ConstNull(pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null")
|
||||
if exc_msg is not None:
|
||||
llvmlite.build_store(builder, exc_msg, trans._eh_msg_out_param)
|
||||
self._eh_ret_default(trans, pool, builder)
|
||||
@@ -603,8 +569,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
n: sizet = len(items)
|
||||
|
||||
# 保存外层 __with_ctx(嵌套 with 时退出后恢复)
|
||||
old_ctx_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, "__with_ctx")
|
||||
old_ctx_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "__with_ctx")
|
||||
|
||||
# 记录每个 item 的类名(__exit__ 调用时设置 __with_ctx 类型用)
|
||||
ctx_class_buf: sizet* = pool.alloc(8 * n)
|
||||
@@ -623,9 +588,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if item is None or item.context_expr is None:
|
||||
continue
|
||||
# 翻译 context_expr(对象构造,如 MemPool(arena, 4096))
|
||||
ctx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, item.context_expr,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
ctx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, item.context_expr, trans._funcs, trans._func_count, trans)
|
||||
if ctx_val is None:
|
||||
continue
|
||||
# 提取类名(注解类名,Attribute 时带模块前缀,如 "memhub.MemPool"——
|
||||
@@ -651,19 +614,16 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
elif cfn.kind() == ast.ASTKind.Name:
|
||||
cls_name = (ast.Name*(cfn)).id
|
||||
# context 对象存入 __with_ctx(方法调用解析 self 用)
|
||||
ctx_alloca: llvmlite.Value* = llvmlite.build_alloca(
|
||||
builder, ctx_val.Ty)
|
||||
ctx_alloca: llvmlite.Value* = llvmlite.build_alloca(builder, ctx_val.Ty)
|
||||
if ctx_alloca is None:
|
||||
continue
|
||||
llvmlite.build_store(builder, ctx_val, ctx_alloca)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, "__with_ctx", ctx_alloca)
|
||||
if cls_name is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, "__with_ctx", cls_name)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, "__with_ctx", cls_name)
|
||||
ctx_class_buf[i] = sizet(cls_name)
|
||||
# 调用 __enter__()
|
||||
enter_val: llvmlite.Value* = self._with_ctx_call(
|
||||
trans, pool, builder, mod, "__enter__")
|
||||
enter_val: llvmlite.Value* = self._with_ctx_call(trans, pool, builder, mod, "__enter__")
|
||||
# asname 绑定(__enter__ 返回值,缺失时退回 context 对象)
|
||||
if item.optional_vars is not None:
|
||||
ov: ast.AST* = item.optional_vars
|
||||
@@ -674,14 +634,12 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if bind_val is None:
|
||||
bind_val = ctx_val
|
||||
if bind_val is not None:
|
||||
asn_alloca: llvmlite.Value* = llvmlite.build_alloca(
|
||||
builder, bind_val.Ty)
|
||||
asn_alloca: llvmlite.Value* = llvmlite.build_alloca(builder, bind_val.Ty)
|
||||
if asn_alloca is not None:
|
||||
llvmlite.build_store(builder, bind_val, asn_alloca)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, asname, asn_alloca)
|
||||
if cls_name is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, asname, cls_name)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, asname, cls_name)
|
||||
# FakeDuck: __provides__ 元数据 → 生成 _push_provider 调用
|
||||
# (对齐 TPC HandlesWith.py L138-159;经 gen 单例委托 CallGenMixin。
|
||||
# 类名去模块前缀后查 __provides__ 表,如 memhub.MemBuddy → MemBuddy)
|
||||
@@ -691,8 +649,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if fd_dot is not None:
|
||||
fd_cls_bare = fd_dot + 1
|
||||
if fd_cls_bare is not None:
|
||||
self.Gen.CallGenFd._emit_provider_push(
|
||||
trans, pool, builder, mod, fd_cls_bare, ctx_val)
|
||||
self.Gen.CallGenFd._emit_provider_push(trans, pool, builder, mod, fd_cls_bare, ctx_val)
|
||||
|
||||
# 2. 翻译 body
|
||||
body: list[ast.AST*]* = wt.children
|
||||
@@ -714,16 +671,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if fd_dot_p is not None:
|
||||
fd_cls_bare_p = fd_dot_p + 1
|
||||
if fd_cls_bare_p is not None:
|
||||
self.Gen.CallGenFd._emit_provider_pop(
|
||||
trans, pool, builder, mod, fd_cls_bare_p)
|
||||
self.Gen.CallGenFd._emit_provider_pop(trans, pool, builder, mod, fd_cls_bare_p)
|
||||
|
||||
# 3. 逆序调用 __exit__()(Python with 语义:后进先出)
|
||||
for i in range(n):
|
||||
ci: int = n - 1 - i
|
||||
if ctx_class_buf[ci] != 0:
|
||||
cls_ci: str = (str | t.CPtr)(ctx_class_buf[ci])
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, "__with_ctx", cls_ci)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, "__with_ctx", cls_ci)
|
||||
self._with_ctx_call(trans, pool, builder, mod, "__exit__")
|
||||
|
||||
# 4. 恢复外层 __with_ctx
|
||||
@@ -737,18 +692,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
mod: llvmlite.LLVMModule*,
|
||||
method_name: str) -> llvmlite.Value*:
|
||||
"""构造并翻译 __with_ctx.<method_name>() 调用(__enter__/__exit__)"""
|
||||
if pool is None or method_name is None:
|
||||
return None
|
||||
if pool is None or method_name is None: return None
|
||||
name_node: ast.AST* = ast.Name(pool, "__with_ctx", ast.ASTCtx.Load)
|
||||
if name_node is None:
|
||||
return None
|
||||
attr_node: ast.AST* = ast.Attribute(
|
||||
pool, name_node, method_name, ast.ASTCtx.Load)
|
||||
if attr_node is None:
|
||||
return None
|
||||
if name_node is None: return None
|
||||
attr_node: ast.AST* = ast.Attribute(pool, name_node, method_name, ast.ASTCtx.Load)
|
||||
if attr_node is None: return None
|
||||
call_node: ast.AST* = ast.Call(pool, attr_node, None, None)
|
||||
if call_node is None:
|
||||
return None
|
||||
return self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, call_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if call_node is None: return None
|
||||
return self.Gen.ExprGen.translate_value(builder, pool, mod, call_node, trans._funcs, trans._func_count, trans)
|
||||
@@ -578,8 +578,7 @@ novirtual class StructGenMixin:
|
||||
if default_val.kind() == ast.ASTKind.List: return self._deep_copy_list_ast(pool, default_val)
|
||||
if default_val.kind() != ast.ASTKind.Constant: return None
|
||||
src_c: ast.Constant* = ast.Constant*(default_val)
|
||||
dst_c: ast.Constant* = ast.Constant*(
|
||||
pool.alloc_tagged(ast.Constant.__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_641))
|
||||
dst_c: ast.Constant* = ast.Constant*(pool.alloc_tagged(ast.Constant.__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_641))
|
||||
if dst_c is None:
|
||||
return None
|
||||
string.memset(dst_c, 0, ast.Constant.__sizeof__())
|
||||
@@ -639,8 +638,7 @@ novirtual class StructGenMixin:
|
||||
src_elts_l: list[ast.AST*]* = src_l.elts
|
||||
if src_elts_l is not None:
|
||||
cnt_l: sizet = len(src_elts_l)
|
||||
lst_copy_l: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)(
|
||||
pool.alloc_tagged(list[ast.AST*].__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_693))
|
||||
lst_copy_l: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)(pool.alloc_tagged(list[ast.AST*].__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_693))
|
||||
if lst_copy_l is not None:
|
||||
string.memset(lst_copy_l, 0, list[ast.AST*].__sizeof__())
|
||||
# 计数**绝不先按源计数写死**:必须在填充循环里按"实际写入槽数"落定
|
||||
@@ -672,8 +670,7 @@ novirtual class StructGenMixin:
|
||||
# 源列表自身存在空元素,说明产生源已损坏(计数 > 实际填充)
|
||||
# ——响亮失败,绝不静默补 0。
|
||||
if elem_src_l is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
default_val,
|
||||
self.Gen.TypeGenErr.fatal_error(default_val,
|
||||
f"字段默认值深拷贝:列表字面量第 {li_l} 个元素为空 AST 元素(指针为 0)。"
|
||||
f"上层某处产生了空 AST 元素(元素计数与实际填充不一致),"
|
||||
f"拒绝静默补 0 生成残缺的默认值;已终止编译。",
|
||||
@@ -681,8 +678,7 @@ novirtual class StructGenMixin:
|
||||
return None
|
||||
elem_dst_l: ast.AST* = self._deep_copy_default_ast(pool, elem_src_l)
|
||||
if elem_dst_l is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
elem_src_l,
|
||||
self.Gen.TypeGenErr.fatal_error(elem_src_l,
|
||||
f"字段默认值深拷贝:列表字面量第 {li_l} 个元素(kind={elem_src_l.kind()})"
|
||||
f"既非 Constant 也非 List,无法深拷贝到永久池。若在此静默跳过该槽,"
|
||||
f"会形成【计数 > 实际填充数】的空槽(后续 elts.get 读到裸 0 崩溃);"
|
||||
@@ -1175,11 +1171,9 @@ novirtual class StructGenMixin:
|
||||
self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_q)
|
||||
rn_alias_q: int = -1
|
||||
if rn_is_renum_q != 0:
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
rn_cls_q, field_name)
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(rn_cls_q, field_name)
|
||||
if rn_alias_q < 1 and bare_q is not rn_cls_q:
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
bare_q, field_name)
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(bare_q, field_name)
|
||||
if rn_alias_q >= 1:
|
||||
rn_fe_q: GenTypes.FieldEntry* = \
|
||||
self._get_field_entry(mod_entry_q, rn_alias_q)
|
||||
@@ -1233,13 +1227,11 @@ novirtual class StructGenMixin:
|
||||
rn_is_renum_l = self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_l)
|
||||
rn_alias_l: int = -1
|
||||
if rn_is_renum_l != 0:
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
rn_cls_l, field_name)
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(rn_cls_l, field_name)
|
||||
if rn_alias_l < 1 and class_name is not rn_cls_l:
|
||||
# 双保险:别名表可能仍持有旧 AST 指针(_update_renum_alias_class_ptr
|
||||
# 未执行/多模块重复注册场景),用调用方 class_name 再试一次
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
class_name, field_name)
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(class_name, field_name)
|
||||
if rn_alias_l >= 1:
|
||||
rn_fe_l: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(entry, rn_alias_l)
|
||||
@@ -1835,9 +1827,7 @@ novirtual class StructGenMixin:
|
||||
# (G3 LinkedNode.prepend 挂起候选),超限立即报错终止
|
||||
cnt_ef += 1
|
||||
if cnt_ef > 100000:
|
||||
VLogger.error(
|
||||
"字段链表疑似成环(_ensure_field_types_in_module),强制终止",
|
||||
"STRUCT")
|
||||
VLogger.error("字段链表疑似成环(_ensure_field_types_in_module),强制终止", "STRUCT")
|
||||
stdlib.exit(1)
|
||||
if fld.Ty is not None:
|
||||
# 值类型子结构体(如 FILETIME)需要完整定义
|
||||
|
||||
@@ -463,8 +463,7 @@ novirtual class Translator:
|
||||
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
# 声明 printf
|
||||
printf_func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, "printf", i32_ty)
|
||||
printf_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "printf", i32_ty)
|
||||
if printf_func is None:
|
||||
VLogger.error("CreateDeclare printf returned NULL", "TR")
|
||||
return 1
|
||||
@@ -474,18 +473,15 @@ novirtual class Translator:
|
||||
# declare void @llvm.va_start(i8*)
|
||||
# declare void @llvm.va_end(i8*)
|
||||
void_ty_decl: llvmlite.LLVMType* = llvmlite.Void(pool)
|
||||
va_start_func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, "llvm.va_start", void_ty_decl)
|
||||
va_start_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "llvm.va_start", void_ty_decl)
|
||||
if va_start_func is not None:
|
||||
llvmlite.add_param(pool, va_start_func, i8_ptr_ty, "ap")
|
||||
va_end_func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, "llvm.va_end", void_ty_decl)
|
||||
va_end_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "llvm.va_end", void_ty_decl)
|
||||
if va_end_func is not None:
|
||||
llvmlite.add_param(pool, va_end_func, i8_ptr_ty, "ap")
|
||||
|
||||
# 声明 malloc(闭包分配用)
|
||||
malloc_func: llvmlite.Function* = llvmlite.create_declare(
|
||||
pool, mod, "malloc", i8_ptr_ty)
|
||||
malloc_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "malloc", i8_ptr_ty)
|
||||
if malloc_func is not None:
|
||||
i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool)
|
||||
llvmlite.add_param(pool, malloc_func, i64_ty, "size")
|
||||
@@ -571,9 +567,7 @@ novirtual class Translator:
|
||||
if self._imported_modules is not None:
|
||||
# 错误上下文帧:当前模块触发依赖 stub 加载的 import 位置
|
||||
GenApi.push_trace(GenApi.get_current_file(), cur_imp_lineno)
|
||||
StubMergerBuild.LoadDepVpiIntoModule(
|
||||
pool, mod, self._imported_modules, self._from_imports,
|
||||
GenApi.get_temp_dir(), self)
|
||||
StubMergerBuild.LoadDepVpiIntoModule(pool, mod, self._imported_modules, self._from_imports, GenApi.get_temp_dir(), self)
|
||||
GenApi.pop_trace()
|
||||
# 预注册模块级变量(AnnAssign/Assign)到 SymTab
|
||||
# 解决时序问题:class Logger 的 __init__ 引用 _mbuddy 时,
|
||||
@@ -629,15 +623,13 @@ novirtual class Translator:
|
||||
# (Phase1 1b / Phase2 pre-inc / PhaseA)——否则 _list/_dict 显式
|
||||
# import memhub 且 memhub 用容器泛型时成 2-环,Phase A 永不收敛。
|
||||
if self._ContainerInjectionCreatesCycle("_dict") == 0:
|
||||
self._imported_modules = GenApi.add_imported_module(
|
||||
pool, self._imported_modules, "_dict")
|
||||
self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_dict")
|
||||
if need_list_box[0] != 0:
|
||||
GenApi.add_visible_struct(pool, "list")
|
||||
if self._imported_modules is None or \
|
||||
GenApi.is_module_imported(self._imported_modules, "_list") == 0:
|
||||
if self._ContainerInjectionCreatesCycle("_list") == 0:
|
||||
self._imported_modules = GenApi.add_imported_module(
|
||||
pool, self._imported_modules, "_list")
|
||||
self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_list")
|
||||
stdlib.free(need_list_box)
|
||||
stdlib.free(need_dict_box)
|
||||
|
||||
@@ -736,8 +728,7 @@ novirtual class Translator:
|
||||
if arg_s is not None:
|
||||
ag_s: ast.Arg* = ast.Arg*(arg_s)
|
||||
if ag_s.annotation is not None:
|
||||
self._check_container_type_node(
|
||||
ag_s.annotation, need_list_box, need_dict_box)
|
||||
self._check_container_type_node(ag_s.annotation, need_list_box, need_dict_box)
|
||||
# `[...]`/`{}` 字面量不触发 _list/_dict 导入:字面量广泛用于编译期常量列表
|
||||
# (c.Asm 的 op/inp/out CLOBBER 参数、数组数据初始化),并非 list 容器使用。
|
||||
# list/dict 容器的真实使用由类型位置检测覆盖:`x: list` / `list[...]` 注解、
|
||||
|
||||
@@ -209,10 +209,7 @@ novirtual class TranslatorGenMixin:
|
||||
|
||||
# 元素数超过声明长度 → fail-fast(不按声明长度截断、静默丢弃多余元素)。
|
||||
if sizet(arr_count) < elts_count:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
list_node,
|
||||
f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许静默截断",
|
||||
"OverflowError")
|
||||
self.Gen.TypeGenErr.fatal_error(list_node, f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许静默截断", "OverflowError")
|
||||
return None
|
||||
|
||||
# 非整数元素类型(struct/指针等聚合):不存在 "%s %lld" 文本展开,仅当列表
|
||||
@@ -252,23 +249,20 @@ novirtual class TranslatorGenMixin:
|
||||
if en_n is not None:
|
||||
ek_n: int = en_n.kind()
|
||||
if ek_n == ast.ASTKind.List:
|
||||
sub_n = self._build_array_initializer_text(
|
||||
pool, elem_ty, ast.List*(en_n))
|
||||
sub_n = self._build_array_initializer_text(pool, elem_ty, ast.List*(en_n))
|
||||
elif ek_n == ast.ASTKind.Set:
|
||||
# 花括号行字面量(如点阵字库 {0x00, ...}):Set.elts
|
||||
# 与 List 同构,包装为临时 List 递归生成子数组文本
|
||||
se_n: rawptr[ast.Set] = rawptr[ast.Set](en_n)
|
||||
if se_n is not None and se_n.elts is not None:
|
||||
sub_n = self._build_array_initializer_text(
|
||||
pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load))
|
||||
sub_n = self._build_array_initializer_text(pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load))
|
||||
if sub_n is None:
|
||||
# 元素缺失/无法展开:子数组整体零初始化
|
||||
sub_n = "zeroinitializer"
|
||||
if i_n > 0:
|
||||
written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, ", ")
|
||||
pos_n += sizet(written_n)
|
||||
written_n = viperlib.snprintf(
|
||||
buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n)
|
||||
written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n)
|
||||
pos_n += sizet(written_n)
|
||||
i_n += 1
|
||||
viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]")
|
||||
@@ -408,8 +402,7 @@ novirtual class TranslatorGenMixin:
|
||||
viperlib.snprintf(str_name_buf, 64, ".str.%s", var_name)
|
||||
|
||||
# 调用 llvmlite.create_global_string 创建字符串常量全局
|
||||
str_gv: llvmlite.GlobalVariable* = llvmlite.create_global_string(
|
||||
pool, mod, str_name_buf, str_val)
|
||||
str_gv: llvmlite.GlobalVariable* = llvmlite.create_global_string(pool, mod, str_name_buf, str_val)
|
||||
if str_gv is None:
|
||||
return None
|
||||
|
||||
@@ -604,9 +597,7 @@ novirtual class TranslatorGenMixin:
|
||||
return None
|
||||
sec_val: str = self.Gen.FuncGenBase._get_attr_call_arg_str(hit)
|
||||
if sec_val is None or sec_val[0] == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级变量 '{var_name}' 的 t.attr.section(...) 段名缺失或为空",
|
||||
"ValueError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 的 t.attr.section(...) 段名缺失或为空", "ValueError")
|
||||
return None
|
||||
return sec_val
|
||||
def _extract_global_attr_aligned(self, node: ast.AST*,
|
||||
@@ -621,9 +612,7 @@ novirtual class TranslatorGenMixin:
|
||||
return 0
|
||||
al_val: int = self.Gen.ClassGenBase._tattr_aligned_int(hit)
|
||||
if al_val <= 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级变量 '{var_name}' 的 t.attr.aligned(N) 需要正整数字面量 N",
|
||||
"ValueError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 的 t.attr.aligned(N) 需要正整数字面量 N", "ValueError")
|
||||
return 0
|
||||
return al_val
|
||||
def _extract_global_attr_weak(self, node: ast.AST*) -> int:
|
||||
@@ -656,16 +645,14 @@ novirtual class TranslatorGenMixin:
|
||||
if nm_cd.id is not None:
|
||||
if self.Gen.AssignGen.is_cdefine_annotation(aa_cd.annotation) != 0:
|
||||
# 浮点/整数自动识别注册(浮点 CDefine 如 vipermath U_M_PI)
|
||||
self.Gen.AssignGen._register_cdefine_from_value(
|
||||
pool, nm_cd.id, aa_cd.value, aa_cd.annotation)
|
||||
self.Gen.AssignGen._register_cdefine_from_value(pool, nm_cd.id, aa_cd.value, aa_cd.annotation)
|
||||
return 0
|
||||
# CTypedef 注解(如 posix.vp mode_t: t.CTypedef = uint32):
|
||||
# 不创建全局变量(否则生成 @mode_t 符号 → 链接 duplicate symbol)。
|
||||
# 预注册阶段按需注册到 CTypedef 表:翻译期表已被 clear_ctypedefs 清空
|
||||
# (每文件隔离),不注册则函数参数注解查表失败 → NameError。
|
||||
if self.Gen.TypeGenCType._is_ctypedef_annotation(aa_cd.annotation) != 0:
|
||||
ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(
|
||||
pool, aa_cd.value)
|
||||
ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, aa_cd.value)
|
||||
if ctd_str is not None:
|
||||
self.Gen.TypeGenCType.register_ctypedef(pool, nm_cd.id, ctd_str)
|
||||
return 0
|
||||
@@ -712,20 +699,15 @@ novirtual class TranslatorGenMixin:
|
||||
# (CallGenLeafKit.vp:698-699、:783-788),跨文件查找可见。
|
||||
# t.CDefine/t.CTypedef 等分支已在 :675-689 提前返回,行为不变。
|
||||
if annot_node is not None:
|
||||
ml_callable_ret: llvmlite.LLVMType* = (
|
||||
self.Gen.TypeGenErr.try_extract_callable_ret(
|
||||
pool, annot_node, trans._imported_modules,
|
||||
trans._from_imports, trans))
|
||||
ml_callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot_node, trans._imported_modules,trans._from_imports, trans)
|
||||
if ml_callable_ret is not None:
|
||||
# 返回值:0=成功/同类型幂等命中;非 0 已在 register_func_ptr_sig
|
||||
# 内部 fatal_error 终止编译,此处分支仅防御(见 AssignGenMixin 同处)。
|
||||
if self.Gen.CallGenLeafKit.register_func_ptr_sig(
|
||||
pool, var_name, ml_callable_ret, aa) != 0:
|
||||
if self.Gen.CallGenLeafKit.register_func_ptr_sig(pool, var_name, ml_callable_ret, aa) != 0:
|
||||
return 0
|
||||
# 解析类型
|
||||
if aa.annotation is not None:
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if resolved is not None:
|
||||
# 对象类模块级变量(@t.Object/@t.CVTable:对象即指针)→ Ptr(struct):
|
||||
# 裸类名注解 resolve 返回 struct 值,模块级变量此处需包装 Ptr;若建成
|
||||
@@ -757,8 +739,7 @@ novirtual class TranslatorGenMixin:
|
||||
# [S4 fail-fast] 模块级变量有注解但解析失败 → 不再静默用 i32
|
||||
# (类型错会使全局存储尺寸/字段访问/ABI 全错);前向引用未注册类
|
||||
# 应收敛为多遍注册而非回退 i32。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
aa.annotation, f"模块级变量 '{var_name}' 类型注解解析失败", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(aa.annotation, f"模块级变量 '{var_name}' 类型注解解析失败", "NameError")
|
||||
return 0
|
||||
# 解析初始值(支持整数、负数字面量、列表字面量、字符串字面量)
|
||||
if aa.value is not None:
|
||||
@@ -853,20 +834,15 @@ novirtual class TranslatorGenMixin:
|
||||
case _:
|
||||
pass
|
||||
if is_fty_g == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型",
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型",
|
||||
"TypeError")
|
||||
return 0
|
||||
if self.Gen.AssignGen._recover_float_literal(
|
||||
var_name, t.CPtr(c.Addr(init_fval)), 0) != 1:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级浮点变量 '{var_name}' 初始化值源文件恢复失败",
|
||||
"InternalCompilerError")
|
||||
if self.Gen.AssignGen._recover_float_literal(var_name, t.CPtr(c.Addr(init_fval)), 0) != 1:
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级浮点变量 '{var_name}' 初始化值源文件恢复失败", "InternalCompilerError")
|
||||
return 0
|
||||
|
||||
# 检查是否已注册
|
||||
existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, var_name)
|
||||
existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, var_name)
|
||||
if existing is not None:
|
||||
return 0
|
||||
|
||||
@@ -884,8 +860,7 @@ novirtual class TranslatorGenMixin:
|
||||
# 无法在 LLVM MC 中解析)。
|
||||
is_global_cexport: int = 0
|
||||
if annot_node is not None:
|
||||
is_global_cexport = self.Gen.TypeGenErr.has_decorator_marker(
|
||||
annot_node, "CExport", 0)
|
||||
is_global_cexport = self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CExport", 0)
|
||||
# 全局变量侧 t.attr.* 属性(`T | t.attr.xxx` 注解联合形态):
|
||||
# section→gv.Section、aligned→gv.Align、weak→gv.Linkage(见下方应用点)。
|
||||
# 仅在 AnnAssign(annot_node 非 None)时存在,与 t.CExport 同一条路。
|
||||
@@ -956,13 +931,11 @@ novirtual class TranslatorGenMixin:
|
||||
case _:
|
||||
pass
|
||||
if is_arr_g != 0:
|
||||
arr_str_init: str = self._build_string_array_initializer_text(
|
||||
pool, var_ty, init_str_val)
|
||||
arr_str_init: str = self._build_string_array_initializer_text(pool, var_ty, init_str_val)
|
||||
if arr_str_init is not None:
|
||||
gv.Initializer = arr_str_init
|
||||
else:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级数组变量 '{var_name}' 字符串初始化器构建失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级数组变量 '{var_name}' 字符串初始化器构建失败", "TypeError")
|
||||
else:
|
||||
# 指针类型(如 b64_tab: t.CArray[char, None] = "ABC..."):
|
||||
# 创建字符串常量全局 + GEP 引用
|
||||
@@ -970,8 +943,7 @@ novirtual class TranslatorGenMixin:
|
||||
if str_init is not None:
|
||||
gv.Initializer = str_init
|
||||
else:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级变量 '{var_name}' 初始化器构建失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 初始化器构建失败", "TypeError")
|
||||
elif init_kind == 4:
|
||||
# 浮点初始值:LLVM IR 的浮点常量必须写成位模式文本(0x%016llx / 0x%08x)——
|
||||
# 十进制文本经 llc 解析对部分值有 ±1 ulp 误差(见 llvmlite.ConstFloat 注释)。
|
||||
@@ -980,8 +952,7 @@ novirtual class TranslatorGenMixin:
|
||||
if fc_g is not None and fc_g.Name is not None:
|
||||
gv.Initializer = fc_g.Name
|
||||
else:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"模块级变量 '{var_name}' 浮点初始化器构建失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 浮点初始化器构建失败", "TypeError")
|
||||
else:
|
||||
# 使用 zeroinitializer 而非 "0":指针类型必须用 null/zeroinitializer,
|
||||
# 整数/聚合类型也兼容 zeroinitializer,避免 "integer constant must have integer type"
|
||||
@@ -1019,8 +990,7 @@ novirtual class TranslatorGenMixin:
|
||||
vt_sha1 = resolved_stg_entry.ModuleSha1
|
||||
if vt_sha1 is None:
|
||||
vt_sha1 = trans.ModuleSha1
|
||||
vt_mangled: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
vt_sha1, vt_name_buf)
|
||||
vt_mangled: str = self.Gen.FuncGenBase._mangle_name_with_sha1(vt_sha1, vt_name_buf)
|
||||
if vt_mangled is not None:
|
||||
# 完整 struct 初始化器(LLVM 拒绝部分初始化):
|
||||
# 字段 0 = __vtable__(i8* @vtable),其余用户字段按类型零值。
|
||||
@@ -1038,16 +1008,14 @@ novirtual class TranslatorGenMixin:
|
||||
# 如 `_mbuddy: MemBuddy` 的字段默认不再丢失);
|
||||
# 全部默认值恰为零时回退逐字段零值,避免无谓文本。
|
||||
# 两者均列全字段(LLVM 要求初始化器元素数匹配)。
|
||||
rest_v: str = self._build_stg_struct_body_text(
|
||||
pool, resolved_stg_entry, 1)
|
||||
rest_v: str = self._build_stg_struct_body_text(pool, resolved_stg_entry, 1)
|
||||
if rest_v is not None:
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", rest_v)
|
||||
pos_v += sizet(written_v)
|
||||
else:
|
||||
fc_v: int = resolved_stg_entry.FieldCount
|
||||
for fi_v in range(1, fc_v):
|
||||
fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(
|
||||
resolved_stg_entry, fi_v)
|
||||
fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(resolved_stg_entry, fi_v)
|
||||
if fe_v is None or fe_v.Ty is None:
|
||||
continue
|
||||
ty_buf_v: str = pool.alloc(128)
|
||||
@@ -1065,16 +1033,14 @@ novirtual class TranslatorGenMixin:
|
||||
# 无 vtable 的对象全局(@t.Object / 普通类):按字段默认值生成常量初始化器;
|
||||
# 一律 zeroinitializer 会丢掉全部字段默认值(模块级 X: T = T() 的构造调用
|
||||
# 不发射)。无任何非零默认值时返回 None → 保持 zeroinitializer(零开销)。
|
||||
stg_default_text: str = self._build_stg_struct_init_text(
|
||||
pool, resolved_stg_entry, 0)
|
||||
stg_default_text: str = self._build_stg_struct_init_text(pool, resolved_stg_entry, 0)
|
||||
if stg_default_text is not None:
|
||||
stg_init_text = stg_default_text
|
||||
stg_name_len: sizet = sizet(string.strlen(mangled_name)) + 8
|
||||
stg_name_buf: str = pool.alloc(stg_name_len)
|
||||
if stg_name_buf is not None:
|
||||
viperlib.snprintf(stg_name_buf, stg_name_len, "%s.stg", mangled_name)
|
||||
stg_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(
|
||||
pool, stg_name_buf, resolved_stg_ty)
|
||||
stg_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, stg_name_buf, resolved_stg_ty)
|
||||
if stg_gv is not None:
|
||||
llvmlite.module_add_global(mod, stg_gv)
|
||||
stg_gv.Linkage = None
|
||||
@@ -1093,8 +1059,7 @@ novirtual class TranslatorGenMixin:
|
||||
gv.Initializer = stg_init_buf
|
||||
# 注册 storage 引用(key: var_name.__stg),供 AssignGenMixin
|
||||
# 全局赋值分支检测对象类全局并复制对象到 storage。
|
||||
stg_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(
|
||||
pool, stg_name_buf, resolved_stg_ty)
|
||||
stg_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(pool, stg_name_buf, resolved_stg_ty)
|
||||
if stg_ref is not None:
|
||||
stg_key_len: sizet = sizet(string.strlen(var_name)) + 8
|
||||
stg_key: str = pool.alloc(stg_key_len)
|
||||
@@ -1122,8 +1087,7 @@ novirtual class TranslatorGenMixin:
|
||||
# const 对象全局:注解含 t.CConst 且类型非指针 ⇒ 登记 IsConst,
|
||||
# 之后对该全局名的赋值/增量赋值/元素赋值 fail-fast(判据同 TPC
|
||||
# 的 Gen.global_const_flags,见 Debugger/type-descriptors.md)。
|
||||
if self.Gen.TypeGenErr.is_const_object_marker(
|
||||
annot_node, var_ty) != 0:
|
||||
if self.Gen.TypeGenErr.is_const_object_marker(annot_node, var_ty) != 0:
|
||||
self.Gen.VarGen.set_var_const(trans.SymTab, var_name)
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CVolatile", 0) != 0:
|
||||
self.Gen.VarGen.set_var_volatile(trans.SymTab, var_name)
|
||||
@@ -1137,11 +1101,9 @@ novirtual class TranslatorGenMixin:
|
||||
if k == ast.ASTKind.AnnAssign:
|
||||
aa_ml: ast.AnnAssign* = ast.AnnAssign*(node)
|
||||
if aa_ml is not None and aa_ml.annotation is not None:
|
||||
cls_nm_ml: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
|
||||
aa_ml.annotation, trans._imported_modules, pool, trans._from_imports)
|
||||
cls_nm_ml: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(aa_ml.annotation, trans._imported_modules, pool, trans._from_imports)
|
||||
if cls_nm_ml is not None:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, var_name, cls_nm_ml)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, var_name, cls_nm_ml)
|
||||
# 模块级 str|t.CPtr / bytes|t.CPtr 全局:标记 IsPtrElement
|
||||
# (i8** 语义,var[i] 按 8 字节指针步长),对齐 TPC 的
|
||||
# global_var_ptr_element(_argv 等字符串指针数组)。否则
|
||||
@@ -1149,12 +1111,9 @@ novirtual class TranslatorGenMixin:
|
||||
if aa_ml.annotation.kind() == ast.ASTKind.BinOp:
|
||||
bop_ml: ast.BinOp* = ast.BinOp*(aa_ml.annotation)
|
||||
if bop_ml.op == ast.OpKind.BitOr:
|
||||
if self.Gen.AssignGen._annotation_contains_name(
|
||||
aa_ml.annotation, "str") != 0 \
|
||||
or self.Gen.AssignGen._annotation_contains_name(
|
||||
aa_ml.annotation, "bytes") != 0:
|
||||
self.Gen.VarGen.set_var_ptr_element(
|
||||
trans.SymTab, var_name)
|
||||
if self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "str") != 0 \
|
||||
or self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "bytes") != 0:
|
||||
self.Gen.VarGen.set_var_ptr_element(trans.SymTab, var_name)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -1181,14 +1140,12 @@ novirtual class TranslatorGenMixin:
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
mod: llvmlite.LLVMModule* = trans.Module
|
||||
|
||||
main_func: llvmlite.Function* = llvmlite.create_function(
|
||||
pool, mod, "main", i32_ty)
|
||||
main_func: llvmlite.Function* = llvmlite.create_function(pool, mod, "main", i32_ty)
|
||||
if main_func is None:
|
||||
VLogger.error("CreateFunction main returned NULL", "TR")
|
||||
return 0
|
||||
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, main_func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, main_func, "entry")
|
||||
if entry_blk is None:
|
||||
VLogger.error("CreateBlock returned NULL", "TR")
|
||||
return 0
|
||||
|
||||
@@ -23,12 +23,8 @@ import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
|
||||
# ============================================================
|
||||
# TypeGenBase - 类型表基础设施:字段 + InitTypeGen + trace/临时目录/generic 上下文
|
||||
#
|
||||
# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesType 委托。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenBase:
|
||||
novirtual class TypeGenBase:
|
||||
"""字段 + InitTypeGen + trace/临时目录/generic 上下文"""
|
||||
|
||||
# --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) ---
|
||||
@@ -128,8 +124,7 @@ class TypeGenBase:
|
||||
Specs: TSpec.TypeSpecArena*
|
||||
def InitTypeGen(self) -> int:
|
||||
"""初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)"""
|
||||
if self is None:
|
||||
return 1
|
||||
if self is None: return 1
|
||||
self.TraceFrames = None
|
||||
self.TraceCount = 0
|
||||
self.GenericTpNames = None
|
||||
@@ -181,15 +176,12 @@ class TypeGenBase:
|
||||
# ============================================================
|
||||
def ensure_spec_arena(self) -> TSpec.TypeSpecArena*:
|
||||
"""确保 TypeSpec 驻留表已创建,返回 arena;失败返回 None"""
|
||||
if self.Specs is not None:
|
||||
return self.Specs
|
||||
if self.Specs is not None: return self.Specs
|
||||
size: sizet = TSpec.TypeSpecArena.__sizeof__()
|
||||
arena: TSpec.TypeSpecArena* = TSpec.TypeSpecArena*(CompilerFactory.factory.PermPool.alloc(size))
|
||||
if arena is None:
|
||||
return None
|
||||
if arena is None: return None
|
||||
string.memset(arena, 0, size)
|
||||
if TSpec.SpecArenaInit(arena, 0) != 0:
|
||||
return None
|
||||
if TSpec.SpecArenaInit(arena, 0) != 0: return None
|
||||
self.Specs = arena
|
||||
return arena
|
||||
# ============================================================
|
||||
@@ -199,30 +191,24 @@ class TypeGenBase:
|
||||
|
||||
def _ensure_trace_init(self) -> int:
|
||||
"""确保调用栈已初始化(懒加载,用 malloc 不依赖 pool)"""
|
||||
if self.TraceFrames is not None:
|
||||
return 1
|
||||
if self.TraceFrames is not None: return 1
|
||||
entry_size: sizet = GenTypes.TraceFrame.__sizeof__()
|
||||
self.TraceFrames = CompilerFactory.factory.PermPool.alloc(entry_size * TypeGenMixin.TRACE_MAX)
|
||||
if self.TraceFrames is None:
|
||||
return 0
|
||||
if self.TraceFrames is None: return 0
|
||||
string.memset(self.TraceFrames, 0, entry_size * TypeGenMixin.TRACE_MAX)
|
||||
return 1
|
||||
def _get_trace_frame(self, i: int) -> rawptr[GenTypes.TraceFrame]:
|
||||
"""获取第 i 个 TraceFrame 槽位"""
|
||||
if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX:
|
||||
return None
|
||||
if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX: return None
|
||||
entry_size: sizet = GenTypes.TraceFrame.__sizeof__()
|
||||
addr: uint64 = uint64(self.TraceFrames) + i * entry_size
|
||||
return rawptr[GenTypes.TraceFrame](addr)
|
||||
def push_trace(self, file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None:
|
||||
"""压入一个翻译上下文帧(进入新的翻译作用域时调用)"""
|
||||
if self._ensure_trace_init() == 0:
|
||||
return
|
||||
if self.TraceCount >= TypeGenMixin.TRACE_MAX:
|
||||
return
|
||||
if self._ensure_trace_init() == 0: return
|
||||
if self.TraceCount >= TypeGenMixin.TRACE_MAX: return
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount)
|
||||
if frame is None:
|
||||
return
|
||||
if frame is None: return
|
||||
frame.file_name = file_name
|
||||
frame.lineno = lineno
|
||||
frame.col_start = col_start
|
||||
@@ -230,8 +216,7 @@ class TypeGenBase:
|
||||
self.TraceCount += 1
|
||||
def pop_trace(self) -> None:
|
||||
"""弹出栈顶帧(退出翻译作用域时调用)"""
|
||||
if self.TraceCount <= 0:
|
||||
return
|
||||
if self.TraceCount <= 0: return
|
||||
self.TraceCount -= 1
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount)
|
||||
if frame is not None:
|
||||
@@ -241,7 +226,6 @@ class TypeGenBase:
|
||||
frame.col_end = 0
|
||||
def clear_trace(self) -> None:
|
||||
"""清空调用栈(每个文件翻译开始前调用)"""
|
||||
i: int
|
||||
for i in range(self.TraceCount):
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(i)
|
||||
if frame is not None:
|
||||
|
||||
@@ -22,22 +22,17 @@ import lib.core.Gen.Type.TypeGenBase as TypeGenBase
|
||||
# 槽存槽下标 + 1(0=空槽)。CDefineNames 只追加不重排 ⇒ 槽下标稳定;
|
||||
# Built == len(CDefineNames) 才可信。
|
||||
# ============================================================
|
||||
CDEFINE_IDX_CAP: t.CDefine = 4096
|
||||
# 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致)
|
||||
CDEF_IDX_FNV_OFFSET: t.CDefine = 2166136261
|
||||
CDEF_IDX_FNV_PRIME: t.CDefine = 16777619
|
||||
CDEF_IDX_FNV_MASK: t.CDefine = 4294967295
|
||||
define CDEFINE_IDX_CAP = 4096
|
||||
# 索引哈希常量(32 位 FNV-1a)
|
||||
define CDEF_IDX_FNV_OFFSET = 2166136261
|
||||
define CDEF_IDX_FNV_PRIME = 16777619
|
||||
define CDEF_IDX_FNV_MASK = 4294967295
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeGenCDef - TypeGenMixin 拆分(阶段 D):CDefine 编译期常量表(register/lookup/is/set/clear)
|
||||
#
|
||||
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
"""CDefine 编译期常量表(register/lookup/is/set/clear)"""
|
||||
|
||||
# ============================================================
|
||||
@@ -169,8 +164,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 建表失败(池不可用/耗尽)⇒ 明确报错并返回,绝不让下面的 append
|
||||
# 落到 None 或未初始化地址(原实现无检查 ⇒ append 写进 NULL/0xCD 区崩)
|
||||
if tn is None or tv is None or td is None or tsf is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
return
|
||||
self.CDefineNames = tn
|
||||
self.CDefineValues = tv
|
||||
@@ -181,8 +175,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 不写垃圾(append 之前必有非空断言)
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
name_copy: str = pool.alloc(string.strlen(name) + 1)
|
||||
if name_copy is None:
|
||||
@@ -223,8 +216,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
td: list[int] | t.CPtr = list[int](tp, 64)
|
||||
tsf: list[int] | t.CPtr = list[int](tp, 64)
|
||||
if tn is None or tv is None or td is None or tsf is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 浮点表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
return
|
||||
self.CDefineNames = tn
|
||||
self.CDefineValues = tv
|
||||
@@ -234,8 +226,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 浮点表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
name_copy_d: str = pool.alloc(string.strlen(name) + 1)
|
||||
if name_copy_d is None:
|
||||
@@ -281,8 +272,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
td: list[int] | t.CPtr = list[int](tp, 64)
|
||||
tsf: list[int] | t.CPtr = list[int](tp, 64)
|
||||
if tn is None or tv is None or td is None or tsf is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 字符串表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 字符串表分配失败(表本体池不可用或耗尽)", "MemoryError")
|
||||
return
|
||||
self.CDefineNames = tn
|
||||
self.CDefineValues = tv
|
||||
@@ -292,8 +282,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, "CDefine 字符串表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 字符串表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
ncopy_s: str = pool.alloc(string.strlen(name) + 1)
|
||||
if ncopy_s is None:
|
||||
|
||||
@@ -23,18 +23,17 @@ import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
# 槽存槽下标 + 1(0=空槽)。CTypedefNames 只追加不重排(同名注册原地更新类型串)
|
||||
# ⇒ 槽下标稳定;Built == len(CTypedefNames) 才可信。
|
||||
# ============================================================
|
||||
CTYPEDEF_IDX_CAP: t.CDefine = 4096
|
||||
define CTYPEDEF_IDX_CAP = 4096
|
||||
# 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致)
|
||||
CTYPEDEF_IDX_FNV_OFFSET: t.CDefine = 2166136261
|
||||
CTYPEDEF_IDX_FNV_PRIME: t.CDefine = 16777619
|
||||
CTYPEDEF_IDX_FNV_MASK: t.CDefine = 4294967295
|
||||
define CTYPEDEF_IDX_FNV_OFFSET = 2166136261
|
||||
define CTYPEDEF_IDX_FNV_PRIME = 16777619
|
||||
define CTYPEDEF_IDX_FNV_MASK = 4294967295
|
||||
|
||||
|
||||
def _ctypedef_idx_hash(name: str) -> uint64:
|
||||
"""CTypedef 名 → 64 位哈希(32 位 FNV-1a,逐字节到 NUL 结束)"""
|
||||
h: uint64 = uint64(CTYPEDEF_IDX_FNV_OFFSET)
|
||||
if name is None:
|
||||
return h
|
||||
if name is None: return h
|
||||
i: sizet = 0
|
||||
while name[i] != '\0':
|
||||
h = (h ^ uint64(int(name[i]))) * uint64(CTYPEDEF_IDX_FNV_PRIME)
|
||||
@@ -222,15 +221,13 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if self.LastBuiltinsTypedefNameBuf is None:
|
||||
self.LastBuiltinsTypedefNameBuf = stdlib.malloc(need)
|
||||
else:
|
||||
self.LastBuiltinsTypedefNameBuf = stdlib.realloc(
|
||||
self.LastBuiltinsTypedefNameBuf, need)
|
||||
self.LastBuiltinsTypedefNameBuf = stdlib.realloc(self.LastBuiltinsTypedefNameBuf, need)
|
||||
buf: str = self.LastBuiltinsTypedefNameBuf
|
||||
else:
|
||||
if self.LastBuiltinsTypedefResultBuf is None:
|
||||
self.LastBuiltinsTypedefResultBuf = stdlib.malloc(need)
|
||||
else:
|
||||
self.LastBuiltinsTypedefResultBuf = stdlib.realloc(
|
||||
self.LastBuiltinsTypedefResultBuf, need)
|
||||
self.LastBuiltinsTypedefResultBuf = stdlib.realloc(self.LastBuiltinsTypedefResultBuf, need)
|
||||
buf = self.LastBuiltinsTypedefResultBuf
|
||||
if buf is None:
|
||||
return None
|
||||
@@ -707,8 +704,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# ExprGenMixin 方法,TypeGenMixin 直接调用会生成未定义引用)
|
||||
if (from_imports is not None or imported_modules is not None) \
|
||||
and pool is not None:
|
||||
x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, nm.id, from_imports, imported_modules)
|
||||
x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, nm.id, from_imports, imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
self.ConstEvalOk = 1
|
||||
return x_val
|
||||
@@ -739,8 +735,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
for mi in range(mod_len):
|
||||
fi_buf[2 + mi] = at_mod.id[mi]
|
||||
fi_buf[2 + mod_len] = '\0'
|
||||
av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, at.attr, fi_buf, imported_modules)
|
||||
av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, at.attr, fi_buf, imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
self.ConstEvalOk = 1
|
||||
return av
|
||||
|
||||
@@ -22,21 +22,15 @@ import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
|
||||
# ============================================================
|
||||
# TypeGenErr - 错误上报/源行读取/类型推断(fatal_error/infer_* 等)
|
||||
#
|
||||
# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesType 委托。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
novirtual class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
"""错误上报/源行读取/类型推断(fatal_error/infer_* 等)"""
|
||||
|
||||
def _read_source_line(self, file_path: str, lineno: int) -> str:
|
||||
"""从源文件读取第 lineno 行内容"""
|
||||
if file_path is None or lineno <= 0:
|
||||
return None
|
||||
if file_path is None or lineno <= 0: return None
|
||||
f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R)
|
||||
if f.closed:
|
||||
return None
|
||||
if f.closed: return None
|
||||
# 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 →
|
||||
# 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第
|
||||
# 8390 行)。64MB 上限防御异常超大文件整体读取。
|
||||
@@ -355,10 +349,8 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
|
||||
elif k == ast.ASTKind.BinOp:
|
||||
binop: ast.BinOp* = ast.BinOp*(node)
|
||||
lhs_ty: llvmlite.LLVMType* = self.infer_expr_type(
|
||||
pool, binop.left, param_types)
|
||||
rhs_ty: llvmlite.LLVMType* = self.infer_expr_type(
|
||||
pool, binop.right, param_types)
|
||||
lhs_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, binop.left, param_types)
|
||||
rhs_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, binop.right, param_types)
|
||||
lhs_bits: int = self.get_llvm_type_bits(lhs_ty)
|
||||
rhs_bits: int = self.get_llvm_type_bits(rhs_ty)
|
||||
if lhs_bits >= rhs_bits:
|
||||
@@ -380,8 +372,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
|
||||
rt: rawptr[ast.Return] = rawptr[ast.Return](stmt)
|
||||
if rt.value is not None:
|
||||
expr_ty: llvmlite.LLVMType* = self.infer_expr_type(
|
||||
pool, rt.value, param_types)
|
||||
expr_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, rt.value, param_types)
|
||||
if expr_ty is not None:
|
||||
cur_bits: int = self.get_llvm_type_bits(ret_ty)
|
||||
new_bits: int = self.get_llvm_type_bits(expr_ty)
|
||||
|
||||
@@ -26,13 +26,12 @@ import lib.core.Gen.Type.TypeGenBase as TypeGenBase
|
||||
# ============================================================
|
||||
# 常量(与 HandlesType 保持一致)
|
||||
# ============================================================
|
||||
TRACE_MAX: t.CDefine = 32
|
||||
MAX_CTYPEDEF_DEPTH: t.CDefine = 10
|
||||
define TRACE_MAX = 32
|
||||
define MAX_CTYPEDEF_DEPTH = 10
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeGenMixin - 类型映射/注解解析/编译期常量表/错误上报
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenMixin(TypeGenBase.TypeGenBase):
|
||||
novirtual class TypeGenMixin(TypeGenBase.TypeGenBase):
|
||||
"""类型映射与解析 Mixin(阶段 D 拆分后顶层,方法全部在子 Mixin)"""
|
||||
@@ -27,13 +27,8 @@ import w32.fileio as fileio
|
||||
|
||||
# ============================================================
|
||||
# TypeGenResolve - TypeGenMixin 拆分(阶段 D):类型映射/注解解析(map_t_type/resolve_annotation_type 等)
|
||||
#
|
||||
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
"""类型映射/注解解析(map_t_type/resolve_annotation_type 等)"""
|
||||
|
||||
def _get_type_name_from_annotation(self, pool: memhub.MemBuddy*,
|
||||
@@ -179,8 +174,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
es3: str = self._subscript_slice_to_str(pool, e3)
|
||||
if es3 is None:
|
||||
# 类型名缺失 ⇒ 立即报错(静默丢弃会拼出错误类型串)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
e3, "类型注解的元素无法解析为类型名(列表/元组注解)", "NameError")
|
||||
self.Gen.TypeGenErr.fatal_error(e3, "类型注解的元素无法解析为类型名(列表/元组注解)", "NameError")
|
||||
return None
|
||||
cnt3 += 1
|
||||
total3 += string.strlen(es3)
|
||||
@@ -468,8 +462,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
mod_buf[mod_len] = '\0'
|
||||
# 4a. mod 是 import 别名(import X as mod 注册 "mod:X")→ 完整模块名 → SHA1
|
||||
if from_imports is not None:
|
||||
orig_mod: str = self.Gen.ImportsGen.lookup_from_import(
|
||||
from_imports, mod_buf, 0)
|
||||
orig_mod: str = self.Gen.ImportsGen.lookup_from_import(from_imports, mod_buf, 0)
|
||||
if orig_mod is not None:
|
||||
sha1a: str = self.Gen.CallGenBase._lookup_sha1_from_modname_raw(pool, orig_mod)
|
||||
if sha1a is not None:
|
||||
@@ -486,8 +479,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return type_name
|
||||
# ---- 5. 裸名 "Class":查 from_imports 所属模块 SHA1 ----
|
||||
if from_imports is not None:
|
||||
sha1c: str = self.Gen.CallGenBase._lookup_mod_sha1(
|
||||
pool, from_imports, type_name, 0)
|
||||
sha1c: str = self.Gen.CallGenBase._lookup_mod_sha1(pool, from_imports, type_name, 0)
|
||||
if sha1c is not None:
|
||||
res_c: str = self._concat_sha1_class(pool, sha1c, type_name)
|
||||
if res_c is not None:
|
||||
@@ -572,8 +564,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
left_buf[left_len] = '\0'
|
||||
left_node: ast.AST* = self._parse_type_string(pool, left_buf, ctx)
|
||||
# 右段前导空格由递归入口跳过
|
||||
right_node: ast.AST* = self._parse_type_string(
|
||||
pool, type_str + pipe_idx + 1, ctx)
|
||||
right_node: ast.AST* = self._parse_type_string(pool, type_str + pipe_idx + 1, ctx)
|
||||
stdlib.free(left_buf)
|
||||
if left_node is not None and right_node is not None:
|
||||
return ast.BinOp(pool, left_node, ast.OpKind.BitOr, right_node)
|
||||
@@ -726,8 +717,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
inner_rt: ast.AST* = self._parse_type_string(pool, ts_rt, ast.ASTCtx.Load)
|
||||
if inner_rt is not None:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
ity_rt: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, inner_rt, imported_modules, from_imports, trans, 1)
|
||||
ity_rt: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_rt, imported_modules, from_imports, trans, 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
self.Gen.TypeGenCType._ctypedef_pop_visiting()
|
||||
if ity_rt is not None:
|
||||
@@ -742,8 +732,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if btd_node_r is not None:
|
||||
if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
btd_ty_r: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, btd_node_r, imported_modules, from_imports, trans, 1)
|
||||
btd_ty_r: llvmlite.LLVMType* = self.resolve_annotation_type(pool, btd_node_r, imported_modules, from_imports, trans, 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
if btd_ty_r is not None:
|
||||
return btd_ty_r
|
||||
@@ -759,8 +748,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if lib_node is not None:
|
||||
if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
lib_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, lib_node, imported_modules, from_imports, trans, 1)
|
||||
lib_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, lib_node, imported_modules, from_imports, trans, 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
if lib_ty is not None:
|
||||
return lib_ty
|
||||
@@ -1267,8 +1255,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
string.strncpy(m_tb, m_buf + m_ls + m_vs, m_vlen)
|
||||
m_tb[m_vlen] = '\0'
|
||||
# 写入持久缓存(首次遇到的名字为准)
|
||||
self._register_lib_typedef_cache(
|
||||
m_real, m_buf + m_ls, m_nl, m_tb)
|
||||
self._register_lib_typedef_cache(m_real, m_buf + m_ls, m_nl, m_tb)
|
||||
# 原实现语义:attr 的首次匹配值
|
||||
if m_res is None and m_nl == attr_len:
|
||||
m_nm_ok: int = 1
|
||||
@@ -1581,8 +1568,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if at.value is not None:
|
||||
prefix: str = self.annotation_to_str(at.value)
|
||||
if prefix is not None:
|
||||
buf: str = stdlib.malloc(
|
||||
string.strlen(prefix) + string.strlen(at.attr) + 2)
|
||||
buf: str = stdlib.malloc(string.strlen(prefix) + string.strlen(at.attr) + 2)
|
||||
if buf is not None:
|
||||
viperlib.snprintf(buf,
|
||||
string.strlen(prefix) + string.strlen(at.attr) + 2,
|
||||
@@ -1608,8 +1594,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
left_s: str = self.annotation_to_str(bo.left)
|
||||
right_s: str = self.annotation_to_str(bo.right)
|
||||
if left_s is not None and right_s is not None:
|
||||
buf3: str = stdlib.malloc(
|
||||
string.strlen(left_s) + string.strlen(right_s) + 5)
|
||||
buf3: str = stdlib.malloc(string.strlen(left_s) + string.strlen(right_s) + 5)
|
||||
if buf3 is not None:
|
||||
viperlib.snprintf(buf3,
|
||||
string.strlen(left_s) + string.strlen(right_s) + 5,
|
||||
@@ -1727,8 +1712,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if alias_mod2 is not None:
|
||||
real_mod2 = alias_mod2
|
||||
# 返回模块限定名 "module.Class"(如 "memhub.MemBuddy")
|
||||
mod_qual_buf: str = stdlib.malloc(
|
||||
string.strlen(real_mod2) + string.strlen(at.attr) + 2)
|
||||
mod_qual_buf: str = stdlib.malloc(string.strlen(real_mod2) + string.strlen(at.attr) + 2)
|
||||
if mod_qual_buf is not None:
|
||||
viperlib.snprintf(mod_qual_buf,
|
||||
string.strlen(real_mod2) + string.strlen(at.attr) + 2,
|
||||
@@ -1782,15 +1766,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
rp_nm: ast.Name* = ast.Name*(sub.value)
|
||||
if rp_nm.id is not None and string.strcmp(rp_nm.id, "rawptr") == 0:
|
||||
if sub.slice is not None:
|
||||
return self.extract_class_name_from_annotation(
|
||||
sub.slice, imported_modules, pool, from_imports)
|
||||
return self.extract_class_name_from_annotation(sub.slice, imported_modules, pool, from_imports)
|
||||
return None
|
||||
# 递归取 base 时必须把 from_imports 一并下传:否则同一份注解在派发名/查表键/
|
||||
# 注册键三处算出的 mangled 名不一致(如 list[ast.AST*] 的元素段),
|
||||
# 出现「alloca 裸 list* / pass1 按 list[ast.ASTptr] / pass2 按 list[ast.ClassDefptr]」
|
||||
# 的分裂崩溃。其余调用点均已传。
|
||||
base_name: str = self.extract_class_name_from_annotation(
|
||||
sub.value, imported_modules, pool, from_imports)
|
||||
base_name: str = self.extract_class_name_from_annotation(sub.value, imported_modules, pool, from_imports)
|
||||
if base_name is None:
|
||||
return None
|
||||
# pool 不可用时,只返回裸类名(向后兼容)
|
||||
@@ -1888,8 +1870,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
tup_elt: ast.AST* = tp_elts.get(tui)
|
||||
if tup_elt is None:
|
||||
continue
|
||||
tup_ety: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, tup_elt, imported_modules, from_imports, trans, depth + 1)
|
||||
tup_ety: llvmlite.LLVMType* = self.resolve_annotation_type(pool, tup_elt, imported_modules, from_imports, trans, depth + 1)
|
||||
if tup_ety is None:
|
||||
return None
|
||||
tup_node: llvmlite.Function* = llvmlite.new_param_node(pool, tup_ety)
|
||||
@@ -1978,8 +1959,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if inj_owner is None:
|
||||
inj_owner = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name)
|
||||
if inj_owner is not None:
|
||||
ty_inj: llvmlite.LLVMType* = self._repl_opaque_class_ty(
|
||||
pool, inj_owner, gen_mangled)
|
||||
ty_inj: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, inj_owner, gen_mangled)
|
||||
if ty_inj is not None:
|
||||
return ty_inj
|
||||
# 归属未知(模板/归属均未登记)⇒ 保持原口径返回 None,由上层按
|
||||
@@ -2007,14 +1987,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if trans is not None:
|
||||
template_cd_chk: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name)
|
||||
if template_cd_chk is not None:
|
||||
type_args_chk: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(
|
||||
pool, sub.slice, from_imports)
|
||||
type_args_chk: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub.slice, from_imports)
|
||||
if type_args_chk is not None and len(type_args_chk) > 0:
|
||||
# 错误定位:压入触发特化的调用方帧(注解所在文件+行号)
|
||||
gen_cur_f2: str = self.Gen.TypeGenResolve.get_current_file()
|
||||
self.Gen.TypeGenBase.push_trace(gen_cur_f2, sub.lineno)
|
||||
spec_name_chk: str = self.Gen.ClassGenGeneric._specialize_generic_class(
|
||||
trans, gen_cls_name, type_args_chk)
|
||||
spec_name_chk: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, gen_cls_name, type_args_chk)
|
||||
self.Gen.TypeGenBase.pop_trace()
|
||||
if spec_name_chk is not None:
|
||||
gen_spec_ty = self.Gen.StructGen.get_struct_type(gen_mangled)
|
||||
@@ -2042,8 +2020,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 与实际模板名。仅当基名确为泛型模板时才触发(避免误伤 rawptr/CArray 等 builtin)。
|
||||
if trans is not None and trans._declare_only == 0 \
|
||||
and self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) is not None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
sub,
|
||||
self.Gen.TypeGenErr.fatal_error(sub,
|
||||
f"泛型下标 '{gen_mangled}' 未解析出特化结构体(泛型模板='{gen_cls_name}');"
|
||||
f"该注解将退化为裸基类/i8* → 后续 .get() 按错误元素类型分派并截断指针",
|
||||
"TypeError")
|
||||
@@ -2063,8 +2040,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if trans is not None and trans.ReplCtx is not None:
|
||||
gowner_sha1: str = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name)
|
||||
if gowner_sha1 is not None:
|
||||
ty_repl_g: llvmlite.LLVMType* = self._repl_opaque_class_ty(
|
||||
pool, gowner_sha1, gen_mangled)
|
||||
ty_repl_g: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, gowner_sha1, gen_mangled)
|
||||
if ty_repl_g is not None:
|
||||
return ty_repl_g
|
||||
# 未特化:返回 None(不报错,让后续流程处理)
|
||||
@@ -2140,8 +2116,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if string.strcmp(gp_ta, gp_tpn) == 0:
|
||||
# 泛型类型参数自映射(T→T):编译期报错,不静默退化
|
||||
# (静默退化会让运行时数据损坏难定位)。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError")
|
||||
polluted: int = 0
|
||||
gp_j: sizet
|
||||
for gp_j in range(gp_n):
|
||||
@@ -2159,8 +2134,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 实参串包含类型参数名(如 "T | t.CPtr"/"list[T]"):
|
||||
# 解析后仍产出 Name(参数名) → 无条件自递归卡死。编译期
|
||||
# 报错(此前 return None 静默退化)。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError")
|
||||
# 用具体类型名递归解析(支持 BinOp/Attribute 类型实参)
|
||||
gp_sub_node: ast.AST* = self._parse_type_string(pool, gp_ta, nm.ctx)
|
||||
if gp_sub_node is not None:
|
||||
@@ -2180,8 +2154,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if sp_sha_buf2 is not None:
|
||||
string.strncpy(sp_sha_buf2, nm.id, sp_len2 - 1)
|
||||
sp_sha_buf2[sp_len2 - 1] = '\0'
|
||||
sp_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(
|
||||
nm.id + sp_len2, sp_sha_buf2)
|
||||
sp_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(nm.id + sp_len2, sp_sha_buf2)
|
||||
if sp_entry2 is not None and sp_entry2.Ty is not None:
|
||||
if sp_entry2.HasNew != 0:
|
||||
return llvmlite.Ptr(pool, sp_entry2.Ty)
|
||||
@@ -2276,8 +2249,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
inner_node: ast.AST* = self._parse_type_string(pool, ctypedef_str, nm.ctx)
|
||||
if inner_node is not None:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
inner_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, inner_node, imported_modules, from_imports, trans, depth + 1)
|
||||
inner_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_node, imported_modules, from_imports, trans, depth + 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
self.Gen.TypeGenCType._ctypedef_pop_visiting()
|
||||
if inner_ty is not None:
|
||||
@@ -2311,8 +2283,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 用原始名重建节点递归解析(depth 守卫复用 resolve 上限)
|
||||
orig_node_a: ast.AST* = self._parse_type_string(pool, oa_buf, nm.ctx)
|
||||
if orig_node_a is not None:
|
||||
alias_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, orig_node_a, imported_modules, from_imports, trans, depth + 1)
|
||||
alias_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, orig_node_a, imported_modules, from_imports, trans, depth + 1)
|
||||
if alias_ty is not None:
|
||||
return alias_ty
|
||||
# [builtins 最后匹配] 常规路径全部 miss 后的最终兜底:查
|
||||
@@ -2322,8 +2293,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if btd_n is not None:
|
||||
btd_node_n: ast.AST* = self._parse_type_string(pool, btd_n, nm.ctx)
|
||||
if btd_node_n is not None:
|
||||
btd_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, btd_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
btd_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, btd_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
if btd_ty_n is not None:
|
||||
return btd_ty_n
|
||||
# 库 typedef 兜底:stdint / w32.win32base 等库模块的裸 typedef
|
||||
@@ -2336,8 +2306,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if lib_ts_n is not None:
|
||||
lib_node_n: ast.AST* = self._parse_type_string(pool, lib_ts_n, nm.ctx)
|
||||
if lib_node_n is not None:
|
||||
lib_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, lib_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
lib_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, lib_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
if lib_ty_n is not None:
|
||||
return lib_ty_n
|
||||
# [REPL 会话] 归属模块已知(from_imports 解析出 sha1;或本模块自身 =
|
||||
@@ -2359,8 +2328,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
and string.strcmp(trans.ModuleSha1, GenTypes.REPL_SESSION_SHA1) != 0:
|
||||
own_sha_rn = trans.ModuleSha1
|
||||
if own_sha_rn is not None:
|
||||
ty_repl_n: llvmlite.LLVMType* = self._repl_opaque_class_ty(
|
||||
pool, own_sha_rn, nm.id)
|
||||
ty_repl_n: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, own_sha_rn, nm.id)
|
||||
if ty_repl_n is not None:
|
||||
return ty_repl_n
|
||||
return None
|
||||
@@ -2418,8 +2386,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
inner_attr: ast.AST* = self._parse_type_string(pool, ctypedef_attr, ast.ASTCtx.Load)
|
||||
if inner_attr is not None:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
inner_ty_attr: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, inner_attr, imported_modules, from_imports, trans, depth + 1)
|
||||
inner_ty_attr: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_attr, imported_modules, from_imports, trans, depth + 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
self.Gen.TypeGenCType._ctypedef_pop_visiting()
|
||||
if inner_ty_attr is not None:
|
||||
@@ -2453,8 +2420,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if is_builtin_attr == 0:
|
||||
# 模块名 → sha1(精确/后缀/import 别名还原,统一经
|
||||
# StructGenMixin._resolve_module_sha1 逐级尝试)
|
||||
mod_sha1_v: str = self.Gen.StructGen._resolve_module_sha1(
|
||||
val_name.id, from_imports)
|
||||
mod_sha1_v: str = self.Gen.StructGen._resolve_module_sha1(val_name.id, from_imports)
|
||||
mod_sha1_rv = mod_sha1_v
|
||||
if mod_sha1_v is not None:
|
||||
full_q_v: str = self._concat_sha1_class(pool, mod_sha1_v, at.attr)
|
||||
@@ -2486,12 +2452,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
mod_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr)
|
||||
if mod_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0:
|
||||
if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0:
|
||||
mod_td_inner: ast.AST* = self._parse_type_string(
|
||||
pool, mod_td_str, at.ctx)
|
||||
mod_td_inner: ast.AST* = self._parse_type_string(pool, mod_td_str, at.ctx)
|
||||
if mod_td_inner is not None:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
mod_td_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, mod_td_inner, imported_modules, from_imports, trans, depth + 1)
|
||||
mod_td_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, mod_td_inner, imported_modules, from_imports, trans, depth + 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
self.Gen.TypeGenCType._ctypedef_pop_visiting()
|
||||
if mod_td_ty is not None:
|
||||
@@ -2503,8 +2467,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 不可解析被跳过)⇒ 用 opaque 具名类型占位(不写 StructTable ⇒
|
||||
# 字段访问仍按"类未注册"明确报错)。批处理 trans.ReplCtx 恒 None。
|
||||
if trans is not None and trans.ReplCtx is not None and mod_sha1_rv is not None:
|
||||
ty_repl_a: llvmlite.LLVMType* = self._repl_opaque_class_ty(
|
||||
pool, mod_sha1_rv, at.attr)
|
||||
ty_repl_a: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, mod_sha1_rv, at.attr)
|
||||
if ty_repl_a is not None:
|
||||
return ty_repl_a
|
||||
return None
|
||||
@@ -2525,12 +2488,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
nested_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr)
|
||||
if nested_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0:
|
||||
if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0:
|
||||
nested_inner: ast.AST* = self._parse_type_string(
|
||||
pool, nested_td_str, at.ctx)
|
||||
nested_inner: ast.AST* = self._parse_type_string(pool, nested_td_str, at.ctx)
|
||||
if nested_inner is not None:
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth += 1
|
||||
nested_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, nested_inner, imported_modules, from_imports, trans, depth + 1)
|
||||
nested_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, nested_inner, imported_modules, from_imports, trans, depth + 1)
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
self.Gen.TypeGenCType._ctypedef_pop_visiting()
|
||||
if nested_ty is not None:
|
||||
@@ -2551,8 +2512,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if lib_td_na is not None:
|
||||
td_node_na: ast.AST* = self._parse_type_string(pool, lib_td_na, at.ctx)
|
||||
if td_node_na is not None:
|
||||
td_ty_na: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, td_node_na, imported_modules, from_imports, trans, depth + 1)
|
||||
td_ty_na: llvmlite.LLVMType* = self.resolve_annotation_type(pool, td_node_na, imported_modules, from_imports, trans, depth + 1)
|
||||
if td_ty_na is not None:
|
||||
return td_ty_na
|
||||
return None
|
||||
@@ -2593,8 +2553,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
other_is_cvoid = 1
|
||||
if other_is_cvoid != 0:
|
||||
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, other_node, imported_modules, from_imports, trans, depth + 1)
|
||||
other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, other_node, imported_modules, from_imports, trans, depth + 1)
|
||||
# 仅裸名(Name)场景验证解析结果必须是已注册 struct:
|
||||
# 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。
|
||||
# Attribute 场景(Module.Class / t.XXX)resolve 结果直接可用
|
||||
@@ -2664,8 +2623,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
case _:
|
||||
td_res_is_ptr = 0
|
||||
if td_res_is_ptr == 0:
|
||||
td_alias_ty: llvmlite.LLVMType* = self.resolve_typedef_or_map(
|
||||
pool, other_nm_td.id, imported_modules, from_imports, trans)
|
||||
td_alias_ty: llvmlite.LLVMType* = self.resolve_typedef_or_map(pool, other_nm_td.id, imported_modules, from_imports, trans)
|
||||
if td_alias_ty is not None:
|
||||
keep_other_ty = 1
|
||||
if keep_other_ty == 0:
|
||||
@@ -2709,10 +2667,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
cptr_sub_side = bop.right
|
||||
cptr_other = bop.left
|
||||
if cptr_sub_side is not None and cptr_other is not None:
|
||||
cptr_sub_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, cptr_sub_side, imported_modules, from_imports, trans, depth + 1)
|
||||
cptr_other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, cptr_other, imported_modules, from_imports, trans, depth + 1)
|
||||
cptr_sub_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, cptr_sub_side, imported_modules, from_imports, trans, depth + 1)
|
||||
cptr_other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, cptr_other, imported_modules, from_imports, trans, depth + 1)
|
||||
if cptr_sub_ty is not None and cptr_other_ty is not None:
|
||||
# 计算 CPtr 侧外层 Ptr 嵌套数(如 t.CPtr[t.CPtr]=i8** → 2 层)
|
||||
cptr_level: int = 0
|
||||
@@ -2740,12 +2696,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return res_ty
|
||||
|
||||
# 无 CPtr 标记:返回第一个非 None(装饰器标记如 CExport/CExtern 被忽略)
|
||||
left_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, bop.left, imported_modules, from_imports, trans, depth + 1)
|
||||
left_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, bop.left, imported_modules, from_imports, trans, depth + 1)
|
||||
if left_ty is not None:
|
||||
return left_ty
|
||||
right_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, bop.right, imported_modules, from_imports, trans, depth + 1)
|
||||
right_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, bop.right, imported_modules, from_imports, trans, depth + 1)
|
||||
if right_ty is not None:
|
||||
return right_ty
|
||||
return None
|
||||
@@ -2782,12 +2736,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
cnt_arr0: ast.Constant* = ast.Constant*(count_node_arr)
|
||||
if cnt_arr0.const_kind == ast.CONST_NONE:
|
||||
self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是正整型常量(>0),不允许 None(长度自动推导请改用 t.CArray[E])。正确示例:state: array[uint32, 4]")
|
||||
elem_ty_arr: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, elem_node_arr, imported_modules, from_imports, trans, depth + 1)
|
||||
elem_ty_arr: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node_arr, imported_modules, from_imports, trans, depth + 1)
|
||||
if elem_ty_arr is None:
|
||||
return None
|
||||
count_arr: int = self.Gen.TypeGenCType._eval_const_int_expr(
|
||||
count_node_arr, pool, from_imports, imported_modules)
|
||||
count_arr: int = self.Gen.TypeGenCType._eval_const_int_expr(count_node_arr, pool, from_imports, imported_modules)
|
||||
if self.Gen.TypeGenCType.ConstEvalOk == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是整型常量表达式(字面量 / CDefine 常量名 / 常量算术表达式)。正确示例:state: array[uint8, MAX_LEN]")
|
||||
if count_arr <= 0:
|
||||
@@ -2799,8 +2751,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if string.strcmp(gen_nm.id, "CArray") == 0 or string.strcmp(gen_nm.id, "rawarray") == 0:
|
||||
# 单参数: CArray[elem_ty] → Ptr(elem_ty)(静态推导长度数组)
|
||||
if sub.slice.kind() != ast.ASTKind.Tuple:
|
||||
elem_n: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
elem_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
if elem_n is None:
|
||||
return None
|
||||
return llvmlite.Ptr(pool, elem_n)
|
||||
@@ -2812,8 +2763,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
count_node_n: ast.AST* = tup_n.elts.get(1)
|
||||
if elem_node_n is None or count_node_n is None:
|
||||
return None
|
||||
elem_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, elem_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
elem_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
if elem_ty_n is None:
|
||||
return None
|
||||
# count=None → Ptr(elem)(等价单参)
|
||||
@@ -2821,8 +2771,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
cnt_n: ast.Constant* = ast.Constant*(count_node_n)
|
||||
if cnt_n.const_kind == ast.CONST_NONE:
|
||||
return llvmlite.Ptr(pool, elem_ty_n)
|
||||
count_n: int = self.Gen.TypeGenCType._eval_const_int_expr(
|
||||
count_node_n, pool, from_imports, imported_modules)
|
||||
count_n: int = self.Gen.TypeGenCType._eval_const_int_expr(count_node_n, pool, from_imports, imported_modules)
|
||||
if self.Gen.TypeGenCType.ConstEvalOk == 0 or count_n <= 0:
|
||||
return None
|
||||
return llvmlite.Array(pool, elem_ty_n, count_n)
|
||||
@@ -2831,14 +2780,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# "函数返回类型解析失败:注解不可解析"。
|
||||
if string.strcmp(gen_nm.id, "rawptr") == 0:
|
||||
if sub.slice.kind() != ast.ASTKind.Tuple:
|
||||
rp_elem: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
rp_elem: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
if rp_elem is None:
|
||||
return None
|
||||
return llvmlite.Ptr(pool, rp_elem)
|
||||
return None
|
||||
gen_ty_nm: llvmlite.LLVMType* = self._resolve_generic_subscript_ty(
|
||||
pool, sub, gen_nm.id, trans,
|
||||
gen_ty_nm: llvmlite.LLVMType* = self._resolve_generic_subscript_ty(pool, sub, gen_nm.id, trans,
|
||||
imported_modules, from_imports, depth + 1)
|
||||
if gen_ty_nm is not None:
|
||||
return gen_ty_nm
|
||||
@@ -2863,8 +2810,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
string.strcat(fb_str, "]")
|
||||
fb_node: ast.AST* = self._parse_type_string(pool, fb_str, ast.ASTCtx.Load)
|
||||
if fb_node is not None:
|
||||
fb_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, fb_node, imported_modules, from_imports, trans, depth + 1)
|
||||
fb_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, fb_node, imported_modules, from_imports, trans, depth + 1)
|
||||
if fb_ty is not None:
|
||||
return fb_ty
|
||||
return None
|
||||
@@ -2899,8 +2845,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \
|
||||
and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CPtr 模块未导入")
|
||||
inner_cptr_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
inner_cptr_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
if inner_cptr_ty is None:
|
||||
# 元素类型依赖未就绪(如 t.CPtr[类] 中类尚未注册):返回 None 交上层多遍
|
||||
# 收敛,不在此 fatal 中断 Phase 1a 预注册(UINT 等只经 CTypedef 动态表解析,
|
||||
@@ -2916,8 +2861,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 单参数形式: t.CArray[elem_ty] → Ptr(elem_ty)
|
||||
# 相当于 t.CArray[elem_ty, None],表示静态推导长度数组
|
||||
if sub.slice.kind() != ast.ASTKind.Tuple:
|
||||
elem_ty_single: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
elem_ty_single: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
if elem_ty_single is None:
|
||||
# 元素类型依赖未就绪(同 L1807 注释):返回 None 交多遍收敛
|
||||
return None
|
||||
@@ -2935,8 +2879,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if elem_node is None or count_node is None:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素为 None")
|
||||
# 递归解析元素类型
|
||||
elem_ty: llvmlite.LLVMType* = self.resolve_annotation_type(
|
||||
pool, elem_node, imported_modules, from_imports, trans, depth + 1)
|
||||
elem_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node, imported_modules, from_imports, trans, depth + 1)
|
||||
if elem_ty is None:
|
||||
# 元素类型依赖未就绪(如 t.CArray[类, N] 中类尚未注册):返回 None 交上层多遍
|
||||
# 收敛,不在此 fatal 中断 Phase 1a 预注册(UINT 等只经 CTypedef 动态表解析,
|
||||
|
||||
+107
-142
@@ -25,46 +25,28 @@ import lib.core.Gen.GenApi as GenApi
|
||||
# ============================================================
|
||||
# Kind - 基础类型种类
|
||||
# ============================================================
|
||||
TS_UNKNOWN: t.CDefine = 0
|
||||
TS_INT: t.CDefine = 1
|
||||
TS_UINT: t.CDefine = 2
|
||||
TS_FLOAT: t.CDefine = 3
|
||||
TS_BOOL: t.CDefine = 4
|
||||
TS_PTR: t.CDefine = 5
|
||||
TS_ARRAY: t.CDefine = 6
|
||||
TS_STRUCT: t.CDefine = 7
|
||||
TS_VOID: t.CDefine = 8
|
||||
TS_FUNC: t.CDefine = 9
|
||||
TS_UNION: t.CDefine = 10
|
||||
TS_ENUM: t.CDefine = 11
|
||||
define TS_UNKNOWN = 0
|
||||
define TS_INT = 1
|
||||
define TS_UINT = 2
|
||||
define TS_FLOAT = 3
|
||||
define TS_BOOL = 4
|
||||
define TS_PTR = 5
|
||||
define TS_ARRAY = 6
|
||||
define TS_STRUCT = 7
|
||||
define TS_VOID = 8
|
||||
define TS_FUNC = 9
|
||||
define TS_UNION = 10
|
||||
define TS_ENUM = 11
|
||||
|
||||
# ============================================================
|
||||
# IsSigned - 符号性(单一真源,替代 _annot_str_unsigned 的子串扫描)
|
||||
# ============================================================
|
||||
TS_SIGN_UNKNOWN: t.CDefine = -1
|
||||
TS_SIGN_UNSIGNED: t.CDefine = 0
|
||||
TS_SIGN_SIGNED: t.CDefine = 1
|
||||
define TS_SIGN_UNKNOWN = -1
|
||||
define TS_SIGN_UNSIGNED = 0
|
||||
define TS_SIGN_SIGNED = 1
|
||||
|
||||
# 驻留表默认容量与单条类型文本上限(超限 fail-fast,绝不静默丢弃/截断)
|
||||
# 容量 × 文本上限即驻留表键缓冲的 PermPool 占用(8192 × 256 = 2MB)
|
||||
# 注:键文本超 SPEC_TEXT_MAX 的长签名/深嵌套类型 ⇒ 不驻留(保留完整实例,
|
||||
# 仅放弃去重),见 InternSpec —— 截断键会让 strcmp 撞类型、返回错误实例。
|
||||
SPEC_INTERN_MAX: t.CDefine = 8192
|
||||
SPEC_TEXT_MAX: t.CDefine = 256
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 符号性精确名表 - 按「名字切片」判定(**不做子串扫描**)
|
||||
#
|
||||
# 必须精确匹配:strstr 子串扫描会误判 `BYTEPTR`(含 `BYTE`)以及任何含 `uint32`
|
||||
# 子串的名字(含 sha1 前缀名)。
|
||||
# 覆盖范围:本模块只认 t/c 核心原语名与少数内建名;stdint 别名(DWORD/WORD/size_t/
|
||||
# uint32_t/…)由调用方沿 CTypedef 链逐层展开后再落到本函数(链展开需 CTypedef 表,
|
||||
# 不在本模块做,避免反向依赖)。
|
||||
# 口径:SSizeT 为**有符号**;BOOL 按 stdint.vp 定义是 int(**有符号**);
|
||||
# 指针名(BYTEPTR/UINTPTR/INTPTR/CHARPTR/…)返回 UNKNOWN——指针的"无符号"语义
|
||||
# 由 PtrLevel 表达,与整数符号性无关。
|
||||
# ============================================================
|
||||
define SPEC_INTERN_MAX = 8192
|
||||
define SPEC_TEXT_MAX = 256
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -72,18 +54,13 @@ SPEC_TEXT_MAX: t.CDefine = 256
|
||||
# ============================================================
|
||||
def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int:
|
||||
"""切片名比较:长度相同且逐字符相等返回 1,否则 0"""
|
||||
if text is None or lit is None:
|
||||
return 0
|
||||
if end <= start:
|
||||
return 0
|
||||
if text is None or lit is None: return 0
|
||||
if end <= start: return 0
|
||||
ln: sizet = string.strlen(lit)
|
||||
if end - start != ln:
|
||||
return 0
|
||||
k: sizet = 0
|
||||
while k < ln:
|
||||
if end - start != ln: return 0
|
||||
for k in range(ln):
|
||||
if text[start + k] != lit[k]:
|
||||
return 0
|
||||
k += 1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -102,11 +79,9 @@ def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int:
|
||||
# ============================================================
|
||||
def SpecTypeNameBaseIs(name: str, base: str) -> int:
|
||||
"""类型名的容器基名是否精确等于 base(1=是 / 0=否)"""
|
||||
if name is None or base is None:
|
||||
return 0
|
||||
if name is None or base is None: return 0
|
||||
n: sizet = string.strlen(name)
|
||||
if n == 0:
|
||||
return 0
|
||||
if n == 0: return 0
|
||||
# 基名上界:第一个 '['(泛型实参起点;无 '[' 则到串尾)
|
||||
end: sizet = n
|
||||
lb: str = string.strchr(name, '[')
|
||||
@@ -215,7 +190,7 @@ class TypeSpec:
|
||||
Bits: int # 位宽;非整型/浮点为 0
|
||||
IsSigned: int # TS_SIGN_* (-1 未知 / 0 无符号 / 1 有符号)
|
||||
PtrLevel: int # 指针层级(0=非指针)
|
||||
Elem: TypeSpec | t.CPtr # Ptr/Array 的指向或元素(None=无)
|
||||
Elem: TypeSpec* # Ptr/Array 的指向或元素(None=无)
|
||||
ArrayCount: int # Array 的元素个数(0=未知/动态)
|
||||
BaseName: str # 结构体/枚举/类名(带模块 sha1;PermPool 深拷贝)
|
||||
# SourceName: 注解侧「来源名」(替代 AnnotClassName)。
|
||||
@@ -229,7 +204,7 @@ class TypeSpec:
|
||||
# 入键会让 InternSpec 条目暴增且线性查找变慢;驻留本意只是跨 reset 存活,
|
||||
# 而 PermPool 分配天然满足 ⇒ SpecWithSource 返回独立副本、不进表。
|
||||
SourceName: str
|
||||
Ret: TypeSpec | t.CPtr # Func:返回类型
|
||||
Ret: TypeSpec* # Func:返回类型
|
||||
Params: sizet* # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个)
|
||||
ParamCount: int # Func:参数个数
|
||||
IsVarArg: int # Func:1=变参(...)
|
||||
@@ -382,11 +357,11 @@ def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int:
|
||||
# ============================================================
|
||||
# _spec_alloc - 从 PermPool 分配一个清零的 TypeSpec(不驻留,内部用)
|
||||
# ============================================================
|
||||
def _spec_alloc() -> TypeSpec | t.CPtr:
|
||||
def _spec_alloc() -> TypeSpec*:
|
||||
"""分配并清零一个 TypeSpec(PermPool)"""
|
||||
pp: memhub.MemBuddy* = CompilerFactory.factory.PermPool
|
||||
size: sizet = TypeSpec.__sizeof__()
|
||||
sp: TypeSpec | t.CPtr = (TypeSpec | t.CPtr)(pp.alloc(size))
|
||||
sp: TypeSpec* = (TypeSpec*)(pp.alloc(size))
|
||||
if sp is None:
|
||||
return None
|
||||
string.memset(sp, 0, size)
|
||||
@@ -402,9 +377,9 @@ def _spec_alloc() -> TypeSpec | t.CPtr:
|
||||
# ============================================================
|
||||
# _spec_make - 构造一个基础 TypeSpec(不驻留)
|
||||
# ============================================================
|
||||
def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr:
|
||||
def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec*:
|
||||
"""构造基础 TypeSpec(PermPool,不驻留)"""
|
||||
sp: TypeSpec | t.CPtr = _spec_alloc()
|
||||
sp: TypeSpec* = _spec_alloc()
|
||||
if sp is None:
|
||||
return None
|
||||
sp.Kind = kind
|
||||
@@ -416,7 +391,7 @@ def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr:
|
||||
# ============================================================
|
||||
# _spec_set_struct_name - 深拷贝类名到 PermPool(跨文件存活)
|
||||
# ============================================================
|
||||
def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int:
|
||||
def _spec_set_struct_name(sp: TypeSpec*, name: str) -> int:
|
||||
"""把类名深拷贝到 PermPool 并写入 BaseName,返回 0=成功 / 1=失败"""
|
||||
if sp is None or name is None:
|
||||
return 1
|
||||
@@ -435,9 +410,9 @@ def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int:
|
||||
# NewTypeSpec - 构造基础类型(驻留)
|
||||
# ============================================================
|
||||
def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int,
|
||||
bits: int, is_signed: int) -> TypeSpec | t.CPtr:
|
||||
bits: int, is_signed: int) -> TypeSpec*:
|
||||
"""构造基础 TypeSpec 并驻留,失败返回 None"""
|
||||
sp: TypeSpec | t.CPtr = _spec_make(kind, bits, is_signed)
|
||||
sp: TypeSpec* = _spec_make(kind, bits, is_signed)
|
||||
if sp is None:
|
||||
return None
|
||||
return InternSpec(arena, sp)
|
||||
@@ -447,9 +422,9 @@ def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int,
|
||||
# NewTypeStruct - 构造结构体/枚举/类类型(驻留)
|
||||
# ============================================================
|
||||
def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int,
|
||||
base_name: str) -> TypeSpec | t.CPtr:
|
||||
base_name: str) -> TypeSpec*:
|
||||
"""构造 struct/union/enum 类型(BaseName 深拷贝 + 驻留),失败返回 None"""
|
||||
sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN)
|
||||
sp: TypeSpec* = _spec_make(kind, 0, TS_SIGN_UNKNOWN)
|
||||
if sp is None:
|
||||
return None
|
||||
if _spec_set_struct_name(sp, base_name) != 0:
|
||||
@@ -461,11 +436,11 @@ def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int,
|
||||
# NewTypePtr - 构造指针类型(PtrLevel = 元素 PtrLevel + 1,驻留)
|
||||
# ============================================================
|
||||
def NewTypePtr(arena: TypeSpecArena | t.CPtr,
|
||||
elem: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
elem: TypeSpec*) -> TypeSpec*:
|
||||
"""构造指针类型:指向 elem(PtrLevel 逐层递增),失败返回 None"""
|
||||
if elem is None:
|
||||
return None
|
||||
sp: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN)
|
||||
sp: TypeSpec* = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN)
|
||||
if sp is None:
|
||||
return None
|
||||
sp.Elem = elem
|
||||
@@ -480,12 +455,12 @@ def NewTypePtr(arena: TypeSpecArena | t.CPtr,
|
||||
# ============================================================
|
||||
# NewTypeArray - 构造数组类型(ArrayCount 个 elem,驻留)
|
||||
# ============================================================
|
||||
def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr,
|
||||
count: int) -> TypeSpec | t.CPtr:
|
||||
def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec*,
|
||||
count: int) -> TypeSpec*:
|
||||
"""构造数组类型:elem[count](count<=0 表示长度未知/动态),失败返回 None"""
|
||||
if elem is None or count < 0:
|
||||
return None
|
||||
sp: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN)
|
||||
sp: TypeSpec* = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN)
|
||||
if sp is None:
|
||||
return None
|
||||
sp.Elem = elem
|
||||
@@ -501,15 +476,15 @@ def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr,
|
||||
# NewTypeFunc - 构造函数签名类型(ret + 参数数组 + 变参,驻留)
|
||||
# params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个
|
||||
# ============================================================
|
||||
def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr,
|
||||
def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec*,
|
||||
params: sizet*, count: int,
|
||||
is_vararg: int) -> TypeSpec | t.CPtr:
|
||||
is_vararg: int) -> TypeSpec*:
|
||||
"""构造函数签名类型,失败返回 None"""
|
||||
if ret is None or count < 0:
|
||||
return None
|
||||
if count > 0 and params is None:
|
||||
return None
|
||||
sp: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN)
|
||||
sp: TypeSpec* = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN)
|
||||
if sp is None:
|
||||
return None
|
||||
sp.Ret = ret
|
||||
@@ -523,7 +498,7 @@ def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr,
|
||||
# SpecBaseText - 基础类型(非 Ptr/Array/Func)的规范文本
|
||||
# 返回 0=已写入 / 1=不适用/失败
|
||||
# ============================================================
|
||||
def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int:
|
||||
def SpecBaseText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int:
|
||||
"""把基础类型写成规范文本;Ptr/Array/Func 不适用时返回 1"""
|
||||
if sp is None or buf is None or buf_size == 0:
|
||||
return 1
|
||||
@@ -572,12 +547,12 @@ def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int:
|
||||
# fn(INNER,INNER,...)->RET 函数签名(变参追加 "...")
|
||||
# 递归深度上限 32(防环);超限或缓冲不足返回 1(fail-fast 由调用方决定)
|
||||
# ============================================================
|
||||
def SpecToText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int:
|
||||
def SpecToText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int:
|
||||
"""把 TypeSpec 编码为规范文本,返回 0=成功 / 1=失败"""
|
||||
return _spec_to_text(sp, buf, buf_size, 0)
|
||||
|
||||
|
||||
def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet,
|
||||
depth: int) -> int:
|
||||
"""SpecToText 的递归实现(depth 上限 32)"""
|
||||
if sp is None or buf is None or buf_size == 0 or depth > 32:
|
||||
@@ -627,7 +602,7 @@ def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
pos = _spec_text_append(buf, buf_size, pos, ",")
|
||||
if pos >= buf_size:
|
||||
return 1
|
||||
param: TypeSpec | t.CPtr = _spec_param_at(sp, i)
|
||||
param: TypeSpec* = _spec_param_at(sp, i)
|
||||
if param is None:
|
||||
return 1
|
||||
param_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX)
|
||||
@@ -686,7 +661,7 @@ def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet
|
||||
# ============================================================
|
||||
# _spec_param_at - 取函数签名第 i 个参数 TypeSpec 指针
|
||||
# ============================================================
|
||||
def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr:
|
||||
def _spec_param_at(sp: TypeSpec*, index: int) -> TypeSpec*:
|
||||
"""返回 Func 类型第 index 个参数的 TypeSpec 指针,越界返回 None"""
|
||||
if sp is None or sp.Params is None or index < 0 or index >= sp.ParamCount:
|
||||
return None
|
||||
@@ -694,30 +669,30 @@ def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr:
|
||||
slot: sizet* = (sizet*)(addr)
|
||||
if slot is None:
|
||||
return None
|
||||
return (TypeSpec | t.CPtr)(uint64(slot[0]))
|
||||
return (TypeSpec*)(uint64(slot[0]))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TextToSpec - 规范文本解码(SpecToText 的逆;不驻留,由调用方决定是否驻留)
|
||||
# 解析失败返回 None(fail-fast 由调用方决定)
|
||||
# ============================================================
|
||||
def TextToSpec(text: str) -> TypeSpec | t.CPtr:
|
||||
def TextToSpec(text: str) -> TypeSpec*:
|
||||
"""把规范文本解码为 TypeSpec(PermPool,不驻留),失败返回 None"""
|
||||
if text is None:
|
||||
return None
|
||||
return _text_to_spec(text, 0)
|
||||
|
||||
|
||||
def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
def _text_to_spec(text: str, depth: int) -> TypeSpec*:
|
||||
"""TextToSpec 的递归实现(depth 上限 32)"""
|
||||
if text is None or depth > 32:
|
||||
return None
|
||||
# 指针:p:INNER
|
||||
if string.strncmp(text, "p:", 2) == 0:
|
||||
inner: TypeSpec | t.CPtr = _text_to_spec(text + 2, depth + 1)
|
||||
inner: TypeSpec* = _text_to_spec(text + 2, depth + 1)
|
||||
if inner is None:
|
||||
return None
|
||||
sp_p: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN)
|
||||
sp_p: TypeSpec* = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN)
|
||||
if sp_p is None:
|
||||
return None
|
||||
sp_p.Elem = inner
|
||||
@@ -737,10 +712,10 @@ def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
colon: str = string.strchr(rb, ':')
|
||||
if colon is None:
|
||||
return None
|
||||
inner_a: TypeSpec | t.CPtr = _text_to_spec(colon + 1, depth + 1)
|
||||
inner_a: TypeSpec* = _text_to_spec(colon + 1, depth + 1)
|
||||
if inner_a is None:
|
||||
return None
|
||||
sp_a: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN)
|
||||
sp_a: TypeSpec* = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN)
|
||||
if sp_a is None:
|
||||
return None
|
||||
sp_a.Elem = inner_a
|
||||
@@ -779,11 +754,11 @@ def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
# ============================================================
|
||||
# _spec_make_struct - 构造 struct(深拷贝名字)
|
||||
# ============================================================
|
||||
def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr:
|
||||
def _spec_make_struct(kind: int, name: str) -> TypeSpec*:
|
||||
"""构造 struct/union/enum 类型(不驻留),失败返回 None"""
|
||||
if name is None or name[0] == '\0':
|
||||
return None
|
||||
sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN)
|
||||
sp: TypeSpec* = _spec_make(kind, 0, TS_SIGN_UNKNOWN)
|
||||
if sp is None:
|
||||
return None
|
||||
if _spec_set_struct_name(sp, name) != 0:
|
||||
@@ -794,7 +769,7 @@ def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr:
|
||||
# ============================================================
|
||||
# _text_to_func - 解析 "fn(p1,p2,...)->RET"
|
||||
# ============================================================
|
||||
def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
def _text_to_func(text: str, depth: int) -> TypeSpec*:
|
||||
"""解析函数签名文本,失败返回 None"""
|
||||
lp: str = string.strchr(text, '(')
|
||||
if lp is None:
|
||||
@@ -839,7 +814,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
continue
|
||||
if pcount >= 64:
|
||||
return None
|
||||
psp: TypeSpec | t.CPtr = _text_to_spec(seg, depth + 1)
|
||||
psp: TypeSpec* = _text_to_spec(seg, depth + 1)
|
||||
if psp is None:
|
||||
return None
|
||||
slot_p: sizet* = (sizet*)(uint64(param_specs) + uint64(pcount * 8))
|
||||
@@ -847,10 +822,10 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
return None
|
||||
slot_p[0] = sizet(psp)
|
||||
pcount += 1
|
||||
ret: TypeSpec | t.CPtr = _text_to_spec(arrow + 3, depth + 1)
|
||||
ret: TypeSpec* = _text_to_spec(arrow + 3, depth + 1)
|
||||
if ret is None:
|
||||
return None
|
||||
sp_f: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN)
|
||||
sp_f: TypeSpec* = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN)
|
||||
if sp_f is None:
|
||||
return None
|
||||
sp_f.Ret = ret
|
||||
@@ -867,7 +842,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr:
|
||||
# (绝不写入截断键)。
|
||||
# ============================================================
|
||||
def InternSpec(arena: TypeSpecArena | t.CPtr,
|
||||
sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
sp: TypeSpec*) -> TypeSpec*:
|
||||
"""按规范文本键驻留 TypeSpec;失败返回 None"""
|
||||
if arena is None or sp is None:
|
||||
return sp
|
||||
@@ -891,7 +866,7 @@ def InternSpec(arena: TypeSpecArena | t.CPtr,
|
||||
slot_e: sizet* = (sizet*)(uint64(arena.Specs) + uint64(found * 8))
|
||||
if slot_e is None:
|
||||
return None
|
||||
return (TypeSpec | t.CPtr)(uint64(slot_e[0]))
|
||||
return (TypeSpec*)(uint64(slot_e[0]))
|
||||
if arena.Index is None:
|
||||
# 索引不可用:回退原线性查找(规模与类型种数同阶)
|
||||
i: int = 0
|
||||
@@ -901,26 +876,21 @@ def InternSpec(arena: TypeSpecArena | t.CPtr,
|
||||
slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8))
|
||||
if slot_e2 is None:
|
||||
return None
|
||||
return (TypeSpec | t.CPtr)(uint64(slot_e2[0]))
|
||||
return (TypeSpec*)(uint64(slot_e2[0]))
|
||||
i += 1
|
||||
# 未命中:追加。**表满 = fail-fast**:不能返回 None——调用链会把 None 一路传到
|
||||
# entry.Spec,条目静默失去类型信息(如符号性判定恒返回 0 ⇒ zext/sext 方向取错),
|
||||
# 属静默数据损坏,与「不兜底 / fail-fast」原则直接冲突。
|
||||
if arena.Count >= arena.Cap:
|
||||
GenApi.fatal_error(
|
||||
None,
|
||||
f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型",
|
||||
"InternalCompilerError")
|
||||
GenApi.fatal_error(None, f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", "InternalCompilerError")
|
||||
# 仅在 fatal_error 无 gen 通道(no-op)时可达:退化为「不驻留但返回完整实例」,
|
||||
# 守住"不返回 None"这一底线 —— 宁失去同型共享,也不让条目静默丢类型。
|
||||
return sp
|
||||
dst_key: str = _spec_key_at(arena.Keys, arena.Count)
|
||||
if dst_key is None:
|
||||
return None
|
||||
if dst_key is None: return None
|
||||
string.strcpy(dst_key, key_buf)
|
||||
slot_n: sizet* = (sizet*)(uint64(arena.Specs) + uint64(arena.Count * 8))
|
||||
if slot_n is None:
|
||||
return None
|
||||
if slot_n is None: return None
|
||||
slot_n[0] = sizet(sp)
|
||||
# 同步写入哈希索引(下标 = 追加前的 Count)。插入失败仅意味着后续查找对该键
|
||||
# 回退线性扫描,不影响正确性。
|
||||
@@ -932,19 +902,16 @@ def InternSpec(arena: TypeSpecArena | t.CPtr,
|
||||
# ============================================================
|
||||
# 只读访问器(供 S3 起替换旧的字符串判定)
|
||||
# ============================================================
|
||||
def SpecIsPtr(sp: TypeSpec | t.CPtr) -> int:
|
||||
def SpecIsPtr(sp: TypeSpec*) -> int:
|
||||
"""是否指针类型(PtrLevel>0)"""
|
||||
if sp is None:
|
||||
return 0
|
||||
if sp.PtrLevel > 0:
|
||||
return 1
|
||||
if sp is None: return 0
|
||||
if sp.PtrLevel > 0: return 1
|
||||
return 0
|
||||
|
||||
|
||||
def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
def SpecPointedTo(sp: TypeSpec*) -> TypeSpec*:
|
||||
"""指针的指向类型(非指针返回 None)"""
|
||||
if sp is None or sp.Kind != TS_PTR:
|
||||
return None
|
||||
if sp is None or sp.Kind != TS_PTR: return None
|
||||
return sp.Elem
|
||||
|
||||
|
||||
@@ -955,13 +922,11 @@ def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
# 供 SpecWithSign / SpecWithSource / SpecWithElemBits 复用,避免多处重复
|
||||
# 逐字段拷贝(漏字段是最容易引入的隐蔽 bug:例如忘了 IsElemPtr)。
|
||||
# ============================================================
|
||||
def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
def _spec_clone(sp: TypeSpec*) -> TypeSpec*:
|
||||
"""浅拷贝 sp(含全部字段),分配失败返回 None"""
|
||||
if sp is None:
|
||||
return None
|
||||
cp: TypeSpec | t.CPtr = _spec_alloc()
|
||||
if cp is None:
|
||||
return None
|
||||
if sp is None: return None
|
||||
cp: TypeSpec* = _spec_alloc()
|
||||
if cp is None: return None
|
||||
cp.Kind = sp.Kind
|
||||
cp.Bits = sp.Bits
|
||||
cp.IsSigned = sp.IsSigned
|
||||
@@ -994,8 +959,8 @@ def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
# 仅当符号性实际变化才复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。
|
||||
# ============================================================
|
||||
def SpecWithSign(arena: TypeSpecArena | t.CPtr,
|
||||
sp: TypeSpec | t.CPtr,
|
||||
is_signed: int) -> TypeSpec | t.CPtr:
|
||||
sp: TypeSpec*,
|
||||
is_signed: int) -> TypeSpec*:
|
||||
"""复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None"""
|
||||
if sp is None:
|
||||
return None
|
||||
@@ -1009,7 +974,7 @@ def SpecWithSign(arena: TypeSpecArena | t.CPtr,
|
||||
new_signed = TS_SIGN_SIGNED
|
||||
if new_kind == sp.Kind:
|
||||
return sp
|
||||
cp: TypeSpec | t.CPtr = _spec_clone(sp)
|
||||
cp: TypeSpec* = _spec_clone(sp)
|
||||
if cp is None:
|
||||
return None
|
||||
cp.Kind = new_kind
|
||||
@@ -1025,7 +990,7 @@ def SpecWithSign(arena: TypeSpecArena | t.CPtr,
|
||||
# ============================================================
|
||||
# _spec_set_source_name - 深拷贝注解来源名到 PermPool 并写入 SourceName
|
||||
# ============================================================
|
||||
def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int:
|
||||
def _spec_set_source_name(sp: TypeSpec*, name: str) -> int:
|
||||
"""把注解来源名深拷贝到 PermPool 并写入 SourceName,返回 0=成功 / 1=失败"""
|
||||
if sp is None or name is None:
|
||||
return 1
|
||||
@@ -1053,13 +1018,13 @@ def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int:
|
||||
#
|
||||
# 幂等:sp.SourceName 已等于 name 时返回原实例(避免重复副本)。
|
||||
# ============================================================
|
||||
def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr:
|
||||
def SpecWithSource(sp: TypeSpec*, name: str) -> TypeSpec*:
|
||||
"""复制 sp 并设置 SourceName(独立副本,不驻留);name 为空返回原实例"""
|
||||
if sp is None or name is None or name[0] == '\0':
|
||||
return sp
|
||||
if sp.SourceName is not None and string.strcmp(sp.SourceName, name) == 0:
|
||||
return sp
|
||||
cp: TypeSpec | t.CPtr = _spec_clone(sp)
|
||||
cp: TypeSpec* = _spec_clone(sp)
|
||||
if cp is None:
|
||||
return sp
|
||||
if _spec_set_source_name(cp, name) != 0:
|
||||
@@ -1078,27 +1043,27 @@ def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr:
|
||||
# ElemBits 是派生字段(**不在 SpecToText 键内**)⇒ 必须返回独立副本:
|
||||
# 若走 InternSpec 会命中键相同但 ElemBits 未覆盖的实例,覆盖丢失。
|
||||
# ============================================================
|
||||
def SpecWithElemBits(sp: TypeSpec | t.CPtr, elem_bits: int) -> TypeSpec | t.CPtr:
|
||||
def SpecWithElemBits(sp: TypeSpec*, elem_bits: int) -> TypeSpec*:
|
||||
"""复制 sp 并设置 ElemBits(独立副本,不驻留);无变化返回原实例"""
|
||||
if sp is None:
|
||||
return sp
|
||||
if sp.ElemBits == elem_bits:
|
||||
return sp
|
||||
cp: TypeSpec | t.CPtr = _spec_clone(sp)
|
||||
cp: TypeSpec* = _spec_clone(sp)
|
||||
if cp is None:
|
||||
return sp
|
||||
cp.ElemBits = elem_bits
|
||||
return cp
|
||||
|
||||
|
||||
def SpecSourceName(sp: TypeSpec | t.CPtr) -> str:
|
||||
def SpecSourceName(sp: TypeSpec*) -> str:
|
||||
"""Spec 的注解来源名(未设置返回 None)"""
|
||||
if sp is None:
|
||||
return None
|
||||
return sp.SourceName
|
||||
|
||||
|
||||
def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int:
|
||||
def SpecIsUnsigned(sp: TypeSpec*) -> int:
|
||||
"""是否无符号整数(单一真源;未知返回 0)"""
|
||||
if sp is None:
|
||||
return 0
|
||||
@@ -1107,7 +1072,7 @@ def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def SpecBitWidth(sp: TypeSpec | t.CPtr) -> int:
|
||||
def SpecBitWidth(sp: TypeSpec*) -> int:
|
||||
"""位宽(非整形/浮点返回 0)"""
|
||||
if sp is None:
|
||||
return 0
|
||||
@@ -1184,7 +1149,7 @@ def SpecTypeBits(ty: llvmlite.LLVMType*) -> int:
|
||||
SPEC_LLVM_TEXT_MAX_DEPTH: t.CDefine = 100
|
||||
|
||||
|
||||
def SpecToLLVMText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int:
|
||||
def SpecToLLVMText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int:
|
||||
"""TypeSpec → LLVM IR 类型文本(对齐 TypePrint),返回 0=成功 / 1=失败"""
|
||||
if sp is None or buf is None or buf_size == 0:
|
||||
return 1
|
||||
@@ -1204,7 +1169,7 @@ def _spec_llvm_append(buf: str, buf_size: sizet, src: str) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet,
|
||||
depth: int) -> int:
|
||||
"""把 sp 的 LLVM 文本**追加**到 buf 末尾(buf 已有前缀时保持原前缀)"""
|
||||
if sp is None or buf is None:
|
||||
@@ -1238,7 +1203,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
return 0
|
||||
# --- 指针 ---
|
||||
if sp.Kind == TS_PTR:
|
||||
inner: TypeSpec | t.CPtr = sp.Elem
|
||||
inner: TypeSpec* = sp.Elem
|
||||
if inner is None or inner.Kind == TS_VOID:
|
||||
viperlib.snprintf(buf + pos, buf_size - pos, "i8*")
|
||||
return 0
|
||||
@@ -1277,7 +1242,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
if i > 0:
|
||||
if _spec_llvm_append(buf, buf_size, ", ") != 0:
|
||||
return 1
|
||||
ps: TypeSpec | t.CPtr = _spec_param_at(sp, i)
|
||||
ps: TypeSpec* = _spec_param_at(sp, i)
|
||||
if ps is None:
|
||||
return 1
|
||||
if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0:
|
||||
@@ -1315,7 +1280,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet,
|
||||
# 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。
|
||||
# ============================================================
|
||||
def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr,
|
||||
ty: llvmlite.LLVMType*) -> TypeSpec | t.CPtr:
|
||||
ty: llvmlite.LLVMType*) -> TypeSpec*:
|
||||
"""把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None"""
|
||||
if arena is None or ty is None:
|
||||
return None
|
||||
@@ -1341,9 +1306,9 @@ def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr,
|
||||
|
||||
|
||||
def _spec_from_ptr(arena: TypeSpecArena | t.CPtr,
|
||||
pointee: llvmlite.LLVMType*) -> TypeSpec | t.CPtr:
|
||||
pointee: llvmlite.LLVMType*) -> TypeSpec*:
|
||||
"""Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)"""
|
||||
inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pointee)
|
||||
inner: TypeSpec* = SpecFromLLVMType(arena, pointee)
|
||||
if inner is None:
|
||||
return None
|
||||
return NewTypePtr(arena, inner)
|
||||
@@ -1351,9 +1316,9 @@ def _spec_from_ptr(arena: TypeSpecArena | t.CPtr,
|
||||
|
||||
def _spec_from_array(arena: TypeSpecArena | t.CPtr,
|
||||
elem_ty: llvmlite.LLVMType*,
|
||||
count: int) -> TypeSpec | t.CPtr:
|
||||
count: int) -> TypeSpec*:
|
||||
"""[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)"""
|
||||
inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, elem_ty)
|
||||
inner: TypeSpec* = SpecFromLLVMType(arena, elem_ty)
|
||||
if inner is None:
|
||||
return None
|
||||
return NewTypeArray(arena, inner, count)
|
||||
@@ -1362,9 +1327,9 @@ def _spec_from_array(arena: TypeSpecArena | t.CPtr,
|
||||
def _spec_from_func(arena: TypeSpecArena | t.CPtr,
|
||||
ret: llvmlite.LLVMType*,
|
||||
params: llvmlite.Function*,
|
||||
pcount: int) -> TypeSpec | t.CPtr:
|
||||
pcount: int) -> TypeSpec*:
|
||||
"""函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)"""
|
||||
ret_s: TypeSpec | t.CPtr = SpecFromLLVMType(arena, ret)
|
||||
ret_s: TypeSpec* = SpecFromLLVMType(arena, ret)
|
||||
if ret_s is None:
|
||||
return None
|
||||
if pcount <= 0:
|
||||
@@ -1377,7 +1342,7 @@ def _spec_from_func(arena: TypeSpecArena | t.CPtr,
|
||||
i: int = 0
|
||||
while node is not None and i < pcount:
|
||||
pty: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(node)
|
||||
ps: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pty)
|
||||
ps: TypeSpec* = SpecFromLLVMType(arena, pty)
|
||||
if ps is None:
|
||||
return None
|
||||
slot: sizet* = (sizet*)(uint64(params_arr) + uint64(i * 8))
|
||||
@@ -1390,7 +1355,7 @@ def _spec_from_func(arena: TypeSpecArena | t.CPtr,
|
||||
|
||||
|
||||
def _spec_from_struct(arena: TypeSpecArena | t.CPtr,
|
||||
sname: str) -> TypeSpec | t.CPtr:
|
||||
sname: str) -> TypeSpec*:
|
||||
"""有名结构体 → TS_STRUCT + BaseName;匿名结构体 → 无名 TS_STRUCT"""
|
||||
if sname is not None:
|
||||
return NewTypeStruct(arena, TS_STRUCT, sname)
|
||||
@@ -1413,28 +1378,28 @@ def SpecSelfCheck() -> int:
|
||||
return 1
|
||||
|
||||
# 1) u64
|
||||
s_u64: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED)
|
||||
s_u64: TypeSpec* = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED)
|
||||
if s_u64 is None:
|
||||
return 1
|
||||
if _check_roundtrip(s_u64, "u64") != 0:
|
||||
return 1
|
||||
|
||||
# 2) i32
|
||||
s_i32: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED)
|
||||
s_i32: TypeSpec* = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED)
|
||||
if s_i32 is None:
|
||||
return 2
|
||||
if _check_roundtrip(s_i32, "i32") != 0:
|
||||
return 2
|
||||
|
||||
# 3) u64*
|
||||
s_p: TypeSpec | t.CPtr = NewTypePtr(arena, s_u64)
|
||||
s_p: TypeSpec* = NewTypePtr(arena, s_u64)
|
||||
if s_p is None:
|
||||
return 3
|
||||
if _check_roundtrip(s_p, "p:u64") != 0:
|
||||
return 3
|
||||
|
||||
# 4) i8[4]
|
||||
s_arr: TypeSpec | t.CPtr = NewTypeArray(arena, s_i32, 4)
|
||||
s_arr: TypeSpec* = NewTypeArray(arena, s_i32, 4)
|
||||
if s_arr is None:
|
||||
return 4
|
||||
if _check_roundtrip(s_arr, "arr[4]:i32") != 0:
|
||||
@@ -1452,14 +1417,14 @@ def SpecSelfCheck() -> int:
|
||||
if slot1 is None:
|
||||
return 5
|
||||
slot1[0] = sizet(s_u64)
|
||||
s_fn: TypeSpec | t.CPtr = NewTypeFunc(arena, s_i32, params, 2, 1)
|
||||
s_fn: TypeSpec* = NewTypeFunc(arena, s_i32, params, 2, 1)
|
||||
if s_fn is None:
|
||||
return 5
|
||||
if _check_roundtrip(s_fn, "fn(i32,u64,...)->i32") != 0:
|
||||
return 5
|
||||
|
||||
# 6) 驻留去重:同一文本第二次应返回同一实例
|
||||
s_u64_again: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED)
|
||||
s_u64_again: TypeSpec* = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED)
|
||||
if s_u64_again is None:
|
||||
return 6
|
||||
if uint64(s_u64_again) != uint64(s_u64):
|
||||
@@ -1470,7 +1435,7 @@ def SpecSelfCheck() -> int:
|
||||
# ============================================================
|
||||
# _check_roundtrip - 自检辅助:编码应等于 expect,且解码再编码应一致
|
||||
# ============================================================
|
||||
def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int:
|
||||
def _check_roundtrip(sp: TypeSpec*, expect: str) -> int:
|
||||
"""编码比对 + 解码往返一致;返回 0=通过 / 1=失败"""
|
||||
if sp is None or expect is None:
|
||||
return 1
|
||||
@@ -1481,7 +1446,7 @@ def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int:
|
||||
return 1
|
||||
if string.strcmp(buf1, expect) != 0:
|
||||
return 1
|
||||
back: TypeSpec | t.CPtr = TextToSpec(buf1)
|
||||
back: TypeSpec* = TextToSpec(buf1)
|
||||
if back is None:
|
||||
return 1
|
||||
buf2: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX)
|
||||
|
||||
+58
-134
@@ -169,9 +169,7 @@ novirtual class VarGenMixin:
|
||||
# PtrLevel>=1。不满足即上游异常(类型缺失/退化),fail-fast 暴露 ——
|
||||
# 若静默放过,读点 var_is_ptr_element 返回 0 → 下标按 1 字节误算(数据损坏)。
|
||||
if entry.Spec is None or entry.Spec.PtrLevel < 1:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
None, f"变量 '{name}' 标记为 ptr-element,但其 Spec 不可承载指针语义",
|
||||
"InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(None, f"变量 '{name}' 标记为 ptr-element,但其 Spec 不可承载指针语义", "InternalCompilerError")
|
||||
return 1
|
||||
entry.Spec = TSpec.SpecWithElemBits(entry.Spec, 64)
|
||||
return 0
|
||||
@@ -456,8 +454,7 @@ novirtual class VarGenMixin:
|
||||
return None
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
while scope is not None:
|
||||
result: llvmlite.Value* = self.find_var(
|
||||
scope.Vars, scope.VarCount, name)
|
||||
result: llvmlite.Value* = self.find_var(scope.Vars, scope.VarCount, name)
|
||||
if result is not None:
|
||||
return result
|
||||
scope = scope.Parent
|
||||
@@ -518,8 +515,7 @@ novirtual class VarGenMixin:
|
||||
return None
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
while scope is not None:
|
||||
result: llvmlite.Value* = self.find_var(
|
||||
scope.Vars, scope.VarCount, name)
|
||||
result: llvmlite.Value* = self.find_var(scope.Vars, scope.VarCount, name)
|
||||
if result is not None:
|
||||
return result
|
||||
if scope.Kind == SCOPE_MATCH:
|
||||
@@ -609,10 +605,7 @@ novirtual class VarGenMixin:
|
||||
symtab: rawptr[GenTypes.SymbolTable] = trans.SymTab
|
||||
param_alloca: llvmlite.Value* = self.lookup_var(symtab, ctx.CtxParam)
|
||||
if param_alloca is None or param_alloca.Ty is None or param_alloca.Ty.Pointee == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 片段函数缺少 ctx 形参 '{ctx.CtxParam}'(包裹模板与 M2 调用约定不一致)",
|
||||
"InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 片段函数缺少 ctx 形参 '{ctx.CtxParam}'(包裹模板与 M2 调用约定不一致)", "InternalCompilerError")
|
||||
return None
|
||||
return llvmlite.build_load(trans._cur_builder, param_alloca.Ty.Pointee, param_alloca)
|
||||
|
||||
@@ -731,17 +724,10 @@ novirtual class VarGenMixin:
|
||||
return None
|
||||
hit[0] = 1
|
||||
if kw_count != 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)", "TypeError")
|
||||
return None
|
||||
if can != entry.ParamCount:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参,"
|
||||
f"调用处给了 {can} 个(M3 不支持默认参数/缺省补全)",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参,调用处给了 {can} 个(M3 不支持默认参数/缺省补全)", "TypeError")
|
||||
return None
|
||||
ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, ctx, node)
|
||||
if ctx_val is None:
|
||||
@@ -749,16 +735,13 @@ novirtual class VarGenMixin:
|
||||
i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
|
||||
# ① 槽内取函数地址:槽地址是 i8**(Ptr(i8*)),load 得 i8*
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty)
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty)
|
||||
if slot is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError")
|
||||
return None
|
||||
fn_i8: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, slot)
|
||||
if fn_i8 is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError")
|
||||
return None
|
||||
# ② 签名构造前先取形参类型(token → LLVM 类型;不支持 ⇒ 明确报错)
|
||||
ptypes: t.CPtr = pool.alloc(8 * GenTypes.REPL_FUNC_PARAM_MAX)
|
||||
@@ -767,14 +750,9 @@ novirtual class VarGenMixin:
|
||||
string.memset(ptypes, 0, 8 * GenTypes.REPL_FUNC_PARAM_MAX)
|
||||
ai_chk: int
|
||||
for ai_chk in range(entry.ParamCount):
|
||||
pty_chk: llvmlite.LLVMType* = self.repl_func_ty(
|
||||
pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk]))
|
||||
pty_chk: llvmlite.LLVMType* = self.repl_func_ty(pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk]))
|
||||
if pty_chk is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token "
|
||||
f"不受支持(M3 支持 iN/float/double/i8*)",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token 不受支持(M3 支持 iN/float/double/i8*)", "TypeError")
|
||||
return None
|
||||
pty_slot: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai_chk * 8)
|
||||
pty_slot[0] = pty_chk
|
||||
@@ -787,26 +765,17 @@ novirtual class VarGenMixin:
|
||||
for ai in range(entry.ParamCount):
|
||||
arg: ast.AST* = cargs.get(ai)
|
||||
if arg is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失",
|
||||
"SyntaxError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失", "SyntaxError")
|
||||
return None
|
||||
pty_slot2: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai * 8)
|
||||
pty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(pty_slot2[0])
|
||||
arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, pty)
|
||||
arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans, pty)
|
||||
if arg_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败", "TypeError")
|
||||
return None
|
||||
coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, arg_val, pty, arg, trans)
|
||||
coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, pty, arg, trans)
|
||||
if coerced is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容", "TypeError")
|
||||
return None
|
||||
coerced.Next = None
|
||||
tail.Next = coerced
|
||||
@@ -818,11 +787,7 @@ novirtual class VarGenMixin:
|
||||
if entry.RetTag != GenTypes.REPL_TY_VOID:
|
||||
ret_ty = self.repl_func_ty(pool, entry.RetTag, entry.RetBits)
|
||||
if ret_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持"
|
||||
f"(M3 支持 void/iN/float/double/i8*)",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持(M3 支持 void/iN/float/double/i8*)", "TypeError")
|
||||
return None
|
||||
fp_first: llvmlite.Function* = None
|
||||
fp_prev: llvmlite.Function* = None
|
||||
@@ -845,8 +810,7 @@ novirtual class VarGenMixin:
|
||||
func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty)
|
||||
fn_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty)
|
||||
if fn_typed is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError")
|
||||
return None
|
||||
return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty)
|
||||
|
||||
@@ -874,8 +838,7 @@ novirtual class VarGenMixin:
|
||||
# 同型时不发 bitcast:llvmlite 类型非 canonical(同类型不同实例地址不同),
|
||||
# 而 LLVM 拒绝 `bitcast i8* %x to i8*`(同型 cast 非法)——val_ty 为 i8
|
||||
# (char 会话变量)时目标恰是 i8*,必须直接返回 GEP 结果。
|
||||
if base.Ty is not None and self.Gen.AssignGen._stg_ty_equal(
|
||||
pool, base.Ty, target_ptr_ty) != 0:
|
||||
if base.Ty is not None and self.Gen.AssignGen._stg_ty_equal(pool, base.Ty, target_ptr_ty) != 0:
|
||||
return base
|
||||
return llvmlite.build_bitcast(builder, base, target_ptr_ty)
|
||||
|
||||
@@ -1076,8 +1039,7 @@ novirtual class VarGenMixin:
|
||||
return 1
|
||||
perm: memhub.MemBuddy* = self.repl_perm_pool(trans)
|
||||
if perm is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError")
|
||||
return 1
|
||||
tag: int = 0
|
||||
bits: int = 0
|
||||
@@ -1126,15 +1088,13 @@ novirtual class VarGenMixin:
|
||||
sz: int = self.repl_type_size(val_ty)
|
||||
al: int = self.repl_type_align(val_ty)
|
||||
if sz <= 0 or al <= 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 尺寸/对齐未知"
|
||||
f"(无法判定能否放入 {GenTypes.REPL_SLOT_SIZE} 字节槽)",
|
||||
"TypeError")
|
||||
return 1
|
||||
if sz > GenTypes.REPL_SLOT_SIZE or al > GenTypes.REPL_SLOT_SIZE:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 体积 {sz} 字节、"
|
||||
f"对齐 {al} 字节,无法放入 {GenTypes.REPL_SLOT_SIZE} 字节槽"
|
||||
f"(M2 结构体值须内联进槽;大对象请改用对象指针/堆分配)",
|
||||
@@ -1145,8 +1105,7 @@ novirtual class VarGenMixin:
|
||||
kind = GenTypes.REPL_KIND_SCALAR
|
||||
tname = sname
|
||||
else:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 的类型暂不支持"
|
||||
f"(M2 支持 int/bool/浮点/str/bytes/指针/结构体值)",
|
||||
"TypeError")
|
||||
@@ -1160,8 +1119,7 @@ novirtual class VarGenMixin:
|
||||
entry.TyName = self.repl_perm_strdup(perm, tname)
|
||||
return 0
|
||||
if entry.Kind != kind or entry.TyTag != tag:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 已定型为 {self.repl_tag_label(entry.TyTag, entry.Bits)},"
|
||||
f"不能再赋成 {self.repl_tag_label(tag, bits)}(如需换型请重启会话)",
|
||||
"TypeError")
|
||||
@@ -1230,29 +1188,24 @@ novirtual class VarGenMixin:
|
||||
if hit is not None:
|
||||
return hit
|
||||
if ctx.Table is None or ctx.Cap <= 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "REPL: 会话变量表未初始化(宿主未建 ctx)", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话变量表未初始化(宿主未建 ctx)", "InternalCompilerError")
|
||||
return None
|
||||
if ctx.Count >= ctx.Cap:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量已达上限 {ctx.Cap} 个(ctx 槽位用尽),"
|
||||
f"无法为 '{name}' 再分配槽位;请重启会话",
|
||||
"ResourceError")
|
||||
return None
|
||||
perm: memhub.MemBuddy* = self.repl_perm_pool(trans)
|
||||
if perm is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError")
|
||||
return None
|
||||
name_copy: str = self.repl_perm_strdup(perm, name)
|
||||
if name_copy is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话变量 '{name}' 的名字深拷贝失败", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的名字深拷贝失败", "InternalCompilerError")
|
||||
return None
|
||||
entry_size: sizet = GenTypes.ReplVarEntry.__sizeof__()
|
||||
entry: rawptr[GenTypes.ReplVarEntry] = rawptr[GenTypes.ReplVarEntry](
|
||||
uint64(ctx.Table) + uint64(ctx.Count) * uint64(entry_size))
|
||||
entry: rawptr[GenTypes.ReplVarEntry] = rawptr[GenTypes.ReplVarEntry](uint64(ctx.Table) + uint64(ctx.Count) * uint64(entry_size))
|
||||
if entry is None:
|
||||
return None
|
||||
entry.Name = name_copy
|
||||
@@ -1296,8 +1249,7 @@ novirtual class VarGenMixin:
|
||||
i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool)
|
||||
zero64: llvmlite.Value* = llvmlite.const_int64(pool, 0)
|
||||
if tag == GenTypes.REPL_TY_INT:
|
||||
iv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, val, i64_ty, node, trans)
|
||||
iv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, val, i64_ty, node, trans)
|
||||
if iv is None:
|
||||
return 1
|
||||
if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF,
|
||||
@@ -1307,8 +1259,7 @@ novirtual class VarGenMixin:
|
||||
return 1
|
||||
return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64)
|
||||
if tag == GenTypes.REPL_TY_FLOAT:
|
||||
dv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, val, llvmlite.Double(pool), node, trans)
|
||||
dv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, val, llvmlite.Double(pool), node, trans)
|
||||
if dv is None:
|
||||
return 1
|
||||
# double → i64 位模式(bitcast,不做数值转换):宿主按位重解释回 double
|
||||
@@ -1331,8 +1282,7 @@ novirtual class VarGenMixin:
|
||||
if pv is None:
|
||||
return 1
|
||||
# 指针 → i64(ptrtoint):宿主按整数读回后再 inttoptr 成地址
|
||||
pbits: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, pv, i64_ty, node, trans)
|
||||
pbits: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, pv, i64_ty, node, trans)
|
||||
if pbits is None:
|
||||
return 1
|
||||
kind: int = GenTypes.REPL_RES_OBJ
|
||||
@@ -1365,8 +1315,7 @@ novirtual class VarGenMixin:
|
||||
return 1
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, builder, ctx_val, off, llvmlite.Int64(pool))
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, off, llvmlite.Int64(pool))
|
||||
if slot is None:
|
||||
return 1
|
||||
llvmlite.build_store(builder, val, slot)
|
||||
@@ -1383,8 +1332,7 @@ novirtual class VarGenMixin:
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
if pool is None or builder is None:
|
||||
return 1
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, builder, ctx_val, off, llvmlite.Int32(pool))
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, off, llvmlite.Int32(pool))
|
||||
if slot is None:
|
||||
return 1
|
||||
cv: llvmlite.Value* = llvmlite.const_int32(pool, val)
|
||||
@@ -1409,16 +1357,14 @@ novirtual class VarGenMixin:
|
||||
if self.repl_in_frag_scope(trans.SymTab) == 0:
|
||||
return None
|
||||
if entry.Kind == GenTypes.REPL_KIND_UNTYPED:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 尚未赋值(未定型,先执行一条 'x = ...' 或 'x: int = ...')",
|
||||
"NameError")
|
||||
return None
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry)
|
||||
if slot_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 的类型 "
|
||||
f"{self.repl_tag_label(entry.TyTag, entry.Bits)} 在当前片段不可用"
|
||||
f"(跨片段类型可见性属 M4)",
|
||||
@@ -1427,8 +1373,7 @@ novirtual class VarGenMixin:
|
||||
ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node)
|
||||
if ctx_val is None:
|
||||
return None
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty)
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty)
|
||||
if slot is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽地址生成失败", "InternalCompilerError")
|
||||
return None
|
||||
@@ -1452,27 +1397,23 @@ novirtual class VarGenMixin:
|
||||
if self.repl_in_frag_scope(trans.SymTab) == 0:
|
||||
return None
|
||||
if entry.Kind == GenTypes.REPL_KIND_UNTYPED:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 尚未赋值(未定型),无法取址(c.Addr)",
|
||||
"NameError")
|
||||
return None
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry)
|
||||
if slot_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 的类型在当前片段不可用(跨片段类型可见性属 M4)",
|
||||
"NameError")
|
||||
return None
|
||||
ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node)
|
||||
if ctx_val is None:
|
||||
return None
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty)
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty)
|
||||
if slot is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "REPL: 会话槽地址生成失败", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽地址生成失败", "InternalCompilerError")
|
||||
return None
|
||||
# 值内联在槽里(无装箱间接层)⇒ 槽地址即值地址
|
||||
return slot
|
||||
@@ -1494,17 +1435,14 @@ novirtual class VarGenMixin:
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry)
|
||||
if slot_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 的槽类型不可用"
|
||||
f"(类型在当前片段不可解析,或结构体值体积超出槽容量)",
|
||||
"TypeError")
|
||||
return 1
|
||||
store_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, slot_ty, node, trans)
|
||||
store_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, slot_ty, node, trans)
|
||||
if store_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{entry.Name}' 无法把右侧值转换为"
|
||||
f" {self.repl_tag_label(entry.TyTag, entry.Bits)}",
|
||||
"CastError")
|
||||
@@ -1519,8 +1457,7 @@ novirtual class VarGenMixin:
|
||||
if store_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽指针同型化失败", "CastError")
|
||||
return 1
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(
|
||||
pool, builder, ctx_val, entry.Offset, slot_ty)
|
||||
slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, entry.Offset, slot_ty)
|
||||
if slot is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽写入失败", "InternalCompilerError")
|
||||
return 1
|
||||
@@ -1549,8 +1486,7 @@ novirtual class VarGenMixin:
|
||||
if self.repl_in_frag_entry_scope(trans) == 0:
|
||||
return 0
|
||||
if rhs_val.Ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话变量 '{name}' 的赋值右侧类型未知", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的赋值右侧类型未知", "TypeError")
|
||||
return 1
|
||||
if self.repl_seal(trans, entry, rhs_val.Ty, rhs_node) != 0:
|
||||
return 1
|
||||
@@ -1583,17 +1519,14 @@ novirtual class VarGenMixin:
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
if annot_node is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话变量 '{name}' 的注解缺失", "SyntaxError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的注解缺失", "SyntaxError")
|
||||
return 1
|
||||
# 与普通 AnnAssign 同口径:先注册泛型特化,避免 list[X] 退化为裸基类
|
||||
# (裸 list* 会让后续 .get() 误分派并截断指针)
|
||||
self.Gen.AssignGen._prespecialize_generic_annotation(trans, pool, annot_node)
|
||||
annot_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
annot_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if annot_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 的类型注解解析失败"
|
||||
f"(片段无 import;仅内建名 int/str/bytes/bool/float/double/char 等可解析)",
|
||||
"NameError")
|
||||
@@ -1607,13 +1540,11 @@ novirtual class VarGenMixin:
|
||||
# 与普通 AnnAssign 四处同口径:翻译 RHS 前设置上下文(裸名泛型构造推断用)
|
||||
trans.CurAssignAnnot = annot_node
|
||||
trans.CurAssignNode = value_node
|
||||
rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, value_node, None, 0, trans, slot_ty)
|
||||
rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, value_node, None, 0, trans, slot_ty)
|
||||
trans.CurAssignAnnot = None
|
||||
trans.CurAssignNode = None
|
||||
if rhs_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话变量 '{name}' 的初值翻译失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的初值翻译失败", "TypeError")
|
||||
return 1
|
||||
ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node)
|
||||
if ctx_val is None:
|
||||
@@ -1642,24 +1573,20 @@ novirtual class VarGenMixin:
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
if entry.TyTag == GenTypes.REPL_TY_STRUCT:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node,
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
f"REPL: 会话变量 '{name}' 是结构体值,不支持增强赋值",
|
||||
"TypeError")
|
||||
return 1
|
||||
cur_val: llvmlite.Value* = self.repl_try_read(trans, name, node)
|
||||
if cur_val is None:
|
||||
return 1
|
||||
rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, rhs_node, None, 0, trans)
|
||||
rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, rhs_node, None, 0, trans)
|
||||
if rhs_val is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REPL: 增强赋值右侧翻译失败", "TypeError")
|
||||
return 1
|
||||
result: llvmlite.Value* = self.Gen.AssignGen._apply_aug_op(
|
||||
pool, builder, op, cur_val, rhs_val, node, trans, node)
|
||||
result: llvmlite.Value* = self.Gen.AssignGen._apply_aug_op(pool, builder, op, cur_val, rhs_val, node, trans, node)
|
||||
if result is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"REPL: 会话变量 '{name}' 的增强赋值运算失败 op={op}", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的增强赋值运算失败 op={op}", "TypeError")
|
||||
return 1
|
||||
# 写回槽(复用赋值路径:定型已存在 ⇒ 只做转换与存储)
|
||||
return self.repl_try_assign(trans, name, result, node, node)
|
||||
@@ -1676,11 +1603,9 @@ novirtual class VarGenMixin:
|
||||
return 1
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, value_node, None, 0, trans)
|
||||
val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, value_node, None, 0, trans)
|
||||
if val is None or val.Ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
value_node, "REPL: 表达式片段求值失败", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(value_node, "REPL: 表达式片段求值失败", "TypeError")
|
||||
return 1
|
||||
ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, value_node)
|
||||
if ctx_val is None:
|
||||
@@ -1688,8 +1613,7 @@ novirtual class VarGenMixin:
|
||||
# 类型分类用宿主的影子条目(不占会话槽、不进表):每次先复位为未定型
|
||||
sh: rawptr[GenTypes.ReplVarEntry] = trans.ReplCtx.Scratch
|
||||
if sh is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
value_node, "REPL: 会话缺少影子条目(宿主未初始化)", "InternalCompilerError")
|
||||
self.Gen.TypeGenErr.fatal_error(value_node, "REPL: 会话缺少影子条目(宿主未初始化)", "InternalCompilerError")
|
||||
return 1
|
||||
sh.Kind = GenTypes.REPL_KIND_UNTYPED
|
||||
sh.TyTag = 0
|
||||
|
||||
+18
-28
@@ -1,4 +1,4 @@
|
||||
import t, c
|
||||
import t
|
||||
from stdint import *
|
||||
import stdio
|
||||
import stdlib
|
||||
@@ -40,7 +40,7 @@ import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
# ctx(会话内存,宿主 PermPool 一次性分配;布局见 GenTypes 顶部注释):
|
||||
# 偏移 0..63 固定头(magic/version/result_kind/result_a/result_b/var_count/last_frag)
|
||||
# 偏移 64 起为变量槽(每槽 16 字节)。宿主与片段在**同一进程**内共享该内存:
|
||||
# 会话变量只存一份 ⇒ c.Addr(x) 得到的就是槽地址(地址同一性)。
|
||||
# 会话变量只存一份 ⇒ &x 得到的就是槽地址(地址同一性)。
|
||||
# 值的类型按首次赋值推导(`x = 1` 与 `x: int = 1` 等价,均定型并分配槽)。
|
||||
#
|
||||
# 错误可恢复依赖 VLogger 的 jit_flag + setjmp/longjmp:
|
||||
@@ -57,18 +57,18 @@ import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
# ============================================================
|
||||
|
||||
# 输入行缓冲容量(含 NUL 终止符)
|
||||
_REPL_LINE_CAP: t.CDefine = 4096
|
||||
define _REPL_LINE_CAP = 4096
|
||||
|
||||
# 块输入缓冲容量(会话级 PermPool,含 NUL 终止符):续行状态下逐行追加的用户原文,
|
||||
# 行间以一个 '\n' 连接、无行尾换行。
|
||||
# 取 8 KiB 的理由:常见多行块(10 行 × 80 列 ≈ 0.8 KiB)绰绰有余;整段粘贴
|
||||
# 100 行 × 80 列 ≈ 8 KiB 也刚好容纳;再大属异常输入,按"明确报错 + 丢弃该块"
|
||||
# 处理(绝不截断后执行)。上界同时约束包裹源码缓冲的下界(见 _REPL_FRAG_SRC_CAP)。
|
||||
_REPL_BLOCK_CAP: t.CDefine = 8192
|
||||
define _REPL_BLOCK_CAP = 8192
|
||||
|
||||
# jmp_buf 实测大小:mingw-w64 x86_64 setjmp.h 中 _JBLEN=16、_JBTYPE=SETJMP_FLOAT128(16B)
|
||||
# ⇒ 16 * 16 = 256 字节(已用 C 探针 sizeof(jmp_buf) 实测 = 256)
|
||||
_REPL_JMPBUF_SIZE: t.CDefine = 256
|
||||
define _REPL_JMPBUF_SIZE = 256
|
||||
|
||||
# setjmp/longjmp:mingw-w64 x86_64 的 _setjmp 第二参数为 frame 指针,
|
||||
# setjmp 宏即展开为 _setjmp(buf, NULL)(非 SEH 场景传 None 即可)
|
||||
@@ -171,8 +171,7 @@ _REPL_PROJECT_PROBE_CAP: t.CDefine = 16
|
||||
# 片段把 double 的 IEEE754 位模式写进 result_a;宿主按本视图读回即得 double
|
||||
# (位模式重解释,不做数值转换)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ReplFloatView:
|
||||
novirtual class ReplFloatView:
|
||||
"""ctx 头(+16 处按 double 读)"""
|
||||
Magic: int
|
||||
Version: int
|
||||
@@ -188,8 +187,7 @@ class ReplFloatView:
|
||||
# 16 字节(低 8 字节 = 地址,高 8 字节保留)。片段侧按同一偏移(i8** 视图)
|
||||
# load 该地址后间接调用;宿主用本视图写入 ⇒ 两侧对"槽内是什么"只有一个约定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ReplFuncSlotView:
|
||||
novirtual class ReplFuncSlotView:
|
||||
"""ctx 函数指针槽(Addr = 定义片段 DLL 里该函数的入口地址)"""
|
||||
Addr: VOIDPTR
|
||||
Reserved: VOIDPTR
|
||||
@@ -204,8 +202,7 @@ class ReplFuncSlotView:
|
||||
# ReplFuncEntry 的签名 token;调用片段再用 token 重建同型签名 ⇒ 两侧一致。
|
||||
# 形参/返回的 token 数组写进会话 scratch(ReplSigTags/ReplSigBits)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ReplSigOut:
|
||||
novirtual class ReplSigOut:
|
||||
"""签名解析结果(Bad/EHTag 非 0 时拒绝注册)"""
|
||||
RetTag: int # GenTypes.REPL_TY_VOID / INT / FLOAT / STR
|
||||
RetBits: int
|
||||
@@ -529,11 +526,11 @@ def _read_line(h: win32base.HANDLE, buf: bytes, cap: int) -> int:
|
||||
eof: int = 0
|
||||
while total < cap - 1:
|
||||
bytes_read = 0
|
||||
ok = w32file.ReadFile(h, buf + total, 1, t.CPtr(c.Addr(bytes_read)), None)
|
||||
ok = w32file.ReadFile(h, buf + total, 1, &bytes_read, None)
|
||||
if ok == 0 or bytes_read == 0:
|
||||
eof = 1
|
||||
break
|
||||
# 注意:不能用 c.Deref(buf + total)——其 IR 生成 i32 load(读 4 字节),
|
||||
# 注意:不能用 &(buf + total)——其 IR 生成 i32 load(读 4 字节),
|
||||
# 比较 '\n'/'\r' 永不命中;字节索引 buf[total] 才是 i8 load
|
||||
ch: char = buf[total]
|
||||
if ch == 10: # '\n':行结束
|
||||
@@ -933,8 +930,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*,
|
||||
GenApi.SetTempDir(vpi_dir)
|
||||
GenApi.set_current_file_type(vpi_dir)
|
||||
tmp_mod: llvmlite.LLVMModule* = llvmlite.new_module(_perm_pool, _REPL_INC_MOD_NAME)
|
||||
tr_inc: rawptr[HandlesTranslator.Translator] = _perm_pool.alloc(
|
||||
HandlesTranslator.Translator.__sizeof__())
|
||||
tr_inc: rawptr[HandlesTranslator.Translator] = _perm_pool.alloc(HandlesTranslator.Translator.__sizeof__())
|
||||
if tmp_mod is None or tr_inc is None:
|
||||
return 1
|
||||
tr_inc.__before_init__()
|
||||
@@ -978,8 +974,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*,
|
||||
"仍可按需注册)\n", GenApi.get_struct_count())
|
||||
stdio.fflush(None)
|
||||
return 0
|
||||
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](
|
||||
uint64(sr.Entries) + uint64(i) * uint64(es))
|
||||
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(sr.Entries) + uint64(i) * uint64(es))
|
||||
if ent is None or ent.Sha1 is None:
|
||||
st[i] = sizet(1)
|
||||
ReplIncClsFail += 1
|
||||
@@ -1171,8 +1166,7 @@ def ReplInitSession() -> int:
|
||||
ReplScratch.Bits = 0
|
||||
# ⑤' 会话函数表(M3;PermPool,宿主写、Gen 只读)——条目数组清零
|
||||
func_entry_size: sizet = GenTypes.ReplFuncEntry.__sizeof__()
|
||||
ReplFuncTable: rawptr[GenTypes.ReplFuncEntry] = _perm_pool.alloc(
|
||||
func_entry_size * GenTypes.REPL_FUNC_CAP)
|
||||
ReplFuncTable: rawptr[GenTypes.ReplFuncEntry] = _perm_pool.alloc(func_entry_size * GenTypes.REPL_FUNC_CAP)
|
||||
if ReplFuncTable is None:
|
||||
return 1
|
||||
string.memset(ReplFuncTable, 0, func_entry_size * GenTypes.REPL_FUNC_CAP)
|
||||
@@ -1296,8 +1290,7 @@ def _repl_gen_includes_vpi(mb: memhub.MemBuddy*,
|
||||
dl: sizet = string.strlen(vpi_dir)
|
||||
n: int
|
||||
for n in range(sr.Count):
|
||||
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](
|
||||
uint64(sr.Entries) + uint64(n) * es)
|
||||
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(sr.Entries) + uint64(n) * es)
|
||||
if ent is None or ent.Sha1 is None or ent.Path is None:
|
||||
ReplIncVpiFail += 1
|
||||
continue
|
||||
@@ -1871,8 +1864,7 @@ def _repl_func_entry_find(name: str) -> rawptr[GenTypes.ReplFuncEntry]:
|
||||
es: sizet = GenTypes.ReplFuncEntry.__sizeof__()
|
||||
i: int
|
||||
for i in range(ReplCtxObj.FuncCount):
|
||||
e: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry](
|
||||
uint64(ReplCtxObj.FuncTable) + uint64(i) * uint64(es))
|
||||
e: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry](uint64(ReplCtxObj.FuncTable) + uint64(i) * uint64(es))
|
||||
if e.Name is not None and string.strcmp(e.Name, name) == 0:
|
||||
return e
|
||||
return None
|
||||
@@ -2045,8 +2037,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int) -> int:
|
||||
return 1
|
||||
j: int = ReplCtxObj.FuncCount
|
||||
es: sizet = GenTypes.ReplFuncEntry.__sizeof__()
|
||||
ent = rawptr[GenTypes.ReplFuncEntry](
|
||||
uint64(ReplCtxObj.FuncTable) + uint64(j) * uint64(es))
|
||||
ent = rawptr[GenTypes.ReplFuncEntry](uint64(ReplCtxObj.FuncTable) + uint64(j) * uint64(es))
|
||||
nm_c: str = _repl_perm_dup(nm)
|
||||
nm_s: str = _repl_perm_dup(nm)
|
||||
tags_b: bytes = _perm_pool.alloc(GenTypes.REPL_FUNC_PARAM_MAX)
|
||||
@@ -2072,8 +2063,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int) -> int:
|
||||
# 重定义(同签名):只换地址与段号,槽偏移不变
|
||||
ent.FragNo = frag_no
|
||||
# 写 ctx 槽(低 8 字节=地址,高 8 字节保留 0)
|
||||
sv: rawptr[ReplFuncSlotView] = rawptr[ReplFuncSlotView](
|
||||
uint64(ReplCtxBuf) + uint64(ent.SlotOff))
|
||||
sv: rawptr[ReplFuncSlotView] = rawptr[ReplFuncSlotView](uint64(ReplCtxBuf) + uint64(ent.SlotOff))
|
||||
sv.Addr = addr
|
||||
sv.Reserved = None
|
||||
stdio.printf("会话函数 %s: 导出符号 %s → ctx 槽 +%d(定义片段 %d,签名 %s)\n",
|
||||
@@ -2817,7 +2807,7 @@ def run(mb: memhub.MemBuddy*) -> int:
|
||||
|
||||
stdio.printf("TransPyV REPL (M2/M3/M4) - 会话变量 + 会话函数(跨片段)+ ctx 回传结果;\n")
|
||||
stdio.printf(" 支持表达式(1+2)、定义(x = 1 / x: int = 5)、引用(x + 1)、\n")
|
||||
stdio.printf(" 增强赋值(x += 2)、取址(p = c.Addr(x))等;空行跳过,Ctrl+Z 或 EOF 退出\n")
|
||||
stdio.printf(" 增强赋值(x += 2)、取址(p = &x)等;空行跳过,Ctrl+Z 或 EOF 退出\n")
|
||||
stdio.printf(" 多行块:行尾 ':' 进入续行(提示符 ...),空行结束并整块执行一次\n")
|
||||
stdio.printf(" 跨片段函数:块里顶格的 def 会被提升为片段模块的 export def(裸名导出),\n")
|
||||
stdio.printf(" 后续片段可直接调用(如 def f(x: int) -> int: 换行 +4 空格 return x + 1);\n")
|
||||
|
||||
Reference in new issue
Block a user