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:
1 parent
9717ce0107
commit
185a2196ca
57 files changed
+1078
-1078
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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 前缀的依赖函数名与本文件同名声明不会相互顶替。
|
||||
|
||||
@@ -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 到栈缓冲并返回
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user