refactor(tpv): 迁移新语法 R1/R2/R7/R8/R3/R4/R5(指针 T*、短别名、define、&/*、__asm__)

按 wiki/新规范:
- T | t.CPtr → T*(无 | 标准)
- t.CInt/t.CUInt64T/t.CChar/t.CDouble 等 → int/uint64/char/double 等短别名
- X: t.CDefine = Y → define X = Y
- c.Asm → __asm__,c.AsmInp/c.AsmOut → asminp/asmout,t.ASM_DESCR. → ASM_DESCR.
- c.Addr(x) → &x,c.Deref(p) → *p,c.DerefAs(p, v) → *p = v

种子自举通过(96s)。
This commit is contained in:
TermiNexus committed 2026-10-04 22:49:01 +08:00
1 parent 9717ce0107
commit 185a2196ca
57 files changed
+1078 -1078

No files matched your search

+8 -8
View File
@@ -104,8 +104,8 @@ _g_pyi_cdefine_found: int = 0
# 本文件 CDefine 值缓存(vpi 生成专用):vpi 生成早于翻译阶段注册(全局表为空),_GeneratePyiFromAst 开头按声明顺序注册,Name 引用先查本缓存。
# 两个缓存必须是 C 数组(int64* / i8**)而非 list[T]——list[int].get 会误解析为 list[str].get(返回元素地址)、list[str] 联合接收者的 .get 会误分派为 HashTable.get(索引 inttoptr 成 key 指针 → 零页崩溃);索引一律用 t.CPtr(base + i*8) + e[0]。
_g_pyi_cdef_names: str | t.CPtr = None
_g_pyi_cdef_vals: int64 | t.CPtr = None
_g_pyi_cdef_names: str* = None
_g_pyi_cdef_vals: int64* = None
_g_pyi_cdef_count: int = 0
@@ -117,7 +117,7 @@ def _lookup_cdefine_for_pyi(name: str) -> int64:
# 循环上限用 _g_pyi_cdef_count,且绝不能用 len()/.get:i8** 指针数组上 len() 回退 strlen(基址当字符串算长度 → 垃圾小值 → 靠后注册项查不到),.get 会被误分派为 HashTable.get(索引 inttoptr 成 key 指针 → 零页崩溃);用 t.CPtr(base + i*8) + e[0] 依次取名。
pn: sizet = sizet(_g_pyi_cdef_count)
for pi in range(pn):
entry_pc: str | t.CPtr = (str | t.CPtr)(uint64(_g_pyi_cdef_names) + pi * 8)
entry_pc: str* = (str*)(uint64(_g_pyi_cdef_names) + pi * 8)
pnm: str = entry_pc[0]
if pnm is not None and string.strcmp(pnm, name) == 0:
_g_pyi_cdefine_found = 1
@@ -310,7 +310,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
if k == ast.ASTKind.Compare:
cmp_t: rawptr[ast.Compare] = rawptr[ast.Compare](annot)
pos = _PyiTypeStr(buf, buf_size, pos, cmp_t.left, depth + 1)
ops_ct: list[int] | t.CPtr = (list[int] | t.CPtr)(cmp_t.ops)
ops_ct: list[int]* = (list[int]*)(cmp_t.ops)
cmps_ct: list[ast.AST*]* = cmp_t.comparators
if ops_ct is not None:
on_ct: sizet = len(ops_ct)
@@ -826,8 +826,8 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
if ann_pc0.attr is not None and string.strcmp(ann_pc0.attr, "CDefine") == 0:
_g_pyi_cdef_count += 1
if _g_pyi_cdef_count > 0:
_g_pyi_cdef_names = (str | t.CPtr)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_vals = (int64 | t.CPtr)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_names = (str*)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_vals = (int64*)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
# 第二遍:按声明顺序注册(BinOp 内 Name 引用依赖先前注册项)
pci: sizet = 0
cdi: int = 0
@@ -842,7 +842,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
ann_pc: ast.Attribute* = ast.Attribute*(aa_pc.annotation)
if ann_pc.attr is not None and string.strcmp(ann_pc.attr, "CDefine") == 0:
if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None:
slot_pc: str | t.CPtr = (str | t.CPtr)(uint64(_g_pyi_cdef_names) + cdi * 8)
slot_pc: str* = (str*)(uint64(_g_pyi_cdef_names) + cdi * 8)
slot_pc[0] = tgt_pc.id
_g_pyi_cdef_vals[cdi] = _eval_cdefine_value_cache(aa_pc.value)
cdi += 1
@@ -1159,7 +1159,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
if inferred == 1:
pos = _PyiEmit(buf, buf_size, pos, "int")
elif inferred == 2:
pos = _PyiEmit(buf, buf_size, pos, "t.CDouble")
pos = _PyiEmit(buf, buf_size, pos, "double")
elif inferred == 3:
pos = _PyiEmit(buf, buf_size, pos, "str")
elif inferred == 4:
+44 -44
View File
@@ -26,7 +26,7 @@ import lib.Projectrans.Config as Config
# 该机制仅在 ReplStubLayoutMode != 0(REPL 会话初始化)时生效,批处理恒 0。
# ============================================================
_REPL_STUB_CLS_MAX: t.CDefine = 1024
define _REPL_STUB_CLS_MAX = 1024
_REPL_STUB_FIELD_MAX: int = 128
_REPL_STUB_VT_MAX: int = 128
_REPL_STUB_TXT_CAP: sizet = 4194304
@@ -42,22 +42,22 @@ _REPL_STUB_NOCOUNT_OPAQUE: int = -2 # meta 里该 key 是 OPAQUE(无 body
# 布局"不可用 ⇒ 明确拒绝"的原因码(_repl_stub_warn_nodata):把"数据缺失"
# (上层数据没到位,补 meta/重跑即可消除)与"判据拒绝"(数据在但不可信,绝不放行)
# 在文案与汇总计数上分开 —— 两类都会走到"不登记 StructEntry",但成因完全不同。
_REPL_SU_NOSTUB: t.CDefine = 1 # 数据缺失:整个模块没有 {sha1}.meta
_REPL_SU_NOCLASS: t.CDefine = 2 # 判据拒绝:meta 存在但无该类的 STRUCT 行
_REPL_SU_OPAQUE: t.CDefine = 3 # 判据拒绝:meta 里该类为 OPAQUE(无 body)
_REPL_SU_PARENT: t.CDefine = 4 # 上游无数据:父类布局不可用/未在会话注册(走 _repl_stub_warn_parent)
define _REPL_SU_NOSTUB = 1 # 数据缺失:整个模块没有 {sha1}.meta
define _REPL_SU_NOCLASS = 2 # 判据拒绝:meta 存在但无该类的 STRUCT 行
define _REPL_SU_OPAQUE = 3 # 判据拒绝:meta 里该类为 OPAQUE(无 body)
define _REPL_SU_PARENT = 4 # 上游无数据:父类布局不可用/未在会话注册(走 _repl_stub_warn_parent)
# ReplStubClass.Flags / MethodFlags 位
_REPL_SF_CVTABLE: t.CDefine = 1
_REPL_SF_NOVTABLE: t.CDefine = 2
_REPL_SF_ANYFUNC: t.CDefine = 4
_REPL_SF_PACKED: t.CDefine = 8
define _REPL_SF_CVTABLE = 1
define _REPL_SF_NOVTABLE = 2
define _REPL_SF_ANYFUNC = 4
define _REPL_SF_PACKED = 8
# ReplStubClass.State
_REPL_SS_REFUSED: t.CDefine = 0 # 布局不可信:永不登记(字段访问明确失败)
_REPL_SS_OK: t.CDefine = 1 # 完整布局已登记
_REPL_SS_PENDING: t.CDefine = 2 # 父类尚未就绪:留待收尾遍
_REPL_SS_EMPTY: t.CDefine = 3 # 无父类/无虚表/字段类型不可解析:交既有 vpi 注入口径
define _REPL_SS_REFUSED = 0 # 布局不可信:永不登记(字段访问明确失败)
define _REPL_SS_OK = 1 # 完整布局已登记
define _REPL_SS_PENDING = 2 # 父类尚未就绪:留待收尾遍
define _REPL_SS_EMPTY = 3 # 无父类/无虚表/字段类型不可解析:交既有 vpi 注入口径
class ReplStubClass:
Key: str # "<sha1>.<类名>"(= 定义侧命名结构体名)
@@ -97,9 +97,9 @@ class ReplStubClass:
# 故改文本提取:ParseVpiIntoModule 读 .vpi stub 时从 vpi_buf 原始文本(函数末尾才释放,始终有效)按行提取 "def m(...) -> Ret:" 的返回注解字符串缓存到 stdlib(持久,不受 pool 状态影响);
# HandlesExprCall._lookup_method_ret_ty_via_vpi 按 sha1.类名.方法名 查表并用 _resolve_vpi_ret_annot_str 纯字符串解析为 LLVMType,返回类型始终来自方法定义处,无白名单/无硬编码。
# ============================================================
VPI_RET_MAX: t.CDefine = 4096
VPI_KEY_LEN: t.CDefine = 224
VPI_RET_LEN: t.CDefine = 224
define VPI_RET_MAX = 4096
define VPI_KEY_LEN = 224
define VPI_RET_LEN = 224
_g_vpi_ret_keys: bytes = None
_g_vpi_ret_strs: bytes = None
@@ -113,9 +113,9 @@ _g_vpi_ret_cap: int = 0
# 调用点缺参(fill 无法超 declare 补)→ 被调函数按 x64 ABI 读残留寄存器/栈槽垃圾。故与返回注解同源:从 vpi_buf 原始文本按行提取参数注解串缓存,
# 注入 declare 时若 tree 参数数不足则用缓存补全,保证 declare 与 define 参数数一致。
# ============================================================
VPI_PARAM_MAX: t.CDefine = 4096
VPI_PARAM_KEY_LEN: t.CDefine = 224
VPI_PARAM_LEN: t.CDefine = 1024
define VPI_PARAM_MAX = 4096
define VPI_PARAM_KEY_LEN = 224
define VPI_PARAM_LEN = 1024
# ============================================================
# 键表开放寻址索引(名 → 槽下标)
@@ -127,12 +127,12 @@ VPI_PARAM_LEN: t.CDefine = 1024
# 顺序递增排列,查找取链上首个"当前键相等"者 = 原线性扫描首个命中(首注册
# 优先)。可信判据 = Built == Count;不可信/未命中一律回退原线性扫描。
# ============================================================
VPI_RET_IDX_CAP: t.CDefine = 8192
VPI_PARAM_IDX_CAP: t.CDefine = 8192
define VPI_RET_IDX_CAP = 8192
define VPI_PARAM_IDX_CAP = 8192
# 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致)
VPI_IDX_FNV_OFFSET: t.CDefine = 2166136261
VPI_IDX_FNV_PRIME: t.CDefine = 16777619
VPI_IDX_FNV_MASK: t.CDefine = 4294967295
define VPI_IDX_FNV_OFFSET = 2166136261
define VPI_IDX_FNV_PRIME = 16777619
define VPI_IDX_FNV_MASK = 4294967295
_g_vpi_param_keys: bytes = None
_g_vpi_param_strs: bytes = None
@@ -845,7 +845,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
break
string.strncpy(seg_buf_t, annots_t + seg_start_t, seg_len_t)
seg_buf_t[seg_len_t] = '\0'
# 类型形参 token(如 T)→ 特化实参(如 str / rawptr[AST] / AST|t.CPtr):
# 类型形参 token(如 T)→ 特化实参(如 str / rawptr[AST] / AST*):
# 模板注解按源码原样缓存,不替换则 `item: T` 解析不出类型(None 跳过)
tparam_t: bytes = stdlib.malloc(tplen_t + 1)
if tparam_t is not None:
@@ -1069,7 +1069,7 @@ def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str,
self 占位(空串)。本函数只做逐字节等值比较,不解析、不做模板类型形参替换
——调用方是跨模块调用的**热路径**(每个实参一次),不能在此分配/解析。
典型用途:判定定义侧形参注解是否为**裸** `str` / `bytes`(用于"str/bytes
不是通用指针通配"这条规则;`str | t.CPtr` 这类组合段不等值,不受影响)。
不是通用指针通配"这条规则;`str*` 这类组合段不等值,不受影响)。
"""
if want is None or seg_idx < 0:
return 0
@@ -1264,8 +1264,8 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
if hit_r >= 0:
stdlib.free(key_buf)
return _g_vpi_ret_strs + hit_r * VPI_RET_LEN
# 泛型特化归一化匹配:list[AST|t.CPtr].get → list[T].get 模板缓存。
# 命中后把模板注解中的类型参数名(如 T)替换为实参(AST|t.CPtr)再返回。
# 泛型特化归一化匹配:list[AST*].get → list[T].get 模板缓存。
# 命中后把模板注解中的类型参数名(如 T)替换为实参(AST*)再返回。
# 不依赖模板类已注册/特化已发生(base.vp 可能先于 list 模块翻译)。
if cls_name is not None:
lbkt_v: str = string.strchr(cls_name, '[')
@@ -1324,13 +1324,13 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
if seg is None or pool is None:
return None
# 【指针实参唯一规范形 `T*`(用户定口径,2026-09-30)】`rawptr[T]` ≡
# `t.CPtr[T]` ≡ `T | t.CPtr` ⇒ 一律折叠为 `T*`(见 TypeGenResolve
# `t.CPtr[T]` ≡ `T*` ⇒ 一律折叠为 `T*`(见 TypeGenResolve
# ._norm_type_arg_name 规则 1.0/1.5)。为什么必须在此补:_subst_template_arg
# 会用**特化类名 `[...]` 内的已归一实参文本**(如 "{sha}.AST*")替换模板注解
# 里的 T,替换结果再送到本函数解析;本函数此前只认 `rawptr[` / `t.CPtr[` /
# 裸 `t.CPtr`,遇到 `{sha}.AST*` 会落到下方 strrchr('.') 取末段得 "AST*" →
# 查 struct miss → **静默**返回 None(跨模块参数/返回宽度被悄悄收窄)。
# 现场:Test/AstTest/App/main.vp:21 的 `list[ast.AST | t.CPtr] | t.CPtr` 特化链。
# 现场:Test/AstTest/App/main.vp:21 的 `list[ast.AST*] | t.CPtr` 特化链。
# 最小改法:把尾随 `*`(先跳尾随空格)按层数重写回**已存在**的 `rawptr[...]`
# 文本形再走原分支(与 `rawptr[` 分支逐字等价,不新写 Ptr 包装逻辑):
# "{sha}.AST*" → "rawptr[{sha}.AST]";"i8**" → "rawptr[rawptr[i8]]"。
@@ -1482,7 +1482,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
#
# 纯字符串解析,避免 _parse_type_string 跨模块构造 ast.Name/ast.BinOp 时节点 kind() 异常(可能退化为裸函数调用)导致 resolve 得到垃圾类型(如 Ptr(i8))。
#
# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; "char" 等 → map_t_type 映射; "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*; "memhub.MemBuddy*" → Ptr(Struct 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,
@@ -1576,13 +1576,13 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# first_wl =1 段是白名单裸标量名(int/char/str/bytes/bool/float/double)
# first_td =1 段是裸 typedef 别名且已成功解析出**非指针**类型(N13,
# 如 sizet/uint64 ⇒ i64):判据=“解析是否成功”,与定义侧
# TypeGenResolve.resolve_annotation_type 的 BinOp(A | t.CPtr)
# TypeGenResolve.resolve_annotation_type 的 BinOp(A*)
# 分支同源(同一 resolve_typedef_or_map 口径)。
first_qual: int = 0
first_wl: int = 0
first_td: int = 0
# CPtr 下标段(t.CPtr[T]/c.CPtr[T],含嵌套)的联合合并参数:cptr_sub_lvl = 该段解析后的外层 Ptr 层数 N(如 t.CPtr[t.CPtr] ⇒ 2);cptr_sub_ty = 该段解析出的类型本身。
# 与定义侧 `X | t.CPtr[T]` 分支同口径:CPtr 侧贡献 N 层指针、另一侧提供基类型 ⇒ Ptr^N(基类型)。
# 与定义侧 `X*[T]` 分支同口径:CPtr 侧贡献 N 层指针、另一侧提供基类型 ⇒ Ptr^N(基类型)。
# 与 has_cptr(裸 t.CPtr 段)分开记录:裸标记恒「追加 1 层」且有 struct 吸收特例,下标路径无吸收,两者在定义侧分属互斥分支。
cptr_sub_lvl: int = 0
cptr_sub_ty: mlirlite.LLVMType* = None
@@ -1595,7 +1595,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
pos += 1
seg_start: sizet = pos
# 只在**顶层**切 `|`:`[...]` 内的 `|` 属于泛型实参内部的联合注解,裸切会把首段
# 截成 `list[ast.AST`(来自 `list[ast.AST | t.CPtr] | t.CPtr`),该段再经
# 截成 `list[ast.AST`(来自 `list[ast.AST*] | t.CPtr`),该段再经
# strrchr('.') 落到 `AST` ⇒ 定义侧解析成 `AST*`(元素的指针),而正确答案是
# list 专化结构的指针(至少也应落 i8* 通配)。深度计数按 `[`/`]`,与
# _cache_vpi_param_annots_text 的顶层逗号切分同口径。
@@ -1624,7 +1624,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
seg_buf[seg_len2] = '\0'
# CPtr 下标段(t.CPtr[T]/c.CPtr[T],含嵌套如 t.CPtr[t.CPtr]):
# 必须先行识别,不能落普通段分支取 first_ty——定义侧
# TypeGenResolve.vp L2596-2639 对 `X | t.CPtr[T]` 是"CPtr 侧贡献
# TypeGenResolve.vp L2596-2639 对 `X*[T]` 是"CPtr 侧贡献
# N 层指针、另一侧给基类型 ⇒ Ptr^N(X)",与"把该段本身当联合取值"
# 语义不同(如 X=struct S、t.CPtr[t.CPtr]:定义侧 Ptr(Ptr(S)),
# 取该段本身则得 i8**)。此处只记录 N 与段类型,末尾统一合并。
@@ -1652,7 +1652,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
cptr_sub_ty = seg_ty_cs
elif string.strcmp(seg_buf, "t.CPtr") == 0 or string.strcmp(seg_buf, "CPtr") == 0:
has_cptr = 1
elif string.strcmp(seg_buf, "t.CVoid") == 0 or string.strcmp(seg_buf, "CVoid") == 0 \
elif string.strcmp(seg_buf, "void") == 0 or string.strcmp(seg_buf, "CVoid") == 0 \
or string.strcmp(seg_buf, "void") == 0:
# 裸名 void 是 t.CVoid 的别名(用户 2026-10-01):必须与 CVoid 同处理,
# 否则会走 else 分支取到 first_td=1 → Ptr(Void) 这种非法类型
@@ -1665,7 +1665,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 记录该段属性(N12):定义侧 TypeGenResolve.resolve_annotation_type
# 对**裸名** pointee 仅在它解析为已注册结构体、泛型参数名或白名单
# 裸标量时才保留 pointee,否则联合坍缩为 i8*;stub 侧此前无条件
# Ptr(first_ty) → `uint64 | t.CPtr` 两侧不一致(定义 i8* vs declare i64*)。
# Ptr(first_ty) → `uint64*` 两侧不一致(定义 i8* vs declare i64*)。
if string.strchr(seg_buf, 46) is not None:
first_qual = 1
if string.strcmp(seg_buf, "int") == 0 or \
@@ -1700,7 +1700,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
pass
# 复刻定义侧规则(N12/N13):限定名 / 白名单裸标量 / 已注册结构体 / 可解析的非指针裸 typedef 别名 → 保留 pointee;
# 其余(解析失败、裸枚举名、指针别名)→ 联合坍缩为 i8*,与定义侧 resolve_annotation_type 对称(两侧同型即收敛)。
# 指针别名(first_td 不置位,如 VOIDPTR = CVoid|CPtr → i8*):`| t.CPtr`
# 指针别名(first_td 不置位,如 VOIDPTR = CVoid* → i8*):`| t.CPtr`
# **恒追加恰好 1 层** → i8**(不吸收);指针型 T 同理(见下)。
if first_qual != 0 or first_wl != 0 or first_td != 0:
return mlirlite.Ptr(pool, first_ty)
@@ -1809,7 +1809,7 @@ def _extract_sha1_from_path(vpi_path: str) -> str:
# → 参数类型解析失败退化为 i8_ptr_ty → 调用侧整数实参触发「整数隐式转指针已禁止」CastError 误报。
# 本函数在被读 stub 的 import 闭包上递归注册 CTypedef/CDefine(防环、限深),使注解解析上下文完整,参数/返回类型不再静默退化。
# ============================================================
_TYPEDEF_VISIT_MAX: t.CDefine = 1024
define _TYPEDEF_VISIT_MAX = 1024
_g_vpi_typedef_visited: bytes = None
_g_vpi_typedef_visited_count: int = 0
@@ -2348,7 +2348,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
else:
src_mod_buf[sri_src] = ch_src
src_mod_buf[sr_len_src] = '\0'
imported_modules = StubMergerStore.AppendImportedModule(
imported_modules = StubMergerStore.AppendImportedModule(
pool, imported_modules, src_mod_buf)
stdlib.free(src_mod_buf)
@@ -2549,7 +2549,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
# 故在重导出注册发现「源 entry 为空」时,按需把 sub_sha1 的 vpi 注入当前模块再重试注册(注入过程递归触发同一逻辑,依赖闭包自动补齐,与加载顺序无关)。
# 防重入表按 sha1 去重(环直接短路);注入失败不改语义,照原逻辑 return 0,不把可恢复问题升级为 fatal。
# ============================================================
VPI_INJ_MAX: t.CDefine = 1024
define VPI_INJ_MAX = 1024
_vpi_inj_sha1s: bytes = None
_vpi_inj_count: int = 0
_vpi_inj_depth: int = 0
@@ -3105,7 +3105,7 @@ def _AggregateParamTy(mod: mlirlite.LLVMModule*,
# ============================================================
# _inject_global_variable_declare - 从 vpi AnnAssign 创建模块级全局变量 declare
#
# vpi 里模块级全局变量(如 tokens.vp 的 _op_head: OpEntry | t.CPtr = None)需在当前模块创建 external global 声明(短名 @name,COFF 按名链接),
# 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*,
@@ -3272,8 +3272,8 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 依赖版本会占用该名字 → forward_declare_functions 见名已存在即 continue
# (FuncGenDef.vp:178-182)→ 本文件自己的签名被静默丢弃,调用点改按依赖签名
# coerce。现场:includes/socket.vp 的
# `extern def connect(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT)`
# 被 w32.winsock2 的 `connect(..., WSASocketAddr | t.CPtr, ...)` 顶掉 →
# `extern def connect(fd: u64, addr: SocketAddr*, addrlen: INT)`
# 被 w32.winsock2 的 `connect(..., WSASocketAddr*, ...)` 顶掉 →
# socket.vp:236 `connect(self.fd, c.Addr(addr), 16)` 报
# 「指针隐式转指针已禁止:SocketAddr* → WSASocketAddr*」。
# 判据只用**裸名**:带 SHA1 前缀的依赖函数名与本文件同名声明不会相互顶替。
+1 -1
View File
@@ -363,7 +363,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str,
stdlib.free(mod_buf)
continue
# 输出槽防御性初始化(成功路径必全写;未找到/未命中时仅 free 槽本身)
# 槽联合必须用 (sizet*):t.CPtr|t.CPtr 会被折叠成 t.CPtr,
# 槽联合必须用 (sizet*):t.CPtr* 会被折叠成 t.CPtr,
# [0] 变成 1 字节访问 → 指针被截断(0x2e 崩溃根因)。CSizeT 成员为
# 8 字节:写侧 sizet(ptr),读侧必须用 rawptr(slot[0]) 做 u64→
# 指针转换;str(slot[0]) 是内置"数字转字符串"(snprintf 到栈缓冲并返回
+1 -1
View File
@@ -422,7 +422,7 @@ def LookupSha1ByModName(mod_name: str) -> str:
# 批处理不登记(表恒空 ⇒ 查询恒 None ⇒ 批处理路径一字不改)。
# 容量:includes 现有 6 个泛型类定义(list/dict 系 + Vector/GSList/ndarray),取 32 槽。
# ============================================================
GENERIC_OWNER_MAX: t.CDefine = 32
define GENERIC_OWNER_MAX = 32
_generic_owner_names: bytes = None
_generic_owner_sha1s: bytes = None
_generic_owner_count: int = 0
+1 -1
View File
@@ -103,7 +103,7 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
dsha1: str = StubMergerIR._FindSha1ByModName(store_sha1_arr, store_mod_arr, store_count, dname_buf)
stdlib.free(dname_buf)
if dsha1 is not None and StubMergerCollect._is_in_sha1_set(dsha1, reachable_set, reachable_count) != 0:
# 中间 int 变量累加:绕过联合类型(CSizeT|CPtr)+ 整数的指针算术编译 bug
# 中间 int 变量累加:绕过联合类型(CSizeT*)+ 整数的指针算术编译 bug
indg: int = indegree[si]
indg = indg + 1
indegree[si] = indg
+7 -7
View File
@@ -30,16 +30,16 @@ import lib.Projectrans.Config as Config
_mbuddy: memhub.MemBuddy*
# 最大 includes SHA1 数(用于过滤)
MAX_INCLUDES_SHA1: t.CDefine = 1024
define MAX_INCLUDES_SHA1 = 1024
# stub/text 读取缓冲区大小
# 1MB 不够:ast/parser.vp 的 text.ll >1MB,读取本地 text.ll 单次截断
# → 尾部丢字(opt: "end of file in global variable name")。
STUB_READ_BUF_SIZE: t.CDefine = 8388608
define STUB_READ_BUF_SIZE = 8388608
# 最大 includes 条目数
MAX_INCLUDES: t.CDefine = 1024
define MAX_INCLUDES = 1024
# 可达性分析 worklist/processed 缓冲区大小(8192 不够:递归扫描 source_dir
# 后 worklist 含全部 App 文件 imports 的拼接 + BFS 依赖展开,追加82 溢出)
REACH_WORKLIST_BUF: t.CDefine = 65536
define REACH_WORKLIST_BUF = 65536
# 全局 SHA1 映射存储器(内存中,不依赖 _sha1_map.txt 文件)
# Phase1 扫描完成后填充,供所有函数使用
@@ -57,9 +57,9 @@ _includes_deps_str: bytes # 依赖字符串数组(每个 512 字节,MAX_IN
_includes_deps_count: int # 条目数
# 单条依赖字符串最大长度
MAX_DEPS_STR_LEN: t.CDefine = 512
define MAX_DEPS_STR_LEN = 512
# rel_path 最大长度
MAX_REL_PATH_LEN: t.CDefine = 256
define MAX_REL_PATH_LEN = 256
# includes 根目录最大长度(绝对路径,多 includes 支持)
MAX_INC_DIR_LEN: t.CDefine = 512
define MAX_INC_DIR_LEN = 512