refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件)

This commit is contained in:
TermiNexus committed 2026-10-05 07:14:14 +08:00
1 parent 4a685d478f
commit f2ef1bb240
67 files changed
+1140 -3775

No files matched your search

+16 -47
View File
@@ -153,8 +153,7 @@ def _pyi_cdefine_found() -> int:
# 将 text 追加到 buf 的 pos 位置,返回新的 pos。
# 自动处理缓冲区溢出(截断)。
# ============================================================
def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet,
text: str) -> sizet:
def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, text: str) -> sizet:
"""追加 text 到 buf 的 pos 位置,返回新的 pos"""
if buf is None or text is None or pos >= buf_size: return pos
tlen: sizet = string.strlen(text)
@@ -170,8 +169,7 @@ def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet,
#
# 追加 level*4 个空格到 buf 的 pos 位置。
# ============================================================
def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet,
level: int) -> sizet:
def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, level: int) -> sizet:
"""追加 level*4 个空格到 buf,返回新的 pos"""
i: int = 0
while i < level:
@@ -191,8 +189,7 @@ def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet,
# 表外运算符 fail-fast:静默写错运算符会生成错误的类型/长度文本,
# 让下游按错误结果解析(与 TPC 落到未知节点 fail-fast 同语义)。
# ============================================================
def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet,
op: int, node: ast.AST*) -> sizet:
def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, op: int, node: ast.AST*) -> sizet:
"""按运算符种类输出 " OP " 文本,表外运算符 fail-fast"""
if op == ast.OpKind.BitOr: return _PyiEmit(buf, buf_size, pos, " | ")
if op == ast.OpKind.Add: return _PyiEmit(buf, buf_size, pos, " + ")
@@ -216,9 +213,7 @@ def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet,
# 差异项:TPV 额外支持裸 Tuple(TPC 仅在 Subscript.slice 位置接受 Tuple);
# TPC 额外有 Index 分支(vast 遗留类,解析器不产出该节点)。
# ============================================================
def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
annot: ast.AST*,
depth: int = 0) -> sizet:
def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: int = 0) -> sizet:
"""递归生成类型注解字符串,返回新的 pos"""
# 递归深度守卫:AST 损坏成自引用环(Attribute.value/Subscript.slice/
# BinOp.left 等回指祖先)时无限递归直至栈耗尽(Phase1 vpi 生成最先
@@ -404,9 +399,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
# 用默认值填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。
# 支持: Constant(int/str/bool/None), Name(CDefine 常量), UnaryOp。
# ============================================================
def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
node: ast.AST*,
depth: int = 0) -> sizet:
def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, node: ast.AST*, depth: int = 0) -> sizet:
"""生成默认值表达式文本到 buf,返回新的 pos"""
# 递归深度守卫:AST 损坏成自引用环时 fail-fast 终止(同 _PyiTypeStr)
if depth > 64:
@@ -462,8 +455,7 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
# (既有 tuple → struct 通路保留)。vpi 里仍带该装饰器意味着存根过旧,
# fail-fast 提示重新生成,不静默忽略。返回 0 = 装饰器列表里没有 CReturn。
# ============================================================
def _PyiRejectCReturnDecorator(node: ast.AST*,
decorators: list[ast.AST*]*) -> int:
def _PyiRejectCReturnDecorator(node: ast.AST*, decorators: list[ast.AST*]*) -> int:
"""装饰器列表里出现 @c.CReturn 即 fatal_error(返回 0 = 无该装饰器)"""
if decorators is None: return 0
dn: sizet = len(decorators)
@@ -490,9 +482,7 @@ def _PyiRejectCReturnDecorator(node: ast.AST*,
#
# 格式: def name(param: Type, ...) -> ReturnType: pass
# ============================================================
def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
fn: ast.FunctionDef*,
indent_level: int, class_name: str) -> sizet:
def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, fn: ast.FunctionDef*, indent_level: int, class_name: str) -> sizet:
"""生成函数签名到 buf,返回新的 pos"""
# 装饰器
if fn.decorator_list is not None:
@@ -584,8 +574,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
# field: Type
# def method(self: Name, ...) -> RetType: pass
# ============================================================
def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
cls: ast.ClassDef*, indent_level: int) -> sizet:
def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, indent_level: int) -> sizet:
"""生成类定义到 buf,返回新的 pos"""
# 装饰器
if cls.decorator_list is not None:
@@ -720,9 +709,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
# Args: mb 内存池(保留以符合调用约定,实际未使用);tree AST Module 根节点;rel_path 源文件路径(仅用于报错归因的"当前文件",应传绝对路径以便 fatal_error 读取源码行);buf 输出缓冲区;buf_size 缓冲区大小
# Returns: 写入的字节数(0 表示失败)
# ============================================================
def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
rel_path: str, buf: bytes,
buf_size: sizet) -> sizet:
def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf: bytes, buf_size: sizet) -> sizet:
"""从 AST 生成 .vpi 存根文件内容到 buf"""
if tree is None or buf is None or buf_size == 0: return 0
@@ -822,9 +809,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
# fail-fast:别名列表为空 ⇒ 写出 `import ` 这种残缺行,import 名字
# 全丢,包重导出注册随之失效(与下面逐个别名为空的检查互补)。
if imp2.names is None or len(imp2.names) == 0:
GenApi.fatal_error(stmt,
"vpi 生成:import 语句别名列表为空(应为 ≥1 个别名)——AST 构造/解析异常",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:import 语句别名列表为空(应为 ≥1 个别名)——AST 构造/解析异常", "NameError")
if imp2.names is not None:
imp2_names: list[ast.AST*]* = imp2.names
an2: sizet = len(imp2_names)
@@ -842,15 +827,9 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
# 两种成因分开报,便于一次定位:节点指针为空 = Alias 构造失败;
# 节点在而 name 为空 = _copy_str/__init__ 未生效。
if al2 is None:
GenApi.fatal_error(stmt,
"vpi 生成:import 别名**节点指针为空**(Alias(...) 构造未产出对象:"
"pool.alloc 失败或 __init__ 未执行)——import 名字丢失会破坏包重导出注册",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:import 别名**节点指针为空**(Alias(...) 构造未产出对象:" "pool.alloc 失败或 __init__ 未执行)——import 名字丢失会破坏包重导出注册", "NameError")
if al2.name is None or al2.name[0] == '\0':
GenApi.fatal_error(stmt,
"vpi 生成:import 别名节点存在但 **name 为空**(_copy_str 返回 None / "
"__init__ 未赋值 name)——import 名字丢失会破坏包重导出注册",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:import 别名节点存在但 **name 为空**(_copy_str 返回 None / " "__init__ 未赋值 name)——import 名字丢失会破坏包重导出注册", "NameError")
pos = _PyiEmit(buf, buf_size, pos, al2.name)
if al2.asname is not None and string.strlen(al2.asname) > 0:
pos = _PyiEmit(buf, buf_size, pos, " as ")
@@ -872,10 +851,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
# 列表为空或名字为空都说明 AST 坏;静默写出 `from X import ` 会让
# 包重导出注册失效(star 也用于 re-export 判断)。
if ifr.names is None or len(ifr.names) == 0:
GenApi.fatal_error(stmt,
"vpi 生成:from-import 语句别名列表为空(应为 ≥1 个别名,含 '*')"
"——AST 构造/解析异常",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:from-import 语句别名列表为空(应为 ≥1 个别名,含 '*')" "——AST 构造/解析异常", "NameError")
if ifr.names is not None:
ifr_names: list[ast.AST*]* = ifr.names
an3: sizet = len(ifr_names)
@@ -885,15 +861,9 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3))
# fail-fast:同 Import 分支(两种成因分开报,一次定位)。
if al3 is None:
GenApi.fatal_error(stmt,
"vpi 生成:from-import 别名**节点指针为空**(Alias(...) 构造未产出对象:"
"pool.alloc 失败或 __init__ 未执行)——包重导出注册会因此失效",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:from-import 别名**节点指针为空**(Alias(...) 构造未产出对象:" "pool.alloc 失败或 __init__ 未执行)——包重导出注册会因此失效", "NameError")
if al3.name is None or al3.name[0] == '\0':
GenApi.fatal_error(stmt,
"vpi 生成:from-import 别名节点存在但 **name 为空**(_copy_str 返回 None / "
"__init__ 未赋值 name)——包重导出注册会因此失效",
"NameError")
GenApi.fatal_error(stmt, "vpi 生成:from-import 别名节点存在但 **name 为空**(_copy_str 返回 None / " "__init__ 未赋值 name)——包重导出注册会因此失效", "NameError")
pos = _PyiEmit(buf, buf_size, pos, al3.name)
if al3.asname is not None and string.strlen(al3.asname) > 0:
pos = _PyiEmit(buf, buf_size, pos, " as ")
@@ -958,8 +928,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
# 字符串 CDefine(pyzlib.ZLIB_VERSION = "1.3.2" 等)必须输出值,让 stub 自包含(读回端按目标名判定会回退源文件)
sbuf_c: bytes = mb.alloc(string.strlen(cv.str_val) + 6)
if sbuf_c is not None:
viperlib.snprintf(sbuf_c, string.strlen(cv.str_val) + 6,
" = \"%s\"", cv.str_val)
viperlib.snprintf(sbuf_c, string.strlen(cv.str_val) + 6, " = \"%s\"", cv.str_val)
pos = _PyiEmit(buf, buf_size, pos, sbuf_c)
elif cv.const_kind == ast.CONST_NONE: pos = _PyiEmit(buf, buf_size, pos, " = None")
elif aa.value is not None and aa.value.kind() == ast.ASTKind.UnaryOp:
+98 -332
View File
@@ -169,8 +169,7 @@ def _vpi_idx_slot(idx_base: bytes, si: sizet) -> sizet*:
return (sizet*)(uint64(idx_base) + uint64(si) * 8)
def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes,
cap: int, key: bytes) -> int:
def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key: bytes) -> int:
"""在索引中探测 key,返回命中槽下标(>=0);未命中/索引不可用返回 -1
命中判据是"当前键相等"(strcmp),不能只比哈希。
@@ -235,8 +234,7 @@ def _vpi_rebuild_ret_idx(new_cap: int) -> int:
fail: int = 0
ri: int
for ri in range(_g_vpi_ret_count):
if _vpi_idx_insert(new_idx, new_cap, ri,
_g_vpi_ret_keys + ri * VPI_KEY_LEN) != 0:
if _vpi_idx_insert(new_idx, new_cap, ri, _g_vpi_ret_keys + ri * VPI_KEY_LEN) != 0:
fail = 1
break
if fail != 0:
@@ -268,8 +266,7 @@ def _vpi_rebuild_param_idx(new_cap: int) -> int:
fail: int = 0
ri: int
for ri in range(_g_vpi_param_count):
if _vpi_idx_insert(new_idx, new_cap, ri,
_g_vpi_param_keys + ri * VPI_PARAM_KEY_LEN) != 0:
if _vpi_idx_insert(new_idx, new_cap, ri, _g_vpi_param_keys + ri * VPI_PARAM_KEY_LEN) != 0:
fail = 1
break
if fail != 0:
@@ -389,8 +386,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
mname_buf[mname_len] = '\0'
# 无注解的特殊方法(构造/析构)跳过:它们有专门调用路径
skip_def: int = 0
if arrow_pos >= le and (
string.strcmp(mname_buf, "__init__") == 0 or string.strcmp(mname_buf, "__new__") == 0 or string.strcmp(mname_buf, "__before_init__") == 0 or string.strcmp(mname_buf, "__after_init__") == 0):
if arrow_pos >= le and (string.strcmp(mname_buf, "__init__") == 0 or string.strcmp(mname_buf, "__new__") == 0 or string.strcmp(mname_buf, "__before_init__") == 0 or string.strcmp(mname_buf, "__after_init__") == 0):
skip_def = 1
if skip_def == 0:
key_buf: bytes = stdlib.malloc(key_len + 1)
@@ -404,8 +400,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
# 重复(命中即"首个注册优先"= 原线性扫描首个同名);
# 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。
if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
if _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN,
_g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) >= 0:
if _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) >= 0:
dup_key = 1
else:
# 快速路径:重复键必首字节相同(strcmp 判等蕴含首字节
@@ -420,14 +415,12 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
if dup_key == 0 and _g_vpi_ret_count >= _g_vpi_ret_cap: grow_ok = _grow_vpi_ret_cache()
if dup_key == 0 and grow_ok != 0:
string.strcpy(_g_vpi_ret_keys + _g_vpi_ret_count * VPI_KEY_LEN, key_buf)
string.strncpy(_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN,
ret_src, rtype_len)
string.strncpy(_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN, ret_src, rtype_len)
(_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN)[rtype_len] = '\0'
_g_vpi_ret_count += 1
# 同步索引:仅当插入前可信(Built==Count-1,含扩容
# 重建后)且插入成功;否则标记不可信(查找回退扫描)。
if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap,
_g_vpi_ret_count - 1, key_buf) == 0:
if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap, _g_vpi_ret_count - 1, key_buf) == 0:
_g_vpi_ret_idx_built = _g_vpi_ret_count
else: _g_vpi_ret_idx_built = -1
stdlib.free(key_buf)
@@ -598,8 +591,7 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
# 重复(命中即"首个注册优先"= 原线性扫描首个同名);
# 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。
if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
if _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN,
_g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) >= 0:
if _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) >= 0:
dup_key = 1
else:
# 快速路径:重复键必首字节相同(strcmp 判等蕴含首字节
@@ -614,14 +606,12 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
if dup_key == 0 and _g_vpi_param_count >= _g_vpi_param_cap: grow_ok = _grow_vpi_param_cache()
if dup_key == 0 and grow_ok != 0:
string.strcpy(_g_vpi_param_keys + _g_vpi_param_count * VPI_PARAM_KEY_LEN, key_buf)
string.strncpy(_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN,
plist, plist_pos)
string.strncpy(_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN, plist, plist_pos)
(_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN)[plist_pos] = '\0'
_g_vpi_param_count += 1
# 同步索引:仅当插入前可信(Built==Count-1,含扩容
# 重建后)且插入成功;否则标记不可信(查找回退扫描)。
if _g_vpi_param_idx_built == _g_vpi_param_count - 1 and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap,
_g_vpi_param_count - 1, key_buf) == 0:
if _g_vpi_param_idx_built == _g_vpi_param_count - 1 and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap, _g_vpi_param_count - 1, key_buf) == 0:
_g_vpi_param_idx_built = _g_vpi_param_count
else: _g_vpi_param_idx_built = -1
stdlib.free(key_buf)
@@ -676,8 +666,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) ->
# 索引随扩容整体重建且覆盖全表)⇒ 无需再线性扫描;索引不可信 → 回退线性扫描。
hit_p: int = -1
if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
hit_p = _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN,
_g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf)
hit_p = _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf)
else:
# 回退原线性扫描:strcmp 判等蕴含首字节相等;键首字节 = src_sha1[0],缓存含
# 多模块条目,首字节不同者必不相等,直接跳过其 strcmp(仅做否定判定,不改命中)。
@@ -699,13 +688,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) ->
# 调用点 declare 停在调用点实参宽度(如 elem_size 字面量 i32 把定义侧 sizet(i64) 固化窄)。本函数按 {sha1}.{base}[T].{method} 形态定位模板条目,
# 把段内独立的类型形参 token 用特化实参(cls_name 的 [...] 内容)替换后再解析;未命中/多参模板(键段含空格被截断)返回 None,不做兜底推断。
# ============================================================
def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
src_sha1: str,
cls_name: str,
method_name: str,
seg_idx: int,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""特化类 X[arg] 的参数注解段解析(模板 X[T] 注解 + T→arg 替换);未命中 None"""
if pool is None or src_sha1 is None or cls_name is None or method_name is None or _g_vpi_param_keys is None: return None
lbkt_t: str = string.strchr(cls_name, 91) # '[' = 91
@@ -783,14 +766,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
# vpi tree 参数列表被覆盖损坏时(param_count 偏小,尾部默认参数丢失),用 _cache_vpi_param_annots_text 的文本缓存补全:参数位置 p 对应缓存段 p(含首参空串占位)。
# 补全后 declare 参数数与 define 一致,调用点默认参数填充才能生效,避免被调函数读栈垃圾。
# ============================================================
def _repair_declare_params_from_text(pool: memhub.MemBuddy*,
func: mlirlite.Function*,
src_sha1: str,
cls_name: str,
method_name: str,
param_count: int,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> int:
def _repair_declare_params_from_text(pool: memhub.MemBuddy*, func: mlirlite.Function*, src_sha1: str, cls_name: str, method_name: str, param_count: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> int:
"""用 vpi 文本缓存的参数注解补全 declare 参数;返回补全后参数数"""
if func is None or src_sha1 is None or method_name is None: return param_count
prm_annots: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name)
@@ -817,8 +793,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy*,
if seg_buf_r is not None:
string.strncpy(seg_buf_r, prm_annots + seg_start2, seg_len2)
seg_buf_r[seg_len2] = '\0'
rt: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(
pool, seg_buf_r, i32_ty, i8_ptr_ty)
rt: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(pool, seg_buf_r, i32_ty, i8_ptr_ty)
if rt is not None: param_ty_r = rt
stdlib.free(seg_buf_r)
mlirlite.add_param(pool, func, param_ty_r, "arg")
@@ -834,13 +809,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy*,
# 参数类型错会导致调用侧 trunc 传参、callee 按 i64 读栈残留高位 → can=巨值读未写槽位崩溃(SlotsBugTest 根因)。
# 从 @-joined 注解串取第 seg_idx 段(0=self 空段),用 _resolve_vpi_ret_annot_str 解析;空段/未命中返回 None(走 AST 兜底)。
# ============================================================
def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*,
src_sha1: str,
cls_name: str,
method_name: str,
seg_idx: int,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""按段索引解析 vpi 参数注解段为 LLVMType,空段/失败返回 None"""
if pool is None or src_sha1 is None or method_name is None: return None
prm_annots_p: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name)
@@ -859,8 +828,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*,
if seg_buf_p is None: return None
string.strncpy(seg_buf_p, prm_annots_p + seg_start_p, seg_len_p)
seg_buf_p[seg_len_p] = '\0'
seg_ty_p: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(
pool, seg_buf_p, i32_ty, i8_ptr_ty)
seg_ty_p: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(pool, seg_buf_p, i32_ty, i8_ptr_ty)
stdlib.free(seg_buf_p)
return seg_ty_p
@@ -945,8 +913,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
# ============================================================
# _vpi_param_annot_seg_is - 形参注解段等值判定(供"str/bytes 不是通用指针通配"规则)
# ============================================================
def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str,
seg_idx: int, want: str) -> int:
def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str, seg_idx: int, want: str) -> int:
"""vpi 定义侧第 seg_idx 个形参注解段是否**恰等于** want(1=是 / 0=否)
注解串格式(见 _lookup_vpi_param_annots):以 '@' 分隔的段序列,段 0 是
@@ -1105,8 +1072,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
# 匹配兜底仍保留,其键形态不同、不依赖精确键命中);索引不可信 → 回退线性扫描。
hit_r: int = -1
if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
hit_r = _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN,
_g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf)
hit_r = _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf)
else:
# 回退原线性扫描:strcmp 判等蕴含首字节相等(键首字节 = src_sha1[0]),跳过首字节不同者。
key_first: int = key_buf[0]
@@ -1143,16 +1109,14 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
if string.strncmp(gk, src_sha1, sha1_len) == 0 and gk[sha1_len] == '.' and string.strncmp(gk + sha1_len + 1, base_v, base_len_v) == 0 and gk[sha1_len + 1 + base_len_v] == '[':
gklb: str = string.strchr(gk + sha1_len + 1 + base_len_v, ']')
if gklb is not None:
tparam_len_v: sizet = sizet(
uint64(gklb) - uint64(gk + sha1_len + 1 + base_len_v) - 1)
tparam_len_v: sizet = sizet(uint64(gklb) - uint64(gk + sha1_len + 1 + base_len_v) - 1)
meth_start_v: str = gklb + 2 # 跳过 ']' 和 '.'
if tparam_len_v > 0 and string.strcmp(meth_start_v, method_name) == 0:
tparam_v: str = stdlib.malloc(tparam_len_v + 1)
if tparam_v is not None:
string.strncpy(tparam_v, gk + sha1_len + 1 + base_len_v + 1, tparam_len_v)
tparam_v[tparam_len_v] = '\0'
new_annot_v: str = _subst_template_arg(
_g_vpi_ret_strs + gi * VPI_RET_LEN, tparam_v, param_v)
new_annot_v: str = _subst_template_arg(_g_vpi_ret_strs + gi * VPI_RET_LEN, tparam_v, param_v)
stdlib.free(tparam_v)
stdlib.free(base_v)
stdlib.free(param_v)
@@ -1169,8 +1133,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
#
# 纯字符串解析,不构造 AST 节点。
# ============================================================
def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
seg: str) -> mlirlite.LLVMType*:
def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, seg: str) -> mlirlite.LLVMType*:
"""解析单个类型段为 LLVMType,无法识别返回 None"""
if seg is None or pool is None: return None
# 【指针实参唯一规范形 `T*`(用户定口径,2026-09-30)】`rawptr[T]` ≡
@@ -1266,8 +1229,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
if inner_buf_cp is not None:
string.strncpy(inner_buf_cp, seg + cptr_sub_pfx, inner_len_cp)
inner_buf_cp[inner_len_cp] = '\0'
inner_ty_cp: mlirlite.LLVMType* = _resolve_single_vpi_type_str(
pool, inner_buf_cp)
inner_ty_cp: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, inner_buf_cp)
stdlib.free(inner_buf_cp)
if inner_ty_cp is not None: return mlirlite.Ptr(pool, inner_ty_cp)
return None
@@ -1318,10 +1280,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
#
# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; "char" 等 → map_t_type 映射; "X*" → Ptr(Struct X); "t.CPtr" → i8*; "memhub.MemBuddy*" → Ptr(Struct MemBuddy)。
# ============================================================
def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
ret_annot: str,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, ret_annot: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""直接解析 vpi 返回注解字符串为 LLVMType(不构造 AST 节点)"""
if ret_annot is None or pool is None: return None
@@ -1656,8 +1615,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None:
new_cap: int = old_cap * 2
nb: bytes = stdlib.realloc(_g_vpi_typedef_visited, new_cap * 17)
if nb is None:
stdio.printf("[VPI] 防环访问表扩容失败 cap=%d(丢标记引发重解析爆炸,终止)\n",
old_cap)
stdio.printf("[VPI] 防环访问表扩容失败 cap=%d(丢标记引发重解析爆炸,终止)\n", old_cap)
stdio.fflush(None)
stdlib.exit(1)
_g_vpi_typedef_visited = nb
@@ -1667,10 +1625,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None:
_g_vpi_typedef_visited_count += 1
def _vpi_register_typedef_closure(pool: memhub.MemBuddy*,
import_mods: str,
temp_dir: str,
depth: int) -> int:
def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, import_mods: str, temp_dir: str, depth: int) -> int:
"""递归注册 import 闭包模块的 CTypedef/CDefine,返回 0 恒(副作用注册)
仅注册 AnnAssign 的 t.CTypedef/t.CDefine,不注入函数 declare(避免
@@ -1825,10 +1780,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy*,
# Args: pool 内存池;mod 当前 LLVM 模块;vpi_path .vpi 文件路径;trans 翻译器对象
# Returns: 1=成功,0=失败
# ============================================================
def ParseVpiIntoModule(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
vpi_path: str,
trans: HT.Translator*) -> int:
def ParseVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, vpi_path: str, trans: HT.Translator*) -> int:
"""解析 .vpi 文件,将函数声明注入到当前模块
解析 stub 期间临时将错误归因切换到被读 stub 文件(.vpi):
@@ -1843,10 +1795,7 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy*,
return ret
def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
vpi_path: str,
trans: HT.Translator*) -> int:
def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, vpi_path: str, trans: HT.Translator*) -> int:
"""解析 .vpi 文件,将函数声明注入到当前模块(ParseVpiIntoModule 实际实现)"""
if pool is None or mod is None or vpi_path is None or trans is None: return 0
@@ -1985,8 +1934,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
sifr_mod_q = qbuf_r
if sifr_mod is not None:
if stub_ctx is not None:
stub_ctx.ImportedModules = StubMergerStore.AppendImportedModule(
pool, stub_ctx.ImportedModules, sifr_mod_q)
stub_ctx.ImportedModules = StubMergerStore.AppendImportedModule(pool, stub_ctx.ImportedModules, sifr_mod_q)
# 方案A:包 __init__.vpi 的重导出类以包 sha1 注册别名 entry
# (ast.Attribute 定义在 ast.exprs 但归属 ast 包;查找端按包
# sha1 匹配,注册端按定义文件 sha1 → name+sha1 错位 fail-fast。
@@ -2032,13 +1980,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# Expression 定义在 ast.stmts,真因是子模块 sha1 查找/注入失败)。
# 此处直接给出包名与子模块名(含补前缀后的精确名)便于定位。
if is_pkg_init_rt != 0 and sub_sha1_rt is None and sifr_mod is not None and sifr_mod[0] != '\0':
GenApi.fatal_error(
sifr,
f"包 stub 的 from-import 子模块 sha1 查找失败:"
f"包={rel_path_rt if rel_path_rt is not None else '?'},"
f"子模块='{sifr_mod}'(补前缀后='{sifr_mod_q}');"
f"该子模块的类无法注册,引用它们的注解会在后续解析时落空",
"NameError")
GenApi.fatal_error(sifr, f"包 stub 的 from-import 子模块 sha1 查找失败:" f"包={rel_path_rt if rel_path_rt is not None else '?'}," f"子模块='{sifr_mod}'(补前缀后='{sifr_mod_q}');" f"该子模块的类无法注册,引用它们的注解会在后续解析时落空", "NameError")
if sifr.names is not None:
sifr_nn: sizet = len(sifr.names)
sifri: sizet
@@ -2056,15 +1998,12 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# 在此跳过 ⇒ stub 上下文里 star 回退恒失效(同一份约定
# 的两处 loop 又一处不一致)。
if stub_ctx is not None:
stub_ctx.FromImports = StubMergerStore.AppendFromImport(
pool, stub_ctx.FromImports, slocal, sifr_mod_q, sorig)
stub_ctx.FromImports = StubMergerStore.AppendFromImport(pool, stub_ctx.FromImports, slocal, sifr_mod_q, sorig)
# 重导出类以包 sha1 注册(asname 时按别名注册);star 无
# 具体类名,不参与重导出(仅记账,见上)。
if string.strcmp(sial.name, "*") != 0:
if is_pkg_init_rt != 0 and sub_sha1_rt is not None:
_inject_reexport_class_declare(
pool, mod, sial.name, slocal,
sub_sha1_rt, src_sha1, trans)
_inject_reexport_class_declare(pool, mod, sial.name, slocal, sub_sha1_rt, src_sha1, trans)
# 用 stub 自己的 imports 替代当前模块的(stub 注解解析上下文正确性)
if stub_ctx is not None:
@@ -2094,8 +2033,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
if ch_src == '/' or ch_src == '\\': src_mod_buf[sri_src] = '.'
else: src_mod_buf[sri_src] = ch_src
src_mod_buf[sr_len_src] = '\0'
imported_modules = StubMergerStore.AppendImportedModule(
pool, imported_modules, src_mod_buf)
imported_modules = StubMergerStore.AppendImportedModule(pool, imported_modules, src_mod_buf)
stdlib.free(src_mod_buf)
# 递归预注册 stub import 闭包的 CTypedef/CDefine:注解(如 codepage:
@@ -2119,8 +2057,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# 虚表恢复"段;批处理该标志恒 0,本块不执行。
# ============================================================
if ReplStubLayoutMode != 0:
_repl_stub_collect_module(pool, mod, ch, n, trans, src_sha1,
stub_imported_modules, stub_from_imports)
_repl_stub_collect_module(pool, mod, ch, n, trans, src_sha1, stub_imported_modules, stub_from_imports)
# ============================================================
# 第一遍 A:先注册**所有** ClassDef(字段 + 结构体),不处理方法。
@@ -2139,8 +2076,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# T 无法确定;特化方法 define 已在 Phase1 生成,无需 stub 模板 declare。
tp_stub0: list[str]* = class_cd0.type_params
if tp_stub0 is not None and len(tp_stub0) > 0: continue
_inject_class_struct_declare(pool, mod, class_cd0, cls_name_v0, trans,
src_sha1, imported_modules, from_imports)
_inject_class_struct_declare(pool, mod, class_cd0, cls_name_v0, trans, src_sha1, imported_modules, from_imports)
# App 预注册(Phase A-pre,_pre_allow_dep_inject)**跳过方法/函数 declare 注入**:
# 预注册的唯一目的是注册 struct/enum/union(第一遍 A)与包重导出别名(上方
@@ -2180,9 +2116,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
if m_fd1 is None or m_fd1.name is None: continue
# App 预注册跳过方法 declare(原因见上方 pre_skip_fn_declares 注释)。
if pre_skip_fn_declares == 0:
_inject_method_declare(pool, mod, m_fd1, cls_name_v1, trans,
src_sha1, imported_modules, from_imports,
i32_ty, i8_ptr_ty, funcs_ptr, max_funcs)
_inject_method_declare(pool, mod, m_fd1, cls_name_v1, trans, src_sha1, imported_modules, from_imports, i32_ty, i8_ptr_ty, funcs_ptr, max_funcs)
i: sizet
for i in range(n):
@@ -2199,10 +2133,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# 打断多遍收敛(现场 Translator.vpi 的 InjectTracebackInstallCtor
# 形参 rawptr[Translator])。
if pre_skip_fn_declares != 0: continue
_inject_function_declare(pool, mod, fd, trans, src_sha1,
imported_modules, from_imports,
i32_ty, i8_ptr_ty,
funcs_ptr, max_funcs)
_inject_function_declare(pool, mod, fd, trans, src_sha1, imported_modules, from_imports, i32_ty, i8_ptr_ty, funcs_ptr, max_funcs)
continue
# AnnAssign with t.CTypedef → 注册 CTypedef;
@@ -2243,9 +2174,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
cdef_val: int64 = GenApi.extract_cdefine_int_value(aa.value)
GenApi.register_cdefine_constant(pool, cdef_tgt.id, cdef_val)
else:
_inject_global_variable_declare(pool, mod, aa, trans,
stub_imported_modules, stub_from_imports,
i32_ty, i8_ptr_ty, src_sha1)
_inject_global_variable_declare(pool, mod, aa, trans, stub_imported_modules, stub_from_imports, i32_ty, i8_ptr_ty, src_sha1)
continue
# ClassDef → 已在第一遍统一注册(含字段 + 方法 declare),此处跳过
@@ -2291,10 +2220,7 @@ def ResetVpiInjectVisited() -> None:
_vpi_inj_depth = 0
def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
dep_sha1: str,
trans: HT.Translator*) -> int:
def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, dep_sha1: str, trans: HT.Translator*) -> int:
"""按需注入 dep_sha1 对应的 .vpi 到当前模块(防重入),1=就绪 / 0=失败"""
global _vpi_inj_sha1s, _vpi_inj_count, _vpi_inj_depth
if pool is None or mod is None or dep_sha1 is None or trans is None: return 0
@@ -2340,8 +2266,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*,
# 错误却表现为远处注解解析失败。
_vpi_inj_count -= 1
if my_idx_i != _vpi_inj_count:
string.strcpy(_vpi_inj_sha1s + sizet(my_idx_i) * 17,
_vpi_inj_sha1s + sizet(_vpi_inj_count) * 17)
string.strcpy(_vpi_inj_sha1s + sizet(my_idx_i) * 17, _vpi_inj_sha1s + sizet(_vpi_inj_count) * 17)
return 0
return 1
@@ -2356,13 +2281,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*,
#
# Args: src_name 子模块中的原类名;local_name 包命名空间中的名字(或 as 别名);sub_sha1 子模块(定义文件)sha1;pkg_sha1 当前包 __init__ 的 sha1;trans 翻译器对象(源 entry 缺失时按需注入子模块 vpi 需要)
# ============================================================
def _inject_reexport_class_declare(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
src_name: str,
local_name: str,
sub_sha1: str,
pkg_sha1: str,
trans: HT.Translator*) -> int:
def _inject_reexport_class_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, src_name: str, local_name: str, sub_sha1: str, pkg_sha1: str, trans: HT.Translator*) -> int:
"""把包子模块重导出的类以包 sha1 注册别名 entry(方案A:ast.Attribute 归属 ast 包)"""
if pool is None or mod is None or src_name is None or local_name is None: return 0
if sub_sha1 is None or sub_sha1[0] == '\0' or pkg_sha1 is None or pkg_sha1[0] == '\0': return 0
@@ -2462,15 +2381,7 @@ def _vpi_class_is_renum(class_cd: ast.ClassDef*) -> int:
# 2) 未注册 → 解析字段类型 → 创建命名 StructType("sha1.ClassName") → register_struct + add_visible_struct。
# 字段解析失败不 fatal(不注册该类,留给源模块编译注册,后续裸类名引用由调用侧 fail-fast 暴露)。
# ============================================================
def _inject_class_struct_declare(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
class_cd: ast.ClassDef*,
cls_name: str,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str,
name_prefix: str = None) -> int:
def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_cd: ast.ClassDef*, cls_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, name_prefix: str = None) -> int:
"""从 vpi ClassDef 注册类为 struct 类型(含字段),使同 vpi 内裸类名注解可解析
name_prefix:非 None 表示"本类是 prefix 类的嵌套类",注册名取扁平名
@@ -2496,8 +2407,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# 不登记(片段侧字段访问明确失败,绝不按错偏移静默访问)。
# State=EMPTY 的类(无父类/无虚表/字段类型不可解析)不在此列,仍走下方既有口径。
if ReplStubLayoutMode != 0:
se: rawptr[ReplStubClass] = _repl_stub_find(
_repl_stub_key(pool, src_sha1, real_name))
se: rawptr[ReplStubClass] = _repl_stub_find(_repl_stub_key(pool, src_sha1, real_name))
if se is not None and se.State != _REPL_SS_EMPTY:
if se.State == _REPL_SS_PENDING: _repl_stub_try(se, mod)
if se.State == _REPL_SS_OK: GenApi.add_visible_struct(pool, real_name)
@@ -2540,8 +2450,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# (ClassGenDef._translate_nested_classdefs)⇒ 此处按同一命名**先**递归登记。
# 必须早于下方字段注解解析:外层字段可能写成 `外类.内类`,只有扁平名条目已在
# 结构体表里,TypeGenResolve._resolve_nested_class_type 才解析得出类型。
_inject_nested_class_declares(pool, mod, class_cd, real_name, trans,
src_sha1, imported_modules, from_imports)
_inject_nested_class_declares(pool, mod, class_cd, real_name, trans, src_sha1, imported_modules, from_imports)
# 还原"正在定义类"窗口:嵌套递归内的 mark_module_class 会把 CurDefClassName 改成
# 嵌套类名(A_B)。不还原会让外层字段注解的规则 5.5 自引用证据判错(裸类名票名冻结
# 成裸名版本、与定义侧带前缀形式分裂),也会让 `外类.内类` 的守卫①(CurDefClassName
@@ -2566,8 +2475,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
if m_aa_c.target.kind() != ast.ASTKind.Name: continue
m_tgt_c: ast.Name* = ast.Name*(m_aa_c.target)
if m_tgt_c.id is None: continue
field_ty_c: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0)
field_ty_c: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0)
if field_ty_c is None:
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
return 0
@@ -2607,14 +2515,12 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
name_buf_c[sh_len_c] = '.'
string.strcpy(name_buf_c + sh_len_c + 1, real_name)
type_name_c = name_buf_c
struct_ty_c: mlirlite.LLVMType* = mlirlite.Struct(
pool, first_node_c, field_count, type_name_c)
struct_ty_c: mlirlite.LLVMType* = mlirlite.Struct(pool, first_node_c, field_count, type_name_c)
if struct_ty_c is None: return 0
# 5. StdlibAlloc(Phase B)时深拷贝到 perm_pool,跨文件 reset 存活
# (对齐 ClassGenDef.translate_class_def L489-494)
if GenApi.get_stdlib_alloc() != 0:
st_copy_c: mlirlite.LLVMType* = mlirlite.DeepCopyType(
CompilerFactory.factory.PermPool, struct_ty_c)
st_copy_c: mlirlite.LLVMType* = mlirlite.DeepCopyType(CompilerFactory.factory.PermPool, struct_ty_c)
if st_copy_c is not None: struct_ty_c = st_copy_c
# 5.5 前向声明占位命中 ⇒ **占位 Ty 原地写入**(与 ClassGenDef.translate_class_def
# 的 fill_fwd 段逐句同款):给已存在的类型对象 `*existing.Ty` 赋入刚构建的
@@ -2640,8 +2546,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
if _vpi_class_has_packed(class_cd.decorator_list) != 0: mlirlite.module_set_named_type_packed(mod, pool, struct_ty_c, 1)
# 注册名用扁平名 real_name:跨模块引用 `外类.内类` 时 TypeGenResolve 查的是
# 扁平名条目(与定义端 StructGen 的登记名同源)。
entry_c: GenTypes.StructEntry* = GenApi.register_struct(
pool, real_name, struct_ty_c, src_sha1)
entry_c: GenTypes.StructEntry* = GenApi.register_struct(pool, real_name, struct_ty_c, src_sha1)
if entry_c is None: return 0
# B5:vpi 注入注册的 entry 同步 IsPacked——后续跨模块 stub 注入
# (ensure_struct_def_in_module)按 entry.IsPacked 判定 packed,否则读 0
@@ -2674,14 +2579,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# mark_module_class 窗口留在嵌套类上;故外层调用点在其后**再调一次**
# mark_module_class 还原(见 _inject_class_struct_declare 内注释)。
# ============================================================
def _inject_nested_class_declares(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
class_cd: ast.ClassDef*,
prefix_name: str,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str) -> None:
def _inject_nested_class_declares(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_cd: ast.ClassDef*, prefix_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> None:
"""递归登记 class_cd 的所有嵌套 ClassDef 为扁平名类型(前缀 = prefix_name)"""
if pool is None or mod is None or class_cd is None or prefix_name is None: return
children: list[ast.AST*]* = class_cd.children
@@ -2693,9 +2591,7 @@ def _inject_nested_class_declares(pool: memhub.MemBuddy*,
if child_ast.kind() != ast.ASTKind.ClassDef: continue
child_cd: ast.ClassDef* = ast.ClassDef*(child_ast)
if child_cd is None or child_cd.name is None or child_cd.name[0] == '\0': continue
_inject_class_struct_declare(pool, mod, child_cd, child_cd.name, trans,
src_sha1, imported_modules, from_imports,
prefix_name)
_inject_class_struct_declare(pool, mod, child_cd, child_cd.name, trans, src_sha1, imported_modules, from_imports, prefix_name)
# ============================================================
@@ -2705,9 +2601,7 @@ def _inject_nested_class_declares(pool: memhub.MemBuddy*,
# 均报 "use of undefined type"(值类型大小需已知)。vpi 注入类已 add_field 含字段(完整 Ty),在注册表可查时注册完整定义;
# 指针引用(Ptr(Struct))无需——_scan_type_for_cross_module_refs 的 Ptr 分支添加 opaque 即可。
# ============================================================
def _ensure_full_value_types(mod: mlirlite.LLVMModule*,
pool: memhub.MemBuddy*,
ty: mlirlite.LLVMType*) -> None:
def _ensure_full_value_types(mod: mlirlite.LLVMModule*, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> None:
"""递归为值 struct / 数组元素 struct 注册完整定义(递归深度守卫)"""
if mod is None or pool is None or ty is None: return
match ty:
@@ -2740,10 +2634,7 @@ def _ensure_full_value_types(mod: mlirlite.LLVMModule*,
# Windows x64 ABI 小结构体(≤8 字节)按整数寄存器传、位兼容,且与定义侧同样降级 ⇒ 同符号签名仍逐字一致)。
# * TPV 内部函数/方法(存在 define 侧)→ Ptr(struct):与定义侧逐字一致,指针目标只需 opaque 声明(module_ensure_opaque_for_type)。
# ============================================================
def _AggregateParamTy(mod: mlirlite.LLVMModule*,
pool: memhub.MemBuddy*,
ty: mlirlite.LLVMType*,
is_c_abi: int) -> mlirlite.LLVMType*:
def _AggregateParamTy(mod: mlirlite.LLVMModule*, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*, is_c_abi: int) -> mlirlite.LLVMType*:
"""裸结构体形参类型(C ABI 按值 / 内部 Ptr(struct),见上方注释)"""
if mod is None or pool is None or ty is None: return ty
if is_c_abi != 0:
@@ -2769,15 +2660,7 @@ def _AggregateParamTy(mod: mlirlite.LLVMModule*,
# vpi 里模块级全局变量(如 tokens.vp 的 _op_head: OpEntry* = None)需在当前模块创建 external global 声明(短名 @name,COFF 按名链接),
# 否则跨模块 from-import 读取全局变量时 find_global_in_module 找不到 → 误杀「跨模块全局变量类型未知(stub 未注入)」。
# ============================================================
def _inject_global_variable_declare(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
aa: ast.AnnAssign*,
trans: HT.Translator*,
imported_modules: str,
from_imports: str,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
src_sha1: str) -> None:
def _inject_global_variable_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, aa: ast.AnnAssign*, trans: HT.Translator*, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, src_sha1: str) -> None:
"""从 vpi AnnAssign 创建模块级全局变量 external declare(mangled 名 @<src_sha1>.<name>)"""
if pool is None or mod is None or aa is None or trans is None: return
tgt_v: ast.AST* = aa.target
@@ -2818,8 +2701,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
# 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针)
resolved_v: mlirlite.LLVMType* = None
if aa.annotation is not None:
resolved_v = GenApi.resolve_annotation_type(
pool, aa.annotation, imported_modules, from_imports, trans)
resolved_v = GenApi.resolve_annotation_type(pool, aa.annotation, imported_modules, from_imports, trans)
if resolved_v is None:
return # 类型解析失败跳过:调用侧有 fail-fast 定位
gv_ty_v: mlirlite.LLVMType* = resolved_v
@@ -2863,17 +2745,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
# 用 find_func_in_module 去重,创建 declare 并添加参数,
# 注册到函数表。
# ============================================================
def _inject_function_declare(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
fd: ast.FunctionDef*,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
funcs_ptr: GenTypes.FuncEntry*,
max_funcs: int) -> None:
def _inject_function_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, fd: ast.FunctionDef*, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None:
"""为 FunctionDef 创建 declare 声明并注入到模块"""
if fd.name is None: return
@@ -2938,8 +2810,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
ret_annot_fd: str = _lookup_vpi_ret_annot(src_sha1, None, fd.name)
if ret_annot_fd is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot_fd, i32_ty, i8_ptr_ty)
if ret_ty is None and fd.returns is not None:
ret_ty = GenApi.resolve_annotation_type(
pool, fd.returns, imported_modules, from_imports, trans)
ret_ty = GenApi.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans)
# 如果返回类型是纯 t.State(无实际类型),用 Void
if ret_ty is None and fd.returns is not None:
# t.State/t.CExtern 是存储类装饰器标记,非真实返回类型。
@@ -2952,9 +2823,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
if rk2_rt == ast.ASTKind.Name or rk2_rt == ast.ASTKind.Constant: is_pure_marker_rt = 1
elif rk2_rt == ast.ASTKind.Attribute:
pm_at: ast.Attribute* = ast.Attribute*(fd.returns)
if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0
or string.strcmp(pm_at.attr, "CExtern") == 0
or string.strcmp(pm_at.attr, "CExport") == 0):
if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0 or string.strcmp(pm_at.attr, "CExtern") == 0 or string.strcmp(pm_at.attr, "CExport") == 0):
is_pure_marker_rt = 1
if is_pure_marker_rt != 0: ret_ty = mlirlite.Void(pool)
elif has_state != 0 or has_extern != 0 or has_export != 0:
@@ -2965,9 +2834,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32;
# 无注解(fd.returns is None)是合法默认,保持下方 i32。
if ret_ty is None and fd.returns is not None:
GenApi.fatal_error(
fd.returns, f"extern 声明 '{fd.name}' 返回类型注解解析失败",
"NameError")
GenApi.fatal_error(fd.returns, f"extern 声明 '{fd.name}' 返回类型注解解析失败", "NameError")
# 默认返回 i32
if ret_ty is None: ret_ty = i32_ty
@@ -2977,8 +2844,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
mlirlite.module_ensure_opaque_for_type(mod, pool, ret_ty)
# 创建 declare
func: mlirlite.Function* = mlirlite.create_declare(
pool, mod, mangled_name, ret_ty)
func: mlirlite.Function* = mlirlite.create_declare(pool, mod, mangled_name, ret_ty)
if func is None: return
# 提取参数并添加到 declare
@@ -2995,9 +2861,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 返回垃圾大数 → for 循环 add_param 海量次 → Params 链超长,
# dump 时步数哨兵误报"链表成环"。超限立即报错定位。
if param_count < 0 or param_count > 128:
stdio.printf(
"[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n",
fd.name, param_count, uint64(fd.args))
stdio.printf("[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n", fd.name, param_count, uint64(fd.args))
# 终止点收敛:REPL 会话内 longjmp 回 REPL 循环(诊断已打印)
VLogger.repl_abort()
pi: sizet
@@ -3013,8 +2877,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
# callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest
# 根因)。段索引 = pi(模块级函数无 self,0=首参)。
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(
pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty)
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty)
if pseg_ty is not None:
match pseg_ty:
case mlirlite.LLVMType.Struct(_, _, _):
@@ -3026,8 +2889,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
case _:
param_ty = pseg_ty
elif ag.annotation is not None:
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, ag.annotation, imported_modules, from_imports, trans)
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, ag.annotation, imported_modules, from_imports, trans)
if resolved_ty is not None:
# CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。
# 裸结构体参数 → _AggregateParamTy(同一判据)。
@@ -3041,16 +2903,12 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
else:
# [S4 fail-fast] 有注解却解析不出类型 → 不再静默退 i8*
# (无注解 ag.annotation is None 是合法默认,保持 i8*)
GenApi.fatal_error(
ag.annotation,
f"extern 声明 '{fd.name}' 形参 '{pname}' 类型注解解析失败",
"NameError")
GenApi.fatal_error(ag.annotation, f"extern 声明 '{fd.name}' 形参 '{pname}' 类型注解解析失败", "NameError")
mlirlite.add_param(pool, func, param_ty, pname)
# 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失)
# → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾。用 vpi 文本
# 缓存的参数注解补全 declare 参数(与 define 参数数一致)。
param_count = _repair_declare_params_from_text(
pool, func, src_sha1, None, fd.name, param_count, i32_ty, i8_ptr_ty)
param_count = _repair_declare_params_from_text(pool, func, src_sha1, None, fd.name, param_count, i32_ty, i8_ptr_ty)
# *args 变长参数:标记 IsVarArg=1,使调用侧走 C ABI 参数提升
# (i8/i16 → i32,float → double),避免 %d/%x 等格式因参数按 i64
# 传递而读错(第二个 %x 读到第一个 i64 槽的高 4 字节)。
@@ -3067,9 +2925,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 越界写 perm_pool(覆盖当前模块 AST/表,SlotsBugTest 崩溃根因
# 候选)。与 param_count 哨兵(L1493-1497)对齐:垃圾值放弃
# 注册默认值(跨模块缺参调用走零值兜底),阻断越界写。
stdio.printf(
"[VPIS] 默认参数数异常: 函数名=%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n",
fd.name, fd_default_count)
stdio.printf("[VPIS] 默认参数数异常: 函数名=%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", fd.name, fd_default_count)
fd_defaults = None
fd_default_count = 0
else: fd_defaults = fd_dlist
@@ -3077,8 +2933,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 注册到函数表(用裸名 fd.name,不是 mangled_name)
if funcs_ptr is not None:
cur_count: int = trans._func_count
if GenApi.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs,
fd_defaults, fd_default_count, param_count, None, src_sha1) == 0:
if GenApi.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, fd_defaults, fd_default_count, param_count, None, src_sha1) == 0:
trans._func_count = cur_count + 1
# 补全全局函数表 Spec(参数已全部添加,对齐 FuncGenDef 行为):
# vpi 注入路径若不补全,跨模块 vtable 生成 find_func_entry_global()
@@ -3092,18 +2947,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 方法混淆名 {src_sha1}.{ClassName}.{method};参数类型从 vpi 注解解析(self 无注解时默认为 i8*)。
# 注入正确签名可避免调用时 _ensure_method_declare 用实参类型创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。
# ============================================================
def _inject_method_declare(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
m_fd: ast.FunctionDef*,
cls_name: str,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
funcs_ptr: GenTypes.FuncEntry*,
max_funcs: int) -> None:
def _inject_method_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, m_fd: ast.FunctionDef*, cls_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None:
"""为 ClassDef 内方法创建 declare 声明并注入到模块"""
if m_fd is None or m_fd.name is None or cls_name is None: return
if src_sha1 is None: return
@@ -3141,8 +2985,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
ret_annot: str = _lookup_vpi_ret_annot(src_sha1, cls_name, m_fd.name)
if ret_annot is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot, i32_ty, i8_ptr_ty)
if ret_ty is None and m_fd.returns is not None:
ret_ty = GenApi.resolve_annotation_type(
pool, m_fd.returns, imported_modules, from_imports, trans)
ret_ty = GenApi.resolve_annotation_type(pool, m_fd.returns, imported_modules, from_imports, trans)
# __new__ 无返回注解时推断为类指针(__new__ 返回 self 指针,默认 i32 会截断指针)
if ret_ty is None and string.strcmp(m_fd.name, "__new__") == 0:
cls_ty: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name)
@@ -3150,10 +2993,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32;
# __new__ 无注解、普通方法无注解均走下方 i32 合法默认。
if ret_ty is None and m_fd.returns is not None:
GenApi.fatal_error(
m_fd.returns,
f"extern 方法 '{cls_name}.{m_fd.name}' 返回类型注解解析失败",
"NameError")
GenApi.fatal_error(m_fd.returns, f"extern 方法 '{cls_name}.{m_fd.name}' 返回类型注解解析失败", "NameError")
# __init__ 无返回注解 → 与定义端一致取 Void(定义端
# ClassGenVTable._translate_method 对 __init__ 恒 Void)。若按"普通方法无注解"
# 退成下方 i32 默认,就会出现 declare i32 / define void 的返回类型分裂:
@@ -3162,8 +3002,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
if ret_ty is None: ret_ty = i32_ty
# 创建 declare
func: mlirlite.Function* = mlirlite.create_declare(
pool, mod, mangled_name, ret_ty)
func: mlirlite.Function* = mlirlite.create_declare(pool, mod, mangled_name, ret_ty)
if func is None: return
# 提取参数并添加到 declare
@@ -3178,9 +3017,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 参数数上限哨兵(fail-fast):与 _inject_function_declare 同因
# (vpi tree 深层节点被覆盖损坏时 __len__() 返回垃圾大数)。
if param_count < 0 or param_count > 128:
stdio.printf(
"[VPIS] 参数数异常: 方法名=%s.%s param_count=%d(m_fd.args=%llu,tree 可能被覆盖,终止)\n",
cls_name, m_fd.name, param_count, uint64(m_fd.args))
stdio.printf("[VPIS] 参数数异常: 方法名=%s.%s param_count=%d(m_fd.args=%llu,tree 可能被覆盖,终止)\n", cls_name, m_fd.name, param_count, uint64(m_fd.args))
# 终止点收敛:REPL 会话内 longjmp 回 REPL 循环(诊断已打印)
VLogger.repl_abort()
pi: sizet
@@ -3194,8 +3031,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 签名一致,消除跨模块声明/定义歧义。调用侧按形参 coerce 自动
# bitcast(见 _call_method_on_ptr/_translate_method_call 的 coerce
# 块)。类类型未注册时兜底走下方注解解析/i8*(保持原行为)。
if pi == 0 and (string.strcmp(pname, "self") == 0
or string.strcmp(pname, "cls") == 0):
if pi == 0 and (string.strcmp(pname, "self") == 0 or string.strcmp(pname, "cls") == 0):
cls_ty_sd: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name)
if cls_ty_sd is not None:
mlirlite.add_param(pool, func, mlirlite.Ptr(pool, cls_ty_sd), pname)
@@ -3206,8 +3042,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
# callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃,
# SlotsBugTest 根因)。段索引 = pi(0=self 空段)。
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(
pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty)
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty)
if pseg_ty is not None:
match pseg_ty:
case mlirlite.LLVMType.Struct(_, _, _):
@@ -3221,8 +3056,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
case _:
param_ty = pseg_ty
elif ag.annotation is not None:
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, ag.annotation, imported_modules, from_imports, trans)
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, ag.annotation, imported_modules, from_imports, trans)
if resolved_ty is not None:
# CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。
# 裸结构体参数 → _AggregateParamTy(同一判据,is_c_abi=0)。
@@ -3236,18 +3070,14 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
else:
# [S4 fail-fast] 有注解却解析不出类型 → 不再静默退 i8*
# (无注解 ag.annotation is None 是合法默认,保持 i8*)
GenApi.fatal_error(
ag.annotation,
f"extern 方法 '{cls_name}.{m_fd.name}' 形参 '{pname}' 类型注解解析失败",
"NameError")
GenApi.fatal_error(ag.annotation, f"extern 方法 '{cls_name}.{m_fd.name}' 形参 '{pname}' 类型注解解析失败", "NameError")
mlirlite.add_param(pool, func, param_ty, pname)
# 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失)
# → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾(跨模块 CDefine
# 查找 depth=160 假递归根因)。用 vpi 文本缓存的参数注解补全 declare
# 参数(与 define 参数数一致,调用点默认参数填充才能生效)。
param_count = _repair_declare_params_from_text(
pool, func, src_sha1, cls_name, m_fd.name, param_count, i32_ty, i8_ptr_ty)
param_count = _repair_declare_params_from_text(pool, func, src_sha1, cls_name, m_fd.name, param_count, i32_ty, i8_ptr_ty)
# OOP iter 协议:__next__ 方法 stub 声明带隐藏 __stop_iter_flag__(i1*),
# 与 _translate_method 的 define 签名一致(对齐 TPC HandlesFunctions.py
@@ -3268,9 +3098,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
if md_default_count < 0 or md_default_count > 128:
# 同 _inject_function_declare:vpi tree 深层节点被覆盖时
# defaults len 可能为垃圾大数 → 越界写 perm_pool。放弃注册。
stdio.printf(
"[VPIS] 默认参数数异常: 方法名=%s.%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n",
cls_name, m_fd.name, md_default_count)
stdio.printf("[VPIS] 默认参数数异常: 方法名=%s.%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", cls_name, m_fd.name, md_default_count)
md_defaults = None
md_default_count = 0
else: md_defaults = md_dlist
@@ -3283,8 +3111,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
cur_count: int = trans._func_count
param_count_no_self: int = param_count
if param_count_no_self > 0: param_count_no_self -= 1
if GenApi.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs,
md_defaults, md_default_count, param_count_no_self, None, src_sha1) == 0:
if GenApi.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, md_defaults, md_default_count, param_count_no_self, None, src_sha1) == 0:
trans._func_count = cur_count + 1
# 补全全局函数表 Spec(参数已全部添加,对齐 ClassGenVTable 行为):
# vpi 注入的方法声明若不补全 Spec,跨模块继承 vtable 生成时
@@ -3299,8 +3126,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 提取 NAME: t.CTypedef = Type 中的名称和类型表达式字符串,
# 调用 register_ctypedef 注册到动态 CTypedef 表。
# ============================================================
def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*,
aa: ast.AnnAssign*) -> None:
def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*, aa: ast.AnnAssign*) -> None:
"""从 AnnAssign 节点提取并注册 CTypedef"""
if aa is None or pool is None: return
# 提取目标名称(必须是 Name 节点)
@@ -3610,8 +3436,7 @@ def _repl_stub_deco_flags(deco_list: list[ast.AST*]*) -> int:
return flags
def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int,
first: rawptr[ReplStubClass]) -> int:
def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int, first: rawptr[ReplStubClass]) -> int:
"""本类第 mi 个方法是否进虚表(转写 ClassGenBase._should_method_be_virtual)"""
if e is None or e.MethodFlags is None or mi < 0 or mi >= e.MethodCount: return 0
mf: int = int(e.MethodFlags[mi])
@@ -3630,10 +3455,7 @@ def _repl_stub_warn_refuse(e: rawptr[ReplStubClass], why: str, a: int, b: int) -
ReplStubRefused += 1
if ReplStubWarnLeft <= 0: return
ReplStubWarnLeft -= 1
stdio.printf("includes 类布局: %s.%s 布局不可信 ⇒ 明确拒绝(原因=判据拒绝:%s;"
"存根字段数=%d ≠ 展平字段数+虚表位=%d)。该类字段访问被明确拒绝"
"(方法调用不受影响)\n",
e.Sha1, e.ClassName, why, a, b)
stdio.printf("includes 类布局: %s.%s 布局不可信 ⇒ 明确拒绝(原因=判据拒绝:%s;" "存根字段数=%d ≠ 展平字段数+虚表位=%d)。该类字段访问被明确拒绝" "(方法调用不受影响)\n", e.Sha1, e.ClassName, why, a, b)
def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None:
@@ -3655,25 +3477,13 @@ def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None:
ReplStubWarnLeft -= 1
if cause == _REPL_SU_NOSTUB:
# 数据缺失:连模块布局元数据都没有(LayoutCount = -1 只是"没读到"的哨兵)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『数据缺失』:"
"模块 %s 没有 {sha1}.meta 布局元数据;meta 字段数=无 / 推断字段数=未计算 ⇒ "
"两侧都没数据,『未做比较』,不是字段数不符)。该类字段访问被"
"拒绝(方法调用不受影响);补上该模块 meta(同一工程先跑一次批处理,"
"Phase A/B 会落盘 {sha1}.meta)后用同一 --project 重跑 REPL 即恢复\n",
e.Sha1, e.ClassName, e.Sha1)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『数据缺失』:" "模块 %s 没有 {sha1}.meta 布局元数据;meta 字段数=无 / 推断字段数=未计算 ⇒ " "两侧都没数据,『未做比较』,不是字段数不符)。该类字段访问被" "拒绝(方法调用不受影响);补上该模块 meta(同一工程先跑一次批处理," "Phase A/B 会落盘 {sha1}.meta)后用同一 --project 重跑 REPL 即恢复\n", e.Sha1, e.ClassName, e.Sha1)
elif cause == _REPL_SU_OPAQUE:
# 判据拒绝:meta 里该 key 是 OPAQUE(无 body ⇒ 无字段数可比)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:"
"meta %s.meta 里键 %s 为 OPAQUE 声明(无 body);meta 字段数=不可得 / "
"推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问被拒绝"
"(方法调用不受影响)\n", e.Sha1, e.ClassName, e.Sha1, e.Key)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" "meta %s.meta 里键 %s 为 OPAQUE 声明(无 body);meta 字段数=不可得 / " "推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问被拒绝" "(方法调用不受影响)\n", e.Sha1, e.ClassName, e.Sha1, e.Key)
else:
# 判据拒绝:meta 在,但没有该类的 STRUCT 行(LayoutCount = -1 只是"未找到"的哨兵)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:"
"meta %s.meta 存在但其中没有键 %s 的 `STRUCT … FIELDS n / OPAQUE` 记录;"
"meta 字段数=未找到 / 推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问"
"被拒绝(方法调用不受影响);若该类确实定义于该模块,说明 meta 陈旧/"
"不完整,请重建\n", e.Sha1, e.ClassName, e.Sha1, e.Key)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" "meta %s.meta 存在但其中没有键 %s 的 `STRUCT … FIELDS n / OPAQUE` 记录;" "meta 字段数=未找到 / 推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问" "被拒绝(方法调用不受影响);若该类确实定义于该模块,说明 meta 陈旧/" "不完整,请重建\n", e.Sha1, e.ClassName, e.Sha1, e.Key)
def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) -> None:
@@ -3683,9 +3493,7 @@ def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) ->
ReplStubRefusedParent += 1
if ReplStubWarnLeft <= 0: return
ReplStubWarnLeft -= 1
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『上游无数据』:%s,"
"父类=%s;父类字段与虚表位无法展平 ⇒ 本类未做字段数比较)。该类字段访问"
"被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname)
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『上游无数据』:%s," "父类=%s;父类字段与虚表位无法展平 ⇒ 本类未做字段数比较)。该类字段访问" "被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname)
def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
@@ -3714,8 +3522,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
# ⇒ 展平出来的本类字段数不可用:既不比较(避免误报"字段数不符")、也不放行
# (M4.2:布局不可信 ⇒ 明确拒绝)。
e.State = _REPL_SS_REFUSED
_repl_stub_warn_parent(e, "父类的字段类型未全部解析(其字段数不完整)",
pe.ClassName)
_repl_stub_warn_parent(e, "父类的字段类型未全部解析(其字段数不完整)", pe.ClassName)
return -1
first: rawptr[ReplStubClass] = None
if e.BaseCount > 0: first = _repl_stub_find_base(e, 0)
@@ -3788,9 +3595,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
if vn == e.VtArity: e.VtTrust = 1
elif ReplStubWarnLeft > 0:
ReplStubWarnLeft -= 1
stdio.printf("includes 类布局: %s.%s 的虚表槽数与存根不符(%d vs %d)"
"——该类不做虚分派(退化为直接调用,会话继续)\n",
e.Sha1, e.ClassName, vn, e.VtArity)
stdio.printf("includes 类布局: %s.%s 的虚表槽数与存根不符(%d vs %d)" "——该类不做虚分派(退化为直接调用,会话继续)\n", e.Sha1, e.ClassName, vn, e.VtArity)
# ⑥ 建 LLVM 结构体(命名 "%<sha1>.<类名>",与定义侧同口径)
total: int = cn + hv
i8_ptr: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
@@ -3818,8 +3623,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
struct_ty: mlirlite.LLVMType* = mlirlite.Struct(pool, first_node, total, e.Key)
if struct_ty is None: return 0
# ⑦ 登记(StdlibAlloc=1 期间的注册走 PermPool,跨片段存活)
entry: GenTypes.StructEntry* = GenApi.register_struct(
pool, e.ClassName, struct_ty, e.Sha1)
entry: GenTypes.StructEntry* = GenApi.register_struct(pool, e.ClassName, struct_ty, e.Sha1)
if entry is None:
e.State = _REPL_SS_REFUSED
return -1
@@ -3863,15 +3667,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
return 1
def _repl_stub_add_class(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
cd: ast.ClassDef*,
sha1: str,
txt: str,
have_stub: int,
trans: HT.Translator*,
imported_modules: str,
from_imports: str) -> int:
def _repl_stub_add_class(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cd: ast.ClassDef*, sha1: str, txt: str, have_stub: int, trans: HT.Translator*, imported_modules: str, from_imports: str) -> int:
"""收集单个 vpi ClassDef 的布局要素并尝试登记(1=已登记/推迟处理,0=跳过)
have_stub:本模块是否读到了 {sha1}.meta 布局元数据(0 时本模块带父类/虚表的类按
@@ -3918,8 +3714,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
bcnt: int = 0
if pb is not None and GenApi._g_gen is not None:
string.memset(pb, 0, 8 * GenTypes.PARENT_MAX)
bcnt = GenApi._g_gen.ClassGenBase._collect_parents(
pool, cd, pb, GenTypes.PARENT_MAX, trans)
bcnt = GenApi._g_gen.ClassGenBase._collect_parents(pool, cd, pb, GenTypes.PARENT_MAX, trans)
if bcnt > 0:
if bcnt > _REPL_STUB_FIELD_MAX: bcnt = _REPL_STUB_FIELD_MAX
bi: int
@@ -3945,8 +3740,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
if aa2.target.kind() != ast.ASTKind.Name: continue
tg: ast.Name* = ast.Name*(aa2.target)
if tg.id is None or tg.id[0] == '\0': continue
fty2: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, aa2.annotation, imported_modules, from_imports, trans, 0)
fty2: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, aa2.annotation, imported_modules, from_imports, trans, 0)
if fty2 is None:
own_fail = 1
continue
@@ -4010,14 +3804,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
return 1
def _repl_stub_collect_module(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
ch: list[ast.AST*]*,
n: sizet,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str) -> int:
def _repl_stub_collect_module(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, ch: list[ast.AST*]*, n: sizet, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> int:
"""(REPL)为当前模块的类收集布局要素 + 尝试登记;返回处理的类数"""
global ReplStubNoStub, ReplStubWarnLeft
if ReplStubLayoutMode == 0 or pool is None or ch is None: return 0
@@ -4034,11 +3821,7 @@ def _repl_stub_collect_module(pool: memhub.MemBuddy*,
ReplStubNoStub += 1
if ReplStubWarnLeft > 0:
ReplStubWarnLeft -= 1
stdio.printf("includes 类布局: 模块 %s 无 .meta 存根(数据缺失)—— 该模块"
"带父类/虚表的类将逐个按『数据缺失』明确拒绝(读不到布局元数据 ⇒ 无"
"字段数可比,不是字段数不符)。用同一工程先跑一次批处理生成存根,"
"再 `--project .\\project.vpj --repl`(TransPyV 目录)即可复用\n",
src_sha1)
stdio.printf("includes 类布局: 模块 %s 无 .meta 存根(数据缺失)—— 该模块" "带父类/虚表的类将逐个按『数据缺失』明确拒绝(读不到布局元数据 ⇒ 无" "字段数可比,不是字段数不符)。用同一工程先跑一次批处理生成存根," "再 `--project .\\project.vpj --repl`(TransPyV 目录)即可复用\n", src_sha1)
cnt: int = 0
i: sizet
for i in range(n):
@@ -4057,8 +3840,7 @@ def _repl_stub_collect_module(pool: memhub.MemBuddy*,
continue
# REnum 类:布局 {i32 tag, payload} 由 ClassGenEnum 计算,既有路径整体跳过
if _vpi_class_is_renum(cd) != 0: continue
if _repl_stub_add_class(pool, mod, cd, src_sha1, txt, have_stub, trans,
imported_modules, from_imports) != 0:
if _repl_stub_add_class(pool, mod, cd, src_sha1, txt, have_stub, trans, imported_modules, from_imports) != 0:
cnt += 1
if txt is not None: stdlib.free(txt)
return cnt
@@ -4092,30 +3874,14 @@ def ReplStubLayoutFinish() -> int:
if peb is not None and peb.ClassName is not None: pbad = peb.ClassName
break
_repl_stub_warn_parent(e2, "父类未在会话注册或其布局被拒", pbad)
stdio.printf("includes 类布局: 完整布局 %d 个(其中虚表索引可用 %d 个)/ "
"被拒 %d 个 / 缺布局元数据模块 %d 个\n",
ReplStubOk, ReplStubVtOk, ReplStubRefused, ReplStubNoStub)
stdio.printf(" 拒绝原因分布(自证数据来源):数据缺失-模块无 {sha1}.meta %d 个类 / "
"判据拒绝-meta 无此类 %d 个 / 判据拒绝-meta 为 opaque %d 个 / "
"上游无数据-父类不可用 %d 个\n",
ReplStubRefusedNoStub, ReplStubRefusedNoClass,
ReplStubRefusedOpaque, ReplStubRefusedParent)
stdio.printf("includes 类布局: 完整布局 %d 个(其中虚表索引可用 %d 个)/ " "被拒 %d 个 / 缺布局元数据模块 %d 个\n", ReplStubOk, ReplStubVtOk, ReplStubRefused, ReplStubNoStub)
stdio.printf(" 拒绝原因分布(自证数据来源):数据缺失-模块无 {sha1}.meta %d 个类 / " "判据拒绝-meta 无此类 %d 个 / 判据拒绝-meta 为 opaque %d 个 / " "上游无数据-父类不可用 %d 个\n", ReplStubRefusedNoStub, ReplStubRefusedNoClass, ReplStubRefusedOpaque, ReplStubRefusedParent)
if ReplStubRefused > 0 or ReplStubNoStub > 0:
stdio.printf(" 说明:被拒类的字段访问会报『类未注册/属性访问失败』"
"(不按错偏移静默访问);方法调用不受影响。\n")
stdio.printf(" 说明:被拒类的字段访问会报『类未注册/属性访问失败』" "(不按错偏移静默访问);方法调用不受影响。\n")
if ReplStubRefusedNoStub > 0:
stdio.printf(" 其中『数据缺失』的 %d 个类只是没读到模块布局元数据(本会话临时目录 %s "
"缺这些 {sha1}.meta):批处理才会落盘 meta(REPL 分支在 Phase1 之前"
"返回,故 --repl 自身不生成存根)。修法:用同一个工程跑一次批处理"
"(TransPyV 目录:.\\tpv_build\\output\\TransPyV.exe --project "
".\\project.vpj;includes 有改动时加 --rebuild-includes),随后 "
"--project .\\project.vpj --repl 复用其临时目录即可\n", ReplStubRefusedNoStub,
ReplStubTempDir)
stdio.printf(" 其中『数据缺失』的 %d 个类只是没读到模块布局元数据(本会话临时目录 %s " "缺这些 {sha1}.meta):批处理才会落盘 meta(REPL 分支在 Phase1 之前" "返回,故 --repl 自身不生成存根)。修法:用同一个工程跑一次批处理" "(TransPyV 目录:.\\tpv_build\\output\\TransPyV.exe --project " ".\\project.vpj;includes 有改动时加 --rebuild-includes),随后 " "--project .\\project.vpj --repl 复用其临时目录即可\n", ReplStubRefusedNoStub, ReplStubTempDir)
if ReplStubRefusedNoClass + ReplStubRefusedOpaque > 0:
stdio.printf(" 其中『判据拒绝』的 %d 个类:数据在但不可信(存根里没有该类的字段数、"
"或其声明为 opaque),按 M4.2 一律不放行——请确认该类是否本应按结构体"
"登记:应按结构体登记而存根里查不到 ⇒ 存根陈旧/不完整(重建 includes "
"存根)\n", ReplStubRefusedNoClass + ReplStubRefusedOpaque)
stdio.printf(" 其中『判据拒绝』的 %d 个类:数据在但不可信(存根里没有该类的字段数、" "或其声明为 opaque),按 M4.2 一律不放行——请确认该类是否本应按结构体" "登记:应按结构体登记而存根里查不到 ⇒ 存根陈旧/不完整(重建 includes " "存根)\n", ReplStubRefusedNoClass + ReplStubRefusedOpaque)
return ReplStubOk
+6 -19
View File
@@ -53,8 +53,7 @@ def _IsAppModule(mod_name: str) -> int:
# Args: worklist 队列缓冲(原地修改);wl_len 当前长度(值);deps_str 要追加的模块名(空格分隔);processed 已处理集合(空格分隔,查重)
# Returns: 追加后的新长度(>=0);溢出/参数错误返回 -1(调用方 fail-fast)
# ============================================================
def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet,
deps_str: str, processed: str) -> int:
def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, deps_str: str, processed: str) -> int:
if worklist is None or deps_str is None: return -1
cur_len: sizet = wl_len
dl: sizet = string.strlen(deps_str)
@@ -103,11 +102,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet,
# Args: mb 内存池;source_dir App 源文件目录(Config.SourceDir);temp_dir 临时目录(deps.txt 所在位置);reachable_set 输出参数,可达 SHA1 集合缓冲区(MAX_INCLUDES_SHA1 * 17 字节);app_deps App 源文件直接依赖模块名(空格分隔),非空则跳过 App 扫描;includes_dirs includes 根目录(空格分隔)
# Returns: 可达 SHA1 数量(>0 成功;0 无 includes 依赖;<0 失败)
# ============================================================
def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str,
temp_dir: str,
reachable_set: str,
app_deps: str = None,
includes_dirs: str = None) -> int:
def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, reachable_set: str, app_deps: str = None, includes_dirs: str = None) -> int:
"""构建可达 SHA1 集合(依赖图按需扫描,App 优先)"""
if source_dir is None or temp_dir is None or reachable_set is None: return -1
if includes_dirs is None:
@@ -241,8 +236,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str,
tb_abs_slot[0] = 0
tb_rel_slot[0] = 0
tb_inc_slot[0] = 0
tb_found = IncludesScanner.ResolveModuleToPath(
includes_dirs, "traceback", tb_abs, tb_rel, tb_inc)
tb_found = IncludesScanner.ResolveModuleToPath(includes_dirs, "traceback", tb_abs, tb_rel, tb_inc)
if tb_abs is not None: stdlib.free(tb_abs)
if tb_rel is not None: stdlib.free(tb_rel)
if tb_inc is not None: stdlib.free(tb_inc)
@@ -344,8 +338,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str,
abs_slot[0] = 0
rel_slot[0] = 0
inc_slot[0] = 0
rcode: int = IncludesScanner.ResolveModuleToPath(
includes_dirs, mod_buf, out_abs, out_rel, out_inc)
rcode: int = IncludesScanner.ResolveModuleToPath(includes_dirs, mod_buf, out_abs, out_rel, out_inc)
if rcode != 0:
# 内建模块(t/c/builtins 等内部库)或未找到:静默跳过
stdlib.free(out_abs)
@@ -542,8 +535,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str,
# (类型定义 + external 声明 + 定义 + DI 一次齐全,类型定义天然在声明之前),
# 无需再把 stub + 依赖 stub/text 文本合并。
# ============================================================
def LoadFullIR(temp_dir: str, sha1: str,
out_buf: bytes, out_size: sizet) -> sizet:
def LoadFullIR(temp_dir: str, sha1: str, out_buf: bytes, out_size: sizet) -> sizet:
"""读取 {sha1}.full.ll 到 out_buf;返回长度(0=失败)"""
if temp_dir is None or sha1 is None or out_buf is None or out_size == 0: return 0
td_len: sizet = string.strlen(temp_dir)
@@ -573,12 +565,7 @@ def LoadFullIR(temp_dir: str, sha1: str,
# Args: pool 内存池;mod 当前 LLVM 模块;imported_modules 已导入模块名字符串(空格分隔);from_imports from-import 映射字符串("name:module name:module" 格式);temp_dir temp 目录路径;trans 翻译器对象
# Returns: 成功加载的 .vpi 文件数
# ============================================================
def LoadDepVpiIntoModule(pool: memhub.MemBuddy*,
mod: mlirlite.LLVMModule*,
imported_modules: str,
from_imports: str,
temp_dir: str,
trans: rawptr[HandlesTranslator.Translator]) -> int:
def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, imported_modules: str, from_imports: str, temp_dir: str, trans: rawptr[HandlesTranslator.Translator]) -> int:
"""加载依赖模块的 .vpi 文件,将函数声明注入到当前模块"""
if pool is None or mod is None or temp_dir is None or trans is None: return 0
if imported_modules is None: return 0
+2 -7
View File
@@ -84,9 +84,7 @@ def _sliced_path(temp_dir: str, td_len: sizet, sha1: str, ext: str) -> str:
# 数据来源是 PopulateSha1MapStore 填充的全局存储器(不读取 _sha1_map.txt)。
# 用于过滤 stub 文件,避免加载 TransPyV 自身源文件(lib/*)的 stub 导致链接失败。
# ============================================================
def _load_includes_sha1_set(pool: memhub.MemBuddy*,
temp_dir: str,
sha1_set: str) -> int:
def _load_includes_sha1_set(pool: memhub.MemBuddy*, temp_dir: str, sha1_set: str) -> int:
"""从全局内存存储器将 includes 的 SHA1 写入 sha1_set
pool/temp_dir 参数保留以兼容现有调用者,但不再使用。
@@ -118,10 +116,7 @@ def _is_in_sha1_set(sha1: str, sha1_set: str, set_count: int) -> int:
# Args: mb 内存池;temp_dir 临时目录(_sha1_map.txt 写入位置);scan_result IncludesScanner 扫描结果
# Returns: 0 成功,非 0 失败
# ============================================================
def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str,
scan_result: rawptr[IncludesScanner.ScanResult],
filter_set: str,
filter_count: int) -> int:
def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawptr[IncludesScanner.ScanResult], filter_set: str, filter_count: int) -> int:
"""将 includes 扫描结果写入 _sha1_map.txt(人类可读输出,程序内部使用内存存储器)
若 filter_set 不为 None 且 filter_count > 0,只写入 filter_set 中的条目。
+3 -7
View File
@@ -47,8 +47,7 @@ import lib.Stub.StubMerger as StubMerger
# Args: mod 已翻译完成的 LLVM 模块;temp_dir 基础目录;td_len temp_dir 长度;sha1 模块 SHA1
# Returns: 0=成功(失败经 VLogger.error 终止进程)
# ============================================================
def WriteModuleMeta(mod: mlirlite.LLVMModule*, temp_dir: str,
td_len: sizet, sha1: str) -> int:
def WriteModuleMeta(mod: mlirlite.LLVMModule*, temp_dir: str, td_len: sizet, sha1: str) -> int:
"""把本模块的函数定义/结构体布局/虚表清单写入 {sha1}.meta"""
if mod is None or temp_dir is None or sha1 is None:
VLogger.error("meta 写出:参数为空", "Meta")
@@ -216,9 +215,7 @@ def _is_submodule_of_imported(deps_buf: str, mod_name: str) -> int:
# 返回两个数组(sha1_list 和 mod_list),长度存储在 count 中。
# 所有内存由 stdlib.malloc 分配,调用者负责释放。
# ============================================================
def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet,
sha1_list: str,
mod_list: str) -> int:
def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet, sha1_list: str, mod_list: str) -> int:
"""从全局内存存储器复制 sha1→module_name 映射到调用者数组
temp_dir/td_len 参数保留以兼容现有调用者,但不再使用。
@@ -241,8 +238,7 @@ def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet,
# Args: sha1_arr SHA1 数组(每个 17 字节);mod_arr 模块名数组(每个 64 字节);count 映射条目数;mod_name 要查找的模块名
# Returns: SHA1 字符串指针(指向 sha1_arr 内部,无需释放),未找到返回 None
# ============================================================
def _FindSha1ByModName(sha1_arr: str, mod_arr: str,
count: int, mod_name: str) -> str:
def _FindSha1ByModName(sha1_arr: str, mod_arr: str, count: int, mod_name: str) -> str:
"""从模块名查找 SHA1(精确匹配 + 包名回退)
精确匹配失败时,尝试 "{mod_name}.__init__" 回退,
+4 -8
View File
@@ -80,8 +80,7 @@ def AppendImportedModule(pool: memhub.MemBuddy*, cur: str, name: str) -> str:
# 该条目在查找侧仍被当作合法条目解析出错误的 local/mod/orig ⇒ 跨模块类名/
# 别名还原取到错名字(污染 Spec.SourceName)。此处按精确长度分配,无上限。
# ============================================================
def AppendFromImport(pool: memhub.MemBuddy*, cur: str,
local: str, mod: str, orig: str) -> str:
def AppendFromImport(pool: memhub.MemBuddy*, cur: str, local: str, mod: str, orig: str) -> str:
"""追加 from-import 映射(pool 分配),返回新列表"""
if local is None or mod is None: return cur
llen: sizet = string.strlen(local)
@@ -116,8 +115,7 @@ def AppendFromImport(pool: memhub.MemBuddy*, cur: str,
# ============================================================
# AllocImportCtx - 用两个既有上下文串构造记账容器
# ============================================================
def AllocImportCtx(pool: memhub.MemBuddy*,
imported_modules: str, from_imports: str) -> ImportCtx*:
def AllocImportCtx(pool: memhub.MemBuddy*, imported_modules: str, from_imports: str) -> ImportCtx*:
"""构造导入上下文容器(pool 分配);两串可为 None"""
ctx: ImportCtx* = pool.alloc(ImportCtx.__sizeof__())
if ctx is None: return None
@@ -134,8 +132,7 @@ def AllocImportCtx(pool: memhub.MemBuddy*,
# 无别名:`import a.b.c` 时把顶层包名 `a` 也追加(使 a.b.c 作为属性访问 base
# 时 is_module_imported("a") 放行)。
# ============================================================
def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*,
name: str, asname: str) -> int:
def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*, name: str, asname: str) -> int:
"""记账单条 import(就地更新 ctx),返回 0"""
if ctx is None or name is None: return 1
ctx.ImportedModules = AppendImportedModule(pool, ctx.ImportedModules, name)
@@ -151,8 +148,7 @@ def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*,
if pkg_buf is not None:
string.strncpy(pkg_buf, name, pkg_len)
pkg_buf[pkg_len] = '\0'
ctx.ImportedModules = AppendImportedModule(
pool, ctx.ImportedModules, pkg_buf)
ctx.ImportedModules = AppendImportedModule(pool, ctx.ImportedModules, pkg_buf)
return 0
+1 -4
View File
@@ -41,10 +41,7 @@ import lib.Stub.StubMerger as StubMerger
# Args: store_count / store_sha1_arr / store_mod_arr store 元数据;reachable_set / reachable_count 可达集合(_BuildReachableSha1Set 输出);sorted_idx 输出数组(store_count+1 个 8 字节槽),前 N 个为拓扑序 store 索引
# Returns: 拓扑序条数;有环时剩余条目按 store 顺序补齐(避免漏编译)
# ============================================================
def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
store_mod_arr: bytes, reachable_set: bytes,
reachable_count: int,
sorted_idx: sizet*) -> int:
def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes, store_mod_arr: bytes, reachable_set: bytes, reachable_count: int, sorted_idx: sizet*) -> int:
"""对可达 includes 逆拓扑排序(被依赖者先),store 索引写入 sorted_idx"""
if store_count <= 0 or store_sha1_arr is None or store_mod_arr is None or sorted_idx is None: return 0
indegree: sizet* = (sizet*)(stdlib.malloc(8 * (store_count + 1)))