初步清理 t. 类型异味
This commit is contained in:
1 parent
4ce55e3ea3
commit
cfb92e5da5
84 files changed
+7769
-7907
No files matched your search
@@ -60,7 +60,7 @@ def _eval_binop_valid(node: ast.AST | t.CPtr) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _eval_binop_int(node: ast.AST | t.CPtr) -> t.CInt64T:
|
||||
def _eval_binop_int(node: ast.AST | t.CPtr) -> int64:
|
||||
"""递归计算 BinOp 节点的整数值(64 位,避免大整数 CDefine 截断)"""
|
||||
if node is None:
|
||||
return 0
|
||||
@@ -83,8 +83,8 @@ def _eval_binop_int(node: ast.AST | t.CPtr) -> t.CInt64T:
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
if bop.left is None or bop.right is None:
|
||||
return 0
|
||||
lv: t.CInt64T = _eval_binop_int(bop.left)
|
||||
rv: t.CInt64T = _eval_binop_int(bop.right)
|
||||
lv: int64 = _eval_binop_int(bop.left)
|
||||
rv: int64 = _eval_binop_int(bop.right)
|
||||
if bop.op == ast.OpKind.BitOr:
|
||||
return lv | rv
|
||||
if bop.op == ast.OpKind.BitAnd:
|
||||
@@ -126,7 +126,7 @@ _g_pyi_cdefine_found: int = 0
|
||||
# WINDOW_SIZE = 1<<0 = 1、MASK = 0-1 = -1,跨模块读回错误常量根因)。
|
||||
# _GeneratePyiFromAst 开头按声明顺序注册到本缓存,Name 引用先查缓存。
|
||||
# 缓存一律用 C 数组而非 list[T]:
|
||||
# - 值缓存用 C 数组(t.CInt64T*)而非 list[int]:TPC 对 list[int].get 会误解析
|
||||
# - 值缓存用 C 数组(int64*)而非 list[int]:TPC 对 list[int].get 会误解析
|
||||
# 为 list[str].get(返回元素指针 i8*)→ ptrtoint 返回元素地址而非值 → MASK
|
||||
# 变成 20323785277439(地址-1)。C 数组索引 [i] 直接返回 i64 值,可靠。
|
||||
# - 名缓存用 C 数组(str|t.CPtr = i8**,字符串指针数组)而非 list[str]:
|
||||
@@ -135,11 +135,11 @@ _g_pyi_cdefine_found: int = 0
|
||||
# _fnv1a_hash → 解引用零页 access-violation(1.LOG ASan 崩溃根因)。
|
||||
# 读写沿用 argparse.vp 遍历 argv 的可靠模式:t.CPtr(base + i*8) + e[0]。
|
||||
_g_pyi_cdef_names: str | t.CPtr = None
|
||||
_g_pyi_cdef_vals: t.CInt64T | t.CPtr = None
|
||||
_g_pyi_cdef_count: t.CInt = 0
|
||||
_g_pyi_cdef_vals: int64 | t.CPtr = None
|
||||
_g_pyi_cdef_count: int = 0
|
||||
|
||||
|
||||
def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
|
||||
def _lookup_cdefine_for_pyi(name: str) -> int64:
|
||||
"""从本文件缓存 / 本地 CDefine 表查找常量值(用于 .vpi 生成时的 BinOp 计算)"""
|
||||
global _g_pyi_cdefine_found
|
||||
# 优先查本文件 CDefine 缓存(vpi 生成早于翻译阶段注册,全局表为空)
|
||||
@@ -151,15 +151,15 @@ def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
|
||||
# 碰巧正确)。且绝不能对 _g_pyi_cdef_names 调 .get —— list 联合接收者
|
||||
# 会被误分派为 HashTable.get,索引 inttoptr 成 key 指针读零页崩溃
|
||||
# (1.LOG)。用 t.CPtr(base + i*8) + e[0] 取第 i 个名字指针(argparse 模式)。
|
||||
pn: t.CSizeT = t.CSizeT(_g_pyi_cdef_count)
|
||||
pi: t.CSizeT
|
||||
pn: sizet = sizet(_g_pyi_cdef_count)
|
||||
pi: sizet
|
||||
for pi in range(pn):
|
||||
entry_pc: str | t.CPtr = t.CPtr(t.CUInt64T(_g_pyi_cdef_names) + pi * 8)
|
||||
entry_pc: str | t.CPtr = t.CPtr(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
|
||||
return _g_pyi_cdef_vals[pi]
|
||||
val: t.CInt64T = GenApi.lookup_cdefine_constant(name)
|
||||
val: int64 = GenApi.lookup_cdefine_constant(name)
|
||||
if GenApi.is_cdefine_found() != 0:
|
||||
_g_pyi_cdefine_found = 1
|
||||
return val
|
||||
@@ -167,7 +167,7 @@ def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
|
||||
return 0
|
||||
|
||||
|
||||
def _eval_cdefine_value_cache(node: ast.AST | t.CPtr) -> t.CInt64T:
|
||||
def _eval_cdefine_value_cache(node: ast.AST | t.CPtr) -> int64:
|
||||
"""求值 CDefine 值(Constant/UnaryOp/BinOp/Call/Name),供 vpi 预处理注册缓存"""
|
||||
if node is None:
|
||||
return 0
|
||||
@@ -208,15 +208,15 @@ def _pyi_cdefine_found() -> int:
|
||||
# 将 text 追加到 buf 的 pos 位置,返回新的 pos。
|
||||
# 自动处理缓冲区溢出(截断)。
|
||||
# ============================================================
|
||||
def _PyiEmit(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
text: str) -> t.CSizeT:
|
||||
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: t.CSizeT = string.strlen(text)
|
||||
tlen: sizet = string.strlen(text)
|
||||
if tlen == 0:
|
||||
return pos
|
||||
remain: t.CSizeT = buf_size - pos
|
||||
remain: sizet = buf_size - pos
|
||||
if tlen >= remain:
|
||||
tlen = remain - 1
|
||||
if tlen > 0:
|
||||
@@ -229,8 +229,8 @@ def _PyiEmit(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
#
|
||||
# 追加 level*4 个空格到 buf 的 pos 位置。
|
||||
# ============================================================
|
||||
def _PyiIndent(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
level: int) -> t.CSizeT:
|
||||
def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
level: int) -> sizet:
|
||||
"""追加 level*4 个空格到 buf,返回新的 pos"""
|
||||
i: int = 0
|
||||
while i < level:
|
||||
@@ -245,9 +245,9 @@ def _PyiIndent(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 将 AST 类型注解节点转换为字符串表示,写入 buf 的 pos 位置。
|
||||
# 支持: Name, Attribute, Subscript, BinOp(|), Constant(前向引用), Tuple
|
||||
# ============================================================
|
||||
def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
annot: ast.AST | t.CPtr,
|
||||
depth: int = 0) -> t.CSizeT:
|
||||
depth: int = 0) -> sizet:
|
||||
"""递归生成类型注解字符串,返回新的 pos"""
|
||||
# 递归深度守卫:AST 损坏成自引用环(Attribute.value/Subscript.slice/
|
||||
# BinOp.left 等回指祖先)时无限递归直至栈耗尽(Phase1 vpi 生成最先
|
||||
@@ -256,7 +256,7 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
VLogger.error("vpi 类型注解递归过深(AST 环或嵌套超过 64 层)", "StubGen")
|
||||
sys.exit(1)
|
||||
if annot is None:
|
||||
return _PyiEmit(buf, buf_size, pos, "t.CInt")
|
||||
return _PyiEmit(buf, buf_size, pos, "int")
|
||||
|
||||
k: int = annot.kind()
|
||||
|
||||
@@ -265,9 +265,9 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(annot)
|
||||
if nm.id is not None:
|
||||
return _PyiEmit(buf, buf_size, pos, nm.id)
|
||||
return _PyiEmit(buf, buf_size, pos, "t.CInt")
|
||||
return _PyiEmit(buf, buf_size, pos, "int")
|
||||
|
||||
# Attribute: 属性引用 (如 t.CInt, memhub.MemBuddy)
|
||||
# Attribute: 属性引用 (如 int, memhub.MemBuddy)
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(annot)
|
||||
pos = _PyiTypeStr(buf, buf_size, pos, at.value, depth + 1)
|
||||
@@ -304,8 +304,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
return pos
|
||||
if cn.const_kind == ast.CONST_NONE:
|
||||
return _PyiEmit(buf, buf_size, pos, "None")
|
||||
# 数字常量(t.CArray[t.CUInt32T, 64] 的 count 等):输出数值本身,
|
||||
# 而不是回退 t.CInt——否则 vpi 生成 "t.CArray[..., t.CInt]" 在加载
|
||||
# 数字常量(t.CArray[uint32, 64] 的 count 等):输出数值本身,
|
||||
# 而不是回退 int——否则 vpi 生成 "t.CArray[..., int]" 在加载
|
||||
# stub 时触发 TypeError(count 必须是整数常量、None、CDefine 常量名
|
||||
# 或常量表达式)。
|
||||
if cn.const_kind == ast.CONST_INT or cn.const_kind == ast.CONST_CHAR:
|
||||
@@ -315,15 +315,15 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
pos = _PyiEmit(buf, buf_size, pos, num_buf_ct)
|
||||
stdlib.free(num_buf_ct)
|
||||
return pos
|
||||
return _PyiEmit(buf, buf_size, pos, "t.CInt")
|
||||
return _PyiEmit(buf, buf_size, pos, "int")
|
||||
|
||||
# Tuple: 多参数下标 (如 Dict[str, int])
|
||||
if k == ast.ASTKind.Tuple:
|
||||
tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(annot)
|
||||
if tup.elts is not None:
|
||||
tup_elts: list[ast.AST | t.CPtr] | t.CPtr = tup.elts
|
||||
tn: t.CSizeT = len(tup_elts)
|
||||
ti: t.CSizeT = 0
|
||||
tn: sizet = len(tup_elts)
|
||||
ti: sizet = 0
|
||||
while ti < tn:
|
||||
if ti > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -339,8 +339,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
pos = _PyiEmit(buf, buf_size, pos, "(")
|
||||
if cl.args is not None:
|
||||
cl_args: list[ast.AST | t.CPtr] | t.CPtr = cl.args
|
||||
can: t.CSizeT = len(cl_args)
|
||||
cai: t.CSizeT = 0
|
||||
can: sizet = len(cl_args)
|
||||
cai: sizet = 0
|
||||
while cai < can:
|
||||
if cai > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -350,8 +350,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
pos = _PyiEmit(buf, buf_size, pos, ")")
|
||||
return pos
|
||||
|
||||
# 未知类型,回退到 t.CInt
|
||||
return _PyiEmit(buf, buf_size, pos, "t.CInt")
|
||||
# 未知类型,回退到 int
|
||||
return _PyiEmit(buf, buf_size, pos, "int")
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -363,9 +363,9 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 用默认值填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。
|
||||
# 支持: Constant(int/str/bool/None), Name(CDefine 常量), UnaryOp。
|
||||
# ============================================================
|
||||
def _PyiDefaultStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
node: ast.AST | t.CPtr,
|
||||
depth: int = 0) -> t.CSizeT:
|
||||
depth: int = 0) -> sizet:
|
||||
"""生成默认值表达式文本到 buf,返回新的 pos"""
|
||||
# 递归深度守卫:AST 损坏成自引用环时 fail-fast 终止(同 _PyiTypeStr)
|
||||
if depth > 64:
|
||||
@@ -439,8 +439,8 @@ def _PyiCreturnArgs(decorators: list[ast.AST | t.CPtr] | t.CPtr) -> list[ast.AST
|
||||
"""在装饰器列表里找 @c.CReturn(...),返回其实参列表;未找到返回 None"""
|
||||
if decorators is None:
|
||||
return None
|
||||
dn: t.CSizeT = len(decorators)
|
||||
di: t.CSizeT = 0
|
||||
dn: sizet = len(decorators)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
dnode: ast.AST | t.CPtr = decorators.get(di)
|
||||
di += 1
|
||||
@@ -460,15 +460,15 @@ def _PyiCreturnArgs(decorators: list[ast.AST | t.CPtr] | t.CPtr) -> list[ast.AST
|
||||
#
|
||||
# 格式: def name(param: Type, ...) -> ReturnType: pass
|
||||
# ============================================================
|
||||
def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
fn: ast.FunctionDef | t.CPtr,
|
||||
indent_level: int, class_name: str) -> t.CSizeT:
|
||||
indent_level: int, class_name: str) -> sizet:
|
||||
"""生成函数签名到 buf,返回新的 pos"""
|
||||
# 装饰器
|
||||
if fn.decorator_list is not None:
|
||||
fn_decorator_list: list[ast.AST | t.CPtr] | t.CPtr = fn.decorator_list
|
||||
dn: t.CSizeT = len(fn_decorator_list)
|
||||
di: t.CSizeT = 0
|
||||
dn: sizet = len(fn_decorator_list)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
dec: ast.AST | t.CPtr = fn_decorator_list.get(di)
|
||||
if dec is not None:
|
||||
@@ -493,7 +493,7 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 位置参数
|
||||
if args.args is not None:
|
||||
args_args: list[ast.AST | t.CPtr] | t.CPtr = args.args
|
||||
an: t.CSizeT = len(args_args)
|
||||
an: sizet = len(args_args)
|
||||
# 默认值右对齐到 args 尾部:defaults[i] 对应 args[an - dn + i]。
|
||||
# vpi stub 必须输出 '= <default>',否则 VpiReader 解析后默认参数
|
||||
# 表无条目,跨模块缺参调用(如 depth=0)读到栈垃圾。
|
||||
@@ -501,10 +501,10 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 接收者的 .get 会被 TPC/TPV 误分派——预声明 + 重赋值会解析成
|
||||
# list[int].get 返回 i32 截断指针崩溃;内联声明走 list[ast.ASTptr].get)。
|
||||
arg_defaults: list[ast.AST | t.CPtr] | t.CPtr = args.defaults
|
||||
dn: t.CSizeT = 0
|
||||
dn: sizet = 0
|
||||
if arg_defaults is not None:
|
||||
dn = len(arg_defaults)
|
||||
ai: t.CSizeT = 0
|
||||
ai: sizet = 0
|
||||
while ai < an:
|
||||
if first == 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -516,7 +516,7 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
pos = _PyiEmit(buf, buf_size, pos, ": ")
|
||||
pos = _PyiTypeStr(buf, buf_size, pos, ag.annotation)
|
||||
if arg_defaults is not None and an - dn <= ai:
|
||||
di: t.CSizeT = ai - (an - dn)
|
||||
di: sizet = ai - (an - dn)
|
||||
dnode: ast.AST | t.CPtr = arg_defaults.get(di)
|
||||
if dnode is not None:
|
||||
pos = _PyiEmit(buf, buf_size, pos, " = ")
|
||||
@@ -553,10 +553,10 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 无 `->` 注解但带 @c.CReturn(...):合成 " -> tuple[a, b, c]"(N11)
|
||||
cre_args: list[ast.AST | t.CPtr] | t.CPtr = _PyiCreturnArgs(fn.decorator_list)
|
||||
if cre_args is not None:
|
||||
cre_n: t.CSizeT = len(cre_args)
|
||||
cre_n: sizet = len(cre_args)
|
||||
if cre_n > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, " -> tuple[")
|
||||
cre_i: t.CSizeT = 0
|
||||
cre_i: sizet = 0
|
||||
while cre_i < cre_n:
|
||||
if cre_i > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -576,14 +576,14 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# field: Type
|
||||
# def method(self: Name, ...) -> RetType: pass
|
||||
# ============================================================
|
||||
def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
cls: ast.ClassDef | t.CPtr, indent_level: int) -> t.CSizeT:
|
||||
def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
cls: ast.ClassDef | t.CPtr, indent_level: int) -> sizet:
|
||||
"""生成类定义到 buf,返回新的 pos"""
|
||||
# 装饰器
|
||||
if cls.decorator_list is not None:
|
||||
cls_decorator_list: list[ast.AST | t.CPtr] | t.CPtr = cls.decorator_list
|
||||
dcn: t.CSizeT = len(cls_decorator_list)
|
||||
dci: t.CSizeT = 0
|
||||
dcn: sizet = len(cls_decorator_list)
|
||||
dci: sizet = 0
|
||||
while dci < dcn:
|
||||
ddec: ast.AST | t.CPtr = cls_decorator_list.get(dci)
|
||||
if ddec is not None:
|
||||
@@ -601,10 +601,10 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# PEP 695 类型参数 (class Foo[T]:)
|
||||
if cls.type_params is not None:
|
||||
cls_type_params: list[ast.AST | t.CPtr] | t.CPtr = cls.type_params
|
||||
tpn: t.CSizeT = len(cls_type_params)
|
||||
tpn: sizet = len(cls_type_params)
|
||||
if tpn > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "[")
|
||||
tpi: t.CSizeT = 0
|
||||
tpi: sizet = 0
|
||||
while tpi < tpn:
|
||||
if tpi > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -617,10 +617,10 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# 基类
|
||||
if cls.bases is not None:
|
||||
cls_bases: list[ast.AST | t.CPtr] | t.CPtr = cls.bases
|
||||
bn: t.CSizeT = len(cls_bases)
|
||||
bn: sizet = len(cls_bases)
|
||||
if bn > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "(")
|
||||
bi: t.CSizeT = 0
|
||||
bi: sizet = 0
|
||||
while bi < bn:
|
||||
if bi > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -636,8 +636,8 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
|
||||
if cls.children is not None:
|
||||
cls_children: list[ast.AST | t.CPtr] | t.CPtr = cls.children
|
||||
cn: t.CSizeT = len(cls_children)
|
||||
ci: t.CSizeT = 0
|
||||
cn: sizet = len(cls_children)
|
||||
ci: sizet = 0
|
||||
while ci < cn:
|
||||
stmt: ast.AST | t.CPtr = cls_children.get(ci)
|
||||
if stmt is not None:
|
||||
@@ -650,8 +650,8 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
if mfn.name is not None and string.strcmp(mfn.name, "__init__") == 0:
|
||||
if mfn.children is not None:
|
||||
mfn_children: list[ast.AST | t.CPtr] | t.CPtr = mfn.children
|
||||
icn: t.CSizeT = len(mfn_children)
|
||||
ici: t.CSizeT = 0
|
||||
icn: sizet = len(mfn_children)
|
||||
ici: sizet = 0
|
||||
while ici < icn:
|
||||
ibody: ast.AST | t.CPtr = mfn_children.get(ici)
|
||||
if ibody is not None and ibody.kind() == ast.ASTKind.AnnAssign:
|
||||
@@ -721,12 +721,12 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
|
||||
# ============================================================
|
||||
def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
rel_path: str, buf: bytes,
|
||||
buf_size: t.CSizeT) -> t.CSizeT:
|
||||
buf_size: sizet) -> sizet:
|
||||
"""从 AST 生成 .vpi 存根文件内容到 buf"""
|
||||
if tree is None or buf is None or buf_size == 0:
|
||||
return 0
|
||||
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
|
||||
# 预处理:按声明顺序注册本文件 CDefine 到 _g_pyi 缓存(供 BinOp 求值)
|
||||
# vpi 生成(Phase1 L1614)早于翻译阶段的 CDefine 注册(L1629+),直接查
|
||||
@@ -737,7 +737,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
global _g_pyi_cdef_names, _g_pyi_cdef_vals, _g_pyi_cdef_count
|
||||
if tree.children is not None:
|
||||
pre_children: list[ast.AST | t.CPtr] | t.CPtr = tree.children
|
||||
pcn: t.CSizeT = len(pre_children)
|
||||
pcn: sizet = len(pre_children)
|
||||
# 第一遍:数本文件 t.CDefine 声明数(C 数组需先定长分配)
|
||||
_g_pyi_cdef_count = 0
|
||||
for pci0 in range(pcn):
|
||||
@@ -752,11 +752,11 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
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(t.CSizeT(_g_pyi_cdef_count) * 8))
|
||||
_g_pyi_cdef_vals = (t.CInt64T | t.CPtr)(mb.alloc(t.CSizeT(_g_pyi_cdef_count) * 8))
|
||||
_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))
|
||||
# 第二遍:按声明顺序注册(BinOp 内 Name 引用依赖先前注册项)
|
||||
pci: t.CSizeT = 0
|
||||
cdi: t.CInt = 0
|
||||
pci: sizet = 0
|
||||
cdi: int = 0
|
||||
for pci in range(pcn):
|
||||
stmt_pc: ast.AST | t.CPtr = pre_children.get(pci)
|
||||
if stmt_pc is not None and stmt_pc.kind() == ast.ASTKind.AnnAssign:
|
||||
@@ -768,7 +768,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
ann_pc: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(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 = t.CPtr(t.CUInt64T(_g_pyi_cdef_names) + cdi * 8)
|
||||
slot_pc: str | t.CPtr = t.CPtr(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
|
||||
@@ -782,7 +782,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
return pos
|
||||
|
||||
tree_children: list[ast.AST | t.CPtr] | t.CPtr = tree.children
|
||||
n: t.CSizeT = len(tree_children)
|
||||
n: sizet = len(tree_children)
|
||||
|
||||
# 第一遍扫描:检测 import t/c
|
||||
has_import_t: int = 0
|
||||
@@ -793,7 +793,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
imp: ast.Import | t.CPtr = (ast.Import | t.CPtr)(stmt)
|
||||
if imp.names is not None:
|
||||
imp_names: list[ast.AST | t.CPtr] | t.CPtr = imp.names
|
||||
an: t.CSizeT = len(imp_names)
|
||||
an: sizet = len(imp_names)
|
||||
for ai in range(an):
|
||||
al: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_names.get(ai))
|
||||
if al is not None and al.name is not None:
|
||||
@@ -824,8 +824,8 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
pos = _PyiEmit(buf, buf_size, pos, "import ")
|
||||
if imp2.names is not None:
|
||||
imp2_names: list[ast.AST | t.CPtr] | t.CPtr = imp2.names
|
||||
an2: t.CSizeT = len(imp2_names)
|
||||
ai2: t.CSizeT = 0
|
||||
an2: sizet = len(imp2_names)
|
||||
ai2: sizet = 0
|
||||
while ai2 < an2:
|
||||
if ai2 > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -851,8 +851,8 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
pos = _PyiEmit(buf, buf_size, pos, " import ")
|
||||
if ifr.names is not None:
|
||||
ifr_names: list[ast.AST | t.CPtr] | t.CPtr = ifr.names
|
||||
an3: t.CSizeT = len(ifr_names)
|
||||
ai3: t.CSizeT = 0
|
||||
an3: sizet = len(ifr_names)
|
||||
ai3: sizet = 0
|
||||
while ai3 < an3:
|
||||
if ai3 > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, ", ")
|
||||
@@ -885,7 +885,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
pos = _PyiEmit(buf, buf_size, pos, ": ")
|
||||
pos = _PyiTypeStr(buf, buf_size, pos, aa.annotation)
|
||||
# 如果有值(如 CDefine 常量),输出 = value
|
||||
# CTypedef 特殊处理:值是类型表达式(如 VOIDPTR / t.CVoid | t.CPtr),
|
||||
# CTypedef 特殊处理:值是类型表达式(如 VOIDPTR / t.CPtr),
|
||||
# 不是整数,用 _PyiTypeStr 输出类型字符串
|
||||
is_ctypedef_ann: int = 0
|
||||
if aa.annotation is not None and aa.annotation.kind() == ast.ASTKind.Attribute:
|
||||
@@ -940,7 +940,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
and uop_cv.operand.kind() == ast.ASTKind.Constant:
|
||||
uop_const: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_cv.operand)
|
||||
if uop_const.const_kind == ast.CONST_INT and num_buf_u is not None:
|
||||
neg_val: t.CInt64T = -uop_const.int_val
|
||||
neg_val: int64 = -uop_const.int_val
|
||||
viperlib.snprintf(num_buf_u, 32, " = %lld", neg_val)
|
||||
pos = _PyiEmit(buf, buf_size, pos, num_buf_u)
|
||||
elif aa.value is not None and aa.value.kind() == ast.ASTKind.Call:
|
||||
@@ -974,7 +974,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
and uop_ca.operand.kind() == ast.ASTKind.Constant:
|
||||
uoc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_ca.operand)
|
||||
if uoc.const_kind == ast.CONST_INT and num_buf_cu is not None:
|
||||
neg_c_val: t.CInt64T = -uoc.int_val
|
||||
neg_c_val: int64 = -uoc.int_val
|
||||
viperlib.snprintf(num_buf_cu, 32, " = %lld", neg_c_val)
|
||||
pos = _PyiEmit(buf, buf_size, pos, num_buf_cu)
|
||||
elif uoc.const_kind == ast.CONST_FLOAT:
|
||||
@@ -988,7 +988,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
elif arg_kind == ast.ASTKind.BinOp:
|
||||
# Call 内部的 BinOp(如 t.CUnsignedLong(A | B))
|
||||
# 递归计算 BinOp 值
|
||||
binop_val_bo: t.CInt64T = _eval_binop_int(first_arg)
|
||||
binop_val_bo: int64 = _eval_binop_int(first_arg)
|
||||
num_buf_bo: bytes = mb.alloc(32)
|
||||
if (binop_val_bo != 0 or _eval_binop_valid(first_arg) != 0) \
|
||||
and num_buf_bo is not None:
|
||||
@@ -997,7 +997,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
elif aa.value is not None and aa.value.kind() == ast.ASTKind.BinOp:
|
||||
# 处理 BinOp 常量(如 FOREGROUND_COMBO = FOREGROUND_RED | FOREGROUND_GREEN)
|
||||
# 递归计算 BinOp 值并输出
|
||||
binop_val_av: t.CInt64T = _eval_binop_int(aa.value)
|
||||
binop_val_av: int64 = _eval_binop_int(aa.value)
|
||||
if binop_val_av != 0 or _eval_binop_valid(aa.value) != 0:
|
||||
num_buf_b: bytes = mb.alloc(32)
|
||||
if num_buf_b is not None:
|
||||
@@ -1017,7 +1017,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
asg: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(stmt)
|
||||
if asg.targets is not None and asg.value is not None:
|
||||
asg_targets: list[ast.AST | t.CPtr] | t.CPtr = asg.targets
|
||||
atn: t.CSizeT = len(asg_targets)
|
||||
atn: sizet = len(asg_targets)
|
||||
if atn == 1:
|
||||
atg: ast.AST | t.CPtr = asg_targets.get(0)
|
||||
if atg is not None and atg.kind() == ast.ASTKind.Name:
|
||||
@@ -1041,7 +1041,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
|
||||
pos = _PyiEmit(buf, buf_size, pos, agn.id)
|
||||
pos = _PyiEmit(buf, buf_size, pos, ": ")
|
||||
if inferred == 1:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "t.CInt")
|
||||
pos = _PyiEmit(buf, buf_size, pos, "int")
|
||||
elif inferred == 2:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "t.CDouble")
|
||||
elif inferred == 3:
|
||||
|
||||
+155
-155
@@ -85,26 +85,26 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
string.memset(_g_vpi_ret_keys, 0, VPI_RET_MAX * VPI_KEY_LEN)
|
||||
string.memset(_g_vpi_ret_strs, 0, VPI_RET_MAX * VPI_RET_LEN)
|
||||
_g_vpi_ret_cap = VPI_RET_MAX
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
buf_len: t.CSizeT = string.strlen(vpi_buf)
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
buf_len: sizet = string.strlen(vpi_buf)
|
||||
cur_cls: bytes = None
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
line_no: int = 0
|
||||
while pos < buf_len:
|
||||
ls: t.CSizeT = pos
|
||||
le: t.CSizeT = pos
|
||||
ls: sizet = pos
|
||||
le: sizet = pos
|
||||
while le < buf_len and vpi_buf[le] != '\n':
|
||||
le += 1
|
||||
line_len: t.CSizeT = le - ls
|
||||
line_len: sizet = le - ls
|
||||
# 跳过前导空格,检查 class/def
|
||||
i: t.CSizeT = ls
|
||||
i: sizet = ls
|
||||
while i < le and vpi_buf[i] == ' ':
|
||||
i += 1
|
||||
if i < le:
|
||||
# class X:
|
||||
if line_len >= 6 and string.strncmp(vpi_buf + i, "class ", 6) == 0:
|
||||
cstart: t.CSizeT = i + 6
|
||||
cend: t.CSizeT = cstart
|
||||
cstart: sizet = i + 6
|
||||
cend: sizet = cstart
|
||||
# 类名提取:到 ':' / ' ' / '(' 前停止(继承基类括号不入类名,
|
||||
# 如 "class MemBuddy(MemManager):" → "MemBuddy",与调用方短名一致)
|
||||
while cend < le and vpi_buf[cend] != ':' and vpi_buf[cend] != ' ' and vpi_buf[cend] != '(':
|
||||
@@ -123,14 +123,14 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
if i == ls and cur_cls is not None:
|
||||
stdlib.free(cur_cls)
|
||||
cur_cls = None
|
||||
dstart: t.CSizeT = i + 4
|
||||
dend: t.CSizeT = dstart
|
||||
dstart: sizet = i + 4
|
||||
dend: sizet = dstart
|
||||
while dend < le and vpi_buf[dend] != '(':
|
||||
dend += 1
|
||||
# 方法名 = [dstart, dend)
|
||||
# 找 "->"
|
||||
rpos: t.CSizeT = dstart
|
||||
arrow_pos: t.CSizeT = le
|
||||
rpos: sizet = dstart
|
||||
arrow_pos: sizet = le
|
||||
while rpos < le - 1:
|
||||
if vpi_buf[rpos] == '-' and vpi_buf[rpos + 1] == '>':
|
||||
arrow_pos = rpos
|
||||
@@ -141,13 +141,13 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
# (与 HandlesType.infer_return_type 无 return 语句时的默认行为一致,
|
||||
# 如 json._append_child / __setitem__ 无注解实际编译为 i32)。
|
||||
ret_src: str = None
|
||||
rtype_len: t.CSizeT = 0
|
||||
rtype_len: sizet = 0
|
||||
if arrow_pos < le:
|
||||
# 返回类型 = arrow_pos+2 跳过空格 到 ':' 前
|
||||
rstart2: t.CSizeT = arrow_pos + 2
|
||||
rstart2: sizet = arrow_pos + 2
|
||||
while rstart2 < le and vpi_buf[rstart2] == ' ':
|
||||
rstart2 += 1
|
||||
rend2: t.CSizeT = rstart2
|
||||
rend2: sizet = rstart2
|
||||
while rend2 < le and vpi_buf[rend2] != ':':
|
||||
rend2 += 1
|
||||
if rend2 > rstart2:
|
||||
@@ -159,11 +159,11 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
ret_src = "i32"
|
||||
if ret_src is not None:
|
||||
# 构造 key 和 ret_str,存入缓存
|
||||
mname_len: t.CSizeT = dend - dstart
|
||||
cls_len2: t.CSizeT = 0
|
||||
mname_len: sizet = dend - dstart
|
||||
cls_len2: sizet = 0
|
||||
if cur_cls is not None:
|
||||
cls_len2 = string.strlen(cur_cls)
|
||||
key_len: t.CSizeT = sha1_len + 1 + cls_len2 + 1 + mname_len
|
||||
key_len: sizet = sha1_len + 1 + cls_len2 + 1 + mname_len
|
||||
if key_len < VPI_KEY_LEN and rtype_len < VPI_RET_LEN:
|
||||
# 方法名复制到临时缓冲(vpi_buf+dstart 非 null 结尾,不能直接 snprintf)
|
||||
mname_buf: bytes = stdlib.malloc(mname_len + 1)
|
||||
@@ -234,23 +234,23 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
string.memset(_g_vpi_param_keys, 0, VPI_PARAM_MAX * VPI_PARAM_KEY_LEN)
|
||||
string.memset(_g_vpi_param_strs, 0, VPI_PARAM_MAX * VPI_PARAM_LEN)
|
||||
_g_vpi_param_cap = VPI_PARAM_MAX
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
buf_len: t.CSizeT = string.strlen(vpi_buf)
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
buf_len: sizet = string.strlen(vpi_buf)
|
||||
cur_cls: bytes = None
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos < buf_len:
|
||||
ls: t.CSizeT = pos
|
||||
le: t.CSizeT = pos
|
||||
ls: sizet = pos
|
||||
le: sizet = pos
|
||||
while le < buf_len and vpi_buf[le] != '\n':
|
||||
le += 1
|
||||
line_len: t.CSizeT = le - ls
|
||||
i: t.CSizeT = ls
|
||||
line_len: sizet = le - ls
|
||||
i: sizet = ls
|
||||
while i < le and vpi_buf[i] == ' ':
|
||||
i += 1
|
||||
if i < le:
|
||||
if line_len >= 6 and string.strncmp(vpi_buf + i, "class ", 6) == 0:
|
||||
cstart: t.CSizeT = i + 6
|
||||
cend: t.CSizeT = cstart
|
||||
cstart: sizet = i + 6
|
||||
cend: sizet = cstart
|
||||
while cend < le and vpi_buf[cend] != ':' and vpi_buf[cend] != ' ' and vpi_buf[cend] != '(':
|
||||
cend += 1
|
||||
if cend > cstart:
|
||||
@@ -265,19 +265,19 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
if i == ls and cur_cls is not None:
|
||||
stdlib.free(cur_cls)
|
||||
cur_cls = None
|
||||
dstart: t.CSizeT = i + 4
|
||||
dend: t.CSizeT = dstart
|
||||
dstart: sizet = i + 4
|
||||
dend: sizet = dstart
|
||||
while dend < le and vpi_buf[dend] != '(':
|
||||
dend += 1
|
||||
if dend >= le:
|
||||
pos = le + 1
|
||||
continue
|
||||
# 找匹配的 ')'(深度感知:注解可含 t.CArray[...] / tuple[...] 括号)
|
||||
p: t.CSizeT = dend + 1
|
||||
p: sizet = dend + 1
|
||||
pdepth: int = 0
|
||||
pend: t.CSizeT = dend
|
||||
pend: sizet = dend
|
||||
while p < le:
|
||||
ch_p: t.CChar = vpi_buf[p]
|
||||
ch_p: char = vpi_buf[p]
|
||||
if ch_p == '(' or ch_p == '[' or ch_p == '{':
|
||||
pdepth += 1
|
||||
elif ch_p == ')' or ch_p == ']' or ch_p == '}':
|
||||
@@ -292,18 +292,18 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
pos = le + 1
|
||||
continue
|
||||
plist[0] = '\0'
|
||||
plist_pos: t.CSizeT = 0
|
||||
plist_pos: sizet = 0
|
||||
seg_written: int = 0
|
||||
seg_cur: t.CSizeT = dend + 1
|
||||
seg_cur: sizet = dend + 1
|
||||
while seg_cur < pend:
|
||||
while seg_cur < pend and (vpi_buf[seg_cur] == ' ' or vpi_buf[seg_cur] == ','):
|
||||
seg_cur += 1
|
||||
if seg_cur >= pend:
|
||||
break
|
||||
s_start: t.CSizeT = seg_cur
|
||||
s_start: sizet = seg_cur
|
||||
sd: int = 0
|
||||
while seg_cur < pend:
|
||||
ch_s: t.CChar = vpi_buf[seg_cur]
|
||||
ch_s: char = vpi_buf[seg_cur]
|
||||
if ch_s == '(' or ch_s == '[' or ch_s == '{':
|
||||
sd += 1
|
||||
elif ch_s == ')' or ch_s == ']' or ch_s == '}':
|
||||
@@ -311,9 +311,9 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
elif ch_s == ',' and sd == 0:
|
||||
break
|
||||
seg_cur += 1
|
||||
s_end: t.CSizeT = seg_cur
|
||||
s_end: sizet = seg_cur
|
||||
# 跳过 * / **(vararg/kwarg 不入 args 列表)
|
||||
st: t.CSizeT = s_start
|
||||
st: sizet = s_start
|
||||
while st < s_end and vpi_buf[st] == ' ':
|
||||
st += 1
|
||||
if st < s_end and vpi_buf[st] == '*':
|
||||
@@ -321,10 +321,10 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
seg_cur += 1
|
||||
continue
|
||||
# 截断默认值(顶层 '=',如 ": str = None")
|
||||
e_pos: t.CSizeT = st
|
||||
e_pos: sizet = st
|
||||
ed: int = 0
|
||||
while e_pos < s_end:
|
||||
ch_e: t.CChar = vpi_buf[e_pos]
|
||||
ch_e: char = vpi_buf[e_pos]
|
||||
if ch_e == '(' or ch_e == '[' or ch_e == '{':
|
||||
ed += 1
|
||||
elif ch_e == ')' or ch_e == ']' or ch_e == '}':
|
||||
@@ -334,11 +334,11 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
e_pos += 1
|
||||
s_end = e_pos
|
||||
# 提取注解:顶层 ':' 之后(无 ':' → 空串,如 self)
|
||||
c_pos: t.CSizeT = st
|
||||
c_pos: sizet = st
|
||||
cd2: int = 0
|
||||
annot_start: t.CSizeT = s_end
|
||||
annot_start: sizet = s_end
|
||||
while c_pos < s_end:
|
||||
ch_c: t.CChar = vpi_buf[c_pos]
|
||||
ch_c: char = vpi_buf[c_pos]
|
||||
if ch_c == '(' or ch_c == '[' or ch_c == '{':
|
||||
cd2 += 1
|
||||
elif ch_c == ')' or ch_c == ']' or ch_c == '}':
|
||||
@@ -347,17 +347,17 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
annot_start = c_pos + 1
|
||||
break
|
||||
c_pos += 1
|
||||
a_start: t.CSizeT = annot_start
|
||||
a_start: sizet = annot_start
|
||||
while a_start < s_end and vpi_buf[a_start] == ' ':
|
||||
a_start += 1
|
||||
a_end: t.CSizeT = s_end
|
||||
a_end: sizet = s_end
|
||||
while a_end > a_start and vpi_buf[a_end - 1] == ' ':
|
||||
a_end -= 1
|
||||
if plist_pos + (a_end - a_start) + 1 < VPI_PARAM_LEN:
|
||||
if seg_written > 0:
|
||||
plist[plist_pos] = '@'
|
||||
plist_pos += 1
|
||||
ai2: t.CSizeT
|
||||
ai2: sizet
|
||||
for ai2 in range(a_end - a_start):
|
||||
plist[plist_pos] = vpi_buf[a_start + ai2]
|
||||
plist_pos += 1
|
||||
@@ -367,11 +367,11 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
seg_cur += 1
|
||||
# 存入缓存(key = sha1.class.method / sha1.method,去重)
|
||||
if plist_pos > 0 and plist[0] != '\0':
|
||||
mname_len: t.CSizeT = dend - dstart
|
||||
cls_len2: t.CSizeT = 0
|
||||
mname_len: sizet = dend - dstart
|
||||
cls_len2: sizet = 0
|
||||
if cur_cls is not None:
|
||||
cls_len2 = string.strlen(cur_cls)
|
||||
key_len: t.CSizeT = sha1_len + 1 + cls_len2 + 1 + mname_len
|
||||
key_len: sizet = sha1_len + 1 + cls_len2 + 1 + mname_len
|
||||
if key_len < VPI_PARAM_KEY_LEN:
|
||||
mname_buf: bytes = stdlib.malloc(mname_len + 1)
|
||||
if mname_buf is not None:
|
||||
@@ -437,12 +437,12 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) ->
|
||||
"""查参数注解缓存;返回注解串('@' 分隔,含首参空串占位)或 None"""
|
||||
if src_sha1 is None or method_name is None or _g_vpi_param_keys is None:
|
||||
return None
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
mlen: t.CSizeT = string.strlen(method_name)
|
||||
clen: t.CSizeT = 0
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
mlen: sizet = string.strlen(method_name)
|
||||
clen: sizet = 0
|
||||
if cls_name is not None:
|
||||
clen = string.strlen(cls_name)
|
||||
key_len: t.CSizeT = sha1_len + clen + mlen + 2
|
||||
key_len: sizet = sha1_len + clen + mlen + 2
|
||||
if key_len >= VPI_PARAM_KEY_LEN:
|
||||
return None
|
||||
key_buf: bytes = stdlib.malloc(key_len + 1)
|
||||
@@ -486,7 +486,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
|
||||
return param_count
|
||||
# 统计文本参数数('@' 分隔;段数 = 分隔符数 + 1,含首参)
|
||||
pa_count: int = 1
|
||||
pi2: t.CSizeT = 0
|
||||
pi2: sizet = 0
|
||||
while prm_annots[pi2] != '\0':
|
||||
if prm_annots[pi2] == '@':
|
||||
pa_count += 1
|
||||
@@ -495,12 +495,12 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
|
||||
return param_count
|
||||
# 补全缺失参数:段索引 >= param_count 的段即缺失参数位置
|
||||
seg_idx: int = 0
|
||||
seg_start2: t.CSizeT = 0
|
||||
cur2: t.CSizeT = 0
|
||||
seg_start2: sizet = 0
|
||||
cur2: sizet = 0
|
||||
while prm_annots[cur2] != '\0':
|
||||
while prm_annots[cur2] != '\0' and prm_annots[cur2] != '@':
|
||||
cur2 += 1
|
||||
seg_len2: t.CSizeT = cur2 - seg_start2
|
||||
seg_len2: sizet = cur2 - seg_start2
|
||||
if prm_annots[cur2] == '@':
|
||||
cur2 += 1
|
||||
if seg_idx >= param_count:
|
||||
@@ -526,7 +526,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
|
||||
#
|
||||
# 返回类型已用字符串注解缓存解析(绕开 vpi tree 深层节点 kind() 损坏,见
|
||||
# _inject_method_declare L1673-1675 注释);参数此前仍走 AST
|
||||
# resolve_annotation_type,同样会得垃圾类型(如 t.CSizeT → i32),跨模块
|
||||
# resolve_annotation_type,同样会得垃圾类型(如 sizet → i32),跨模块
|
||||
# declare 参数类型错 → 调用侧 trunc i64→i32 传参、callee 按 i64 读栈残留
|
||||
# 垃圾高位 → can=巨值读未写槽位崩溃(SlotsBugTest 根因)。
|
||||
# 此处与返回类型同源:从 @-joined 注解串取第 seg_idx 段(0=self 空段),
|
||||
@@ -545,7 +545,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy | t.CPtr,
|
||||
prm_annots_p: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name)
|
||||
if prm_annots_p is None or prm_annots_p[0] == '\0':
|
||||
return None
|
||||
cur_p: t.CSizeT = 0
|
||||
cur_p: sizet = 0
|
||||
cur_seg_p: int = 0
|
||||
while cur_seg_p < seg_idx and prm_annots_p[cur_p] != '\0':
|
||||
while prm_annots_p[cur_p] != '\0' and prm_annots_p[cur_p] != '@':
|
||||
@@ -553,8 +553,8 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy | t.CPtr,
|
||||
if prm_annots_p[cur_p] == '@':
|
||||
cur_p += 1
|
||||
cur_seg_p += 1
|
||||
seg_start_p: t.CSizeT = cur_p
|
||||
seg_len_p: t.CSizeT = 0
|
||||
seg_start_p: sizet = cur_p
|
||||
seg_len_p: sizet = 0
|
||||
while prm_annots_p[seg_start_p + seg_len_p] != '\0' \
|
||||
and prm_annots_p[seg_start_p + seg_len_p] != '@':
|
||||
seg_len_p += 1
|
||||
@@ -615,7 +615,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
"""按需加载模块 vpi stub 的返回注解缓存,返回 1=已就绪 / 0=失败"""
|
||||
if src_sha1 is None or temp_dir is None:
|
||||
return 0
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
if sha1_len < 2:
|
||||
return 0
|
||||
# 该模块已有缓存条目 → 跳过(幂等)
|
||||
@@ -626,8 +626,8 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
if string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
return 1
|
||||
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
|
||||
td_len: t.CSizeT = string.strlen(temp_dir)
|
||||
path_len: t.CSizeT = td_len + sha1_len + 12
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
path_len: sizet = td_len + sha1_len + 12
|
||||
vpi_path: bytes = stdlib.malloc(path_len)
|
||||
if vpi_path is None:
|
||||
return 0
|
||||
@@ -673,7 +673,7 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
"""按需加载模块 vpi stub 的参数注解缓存,返回 1=已就绪 / 0=失败"""
|
||||
if src_sha1 is None or temp_dir is None:
|
||||
return 0
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
if sha1_len < 2:
|
||||
return 0
|
||||
# 该模块已有参数缓存条目 → 跳过(幂等)
|
||||
@@ -684,8 +684,8 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
if string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
return 1
|
||||
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
|
||||
td_len: t.CSizeT = string.strlen(temp_dir)
|
||||
path_len: t.CSizeT = td_len + sha1_len + 12
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
path_len: sizet = td_len + sha1_len + 12
|
||||
vpi_path: bytes = stdlib.malloc(path_len)
|
||||
if vpi_path is None:
|
||||
return 0
|
||||
@@ -721,31 +721,31 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
#
|
||||
# 泛型模板返回注解(如 list[T].get -> T)中的类型参数名(T)
|
||||
# 需替换为实际特化实参(AST|t.CPtr)后才能解析。仅替换前后
|
||||
# 非字母数字下划线边界的独立 token(避免误替换 t.CSizeT 等)。
|
||||
# 非字母数字下划线边界的独立 token(避免误替换 sizet 等)。
|
||||
# 返回 stdlib 新分配字符串(调用者负责 free);失败返回 None。
|
||||
# ============================================================
|
||||
def _subst_template_arg(annot: str, tparam: str, targ: str) -> str:
|
||||
"""替换 annot 中独立的 tparam token 为 targ"""
|
||||
if annot is None or tparam is None or targ is None:
|
||||
return None
|
||||
alen: t.CSizeT = string.strlen(annot)
|
||||
tplen: t.CSizeT = string.strlen(tparam)
|
||||
tglen: t.CSizeT = string.strlen(targ)
|
||||
alen: sizet = string.strlen(annot)
|
||||
tplen: sizet = string.strlen(tparam)
|
||||
tglen: sizet = string.strlen(targ)
|
||||
if tplen == 0 or tplen > alen:
|
||||
return annot
|
||||
# 容量 = alen + tglen*8 + 16 只覆盖 ≤8 次替换;替换次数无上限时
|
||||
# opos 会越界写穿 stdlib 堆(哨兵盲区 → CRT 堆损坏后任意 malloc/free
|
||||
# 静默段错误、崩溃点漂移)。按最坏上界分配:每替换消耗 tplen 写 tglen,
|
||||
# 最坏全部被替换 → alen + (alen/tplen)*tglen + 1。
|
||||
max_sub: t.CSizeT = alen / tplen
|
||||
max_sub: sizet = alen / tplen
|
||||
if max_sub == 0:
|
||||
max_sub = 1
|
||||
out_size: t.CSizeT = alen + max_sub * tglen + 1
|
||||
out_size: sizet = alen + max_sub * tglen + 1
|
||||
out: bytes = stdlib.malloc(out_size)
|
||||
if out is None:
|
||||
return None
|
||||
opos: t.CSizeT = 0
|
||||
p: t.CSizeT = 0
|
||||
opos: sizet = 0
|
||||
p: sizet = 0
|
||||
while p < alen:
|
||||
# 防御:opos 超分配即 fail-fast 返回 None(绝不越界写)
|
||||
if opos >= out_size:
|
||||
@@ -790,12 +790,12 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
|
||||
return None
|
||||
if src_sha1 is None or method_name is None:
|
||||
return None
|
||||
sha1_len: t.CSizeT = string.strlen(src_sha1)
|
||||
cl_len: t.CSizeT = 0
|
||||
sha1_len: sizet = string.strlen(src_sha1)
|
||||
cl_len: sizet = 0
|
||||
if cls_name is not None:
|
||||
cl_len = string.strlen(cls_name)
|
||||
me_len: t.CSizeT = string.strlen(method_name)
|
||||
key_len: t.CSizeT = sha1_len + 1 + cl_len + 1 + me_len
|
||||
me_len: sizet = string.strlen(method_name)
|
||||
key_len: sizet = sha1_len + 1 + cl_len + 1 + me_len
|
||||
key_buf: bytes = stdlib.malloc(key_len + 1)
|
||||
if key_buf is None:
|
||||
return None
|
||||
@@ -816,8 +816,8 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
|
||||
if lbkt_v is not None:
|
||||
rbkt_v: str = string.strrchr(cls_name, ']')
|
||||
if rbkt_v is not None and rbkt_v > lbkt_v:
|
||||
base_len_v: t.CSizeT = t.CSizeT(t.CUInt64T(lbkt_v) - t.CUInt64T(cls_name))
|
||||
param_len_v: t.CSizeT = t.CSizeT(t.CUInt64T(rbkt_v) - t.CUInt64T(lbkt_v) - 1)
|
||||
base_len_v: sizet = sizet(uint64(lbkt_v) - uint64(cls_name))
|
||||
param_len_v: sizet = sizet(uint64(rbkt_v) - uint64(lbkt_v) - 1)
|
||||
if base_len_v > 0 and param_len_v > 0:
|
||||
base_v: str = stdlib.malloc(base_len_v + 1)
|
||||
param_v: str = stdlib.malloc(param_len_v + 1)
|
||||
@@ -836,8 +836,8 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
|
||||
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: t.CSizeT = t.CSizeT(
|
||||
t.CUInt64T(gklb) - t.CUInt64T(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)
|
||||
@@ -958,8 +958,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
# resolve 得到垃圾类型(如 Ptr(i8))。此处纯字符串解析避免该问题。
|
||||
#
|
||||
# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1;
|
||||
# "t.CChar" 等 → map_t_type 映射;
|
||||
# "X | t.CPtr" → Ptr(Struct X); "t.CVoid | t.CPtr" → i8*;
|
||||
# "char" 等 → map_t_type 映射;
|
||||
# "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*;
|
||||
# "memhub.MemBuddy | t.CPtr" → Ptr(Struct MemBuddy)。
|
||||
# ============================================================
|
||||
def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
@@ -975,7 +975,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
# b2a_hqx -> tuple[str, t.CUnsignedShort] 之前按普通段解析失败 → 调用侧
|
||||
# 返回类型退化 i8* → tuple 解包失效(hqx 段崩溃根因)。
|
||||
if string.strncmp(ret_annot, "tuple[", 6) == 0:
|
||||
inner_len_t: t.CSizeT = 0
|
||||
inner_len_t: sizet = 0
|
||||
while ret_annot[6 + inner_len_t] != ']' and ret_annot[6 + inner_len_t] != '\0':
|
||||
inner_len_t += 1
|
||||
if ret_annot[6 + inner_len_t] != ']' or inner_len_t == 0:
|
||||
@@ -983,19 +983,19 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
tup_head_t: llvmlite.ParamNode | t.CPtr = None
|
||||
tup_tail_t: llvmlite.ParamNode | t.CPtr = None
|
||||
tup_count_t: int = 0
|
||||
p_t: t.CSizeT = 0
|
||||
p_t: sizet = 0
|
||||
while p_t < inner_len_t:
|
||||
# 跳过前导空格/逗号
|
||||
while p_t < inner_len_t and (ret_annot[6 + p_t] == ' ' or ret_annot[6 + p_t] == ','):
|
||||
p_t += 1
|
||||
seg_s_t: t.CSizeT = p_t
|
||||
seg_s_t: sizet = p_t
|
||||
while p_t < inner_len_t and ret_annot[6 + p_t] != ',':
|
||||
p_t += 1
|
||||
seg_e_t: t.CSizeT = p_t
|
||||
seg_e_t: sizet = p_t
|
||||
while seg_e_t > seg_s_t and ret_annot[6 + seg_e_t - 1] == ' ':
|
||||
seg_e_t -= 1
|
||||
if seg_e_t > seg_s_t:
|
||||
seg_len_t: t.CSizeT = seg_e_t - seg_s_t
|
||||
seg_len_t: sizet = seg_e_t - seg_s_t
|
||||
seg_buf_t: bytes = stdlib.malloc(seg_len_t + 1)
|
||||
if seg_buf_t is None:
|
||||
return None
|
||||
@@ -1022,26 +1022,26 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
has_cvoid: int = 0
|
||||
first_ty: llvmlite.LLVMType | t.CPtr = None
|
||||
# 产生 first_ty 那一段文本的属性(供末尾 has_cptr 分支复刻定义侧规则,N12):
|
||||
# first_qual=1 段是限定名(含 '.',如 t.CUInt64T / mod.Class)
|
||||
# first_qual=1 段是限定名(含 '.',如 uint64 / mod.Class)
|
||||
# first_wl =1 段是白名单裸标量名(int/char/str/bytes/bool/float/double)
|
||||
first_qual: int = 0
|
||||
first_wl: int = 0
|
||||
|
||||
buf_len: t.CSizeT = string.strlen(ret_annot)
|
||||
pos: t.CSizeT = 0
|
||||
buf_len: sizet = string.strlen(ret_annot)
|
||||
pos: sizet = 0
|
||||
while pos <= buf_len:
|
||||
# 跳过前导空格
|
||||
while pos < buf_len and ret_annot[pos] == ' ':
|
||||
pos += 1
|
||||
seg_start: t.CSizeT = pos
|
||||
seg_start: sizet = pos
|
||||
while pos < buf_len and ret_annot[pos] != '|':
|
||||
pos += 1
|
||||
seg_end: t.CSizeT = pos
|
||||
seg_end: sizet = pos
|
||||
# trim 尾随空格
|
||||
while seg_end > seg_start and ret_annot[seg_end - 1] == ' ':
|
||||
seg_end -= 1
|
||||
if seg_end > seg_start:
|
||||
seg_len2: t.CSizeT = seg_end - seg_start
|
||||
seg_len2: sizet = seg_end - seg_start
|
||||
seg_buf: bytes = stdlib.malloc(seg_len2 + 1)
|
||||
if seg_buf is None:
|
||||
break
|
||||
@@ -1109,10 +1109,10 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
# ============================================================
|
||||
|
||||
# .vpi 读取缓冲区大小(256KB,与 PYI_BUF_SIZE 一致)
|
||||
VPI_READ_BUF_SIZE: t.CSizeT = 262144
|
||||
VPI_READ_BUF_SIZE: sizet = 262144
|
||||
|
||||
# SHA1 字符串长度(16 hex 字符)
|
||||
SHA1_LEN: t.CSizeT = 16
|
||||
SHA1_LEN: sizet = 16
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -1133,14 +1133,14 @@ def _extract_sha1_from_path(vpi_path: str) -> str:
|
||||
if vpi_path is None:
|
||||
return None
|
||||
# 查找最后一个路径分隔符 / 或 \
|
||||
total_len: t.CSizeT = string.strlen(vpi_path)
|
||||
total_len: sizet = string.strlen(vpi_path)
|
||||
if total_len < SHA1_LEN + 4: # 至少需要 "xxxx.vpi" 的长度
|
||||
return None
|
||||
# 从后向前查找最后一个 / 或 \
|
||||
sep_pos: t.CSizeT = total_len
|
||||
sep_pos: sizet = total_len
|
||||
while sep_pos > 0:
|
||||
sep_pos -= 1
|
||||
ch: t.CChar = vpi_path[sep_pos]
|
||||
ch: char = vpi_path[sep_pos]
|
||||
if ch == '/' or ch == '\\':
|
||||
sep_pos += 1
|
||||
break
|
||||
@@ -1167,13 +1167,13 @@ def _stub_add_imported(pool: memhub.MemBuddy | t.CPtr,
|
||||
if name is None:
|
||||
return cur
|
||||
if cur is None:
|
||||
nlen: t.CSizeT = string.strlen(name)
|
||||
nlen: sizet = string.strlen(name)
|
||||
buf: str = pool.alloc(nlen + 1)
|
||||
if buf is not None:
|
||||
string.strcpy(buf, name)
|
||||
return buf
|
||||
old_len: t.CSizeT = string.strlen(cur)
|
||||
name_len: t.CSizeT = string.strlen(name)
|
||||
old_len: sizet = string.strlen(cur)
|
||||
name_len: sizet = string.strlen(name)
|
||||
buf2: str = pool.alloc(old_len + 1 + name_len + 1)
|
||||
if buf2 is not None:
|
||||
string.strcpy(buf2, cur)
|
||||
@@ -1199,8 +1199,8 @@ def _stub_add_from(pool: memhub.MemBuddy | t.CPtr,
|
||||
viperlib.snprintf(entry, 256, "%s:%s", local, mod)
|
||||
if cur is None:
|
||||
return entry
|
||||
old_len: t.CSizeT = string.strlen(cur)
|
||||
entry_len: t.CSizeT = string.strlen(entry)
|
||||
old_len: sizet = string.strlen(cur)
|
||||
entry_len: sizet = string.strlen(entry)
|
||||
buf: str = pool.alloc(old_len + 1 + entry_len + 1)
|
||||
if buf is not None:
|
||||
string.strcpy(buf, cur)
|
||||
@@ -1281,18 +1281,18 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
return 0
|
||||
if depth > 8:
|
||||
return 0
|
||||
td_len: t.CSizeT = string.strlen(temp_dir)
|
||||
total_len: t.CSizeT = string.strlen(import_mods)
|
||||
pos: t.CSizeT = 0
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
total_len: sizet = string.strlen(import_mods)
|
||||
pos: sizet = 0
|
||||
while pos < total_len:
|
||||
while pos < total_len and import_mods[pos] == ' ':
|
||||
pos += 1
|
||||
if pos >= total_len:
|
||||
break
|
||||
m_start: t.CSizeT = pos
|
||||
m_start: sizet = pos
|
||||
while pos < total_len and import_mods[pos] != ' ':
|
||||
pos += 1
|
||||
m_len: t.CSizeT = pos - m_start
|
||||
m_len: sizet = pos - m_start
|
||||
if m_len == 0:
|
||||
continue
|
||||
# t/c 内建库不编译,无 vpi stub
|
||||
@@ -1311,7 +1311,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
continue
|
||||
# 构造 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(手写拼接,与
|
||||
# _ensure_vpi_ret_annot_loaded 一致,避免引入 StubMergerCollect 环依赖)
|
||||
path_len_r: t.CSizeT = td_len + 16 + 12
|
||||
path_len_r: sizet = td_len + 16 + 12
|
||||
vpi_path_r: bytes = stdlib.malloc(path_len_r)
|
||||
if vpi_path_r is None:
|
||||
continue
|
||||
@@ -1346,13 +1346,13 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
tree_r: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens_r)
|
||||
if tree_r is not None and tree_r.children is not None:
|
||||
ch_r: list[ast.AST | t.CPtr] | t.CPtr = tree_r.children
|
||||
cn_r: t.CSizeT = len(ch_r)
|
||||
cn_r: sizet = len(ch_r)
|
||||
# 第一遍:收集子模块 imports(递归闭包)
|
||||
sub_imports: bytes = stdlib.malloc(4096)
|
||||
if sub_imports is not None:
|
||||
sub_imports[0] = '\0'
|
||||
sub_len: t.CSizeT = 0
|
||||
ci_r: t.CSizeT
|
||||
sub_len: sizet = 0
|
||||
ci_r: sizet
|
||||
for ci_r in range(cn_r):
|
||||
child_r: ast.AST | t.CPtr = ch_r.get(ci_r)
|
||||
if child_r is None:
|
||||
@@ -1361,12 +1361,12 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
if kk_r == ast.ASTKind.Import:
|
||||
imp_r: ast.Import | t.CPtr = (ast.Import | t.CPtr)(child_r)
|
||||
if imp_r.names is not None:
|
||||
in_n: t.CSizeT = len(imp_r.names)
|
||||
ii_r: t.CSizeT
|
||||
in_n: sizet = len(imp_r.names)
|
||||
ii_r: sizet
|
||||
for ii_r in range(in_n):
|
||||
al_r: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_r.names.get(ii_r))
|
||||
if al_r is not None and al_r.name is not None:
|
||||
il_r: t.CSizeT = string.strlen(al_r.name)
|
||||
il_r: sizet = string.strlen(al_r.name)
|
||||
if sub_len + il_r + 2 < 4096:
|
||||
if sub_len > 0:
|
||||
sub_imports[sub_len] = ' '
|
||||
@@ -1377,7 +1377,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
elif kk_r == ast.ASTKind.ImportFrom:
|
||||
ifr_r: ast.ImportFrom | t.CPtr = (ast.ImportFrom | t.CPtr)(child_r)
|
||||
if ifr_r.module is not None:
|
||||
ml_r: t.CSizeT = string.strlen(ifr_r.module)
|
||||
ml_r: sizet = string.strlen(ifr_r.module)
|
||||
if sub_len + ml_r + 2 < 4096:
|
||||
if sub_len > 0:
|
||||
sub_imports[sub_len] = ' '
|
||||
@@ -1386,7 +1386,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
sub_len += ml_r
|
||||
sub_imports[sub_len] = '\0'
|
||||
# 第二遍:注册本模块 AnnAssign 的 CTypedef/CDefine
|
||||
ci2_r: t.CSizeT
|
||||
ci2_r: sizet
|
||||
for ci2_r in range(cn_r):
|
||||
child2_r: ast.AST | t.CPtr = ch_r.get(ci2_r)
|
||||
if child2_r is None:
|
||||
@@ -1409,7 +1409,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
|
||||
if cn_v.const_kind == ast.CONST_FLOAT:
|
||||
GenApi.register_cdefine_double(pool, cdef_t.id, cn_v.float_val)
|
||||
elif cn_v.const_kind == ast.CONST_INT:
|
||||
cdef_val: t.CInt64T = GenApi.extract_cdefine_int_value(aa_r.value)
|
||||
cdef_val: int64 = GenApi.extract_cdefine_int_value(aa_r.value)
|
||||
GenApi.register_cdefine_constant(pool, cdef_t.id, cdef_val)
|
||||
# 递归处理子模块 imports(防环由 visited 标记保证)
|
||||
if sub_imports[0] != '\0':
|
||||
@@ -1517,7 +1517,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
if src_sha1 is not None:
|
||||
stdlib.free(src_sha1)
|
||||
return 1
|
||||
n: t.CSizeT = len(ch)
|
||||
n: sizet = len(ch)
|
||||
|
||||
# 收集 stub 内被读模块自己的 import 语句,构建独立的注解解析上下文。
|
||||
# .vpi stub 顶部含被读模块的 import(Converter 已写入,如 string.vp 的
|
||||
@@ -1525,7 +1525,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 解析注解——根治跨上下文误报(如 t.CArray[str] 需要 't' 已导入)。
|
||||
stub_imported_modules: str = None
|
||||
stub_from_imports: str = None
|
||||
si: t.CSizeT
|
||||
si: sizet
|
||||
for si in range(n):
|
||||
schild: ast.AST | t.CPtr = ch.get(si)
|
||||
if schild is None:
|
||||
@@ -1534,8 +1534,8 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
if sk == ast.ASTKind.Import:
|
||||
simp: ast.Import | t.CPtr = (ast.Import | t.CPtr)(schild)
|
||||
if simp.names is not None:
|
||||
sn_n: t.CSizeT = len(simp.names)
|
||||
sni: t.CSizeT
|
||||
sn_n: sizet = len(simp.names)
|
||||
sni: sizet
|
||||
for sni in range(sn_n):
|
||||
sal: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(simp.names.get(sni))
|
||||
if sal is not None and sal.name is not None:
|
||||
@@ -1578,8 +1578,8 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
else:
|
||||
sub_sha1_rt = StubMergerStore.LookupSha1ByModName(sifr_mod)
|
||||
if sifr.names is not None:
|
||||
sifr_nn: t.CSizeT = len(sifr.names)
|
||||
sifri: t.CSizeT
|
||||
sifr_nn: sizet = len(sifr.names)
|
||||
sifri: sizet
|
||||
for sifri in range(sifr_nn):
|
||||
sial: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(sifr.names.get(sifri))
|
||||
if sial is not None and sial.name is not None:
|
||||
@@ -1606,7 +1606,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
if stub_from_imports is not None:
|
||||
from_imports = stub_from_imports
|
||||
# 把源模块自己加入 stub 注解上下文:stub 注解(如 __sha512 的 transform
|
||||
# 参数 t.CArray[t.CUInt8T, SHA512_BLOCK_LEN])引用源模块自身的 CDefine,
|
||||
# 参数 t.CArray[uint8, SHA512_BLOCK_LEN])引用源模块自身的 CDefine,
|
||||
# 但 stub 的 import 只含被 import 的模块(t/c/string),不含自己。
|
||||
# 不加则 _eval_const_int_expr 跨模块 CDefine 查找遍历不到源模块
|
||||
# (imported_modules 无 __sha512)→ t.CArray count 报"必须是整数常量"。
|
||||
@@ -1614,15 +1614,15 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
if src_sha1 is not None:
|
||||
stub_rel_src: str = StubMergerStore.LookupSha1RelPath(src_sha1)
|
||||
if stub_rel_src is not None:
|
||||
sr_len_src: t.CSizeT = string.strlen(stub_rel_src)
|
||||
sr_len_src: sizet = string.strlen(stub_rel_src)
|
||||
if sr_len_src > 3 and string.strncmp(stub_rel_src + sr_len_src - 3, ".vp", 3) == 0:
|
||||
sr_len_src -= 3
|
||||
if sr_len_src > 0:
|
||||
src_mod_buf: str = stdlib.malloc(sr_len_src + 1)
|
||||
if src_mod_buf is not None:
|
||||
sri_src: t.CSizeT
|
||||
sri_src: sizet
|
||||
for sri_src in range(sr_len_src):
|
||||
ch_src: t.CChar = stub_rel_src[sri_src]
|
||||
ch_src: char = stub_rel_src[sri_src]
|
||||
if ch_src == '/' or ch_src == '\\':
|
||||
src_mod_buf[sri_src] = '.'
|
||||
else:
|
||||
@@ -1653,7 +1653,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 在 `class devfs_directory` 之前),AnnAssign 全局变量解析裸类名时类
|
||||
# 未注册 → CArray 元素解析失败 fatal(VKernel PhaseA 根因)。
|
||||
# ============================================================
|
||||
i0: t.CSizeT
|
||||
i0: sizet
|
||||
for i0 in range(n):
|
||||
child0: ast.AST | t.CPtr = ch.get(i0)
|
||||
if child0 is None:
|
||||
@@ -1673,7 +1673,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
src_sha1, imported_modules, from_imports)
|
||||
cls_children0: list[ast.AST | t.CPtr] | t.CPtr = class_cd0.children
|
||||
if cls_children0 is not None:
|
||||
cn20: t.CSizeT = len(cls_children0)
|
||||
cn20: sizet = len(cls_children0)
|
||||
for ci20 in range(cn20):
|
||||
m_child0: ast.AST | t.CPtr = cls_children0.get(ci20)
|
||||
if m_child0 is None:
|
||||
@@ -1687,7 +1687,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
src_sha1, imported_modules, from_imports,
|
||||
i32_ty, i8_ptr_ty, funcs_ptr, max_funcs)
|
||||
|
||||
i: t.CSizeT
|
||||
i: sizet
|
||||
for i in range(n):
|
||||
child: ast.AST | t.CPtr = ch.get(i)
|
||||
if child is None:
|
||||
@@ -1746,7 +1746,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 用 register_cdefine_double 注册(走整数提取会 fail-fast)
|
||||
GenApi.register_cdefine_double(pool, cdef_tgt.id, cdef_float_val)
|
||||
elif cdef_is_str == 0:
|
||||
cdef_val: t.CInt64T = GenApi.extract_cdefine_int_value(aa.value)
|
||||
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,
|
||||
@@ -1845,7 +1845,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> in
|
||||
"""检查 vpi ClassDef 装饰器列表是否含 t.attr.packed"""
|
||||
if decorator_list is None:
|
||||
return 0
|
||||
dn: t.CSizeT = len(decorator_list)
|
||||
dn: sizet = len(decorator_list)
|
||||
if dn == 0:
|
||||
return 0
|
||||
for di in range(dn):
|
||||
@@ -1861,7 +1861,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> in
|
||||
continue
|
||||
if cl.args is None:
|
||||
continue
|
||||
an: t.CSizeT = len(cl.args)
|
||||
an: sizet = len(cl.args)
|
||||
for ai in range(an):
|
||||
ag: ast.AST | t.CPtr = cl.args.get(ai)
|
||||
if ag is not None and _vpi_tattr_name(ag, "packed") != 0:
|
||||
@@ -1907,8 +1907,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
GenApi.add_visible_struct(pool, cls_name)
|
||||
return 1
|
||||
# 2. 收集字段类型(AnnAssign 子节点,仿 ClassGenDef.translate_class_def)
|
||||
field_names_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
field_types_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
if field_names_buf is None or field_types_buf is None:
|
||||
return 0
|
||||
string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
@@ -1916,7 +1916,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
field_count: int = 0
|
||||
cls_children_c: list[ast.AST | t.CPtr] | t.CPtr = class_cd.children
|
||||
if cls_children_c is not None:
|
||||
cn_c: t.CSizeT = len(cls_children_c)
|
||||
cn_c: sizet = len(cls_children_c)
|
||||
for ci_c in range(cn_c):
|
||||
m_child_c: ast.AST | t.CPtr = cls_children_c.get(ci_c)
|
||||
if m_child_c is None:
|
||||
@@ -1937,8 +1937,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
|
||||
return 0
|
||||
if field_count < GenTypes.FIELD_MAX:
|
||||
field_names_buf[field_count] = t.CSizeT(m_tgt_c.id)
|
||||
field_types_buf[field_count] = t.CSizeT(field_ty_c)
|
||||
field_names_buf[field_count] = sizet(m_tgt_c.id)
|
||||
field_types_buf[field_count] = sizet(field_ty_c)
|
||||
field_count += 1
|
||||
# 3. vpi 存根不含类字段(只序列化 class 名 + def 签名,见 _cache_vpi_return_
|
||||
# annots_text 的 class/def 行解析)→ field_count 恒为 0。
|
||||
@@ -2092,7 +2092,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
if aa.annotation is not None:
|
||||
is_gv_cexport = GenApi.has_decorator_marker(aa.annotation, "CExport")
|
||||
if src_sha1 is not None and src_sha1[0] != '\0' and is_gv_cexport == 0:
|
||||
ml_v: t.CSizeT = string.strlen(src_sha1) + 1 + string.strlen(gname_v) + 1
|
||||
ml_v: sizet = string.strlen(src_sha1) + 1 + string.strlen(gname_v) + 1
|
||||
gv_name_m = pool.alloc(ml_v)
|
||||
if gv_name_m is not None:
|
||||
viperlib.snprintf(gv_name_m, ml_v, "%s.%s", src_sha1, gname_v)
|
||||
@@ -2255,7 +2255,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
|
||||
# 提取参数并添加到 declare
|
||||
param_count: int = 0
|
||||
fd_defaults: t.CVoid | t.CPtr = None
|
||||
fd_defaults: t.CPtr = None
|
||||
fd_default_count: int = 0
|
||||
if fd.args is not None:
|
||||
args_node: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd.args)
|
||||
@@ -2269,9 +2269,9 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
if param_count < 0 or param_count > 128:
|
||||
stdio.printf(
|
||||
"[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n",
|
||||
fd.name, param_count, t.CUInt64T(fd.args))
|
||||
fd.name, param_count, uint64(fd.args))
|
||||
stdlib.exit(1)
|
||||
pi: t.CSizeT
|
||||
pi: sizet
|
||||
for pi in range(param_count):
|
||||
ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(args_list.get(pi))
|
||||
if ag is None:
|
||||
@@ -2283,7 +2283,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
param_ty: llvmlite.LLVMType | t.CPtr = i8_ptr_ty
|
||||
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
|
||||
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
|
||||
# t.CSizeT→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
|
||||
# sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
|
||||
# callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest
|
||||
# 根因)。段索引 = pi(模块级函数无 self,0=首参)。
|
||||
pseg_ty: llvmlite.LLVMType | t.CPtr = _resolve_vpi_param_annot_seg(
|
||||
@@ -2361,7 +2361,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 方法混淆名: {src_sha1}.{ClassName}.{method}
|
||||
# 参数类型从 vpi 注解解析(self 无注解时默认为 i8*)。
|
||||
# 注入正确签名避免调用时 _ensure_method_declare 用实参类型
|
||||
# 创建错误 declare(如 size: t.CSizeT 被写成 i32 而非 i64)。
|
||||
# 创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。
|
||||
# ============================================================
|
||||
def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
@@ -2382,14 +2382,14 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
return
|
||||
|
||||
# 构造方法查找名: ClassName.method
|
||||
lookup_name_len: t.CSizeT = string.strlen(cls_name) + 1 + string.strlen(m_fd.name) + 1
|
||||
lookup_name_len: sizet = string.strlen(cls_name) + 1 + string.strlen(m_fd.name) + 1
|
||||
lookup_name: str = pool.alloc(lookup_name_len)
|
||||
if lookup_name is None:
|
||||
return
|
||||
viperlib.snprintf(lookup_name, lookup_name_len, "%s.%s", cls_name, m_fd.name)
|
||||
|
||||
# mangled name: {src_sha1}.{ClassName}.{method}
|
||||
mangled_len: t.CSizeT = string.strlen(src_sha1) + 1 + lookup_name_len
|
||||
mangled_len: sizet = string.strlen(src_sha1) + 1 + lookup_name_len
|
||||
mangled_name: str = pool.alloc(mangled_len)
|
||||
if mangled_name is None:
|
||||
return
|
||||
@@ -2427,7 +2427,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
|
||||
# 提取参数并添加到 declare
|
||||
param_count: int = 0
|
||||
md_defaults: t.CVoid | t.CPtr = None
|
||||
md_defaults: t.CPtr = None
|
||||
md_default_count: int = 0
|
||||
if m_fd.args is not None:
|
||||
args_node: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(m_fd.args)
|
||||
@@ -2439,9 +2439,9 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
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, t.CUInt64T(m_fd.args))
|
||||
cls_name, m_fd.name, param_count, uint64(m_fd.args))
|
||||
stdlib.exit(1)
|
||||
pi: t.CSizeT
|
||||
pi: sizet
|
||||
for pi in range(param_count):
|
||||
ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(args_list.get(pi))
|
||||
if ag is None:
|
||||
@@ -2463,7 +2463,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
param_ty: llvmlite.LLVMType | t.CPtr = i8_ptr_ty
|
||||
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
|
||||
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
|
||||
# t.CSizeT→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
|
||||
# sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
|
||||
# callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃,
|
||||
# SlotsBugTest 根因)。段索引 = pi(0=self 空段)。
|
||||
pseg_ty: llvmlite.LLVMType | t.CPtr = _resolve_vpi_param_annot_seg(
|
||||
|
||||
@@ -51,8 +51,8 @@ _SEEN_SLOT: t.CDefine = 274 # 8(hash)+8(pos)+1(flags)+256(name)+1(nul)
|
||||
_SEEN_FUNC_CAP: t.CDefine = 16384
|
||||
_SEEN_GLOBAL_CAP: t.CDefine = 16384
|
||||
_SEEN_TYPE_CAP: t.CDefine = 4096
|
||||
_SEEN_FNV_OFFSET: t.CUInt64T = 0xcbf29ce484222325
|
||||
_SEEN_FNV_PRIME: t.CUInt64T = 0x100000001b3
|
||||
_SEEN_FNV_OFFSET: uint64 = 0xcbf29ce484222325
|
||||
_SEEN_FNV_PRIME: uint64 = 0x100000001b3
|
||||
|
||||
_seen_funcs: bytes # 已见函数签名表(@"sha1.name"( 等)
|
||||
_seen_funcs_count: int
|
||||
@@ -62,29 +62,29 @@ _seen_types: bytes # 已见类型名表(%name)
|
||||
_seen_types_count: int
|
||||
_seen_key_scratch: bytes # 注册键暂存(跨 truncation 窗口复制)
|
||||
|
||||
def _SeenHash(key: str) -> t.CUInt64T:
|
||||
def _SeenHash(key: str) -> uint64:
|
||||
"""FNV-1a 64 位哈希(对齐 includes/hashtable.vp)"""
|
||||
h: t.CUInt64T = _SEEN_FNV_OFFSET
|
||||
h: uint64 = _SEEN_FNV_OFFSET
|
||||
p: str = key
|
||||
while p[0] != 0:
|
||||
h = h ^ t.CUInt64T(p[0])
|
||||
h = h ^ uint64(p[0])
|
||||
h = h * _SEEN_FNV_PRIME
|
||||
p += 1
|
||||
if h < 2:
|
||||
h = 2
|
||||
return h
|
||||
|
||||
def _SeenFind(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CSizeT:
|
||||
def _SeenFind(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> sizet:
|
||||
"""已见表槽位查找:命中返回槽位下标;未命中返回 cap(哨兵)"""
|
||||
if tbl is None or key is None:
|
||||
return cap
|
||||
mask: t.CSizeT = cap - 1
|
||||
idx: t.CSizeT = t.CSizeT(key_hash) & mask
|
||||
i: t.CSizeT = 0
|
||||
mask: sizet = cap - 1
|
||||
idx: sizet = sizet(key_hash) & mask
|
||||
i: sizet = 0
|
||||
while i < cap:
|
||||
off: t.CSizeT = idx * _SEEN_SLOT
|
||||
hp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off)
|
||||
sh: t.CUInt64T = hp[0]
|
||||
off: sizet = idx * _SEEN_SLOT
|
||||
hp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off)
|
||||
sh: uint64 = hp[0]
|
||||
if sh == 0:
|
||||
return cap
|
||||
if sh == key_hash:
|
||||
@@ -95,72 +95,72 @@ def _SeenFind(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CS
|
||||
i += 1
|
||||
return cap
|
||||
|
||||
def _SeenPresent(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> int:
|
||||
def _SeenPresent(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> int:
|
||||
"""已见表查找:返回 0=不存在;>0=存在(返回值 = flags+1)"""
|
||||
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
|
||||
si: sizet = _SeenFind(tbl, cap, key, key_hash)
|
||||
if si >= cap:
|
||||
return 0
|
||||
return t.CInt(tbl[si * _SEEN_SLOT + 16]) + 1
|
||||
return int(tbl[si * _SEEN_SLOT + 16]) + 1
|
||||
|
||||
def _SeenInsert(tbl: bytes, cap: t.CSizeT, count: int, key: str, key_hash: t.CUInt64T,
|
||||
flags: int, pos: t.CSizeT) -> int:
|
||||
def _SeenInsert(tbl: bytes, cap: sizet, count: int, key: str, key_hash: uint64,
|
||||
flags: int, pos: sizet) -> int:
|
||||
"""已见表插入/更新:key 不存在则新登记(返回 count+1);已存在则 OR flags、更新 pos"""
|
||||
if tbl is None or key is None:
|
||||
return count
|
||||
kl: t.CSizeT = string.strlen(key)
|
||||
kl: sizet = string.strlen(key)
|
||||
if kl >= _SEEN_NAME_MAX:
|
||||
return count
|
||||
if count >= cap:
|
||||
VLogger.error(f"已见符号表满(容量 {cap}),新增符号登记被丢弃——去重失效,必须增大容量", "StubMerger")
|
||||
return count
|
||||
mask: t.CSizeT = cap - 1
|
||||
idx: t.CSizeT = t.CSizeT(key_hash) & mask
|
||||
i: t.CSizeT = 0
|
||||
mask: sizet = cap - 1
|
||||
idx: sizet = sizet(key_hash) & mask
|
||||
i: sizet = 0
|
||||
while i < cap:
|
||||
off: t.CSizeT = idx * _SEEN_SLOT
|
||||
hp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off)
|
||||
sh: t.CUInt64T = hp[0]
|
||||
off: sizet = idx * _SEEN_SLOT
|
||||
hp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off)
|
||||
sh: uint64 = hp[0]
|
||||
if sh == 0:
|
||||
hp[0] = key_hash
|
||||
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off + 8)
|
||||
pp[0] = t.CUInt64T(pos)
|
||||
tbl[off + 16] = t.CChar(flags)
|
||||
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off + 8)
|
||||
pp[0] = uint64(pos)
|
||||
tbl[off + 16] = char(flags)
|
||||
string.strcpy(tbl + off + 17, key)
|
||||
return count + 1
|
||||
if sh == key_hash:
|
||||
nm: str = tbl + off + 17
|
||||
if string.strcmp(nm, key) == 0:
|
||||
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off + 8)
|
||||
pp[0] = t.CUInt64T(pos)
|
||||
tbl[off + 16] = t.CChar(t.CInt(tbl[off + 16]) | flags)
|
||||
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off + 8)
|
||||
pp[0] = uint64(pos)
|
||||
tbl[off + 16] = char(int(tbl[off + 16]) | flags)
|
||||
return count
|
||||
idx = (idx + 1) & mask
|
||||
i += 1
|
||||
return count
|
||||
|
||||
def _SeenCommentOut(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T,
|
||||
def _SeenCommentOut(tbl: bytes, cap: sizet, key: str, key_hash: uint64,
|
||||
out_buf: bytes) -> int:
|
||||
"""注释 out_buf 中该符号的活跃行(行首改 ';'),返回 1=已注释 0=无"""
|
||||
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
|
||||
si: sizet = _SeenFind(tbl, cap, key, key_hash)
|
||||
if si >= cap:
|
||||
return 0
|
||||
if t.CInt(tbl[si * _SEEN_SLOT + 16]) != 0:
|
||||
if int(tbl[si * _SEEN_SLOT + 16]) != 0:
|
||||
return 0 # 类型表 flags=1:活跃行为完整定义,无可注释的 opaque
|
||||
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + si * _SEEN_SLOT + 8)
|
||||
p: t.CUInt64T = pp[0]
|
||||
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + si * _SEEN_SLOT + 8)
|
||||
p: uint64 = pp[0]
|
||||
if out_buf is not None:
|
||||
out_buf[t.CSizeT(p)] = ';'
|
||||
out_buf[sizet(p)] = ';'
|
||||
return 1
|
||||
|
||||
def _SeenGetPos(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CSizeT:
|
||||
def _SeenGetPos(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> sizet:
|
||||
"""读取已见表条目记录的活跃行位置;不存在返回 cap(哨兵)"""
|
||||
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
|
||||
si: sizet = _SeenFind(tbl, cap, key, key_hash)
|
||||
if si >= cap:
|
||||
return cap
|
||||
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + si * _SEEN_SLOT + 8)
|
||||
return t.CSizeT(pp[0])
|
||||
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + si * _SEEN_SLOT + 8)
|
||||
return sizet(pp[0])
|
||||
|
||||
def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
def _RegisterStubLines(buf: bytes, buf_len: sizet, base_pos: sizet):
|
||||
"""把本地 stub(整体复制进 out_buf)中的 declare/global/type 全部登记到已见表
|
||||
|
||||
本地 stub.ll 在 BuildCombinedIR 第 1 步整体 strcpy 进 out_buf,不做逐行
|
||||
@@ -174,34 +174,34 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
global _seen_funcs_count, _seen_globals_count, _seen_types_count
|
||||
if buf is None:
|
||||
return
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos < buf_len:
|
||||
ls: t.CSizeT = pos
|
||||
ls: sizet = pos
|
||||
while pos < buf_len:
|
||||
if buf[pos] == '\n':
|
||||
break
|
||||
pos += 1
|
||||
ll: t.CSizeT = pos - ls
|
||||
ll: sizet = pos - ls
|
||||
if pos < buf_len:
|
||||
pos += 1
|
||||
line_pos: t.CSizeT = base_pos + ls
|
||||
line_pos: sizet = base_pos + ls
|
||||
# declare → 函数签名 @"name"(
|
||||
if ll >= 8 and string.strncmp(buf + ls, "declare ", 8) == 0:
|
||||
at: t.CSizeT = ls + 8
|
||||
at: sizet = ls + 8
|
||||
while at < ls + ll:
|
||||
if buf[at] == '@':
|
||||
break
|
||||
at += 1
|
||||
if at < ls + ll:
|
||||
lp: t.CSizeT = at + 1
|
||||
lp: sizet = at + 1
|
||||
while lp < ls + ll:
|
||||
if buf[lp] == '(':
|
||||
break
|
||||
lp += 1
|
||||
if lp < ls + ll:
|
||||
sv_f: t.CChar = buf[lp + 1]
|
||||
sv_f: char = buf[lp + 1]
|
||||
buf[lp + 1] = '\0'
|
||||
kh_f: t.CUInt64T = _SeenHash(buf + at)
|
||||
kh_f: uint64 = _SeenHash(buf + at)
|
||||
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, buf + at, kh_f) == 0:
|
||||
_seen_funcs_count = _SeenInsert(_seen_funcs, _SEEN_FUNC_CAP, _seen_funcs_count, buf + at, kh_f, 0, line_pos)
|
||||
else:
|
||||
@@ -215,15 +215,15 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
if ll >= 5 and buf[ls + 1] == '.' and buf[ls + 2] == 's' and buf[ls + 3] == 't' and buf[ls + 4] == 'r':
|
||||
buf[ls] = ';'
|
||||
continue
|
||||
eq: t.CSizeT = ls + 1
|
||||
eq: sizet = ls + 1
|
||||
while eq < ls + ll:
|
||||
if buf[eq] == '=':
|
||||
break
|
||||
eq += 1
|
||||
if eq < ls + ll:
|
||||
sv_g: t.CChar = buf[eq]
|
||||
sv_g: char = buf[eq]
|
||||
buf[eq] = '\0'
|
||||
kh_g: t.CUInt64T = _SeenHash(buf + ls)
|
||||
kh_g: uint64 = _SeenHash(buf + ls)
|
||||
if _SeenPresent(_seen_globals, _SEEN_GLOBAL_CAP, buf + ls, kh_g) == 0:
|
||||
_seen_globals_count = _SeenInsert(_seen_globals, _SEEN_GLOBAL_CAP, _seen_globals_count, buf + ls, kh_g, 0, line_pos)
|
||||
else:
|
||||
@@ -232,15 +232,15 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
continue
|
||||
# 类型 %name = type ...(完整定义 flags=1,opaque flags=0)
|
||||
if ll > 0 and buf[ls] == '%':
|
||||
eq: t.CSizeT = ls + 1
|
||||
eq: sizet = ls + 1
|
||||
while eq < ls + ll:
|
||||
if buf[eq] == '=':
|
||||
break
|
||||
eq += 1
|
||||
if eq < ls + ll:
|
||||
sv_t: t.CChar = buf[eq]
|
||||
sv_t: char = buf[eq]
|
||||
buf[eq] = '\0'
|
||||
kh_t: t.CUInt64T = _SeenHash(buf + ls)
|
||||
kh_t: uint64 = _SeenHash(buf + ls)
|
||||
is_full: int = 0
|
||||
if eq + 8 <= ls + ll:
|
||||
if buf[eq + 2] == 't' and buf[eq + 3] == 'y' and buf[eq + 4] == 'p' and buf[eq + 5] == 'e' and buf[eq + 6] == ' ':
|
||||
@@ -251,7 +251,7 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
_seen_types_count = _SeenInsert(_seen_types, _SEEN_TYPE_CAP, _seen_types_count, buf + ls, kh_t, is_full, line_pos)
|
||||
elif is_full == 1 and prev_t == 1:
|
||||
# 先 opaque 后完整定义:注释旧行,表升级指向新完整定义行
|
||||
old_pos: t.CSizeT = _SeenGetPos(_seen_types, _SEEN_TYPE_CAP, buf + ls, kh_t)
|
||||
old_pos: sizet = _SeenGetPos(_seen_types, _SEEN_TYPE_CAP, buf + ls, kh_t)
|
||||
if old_pos >= base_pos and old_pos < base_pos + buf_len:
|
||||
buf[old_pos - base_pos] = ';'
|
||||
_seen_types_count = _SeenInsert(_seen_types, _SEEN_TYPE_CAP, _seen_types_count, buf + ls, kh_t, 1, line_pos)
|
||||
@@ -274,9 +274,9 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
|
||||
# 读取 {temp_dir}/{sha1}.stub.ll,跳过 header(;, target, source_filename),
|
||||
# 去重 declare/global,追加到 out_buf。返回新 out_pos。
|
||||
# ============================================================
|
||||
def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_buf: bytes, out_buf: bytes, out_size: t.CSizeT,
|
||||
out_pos: t.CSizeT) -> t.CSizeT:
|
||||
def _LoadAndAppendStub(temp_dir: str, td_len: sizet, dep_sha1: str,
|
||||
dep_buf: bytes, out_buf: bytes, out_size: sizet,
|
||||
out_pos: sizet) -> sizet:
|
||||
"""加载依赖 stub 并追加(跳过 header,去重)"""
|
||||
global _seen_funcs_count, _seen_globals_count, _seen_types_count
|
||||
if temp_dir is None or dep_sha1 is None or dep_buf is None or out_buf is None:
|
||||
@@ -293,7 +293,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if StubMergerStore.LookupSha1RelPath(dep_sha1) is not None:
|
||||
VLogger.error(f"依赖 stub 缺失: {dep_sha1}", "StubMerger")
|
||||
return out_pos
|
||||
dep_br_ls: t.CInt64T = df_ls.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
|
||||
dep_br_ls: int64 = df_ls.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
|
||||
df_ls.close()
|
||||
stdlib.free(dep_path)
|
||||
if dep_br_ls <= 0:
|
||||
@@ -305,14 +305,14 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
|
||||
# 注释掉依赖 stub 中的字符串常量行(模块内部的,不需要)
|
||||
# 简单方案:搜索 "= external unnamed_addr constant" 并将行首的 @ 改为 ;@
|
||||
cfs_pos: t.CSizeT = 0
|
||||
while cfs_pos + 30 < t.CSizeT(dep_br_ls):
|
||||
cfs_pos: sizet = 0
|
||||
while cfs_pos + 30 < sizet(dep_br_ls):
|
||||
ext_p: t.CPtr = string.strstr(dep_buf + cfs_pos, "= external unnamed_addr constant")
|
||||
if ext_p is None:
|
||||
break
|
||||
ext_off2: t.CSizeT = t.CSizeT(t.CUInt64T(ext_p) - t.CUInt64T(dep_buf))
|
||||
ext_off2: sizet = sizet(uint64(ext_p) - uint64(dep_buf))
|
||||
# 向前查找行首的 @
|
||||
ls: t.CSizeT = ext_off2
|
||||
ls: sizet = ext_off2
|
||||
while ls > 0:
|
||||
if dep_buf[ls] == '\n':
|
||||
ls += 1
|
||||
@@ -323,15 +323,15 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
cfs_pos = ext_off2 + 30
|
||||
|
||||
# 跳过 header,追加内容(去重 declare/global/type,已见符号表 O(1) 去重)
|
||||
dep_pos: t.CSizeT = 0
|
||||
dep_pos: sizet = 0
|
||||
skipping: int = 1
|
||||
while dep_pos < dep_br_ls:
|
||||
line_start: t.CSizeT = dep_pos
|
||||
line_start: sizet = dep_pos
|
||||
while dep_pos < dep_br_ls:
|
||||
if dep_buf[dep_pos] == '\n':
|
||||
break
|
||||
dep_pos += 1
|
||||
line_len: t.CSizeT = dep_pos - line_start
|
||||
line_len: sizet = dep_pos - line_start
|
||||
if dep_pos < dep_br_ls:
|
||||
dep_pos += 1
|
||||
if skipping != 0:
|
||||
@@ -350,23 +350,23 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# 注册暂存(append 成功后才登记;reg_key 指向 scratch,insert 当轮完成)
|
||||
reg_tbl: int = 0
|
||||
reg_key: str = None
|
||||
reg_hash: t.CUInt64T = 0
|
||||
reg_hash: uint64 = 0
|
||||
reg_flags: int = 0
|
||||
# 去重:declare(用已见函数表,键 @"name"(,避免误匹配 call 语句)
|
||||
if line_len >= 8 and string.strncmp(dep_buf + line_start, "declare ", 8) == 0:
|
||||
at: t.CSizeT = line_start + 8
|
||||
at: sizet = line_start + 8
|
||||
while at < line_start + line_len:
|
||||
if dep_buf[at] == '@':
|
||||
break
|
||||
at += 1
|
||||
if at < line_start + line_len:
|
||||
lp: t.CSizeT = at + 1
|
||||
lp: sizet = at + 1
|
||||
while lp < line_start + line_len:
|
||||
if dep_buf[lp] == '(':
|
||||
break
|
||||
lp += 1
|
||||
if lp < line_start + line_len:
|
||||
saved: t.CChar = dep_buf[lp + 1]
|
||||
saved: char = dep_buf[lp + 1]
|
||||
dep_buf[lp + 1] = '\0'
|
||||
reg_hash = _SeenHash(dep_buf + at)
|
||||
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, dep_buf + at, reg_hash) != 0:
|
||||
@@ -384,13 +384,13 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if line_len >= 5 and dep_buf[line_start + 1] == '.' and dep_buf[line_start + 2] == 's' \
|
||||
and dep_buf[line_start + 3] == 't' and dep_buf[line_start + 4] == 'r':
|
||||
continue
|
||||
eq: t.CSizeT = line_start + 1
|
||||
eq: sizet = line_start + 1
|
||||
while eq < line_start + line_len:
|
||||
if dep_buf[eq] == '=':
|
||||
break
|
||||
eq += 1
|
||||
if eq < line_start + line_len:
|
||||
saved: t.CChar = dep_buf[eq]
|
||||
saved: char = dep_buf[eq]
|
||||
dep_buf[eq] = '\0'
|
||||
reg_hash = _SeenHash(dep_buf + line_start)
|
||||
if _SeenPresent(_seen_globals, _SEEN_GLOBAL_CAP, dep_buf + line_start, reg_hash) != 0:
|
||||
@@ -406,13 +406,13 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# 当本地 stub 有 opaque 声明而依赖 stub 有完整定义时,注释掉 opaque 行,
|
||||
# 让完整定义被追加,避免 LLC "Cannot allocate unsized type" 错误。
|
||||
if line_len > 0 and dep_buf[line_start] == '%':
|
||||
eq2: t.CSizeT = line_start + 1
|
||||
eq2: sizet = line_start + 1
|
||||
while eq2 < line_start + line_len:
|
||||
if dep_buf[eq2] == '=':
|
||||
break
|
||||
eq2 += 1
|
||||
if eq2 < line_start + line_len:
|
||||
saved2: t.CChar = dep_buf[eq2 + 1]
|
||||
saved2: char = dep_buf[eq2 + 1]
|
||||
dep_buf[eq2 + 1] = '\0'
|
||||
# 检查依赖行是否为完整定义(= type { 或 = type <)
|
||||
dep_is_full_def: int = 0
|
||||
@@ -420,7 +420,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if dep_buf[eq2 + 2] == 't' and dep_buf[eq2 + 3] == 'y' and dep_buf[eq2 + 4] == 'p' and dep_buf[eq2 + 5] == 'e' and dep_buf[eq2 + 6] == ' ':
|
||||
if dep_buf[eq2 + 7] == '{' or dep_buf[eq2 + 7] == '<':
|
||||
dep_is_full_def = 1
|
||||
saved_eq: t.CChar = dep_buf[eq2]
|
||||
saved_eq: char = dep_buf[eq2]
|
||||
dep_buf[eq2] = '\0'
|
||||
reg_hash = _SeenHash(dep_buf + line_start)
|
||||
if dep_is_full_def == 1:
|
||||
@@ -450,7 +450,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_buf[eq2 + 1] = saved2
|
||||
# 追加(append 成功后才登记已见表)
|
||||
if out_pos + line_len + 2 < out_size:
|
||||
reg_pos: t.CSizeT = out_pos
|
||||
reg_pos: sizet = out_pos
|
||||
string.strncpy(out_buf + out_pos, dep_buf + line_start, line_len)
|
||||
out_pos += line_len
|
||||
out_buf[out_pos] = '\n'
|
||||
@@ -469,9 +469,9 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# 读取 {temp_dir}/{sha1}.text.ll,将 define 行转为 declare(提取函数签名),
|
||||
# 跳过函数体,去重后追加到 out_buf。返回新 out_pos。
|
||||
# ============================================================
|
||||
def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_buf: bytes, out_buf: bytes, out_size: t.CSizeT,
|
||||
out_pos: t.CSizeT) -> t.CSizeT:
|
||||
def _LoadAndAppendTextDeclares(temp_dir: str, td_len: sizet, dep_sha1: str,
|
||||
dep_buf: bytes, out_buf: bytes, out_size: sizet,
|
||||
out_pos: sizet) -> sizet:
|
||||
"""从依赖 text.ll 提取 declare(define 转 declare),追加到 out_buf"""
|
||||
global _seen_funcs_count, _seen_globals_count, _seen_types_count
|
||||
if temp_dir is None or dep_sha1 is None or dep_buf is None or out_buf is None:
|
||||
@@ -488,7 +488,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if StubMergerStore.LookupSha1RelPath(dep_sha1) is not None:
|
||||
VLogger.error(f"依赖 text 缺失: {dep_sha1}", "StubMerger")
|
||||
return out_pos
|
||||
text_br: t.CInt64T = tf_lt.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
|
||||
text_br: int64 = tf_lt.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
|
||||
tf_lt.close()
|
||||
stdlib.free(text_path)
|
||||
if text_br <= 0:
|
||||
@@ -498,15 +498,15 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if text_br < StubMerger.STUB_READ_BUF_SIZE:
|
||||
dep_buf[text_br] = '\0'
|
||||
|
||||
dep_pos_lt: t.CSizeT = 0
|
||||
dep_pos_lt: sizet = 0
|
||||
in_body: int = 0
|
||||
while dep_pos_lt < text_br:
|
||||
ls: t.CSizeT = dep_pos_lt
|
||||
ls: sizet = dep_pos_lt
|
||||
while dep_pos_lt < text_br:
|
||||
if dep_buf[dep_pos_lt] == '\n':
|
||||
break
|
||||
dep_pos_lt += 1
|
||||
ll: t.CSizeT = dep_pos_lt - ls
|
||||
ll: sizet = dep_pos_lt - ls
|
||||
if dep_pos_lt < text_br:
|
||||
dep_pos_lt += 1
|
||||
|
||||
@@ -530,7 +530,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# 处理 define 行:转为 declare
|
||||
if ll >= 7 and string.strncmp(dep_buf + ls, "define ", 7) == 0:
|
||||
# 提取 @funcname( 用于去重
|
||||
at_lt: t.CSizeT = ls + 7
|
||||
at_lt: sizet = ls + 7
|
||||
while at_lt < ls + ll:
|
||||
if dep_buf[at_lt] == '@':
|
||||
break
|
||||
@@ -538,7 +538,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if at_lt >= ls + ll:
|
||||
in_body = 1
|
||||
continue
|
||||
lp_lt: t.CSizeT = at_lt + 1
|
||||
lp_lt: sizet = at_lt + 1
|
||||
while lp_lt < ls + ll:
|
||||
if dep_buf[lp_lt] == '(':
|
||||
break
|
||||
@@ -547,9 +547,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
in_body = 1
|
||||
continue
|
||||
# 去重检查:用已见函数表(键 @"name"(,避免误匹配 call 语句)
|
||||
saved_lt: t.CChar = dep_buf[lp_lt + 1]
|
||||
saved_lt: char = dep_buf[lp_lt + 1]
|
||||
dep_buf[lp_lt + 1] = '\0'
|
||||
fh_lt: t.CUInt64T = _SeenHash(dep_buf + at_lt)
|
||||
fh_lt: uint64 = _SeenHash(dep_buf + at_lt)
|
||||
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, dep_buf + at_lt, fh_lt) != 0:
|
||||
dep_buf[lp_lt + 1] = saved_lt
|
||||
in_body = 1
|
||||
@@ -558,7 +558,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_buf[lp_lt + 1] = saved_lt
|
||||
|
||||
# 找行尾的 ' {' 并截断
|
||||
decl_end: t.CSizeT = ls + ll
|
||||
decl_end: sizet = ls + ll
|
||||
if decl_end > ls + 1:
|
||||
if dep_buf[decl_end - 1] == '{' and dep_buf[decl_end - 2] == ' ':
|
||||
decl_end -= 2
|
||||
@@ -570,7 +570,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# declaration"(LLVM 只允许 define 用 linkonce_odr,declare 必须
|
||||
# external)。对齐 TPC Phase2Translator 的 decl_line 剥 linkage 逻辑,
|
||||
# 循环跳过所有 linkage 词。
|
||||
c_start_lt: t.CSizeT = ls + 7
|
||||
c_start_lt: sizet = ls + 7
|
||||
skipped_lt: int = 1
|
||||
while skipped_lt != 0:
|
||||
skipped_lt = 0
|
||||
@@ -598,9 +598,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
string.strncmp(dep_buf + c_start_lt, "private ", 8) == 0:
|
||||
c_start_lt += 8
|
||||
skipped_lt = 1
|
||||
copy_len_lt: t.CSizeT = decl_end - c_start_lt
|
||||
copy_len_lt: sizet = decl_end - c_start_lt
|
||||
if out_pos + 8 + copy_len_lt + 2 < out_size:
|
||||
decl_pos_lt: t.CSizeT = out_pos
|
||||
decl_pos_lt: sizet = out_pos
|
||||
string.strncpy(out_buf + out_pos, "declare ", 8)
|
||||
out_pos += 8
|
||||
string.strncpy(out_buf + out_pos, dep_buf + c_start_lt, copy_len_lt)
|
||||
@@ -616,7 +616,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
# stub.ll 中只有 opaque 声明,需要从 text.ll 中提取完整定义
|
||||
# 用于 alloca 和 getelementptr 等需要完整类型的指令
|
||||
if ll > 0 and dep_buf[ls] == '%':
|
||||
eq_td: t.CSizeT = ls + 1
|
||||
eq_td: sizet = ls + 1
|
||||
while eq_td < ls + ll:
|
||||
if dep_buf[eq_td] == '=':
|
||||
break
|
||||
@@ -632,9 +632,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_is_full_td = 1
|
||||
if dep_is_full_td == 1:
|
||||
# 临时截断到 '=' 之前(不含 '='),键统一为 %name
|
||||
saved_eq_td: t.CChar = dep_buf[eq_td]
|
||||
saved_eq_td: char = dep_buf[eq_td]
|
||||
dep_buf[eq_td] = '\0'
|
||||
th_td: t.CUInt64T = _SeenHash(dep_buf + ls)
|
||||
th_td: uint64 = _SeenHash(dep_buf + ls)
|
||||
# 1. 注释掉 out_buf 中的 opaque 声明(如果有)
|
||||
_SeenCommentOut(_seen_types, _SEEN_TYPE_CAP, dep_buf + ls, th_td, out_buf)
|
||||
# 2. 检查是否已有完整定义(避免重复)
|
||||
@@ -645,7 +645,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
dep_buf[eq_td] = saved_eq_td
|
||||
# 追加完整类型定义
|
||||
if out_pos + ll + 2 < out_size:
|
||||
td_pos: t.CSizeT = out_pos
|
||||
td_pos: sizet = out_pos
|
||||
string.strncpy(out_buf + out_pos, dep_buf + ls, ll)
|
||||
out_pos += ll
|
||||
out_buf[out_pos] = '\n'
|
||||
@@ -664,16 +664,16 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
if ll >= 5 and dep_buf[ls + 1] == '.' and dep_buf[ls + 2] == 's' and dep_buf[ls + 3] == 't' \
|
||||
and dep_buf[ls + 4] == 'r':
|
||||
continue
|
||||
eq_gv: t.CSizeT = ls + 1
|
||||
eq_gv: sizet = ls + 1
|
||||
while eq_gv < ls + ll:
|
||||
if dep_buf[eq_gv] == '=':
|
||||
break
|
||||
eq_gv += 1
|
||||
if eq_gv < ls + ll:
|
||||
# 截断到 '=' 之前(不含 '='),键统一为 @name
|
||||
saved_gv: t.CChar = dep_buf[eq_gv]
|
||||
saved_gv: char = dep_buf[eq_gv]
|
||||
dep_buf[eq_gv] = '\0'
|
||||
gh_gv: t.CUInt64T = _SeenHash(dep_buf + ls)
|
||||
gh_gv: uint64 = _SeenHash(dep_buf + ls)
|
||||
# 依赖方已有同名全局(stub 注入的 external 声明或先前依赖的定义)
|
||||
# 时跳过:跨模块全局(如 _op_head、MemBuddy.vtable)只需一份
|
||||
# 强定义(在定义模块的 text.ll 中),复制进每个依赖方会导致
|
||||
@@ -684,7 +684,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
|
||||
string.strcpy(_seen_key_scratch, dep_buf + ls)
|
||||
dep_buf[eq_gv] = saved_gv
|
||||
if out_pos + ll + 2 < out_size:
|
||||
gv_pos: t.CSizeT = out_pos
|
||||
gv_pos: sizet = out_pos
|
||||
string.strncpy(out_buf + out_pos, dep_buf + ls, ll)
|
||||
out_pos += ll
|
||||
out_buf[out_pos] = '\n'
|
||||
@@ -712,9 +712,9 @@ def _IsAppModule(mod_name: str) -> int:
|
||||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None:
|
||||
return 0
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
midx: t.CSizeT = t.CSizeT(i) * 64
|
||||
midx: sizet = sizet(i) * 64
|
||||
if string.strcmp(StubMerger._sha1_store_mod + midx, mod_name) == 0:
|
||||
iidx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_INC_DIR_LEN
|
||||
iidx: sizet = sizet(i) * StubMerger.MAX_INC_DIR_LEN
|
||||
if StubMerger._sha1_store_incdir[iidx] == '\0':
|
||||
return 1
|
||||
return 0
|
||||
@@ -735,18 +735,18 @@ def _IsAppModule(mod_name: str) -> int:
|
||||
# Returns:
|
||||
# 追加后的新长度(>=0);溢出/参数错误返回 -1(调用方 fail-fast)
|
||||
# ============================================================
|
||||
def _AppendDepsToWorklist(worklist: bytes, wl_len: t.CSizeT,
|
||||
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: t.CSizeT = wl_len
|
||||
dl: t.CSizeT = string.strlen(deps_str)
|
||||
dpos: t.CSizeT = 0
|
||||
cur_len: sizet = wl_len
|
||||
dl: sizet = string.strlen(deps_str)
|
||||
dpos: sizet = 0
|
||||
while dpos < dl:
|
||||
dstart: t.CSizeT = dpos
|
||||
dstart: sizet = dpos
|
||||
while dpos < dl and deps_str[dpos] != ' ':
|
||||
dpos += 1
|
||||
dlen: t.CSizeT = dpos - dstart
|
||||
dlen: sizet = dpos - dstart
|
||||
if dpos < dl:
|
||||
dpos += 1
|
||||
if dlen == 0:
|
||||
@@ -778,7 +778,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: t.CSizeT,
|
||||
VLogger.error("依赖 worklist 溢出", "StubMerger")
|
||||
return -1
|
||||
stdlib.free(dmod)
|
||||
return t.CInt(cur_len)
|
||||
return int(cur_len)
|
||||
# ============================================================
|
||||
# _BuildReachableSha1Set - 构建可达 SHA1 集合(依赖图按需扫描)
|
||||
#
|
||||
@@ -819,28 +819,28 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
VLogger.error("includes_dirs 缺失,无法按需解析依赖图", "Reachable")
|
||||
return -1
|
||||
|
||||
SRC_BUF_SIZE_R: t.CSizeT = 1048576
|
||||
SRC_BUF_SIZE_R: sizet = 1048576
|
||||
|
||||
# 工作列表(空格分隔的模块名)
|
||||
worklist: bytes = stdlib.malloc(StubMerger.REACH_WORKLIST_BUF)
|
||||
if worklist is None:
|
||||
return -1
|
||||
worklist[0] = '\0'
|
||||
wl_len: t.CSizeT = 0
|
||||
wl_len: sizet = 0
|
||||
|
||||
# 1. App 扫描(app_deps 非空时跳过,直接用调用方提供的初始队列)
|
||||
if app_deps is None or app_deps[0] == '\0':
|
||||
VLogger.info("App 扫描:解析 source_dir 的 import 依赖", "Reachable")
|
||||
scan_res_r: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, source_dir)
|
||||
if scan_res_r is not None:
|
||||
es_r: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
|
||||
es_r: sizet = IncludesScanner.FileEntry.__sizeof__()
|
||||
for e_i_r in range(scan_res_r.Count):
|
||||
e_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(
|
||||
t.CVoid(t.CUInt64T(scan_res_r.Entries) + t.CUInt64T(e_i_r) * es_r, t.CPtr))
|
||||
t.CVoid(uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r, t.CPtr))
|
||||
if e_r is None or e_r.Path is None:
|
||||
continue
|
||||
# 文件级 mark:parse 完立即回收 AST(App 全量 parse 驻留会 OOM)
|
||||
app_mark: t.CSizeT = mb.mark()
|
||||
app_mark: sizet = mb.mark()
|
||||
sbuf: bytes = Utils.read_file_to_buf(e_r.Path, SRC_BUF_SIZE_R)
|
||||
if sbuf is None:
|
||||
mb.reset_to(app_mark)
|
||||
@@ -877,13 +877,13 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
StubMergerStore.PopulateIncludesDeps(e_r.Sha1, tr._imported_modules)
|
||||
# 收集 deps 到初始队列(逐模块去重)
|
||||
if tr._imported_modules is not None:
|
||||
im_len_a: t.CSizeT = string.strlen(tr._imported_modules)
|
||||
im_pos_a: t.CSizeT = 0
|
||||
im_len_a: sizet = string.strlen(tr._imported_modules)
|
||||
im_pos_a: sizet = 0
|
||||
while im_pos_a < im_len_a:
|
||||
im_start_a: t.CSizeT = im_pos_a
|
||||
im_start_a: sizet = im_pos_a
|
||||
while im_pos_a < im_len_a and tr._imported_modules[im_pos_a] != ' ':
|
||||
im_pos_a += 1
|
||||
im_mod_len: t.CSizeT = im_pos_a - im_start_a
|
||||
im_mod_len: sizet = im_pos_a - im_start_a
|
||||
if im_pos_a < im_len_a:
|
||||
im_pos_a += 1
|
||||
if im_mod_len == 0:
|
||||
@@ -916,7 +916,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
mb.reset_to(app_mark)
|
||||
else:
|
||||
# app_deps 已提供(Phase2 场景):直接作为初始队列
|
||||
ad_len: t.CSizeT = string.strlen(app_deps)
|
||||
ad_len: sizet = string.strlen(app_deps)
|
||||
if ad_len > 0 and ad_len < StubMerger.REACH_WORKLIST_BUF:
|
||||
string.strcpy(worklist, app_deps)
|
||||
wl_len = ad_len
|
||||
@@ -950,23 +950,23 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
stdlib.free(worklist)
|
||||
return -1
|
||||
processed[0] = '\0'
|
||||
proc_len: t.CSizeT = 0
|
||||
proc_len: sizet = 0
|
||||
reachable_count: int = 0
|
||||
wl_pos: t.CPtr = stdlib.malloc(8)
|
||||
if wl_pos is None:
|
||||
stdlib.free(worklist)
|
||||
stdlib.free(processed)
|
||||
return -1
|
||||
wl_pos_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(wl_pos, t.CPtr))
|
||||
wl_pos_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(wl_pos, t.CPtr))
|
||||
wl_pos_slot[0] = 0
|
||||
|
||||
while wl_pos_slot[0] < wl_len:
|
||||
pos: t.CSizeT = wl_pos_slot[0]
|
||||
pos: sizet = wl_pos_slot[0]
|
||||
# 提取一个模块名(到空格或末尾)
|
||||
name_start: t.CSizeT = pos
|
||||
name_start: sizet = pos
|
||||
while pos < wl_len and worklist[pos] != ' ':
|
||||
pos += 1
|
||||
name_len: t.CSizeT = pos - name_start
|
||||
name_len: sizet = pos - name_start
|
||||
if pos < wl_len:
|
||||
pos += 1
|
||||
wl_pos_slot[0] = pos
|
||||
@@ -1010,7 +1010,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
stdlib.free(processed)
|
||||
stdlib.free(wl_pos)
|
||||
return -1
|
||||
wl_len = t.CSizeT(ret_ap)
|
||||
wl_len = sizet(ret_ap)
|
||||
stdlib.free(mod_buf)
|
||||
continue
|
||||
|
||||
@@ -1028,12 +1028,12 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
stdlib.free(mod_buf)
|
||||
continue
|
||||
# 输出槽防御性初始化(成功路径必全写;未找到/未命中时仅 free 槽本身)
|
||||
# 槽联合必须用 (t.CSizeT | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr,
|
||||
# 槽联合必须用 (sizet | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr,
|
||||
# [0] 变成 1 字节访问 → 指针被截断(0x2e 崩溃根因)。CSizeT 成员为
|
||||
# 8 字节,经 t.CVoid 显式做 u64↔指针转换。
|
||||
abs_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_abs, t.CPtr))
|
||||
rel_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_rel, t.CPtr))
|
||||
inc_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_inc, t.CPtr))
|
||||
abs_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_abs, t.CPtr))
|
||||
rel_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_rel, t.CPtr))
|
||||
inc_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_inc, t.CPtr))
|
||||
abs_slot[0] = 0
|
||||
rel_slot[0] = 0
|
||||
inc_slot[0] = 0
|
||||
@@ -1079,7 +1079,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
stdlib.free(processed)
|
||||
stdlib.free(wl_pos)
|
||||
return -1
|
||||
wl_len = t.CSizeT(ret_ex)
|
||||
wl_len = sizet(ret_ex)
|
||||
stdlib.free(abs_path)
|
||||
stdlib.free(rel_path)
|
||||
stdlib.free(inc_dir)
|
||||
@@ -1095,7 +1095,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
|
||||
# 文件级 mark:parse import 后立即回收 AST(可达 includes 全量
|
||||
# parse 的 AST 若驻留 → 主池 OOM)
|
||||
scan_mark_r: t.CSizeT = mb.mark()
|
||||
scan_mark_r: sizet = mb.mark()
|
||||
sbuf_r: bytes = Utils.read_file_to_buf(abs_path, SRC_BUF_SIZE_R)
|
||||
if sbuf_r is None:
|
||||
stdlib.free(abs_path)
|
||||
@@ -1178,12 +1178,12 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
deps_r2: str = tr_r2._imported_modules
|
||||
StubMergerStore.PopulateIncludesDeps(sha1_r2, deps_r2)
|
||||
if deps_r2 is not None:
|
||||
td_len_w: t.CSizeT = string.strlen(temp_dir)
|
||||
td_len_w: sizet = string.strlen(temp_dir)
|
||||
deps_path_w: str = StubMergerCollect._sliced_path(temp_dir, td_len_w, sha1_r2, "deps.txt")
|
||||
if deps_path_w is not None:
|
||||
df_w: fileio.File | t.CPtr = fileio.File(deps_path_w, fileio.MODE.W)
|
||||
if not df_w.closed:
|
||||
dl_w: t.CSizeT = string.strlen(deps_r2)
|
||||
dl_w: sizet = string.strlen(deps_r2)
|
||||
if dl_w > 0:
|
||||
df_w.write(deps_r2, dl_w)
|
||||
df_w.close()
|
||||
@@ -1204,7 +1204,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
stdlib.free(wl_pos)
|
||||
mb.reset_to(scan_mark_r)
|
||||
return -1
|
||||
wl_len = t.CSizeT(ret_w)
|
||||
wl_len = sizet(ret_w)
|
||||
else:
|
||||
VLogger.debug(f"无依赖: {rel_path}", "Reachable")
|
||||
|
||||
@@ -1239,16 +1239,16 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
|
||||
# _sha1_map.txt 仅作为人类可读输出,程序内部不读取。
|
||||
# ============================================================
|
||||
def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
out_buf: bytes, out_size: t.CSizeT) -> t.CSizeT:
|
||||
out_buf: bytes, out_size: sizet) -> sizet:
|
||||
"""组合本地 stub + 依赖 stubs + 本地 text → out_buf(按需加载)"""
|
||||
global _seen_funcs, _seen_funcs_count, _seen_globals, _seen_globals_count
|
||||
global _seen_types, _seen_types_count, _seen_key_scratch
|
||||
if temp_dir is None or local_sha1 is None or out_buf is None or out_size == 0:
|
||||
return 0
|
||||
|
||||
td_len: t.CSizeT = string.strlen(temp_dir)
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
out_buf[0] = '\0'
|
||||
out_pos: t.CSizeT = 0
|
||||
out_pos: sizet = 0
|
||||
|
||||
# 已见符号表重置(跨构建复用缓冲,仅清零计数 + 全槽位清零)
|
||||
if _seen_funcs is None:
|
||||
@@ -1291,7 +1291,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
sf.close()
|
||||
stdlib.free(stub_path)
|
||||
return 0
|
||||
stub_br: t.CInt64T = sf.read_all(stub_content, StubMerger.STUB_READ_BUF_SIZE)
|
||||
stub_br: int64 = sf.read_all(stub_content, StubMerger.STUB_READ_BUF_SIZE)
|
||||
sf.close()
|
||||
stdlib.free(stub_path)
|
||||
if stub_br <= 0:
|
||||
@@ -1299,18 +1299,18 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
return 0
|
||||
if stub_br < StubMerger.STUB_READ_BUF_SIZE:
|
||||
stub_content[stub_br] = '\0'
|
||||
slen: t.CSizeT = stub_br
|
||||
slen: sizet = stub_br
|
||||
# 修复本地 stub.ll 中字符串常量的非法 IR:
|
||||
# llvmlite OUTPUT_STUB 模式输出 "= external unnamed_addr constant" 的非法形式。
|
||||
# 简单方案:搜索 "= external unnamed_addr constant" 并将 external 替换为 8 个空格。
|
||||
fix_pos: t.CSizeT = 0
|
||||
fix_pos: sizet = 0
|
||||
while fix_pos + 30 < slen:
|
||||
ext_ptr: t.CPtr = string.strstr(stub_content + fix_pos, "= external unnamed_addr constant")
|
||||
if ext_ptr is None:
|
||||
break
|
||||
# ext_ptr 指向 "= external ..." 中的 '='
|
||||
# 'external' 开始于 ext_ptr + 2
|
||||
ext_off: t.CSizeT = t.CSizeT(t.CUInt64T(ext_ptr) - t.CUInt64T(stub_content)) + 2
|
||||
ext_off: sizet = sizet(uint64(ext_ptr) - uint64(stub_content)) + 2
|
||||
if ext_off + 8 <= slen:
|
||||
stub_content[ext_off] = ' '
|
||||
stub_content[ext_off + 1] = ' '
|
||||
@@ -1351,7 +1351,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
if not df_deps.closed:
|
||||
deps_buf = stdlib.malloc(4096)
|
||||
if deps_buf is not None:
|
||||
deps_br: t.CInt64T = df_deps.read_all(deps_buf, 4096)
|
||||
deps_br: int64 = df_deps.read_all(deps_buf, 4096)
|
||||
if deps_br > 0:
|
||||
if deps_br < 4096:
|
||||
deps_buf[deps_br] = '\0'
|
||||
@@ -1410,7 +1410,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
if dep_buf is not None:
|
||||
si: int = 0
|
||||
while si < all_count:
|
||||
dep_sha1: str = all_sha1_arr + t.CSizeT(si) * 17
|
||||
dep_sha1: str = all_sha1_arr + sizet(si) * 17
|
||||
if string.strcmp(dep_sha1, local_sha1) == 0:
|
||||
si += 1
|
||||
continue
|
||||
@@ -1419,12 +1419,12 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
is_include: int = 0
|
||||
if inc_count > 0:
|
||||
for ii in range(inc_count):
|
||||
idx_ii: t.CSizeT = t.CSizeT(ii) * 17
|
||||
idx_ii: sizet = sizet(ii) * 17
|
||||
if string.strcmp(sha1_arr + idx_ii, dep_sha1) != 0:
|
||||
continue
|
||||
is_include = 1
|
||||
if deps_loaded != 0:
|
||||
idx_mi: t.CSizeT = t.CSizeT(ii) * 64
|
||||
idx_mi: sizet = sizet(ii) * 64
|
||||
dep_mod_name: str = mod_arr + idx_mi
|
||||
if GenApi.is_module_imported(deps_buf, dep_mod_name) != 0:
|
||||
should_load = 1
|
||||
@@ -1463,8 +1463,8 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
# 避免到 llc 才报 undefined value 错误。
|
||||
# 仅验证在 includes 映射中找到的模块(t/c 等内部库无 SHA1 映射,自动跳过)。
|
||||
if deps_loaded != 0 and inc_count > 0:
|
||||
dep_total: t.CSizeT = string.strlen(deps_buf)
|
||||
dp: t.CSizeT = 0
|
||||
dep_total: sizet = string.strlen(deps_buf)
|
||||
dp: sizet = 0
|
||||
while dp < dep_total:
|
||||
# 跳过前导空格
|
||||
while dp < dep_total:
|
||||
@@ -1474,12 +1474,12 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
if dp >= dep_total:
|
||||
break
|
||||
# 提取模块名(到下一个空格或末尾)
|
||||
ms: t.CSizeT = dp
|
||||
ms: sizet = dp
|
||||
while dp < dep_total:
|
||||
if deps_buf[dp] == ' ':
|
||||
break
|
||||
dp += 1
|
||||
ml: t.CSizeT = dp - ms
|
||||
ml: sizet = dp - ms
|
||||
if ml == 0:
|
||||
continue
|
||||
# 复制模块名到临时缓冲区并 null 终止
|
||||
@@ -1491,9 +1491,9 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
# 在 includes 映射中查找模块对应的 SHA1
|
||||
found_s: str = None
|
||||
for mi2 in range(inc_count):
|
||||
idx_m2: t.CSizeT = t.CSizeT(mi2) * 64
|
||||
idx_m2: sizet = sizet(mi2) * 64
|
||||
if string.strcmp(mod_arr + idx_m2, mod_nm) == 0:
|
||||
idx_s2: t.CSizeT = t.CSizeT(mi2) * 17
|
||||
idx_s2: sizet = sizet(mi2) * 17
|
||||
found_s = sha1_arr + idx_s2
|
||||
break
|
||||
if found_s is not None:
|
||||
@@ -1522,22 +1522,22 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
tf.close()
|
||||
stdlib.free(text_path)
|
||||
else:
|
||||
text_br: t.CInt64T = tf.read_all(text_content, StubMerger.STUB_READ_BUF_SIZE)
|
||||
text_br: int64 = tf.read_all(text_content, StubMerger.STUB_READ_BUF_SIZE)
|
||||
tf.close()
|
||||
stdlib.free(text_path)
|
||||
if text_br > 0:
|
||||
if text_br < StubMerger.STUB_READ_BUF_SIZE:
|
||||
text_content[text_br] = '\0'
|
||||
# 行级去重追加(与 _LoadAndAppendStub 相同逻辑)
|
||||
tx_pos: t.CSizeT = 0
|
||||
tx_pos: sizet = 0
|
||||
tx_skip: int = 1
|
||||
while tx_pos < text_br:
|
||||
tx_ls: t.CSizeT = tx_pos
|
||||
tx_ls: sizet = tx_pos
|
||||
while tx_pos < text_br:
|
||||
if text_content[tx_pos] == '\n':
|
||||
break
|
||||
tx_pos += 1
|
||||
tx_ll: t.CSizeT = tx_pos - tx_ls
|
||||
tx_ll: sizet = tx_pos - tx_ls
|
||||
if tx_pos < text_br:
|
||||
tx_pos += 1
|
||||
if tx_skip != 0:
|
||||
@@ -1556,23 +1556,23 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
# 注册暂存(append 成功后才登记;tx_key 指向 scratch,insert 当轮完成)
|
||||
tx_reg: int = 0
|
||||
tx_key: str = None
|
||||
tx_hash: t.CUInt64T = 0
|
||||
tx_hash: uint64 = 0
|
||||
tx_flags: int = 0
|
||||
# 去重:declare(用已见函数表,键 @"name"(,避免误匹配 call 语句)
|
||||
if tx_ll >= 8 and string.strncmp(text_content + tx_ls, "declare ", 8) == 0:
|
||||
tx_at: t.CSizeT = tx_ls + 8
|
||||
tx_at: sizet = tx_ls + 8
|
||||
while tx_at < tx_ls + tx_ll:
|
||||
if text_content[tx_at] == '@':
|
||||
break
|
||||
tx_at += 1
|
||||
if tx_at < tx_ls + tx_ll:
|
||||
tx_lp: t.CSizeT = tx_at + 1
|
||||
tx_lp: sizet = tx_at + 1
|
||||
while tx_lp < tx_ls + tx_ll:
|
||||
if text_content[tx_lp] == '(':
|
||||
break
|
||||
tx_lp += 1
|
||||
if tx_lp < tx_ls + tx_ll:
|
||||
tx_sv: t.CChar = text_content[tx_lp + 1]
|
||||
tx_sv: char = text_content[tx_lp + 1]
|
||||
text_content[tx_lp + 1] = '\0'
|
||||
tx_hash = _SeenHash(text_content + tx_at)
|
||||
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, text_content + tx_at, tx_hash) != 0:
|
||||
@@ -1585,19 +1585,19 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
text_content[tx_lp + 1] = tx_sv
|
||||
# 去重:define(注释 out_buf 中已有 declare,避免 declare/define 冲突)
|
||||
if tx_ll >= 7 and string.strncmp(text_content + tx_ls, "define ", 7) == 0:
|
||||
tx_at_d: t.CSizeT = tx_ls + 7
|
||||
tx_at_d: sizet = tx_ls + 7
|
||||
while tx_at_d < tx_ls + tx_ll:
|
||||
if text_content[tx_at_d] == '@':
|
||||
break
|
||||
tx_at_d += 1
|
||||
if tx_at_d < tx_ls + tx_ll:
|
||||
tx_lp_d: t.CSizeT = tx_at_d + 1
|
||||
tx_lp_d: sizet = tx_at_d + 1
|
||||
while tx_lp_d < tx_ls + tx_ll:
|
||||
if text_content[tx_lp_d] == '(':
|
||||
break
|
||||
tx_lp_d += 1
|
||||
if tx_lp_d < tx_ls + tx_ll:
|
||||
tx_sv_d: t.CChar = text_content[tx_lp_d + 1]
|
||||
tx_sv_d: char = text_content[tx_lp_d + 1]
|
||||
text_content[tx_lp_d + 1] = '\0'
|
||||
tx_hash = _SeenHash(text_content + tx_at_d)
|
||||
_SeenCommentOut(_seen_funcs, _SEEN_FUNC_CAP, text_content + tx_at_d, tx_hash, out_buf)
|
||||
@@ -1610,13 +1610,13 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
# stub 中可能是 external 声明或完整定义,以 text 中的定义为准
|
||||
# 注释 out_buf 中同名全局行,然后追加 text 中的定义(键 @name,截断于 '=' 前)
|
||||
if tx_ll > 0 and text_content[tx_ls] == '@':
|
||||
tx_eq: t.CSizeT = tx_ls + 1
|
||||
tx_eq: sizet = tx_ls + 1
|
||||
while tx_eq < tx_ls + tx_ll:
|
||||
if text_content[tx_eq] == '=':
|
||||
break
|
||||
tx_eq += 1
|
||||
if tx_eq < tx_ls + tx_ll:
|
||||
tx_sv2: t.CChar = text_content[tx_eq]
|
||||
tx_sv2: char = text_content[tx_eq]
|
||||
text_content[tx_eq] = '\0'
|
||||
tx_hash = _SeenHash(text_content + tx_ls)
|
||||
_SeenCommentOut(_seen_globals, _SEEN_GLOBAL_CAP, text_content + tx_ls, tx_hash, out_buf)
|
||||
@@ -1627,13 +1627,13 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
text_content[tx_eq] = tx_sv2
|
||||
# 去重:%type = ...(键 %name,截断于 '=' 前)
|
||||
if tx_ll > 0 and text_content[tx_ls] == '%':
|
||||
tx_eq2: t.CSizeT = tx_ls + 1
|
||||
tx_eq2: sizet = tx_ls + 1
|
||||
while tx_eq2 < tx_ls + tx_ll:
|
||||
if text_content[tx_eq2] == '=':
|
||||
break
|
||||
tx_eq2 += 1
|
||||
if tx_eq2 < tx_ls + tx_ll:
|
||||
tx_sv3: t.CChar = text_content[tx_eq2]
|
||||
tx_sv3: char = text_content[tx_eq2]
|
||||
text_content[tx_eq2] = '\0'
|
||||
tx_is_full: int = 0
|
||||
if tx_eq2 + 8 <= tx_ls + tx_ll:
|
||||
@@ -1653,7 +1653,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
text_content[tx_eq2] = tx_sv3
|
||||
# 追加(append 成功后才登记已见表)
|
||||
if out_pos + tx_ll + 2 < out_size:
|
||||
tx_reg_pos: t.CSizeT = out_pos
|
||||
tx_reg_pos: sizet = out_pos
|
||||
string.strncpy(out_buf + out_pos, text_content + tx_ls, tx_ll)
|
||||
out_pos += tx_ll
|
||||
out_buf[out_pos] = '\n'
|
||||
@@ -1715,12 +1715,12 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
|
||||
# → 参数类型退化 i8_ptr_ty → 整数实参误报 CastError(FuncTest 根因)。
|
||||
VpiReader.ResetVpiTypedefVisited()
|
||||
|
||||
td_len: t.CSizeT = string.strlen(temp_dir)
|
||||
total_len: t.CSizeT = string.strlen(imported_modules)
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
total_len: sizet = string.strlen(imported_modules)
|
||||
success_count: int = 0
|
||||
|
||||
# 遍历 imported_modules 中的每个模块名(空格分隔)
|
||||
ci: t.CSizeT = 0
|
||||
ci: sizet = 0
|
||||
while ci < total_len:
|
||||
# 跳过前导空格
|
||||
while ci < total_len and imported_modules[ci] == ' ':
|
||||
@@ -1728,10 +1728,10 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
|
||||
if ci >= total_len:
|
||||
break
|
||||
# 提取模块名(到下一个空格或字符串末尾)
|
||||
word_start: t.CSizeT = ci
|
||||
word_start: sizet = ci
|
||||
while ci < total_len and imported_modules[ci] != ' ':
|
||||
ci += 1
|
||||
word_len: t.CSizeT = ci - word_start
|
||||
word_len: sizet = ci - word_start
|
||||
if word_len == 0:
|
||||
continue
|
||||
|
||||
|
||||
@@ -52,26 +52,26 @@ import lib.Stub.StubMerger as StubMerger
|
||||
# Returns:
|
||||
# 完整路径(stdlib.malloc 分配,需 stdlib.free),None 失败
|
||||
# ============================================================
|
||||
def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
|
||||
def _sliced_path(temp_dir: str, td_len: sizet, sha1: str, ext: str) -> str:
|
||||
"""构建切片路径(stdlib.malloc 分配,调用者负责 free)
|
||||
|
||||
level>0 时自动调用 ensure_dir 创建子目录。
|
||||
"""
|
||||
if temp_dir is None or sha1 is None or ext is None:
|
||||
return None
|
||||
sha1_len: t.CSizeT = string.strlen(sha1)
|
||||
ext_len: t.CSizeT = string.strlen(ext)
|
||||
sha1_len: sizet = string.strlen(sha1)
|
||||
ext_len: sizet = string.strlen(ext)
|
||||
|
||||
# 子目录前缀:复用 Config.slice_subdir(SHA1 切片唯一权威实现,mbuddy 分配无需 free)
|
||||
subdir_buf: str = Config.slice_subdir(sha1, Config.Sha1SliceLevel)
|
||||
sub_len: t.CSizeT = 0
|
||||
sub_len: sizet = 0
|
||||
if subdir_buf is not None:
|
||||
sub_len = string.strlen(subdir_buf)
|
||||
|
||||
# 确保子目录存在: {temp_dir}/{subdir}
|
||||
# 不创建目录会导致 fileio.File(MODE.W) 静默失败(file.closed==True),
|
||||
# 进而 BuildCombinedIR 读不到文件返回 0("BuildCombinedIR 失败")。
|
||||
dir_path_len: t.CSizeT = td_len + sub_len + 2
|
||||
dir_path_len: sizet = td_len + sub_len + 2
|
||||
dir_path: bytes = stdlib.malloc(dir_path_len)
|
||||
if dir_path is not None:
|
||||
viperlib.snprintf(dir_path, dir_path_len, "%s/%s", temp_dir, subdir_buf)
|
||||
@@ -80,7 +80,7 @@ def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
|
||||
|
||||
# 构建完整路径
|
||||
path: str = None
|
||||
path_len: t.CSizeT = 0
|
||||
path_len: sizet = 0
|
||||
if sub_len > 0:
|
||||
path_len = td_len + sub_len + sha1_len + ext_len + 4
|
||||
path = stdlib.malloc(path_len)
|
||||
@@ -111,7 +111,7 @@ def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
|
||||
# Returns:
|
||||
# 收集后的总数量
|
||||
# ============================================================
|
||||
def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
|
||||
def _collect_stub_sha1s(base_dir: str, bd_len: sizet, level: int,
|
||||
out_arr: str, out_count: int, max_count: int) -> int:
|
||||
"""递归扫描子目录,收集 .stub.ll 文件的 SHA1"""
|
||||
if base_dir is None or out_arr is None:
|
||||
@@ -159,7 +159,7 @@ def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
|
||||
if handle != win32base.INVALID_HANDLE_VALUE:
|
||||
while True:
|
||||
# 检查是否是目录(FILE_ATTRIBUTE_DIRECTORY = 0x10 = 16)
|
||||
attrs: t.CUInt32T = find_data.dwFileAttributes
|
||||
attrs: uint32 = find_data.dwFileAttributes
|
||||
if (attrs & 16) != 0:
|
||||
fname = find_data.cFileName
|
||||
if fname is not None:
|
||||
@@ -174,7 +174,7 @@ def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
|
||||
# 构建子目录路径并递归扫描
|
||||
sub_dir: str = Utils.JoinPath(base_dir, fname)
|
||||
if sub_dir is not None:
|
||||
sub_dir_len: t.CSizeT = string.strlen(sub_dir)
|
||||
sub_dir_len: sizet = string.strlen(sub_dir)
|
||||
out_count = _collect_stub_sha1s(sub_dir, sub_dir_len, level - 1, out_arr, out_count, max_count)
|
||||
stdlib.free(sub_dir)
|
||||
if win32file.FindNextFileA(handle, find_data) == 0:
|
||||
@@ -206,8 +206,8 @@ def _load_includes_sha1_set(pool: rowptr[memhub.MemBuddy],
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
if count >= StubMerger.MAX_INCLUDES_SHA1:
|
||||
break
|
||||
idx: t.CSizeT = t.CSizeT(i) * 17
|
||||
string.strcpy(sha1_set + t.CSizeT(count) * 17, StubMerger._sha1_store_arr + idx)
|
||||
idx: sizet = sizet(i) * 17
|
||||
string.strcpy(sha1_set + sizet(count) * 17, StubMerger._sha1_store_arr + idx)
|
||||
count += 1
|
||||
return count
|
||||
# ============================================================
|
||||
@@ -247,7 +247,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
|
||||
return 1
|
||||
|
||||
# 构造路径 temp_dir/_sha1_map.txt
|
||||
dir_len: t.CSizeT = string.strlen(temp_dir)
|
||||
dir_len: sizet = string.strlen(temp_dir)
|
||||
map_path: bytes = stdlib.malloc(dir_len + 32)
|
||||
if map_path is None:
|
||||
return 1
|
||||
@@ -259,7 +259,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
|
||||
return 1
|
||||
|
||||
# 写入每个 include 条目: {sha1}:includes/{rel_path}\n
|
||||
entry_size_w: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
|
||||
entry_size_w: sizet = IncludesScanner.FileEntry.__sizeof__()
|
||||
line_buf: bytes = stdlib.malloc(512)
|
||||
if line_buf is None:
|
||||
f.close()
|
||||
@@ -267,7 +267,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
|
||||
|
||||
written_count: int = 0
|
||||
for i in range(scan_result.Count):
|
||||
ea_w: t.CUInt64T = t.CUInt64T(scan_result.Entries) + i * entry_size_w
|
||||
ea_w: uint64 = uint64(scan_result.Entries) + i * entry_size_w
|
||||
ent_w: rowptr[IncludesScanner.FileEntry] = (rowptr[IncludesScanner.FileEntry])(t.CVoid(ea_w, t.CPtr))
|
||||
if ent_w is None or ent_w.Sha1 is None or ent_w.RelPath is None:
|
||||
continue
|
||||
@@ -276,7 +276,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
|
||||
if _is_in_sha1_set(ent_w.Sha1, filter_set, filter_count) == 0:
|
||||
continue
|
||||
viperlib.snprintf(line_buf, 512, "%s:includes/%s\n", ent_w.Sha1, ent_w.RelPath)
|
||||
line_len_w: t.CSizeT = string.strlen(line_buf)
|
||||
line_len_w: sizet = string.strlen(line_buf)
|
||||
f.write(line_buf, line_len_w)
|
||||
written_count += 1
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import lib.Stub.StubMerger as StubMerger
|
||||
# 与 Phase B+(Phase2.vp 编译缺失 includes 时)的内联判断逻辑一致,
|
||||
# 供 Phase C 链接时区分"声明文件无需 .obj"与"实现文件缺失"。
|
||||
# ============================================================
|
||||
def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
|
||||
def IsDeclOnlyModule(temp_dir: str, td_len: sizet, sha1: str) -> int:
|
||||
"""判断模块是否为纯声明文件(text.ll 无 define 行)"""
|
||||
if temp_dir is None or sha1 is None:
|
||||
return -1
|
||||
@@ -53,7 +53,7 @@ def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
|
||||
if tf_d.closed:
|
||||
return -1
|
||||
tbuf_d: bytes = stdlib.malloc(StubMerger.STUB_READ_BUF_SIZE)
|
||||
tbr_d: t.CInt64T = 0
|
||||
tbr_d: int64 = 0
|
||||
if tbuf_d is not None:
|
||||
tbr_d = tf_d.read_all(tbuf_d, StubMerger.STUB_READ_BUF_SIZE)
|
||||
tf_d.close()
|
||||
@@ -66,14 +66,14 @@ def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
|
||||
if tbr_d < StubMerger.STUB_READ_BUF_SIZE:
|
||||
tbuf_d[tbr_d] = '\0'
|
||||
# 逐行扫描:找 "define " 行即为实现文件
|
||||
tpos_d: t.CSizeT = 0
|
||||
tpos_d: sizet = 0
|
||||
while tpos_d < tbr_d:
|
||||
tls_d: t.CSizeT = tpos_d
|
||||
tls_d: sizet = tpos_d
|
||||
while tpos_d < tbr_d:
|
||||
if tbuf_d[tpos_d] == '\n':
|
||||
break
|
||||
tpos_d += 1
|
||||
tll_d: t.CSizeT = tpos_d - tls_d
|
||||
tll_d: sizet = tpos_d - tls_d
|
||||
if tpos_d < tbr_d:
|
||||
tpos_d += 1
|
||||
if tll_d >= 7 and string.strncmp(tbuf_d + tls_d, "define ", 7) == 0:
|
||||
@@ -99,14 +99,14 @@ def _IsFuncDeclaredOrDefined(out_buf: bytes, func_sig: str) -> int:
|
||||
"""检查 out_buf 中是否已有函数的 declare 或 define 行"""
|
||||
if out_buf is None or func_sig is None:
|
||||
return 0
|
||||
sig_len: t.CSizeT = string.strlen(func_sig)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
sig_len: sizet = string.strlen(func_sig)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if sig_len == 0 or out_len == 0 or sig_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
for pos in range(0, out_len - sig_len + 1):
|
||||
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
|
||||
ls: t.CSizeT = pos
|
||||
ls: sizet = pos
|
||||
while ls > 0 and out_buf[ls - 1] != '\n':
|
||||
ls -= 1
|
||||
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
|
||||
@@ -125,14 +125,14 @@ def _CommentOutDeclareInBuf(out_buf: bytes, func_sig: str) -> int:
|
||||
"""在 out_buf 中搜索 declare 行(包含 func_sig),将其注释掉"""
|
||||
if out_buf is None or func_sig is None:
|
||||
return 0
|
||||
sig_len: t.CSizeT = string.strlen(func_sig)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
sig_len: sizet = string.strlen(func_sig)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if sig_len == 0 or out_len == 0 or sig_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos + sig_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
|
||||
ls: t.CSizeT = pos
|
||||
ls: sizet = pos
|
||||
while ls > 0 and out_buf[ls - 1] != '\n':
|
||||
ls -= 1
|
||||
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
|
||||
@@ -158,11 +158,11 @@ def _CommentOutGlobalInBuf(out_buf: bytes, global_name: str) -> int:
|
||||
"""
|
||||
if out_buf is None or global_name is None:
|
||||
return 0
|
||||
name_len: t.CSizeT = string.strlen(global_name)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
name_len: sizet = string.strlen(global_name)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if name_len == 0 or out_len == 0 or name_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
commented: int = 0
|
||||
while pos + name_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
|
||||
@@ -181,11 +181,11 @@ def _HasGlobalInBuf(out_buf: bytes, global_name: str) -> int:
|
||||
"""
|
||||
if out_buf is None or global_name is None:
|
||||
return 0
|
||||
name_len: t.CSizeT = string.strlen(global_name)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
name_len: sizet = string.strlen(global_name)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if name_len == 0 or out_len == 0 or name_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos + name_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0)
|
||||
@@ -209,17 +209,17 @@ def _CommentOutOpaqueTypeInBuf(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
"""
|
||||
if out_buf is None or type_name_prefix is None:
|
||||
return 0
|
||||
prefix_len: t.CSizeT = string.strlen(type_name_prefix)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
prefix_len: sizet = string.strlen(type_name_prefix)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos + prefix_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0)
|
||||
if pos == 0 or out_buf[pos - 1] == '\n':
|
||||
# 检查后面是否是 " = type opaque"
|
||||
p: t.CSizeT = pos + prefix_len
|
||||
p: sizet = pos + prefix_len
|
||||
# 跳过空格
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
@@ -255,12 +255,12 @@ def _is_submodule_of_imported(deps_buf: str, mod_name: str) -> int:
|
||||
dot_pos: str = string.strchr(mod_name, 46) # '.' = 46
|
||||
if dot_pos is None:
|
||||
return 0
|
||||
pkg_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_pos) - t.CUInt64T(mod_name))
|
||||
pkg_len: sizet = sizet(uint64(dot_pos) - uint64(mod_name))
|
||||
if pkg_len == 0 or pkg_len >= 256:
|
||||
return 0
|
||||
# 构造顶层包名(截断到 '.' 之前)
|
||||
# 直接在 mod_name 上临时截断检查,避免分配
|
||||
saved_ch: t.CChar = mod_name[pkg_len]
|
||||
saved_ch: char = mod_name[pkg_len]
|
||||
mod_name[pkg_len] = '\0'
|
||||
result: int = GenApi.is_module_imported(deps_buf, mod_name)
|
||||
mod_name[pkg_len] = saved_ch
|
||||
@@ -276,11 +276,11 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
"""检查 out_buf 中是否已有 type_name_prefix 的完整定义"""
|
||||
if out_buf is None or type_name_prefix is None:
|
||||
return 0
|
||||
prefix_len: t.CSizeT = string.strlen(type_name_prefix)
|
||||
out_len: t.CSizeT = string.strlen(out_buf)
|
||||
prefix_len: sizet = string.strlen(type_name_prefix)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
|
||||
return 0
|
||||
pos: t.CSizeT = 0
|
||||
pos: sizet = 0
|
||||
while pos + prefix_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0),且未被注释(行首不是 ';')
|
||||
@@ -291,7 +291,7 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
is_line_start = 1
|
||||
if is_line_start == 1:
|
||||
# 检查后面是否是 " = type {" 或 " = type <"
|
||||
p: t.CSizeT = pos + prefix_len
|
||||
p: sizet = pos + prefix_len
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
if p < out_len and out_buf[p] == '=':
|
||||
@@ -313,7 +313,7 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
# 返回两个数组(sha1_list 和 mod_list),长度存储在 count 中。
|
||||
# 所有内存由 stdlib.malloc 分配,调用者负责释放。
|
||||
# ============================================================
|
||||
def _BuildIncludesSha1Map(temp_dir: str, td_len: t.CSizeT,
|
||||
def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet,
|
||||
sha1_list: str,
|
||||
mod_list: str) -> int:
|
||||
"""从全局内存存储器复制 sha1→module_name 映射到调用者数组
|
||||
@@ -329,10 +329,10 @@ def _BuildIncludesSha1Map(temp_dir: str, td_len: t.CSizeT,
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
if count >= StubMerger.MAX_INCLUDES:
|
||||
break
|
||||
idx: t.CSizeT = t.CSizeT(i) * 17
|
||||
idx2: t.CSizeT = t.CSizeT(i) * 64
|
||||
string.strcpy(sha1_list + t.CSizeT(count) * 17, StubMerger._sha1_store_arr + idx)
|
||||
string.strcpy(mod_list + t.CSizeT(count) * 64, StubMerger._sha1_store_mod + idx2)
|
||||
idx: sizet = sizet(i) * 17
|
||||
idx2: sizet = sizet(i) * 64
|
||||
string.strcpy(sha1_list + sizet(count) * 17, StubMerger._sha1_store_arr + idx)
|
||||
string.strcpy(mod_list + sizet(count) * 64, StubMerger._sha1_store_mod + idx2)
|
||||
count += 1
|
||||
return count
|
||||
# ============================================================
|
||||
@@ -363,19 +363,19 @@ def _FindSha1ByModName(sha1_arr: str, mod_arr: str,
|
||||
return None
|
||||
# 第一遍:精确匹配
|
||||
for i in range(count):
|
||||
idx: t.CSizeT = t.CSizeT(i) * 64
|
||||
idx: sizet = sizet(i) * 64
|
||||
if string.strcmp(mod_arr + idx, mod_name) == 0:
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx: sizet = sizet(i) * 17
|
||||
return sha1_arr + sidx
|
||||
# 第二遍:包名回退("ast" → "ast.__init__")
|
||||
nm_len: t.CSizeT = string.strlen(mod_name)
|
||||
nm_len: sizet = string.strlen(mod_name)
|
||||
init_buf: bytes = stdlib.malloc(nm_len + 12)
|
||||
if init_buf is not None:
|
||||
viperlib.snprintf(init_buf, nm_len + 12, "%s.__init__", mod_name)
|
||||
for i in range(count):
|
||||
idx2: t.CSizeT = t.CSizeT(i) * 64
|
||||
idx2: sizet = sizet(i) * 64
|
||||
if string.strcmp(mod_arr + idx2, init_buf) == 0:
|
||||
sidx2: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx2: sizet = sizet(i) * 17
|
||||
stdlib.free(init_buf)
|
||||
return sha1_arr + sidx2
|
||||
stdlib.free(init_buf)
|
||||
@@ -398,11 +398,11 @@ def _AddSha1ToSet(set_buf: str, count: int, sha1: str) -> int:
|
||||
if set_buf is None or sha1 is None:
|
||||
return count
|
||||
for i in range(count):
|
||||
idx: t.CSizeT = t.CSizeT(i) * 17
|
||||
idx: sizet = sizet(i) * 17
|
||||
if string.strcmp(set_buf + idx, sha1) == 0:
|
||||
return count
|
||||
if count < StubMerger.MAX_INCLUDES_SHA1:
|
||||
idx: t.CSizeT = t.CSizeT(count) * 17
|
||||
idx: sizet = sizet(count) * 17
|
||||
string.strcpy(set_buf + idx, sha1)
|
||||
return count + 1
|
||||
return count
|
||||
@@ -72,17 +72,17 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
|
||||
string.memset(StubMerger._sha1_store_incdir, 0, StubMerger.MAX_INCLUDES * StubMerger.MAX_INC_DIR_LEN)
|
||||
StubMerger._sha1_store_count = 0
|
||||
p_bad: int = 0
|
||||
entry_size_p: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
|
||||
entry_size_p: sizet = IncludesScanner.FileEntry.__sizeof__()
|
||||
for i in range(scan_result.Count):
|
||||
if StubMerger._sha1_store_count >= StubMerger.MAX_INCLUDES:
|
||||
VLogger.error("includes SHA1 存储超上限,终止", "StubMerger")
|
||||
ea: t.CUInt64T = t.CUInt64T(scan_result.Entries) + i * entry_size_p
|
||||
ea: uint64 = uint64(scan_result.Entries) + i * entry_size_p
|
||||
ent: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
|
||||
if ent is None or ent.Sha1 is None or ent.RelPath is None:
|
||||
p_bad += 1
|
||||
continue
|
||||
# 构建完整路径 includes/{RelPath}(_PathToModuleName 需要)
|
||||
rp_len: t.CSizeT = string.strlen(ent.RelPath)
|
||||
rp_len: sizet = string.strlen(ent.RelPath)
|
||||
full_path_buf: bytes = stdlib.malloc(rp_len + 10)
|
||||
if full_path_buf is None:
|
||||
p_bad += 1
|
||||
@@ -91,10 +91,10 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
|
||||
mod_name: str = Utils.PathToModuleName(full_path_buf, 1)
|
||||
stdlib.free(full_path_buf)
|
||||
if mod_name is not None:
|
||||
idx: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
|
||||
idx: sizet = sizet(StubMerger._sha1_store_count) * 17
|
||||
string.strcpy(StubMerger._sha1_store_arr + idx, ent.Sha1)
|
||||
idx2: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
|
||||
mn_len: t.CSizeT = string.strlen(mod_name)
|
||||
idx2: sizet = sizet(StubMerger._sha1_store_count) * 64
|
||||
mn_len: sizet = string.strlen(mod_name)
|
||||
if mn_len < 64:
|
||||
string.strcpy(StubMerger._sha1_store_mod + idx2, mod_name)
|
||||
else:
|
||||
@@ -102,16 +102,16 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
|
||||
StubMerger._sha1_store_mod[idx2 + 63] = '\0'
|
||||
stdlib.free(mod_name)
|
||||
# 保存 rel_path(供 Phase2 3.5 编译缺失 includes 使用)
|
||||
idx3: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
idx3: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
if rp_len < StubMerger.MAX_REL_PATH_LEN:
|
||||
string.strcpy(StubMerger._sha1_store_rel + idx3, ent.RelPath)
|
||||
else:
|
||||
string.strncpy(StubMerger._sha1_store_rel + idx3, ent.RelPath, StubMerger.MAX_REL_PATH_LEN - 1)
|
||||
StubMerger._sha1_store_rel[idx3 + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
|
||||
# 保存所属 includes 根目录(Phase2 预注册/按需编译拼路径用)
|
||||
idx_inc: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
idx_inc: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
if ent.IncDir is not None:
|
||||
icd_len: t.CSizeT = string.strlen(ent.IncDir)
|
||||
icd_len: sizet = string.strlen(ent.IncDir)
|
||||
if icd_len < StubMerger.MAX_INC_DIR_LEN:
|
||||
string.strcpy(StubMerger._sha1_store_incdir + idx_inc, ent.IncDir)
|
||||
else:
|
||||
@@ -175,18 +175,18 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int:
|
||||
# LookupSha1ByModName("gfx") 失败 → 后缀匹配劫持到 VKernel 同名 gfx
|
||||
# (VKernel/Kernel/drivers/video/vesafb/gfx.vp,类 Scene3D 归属错乱根因)。
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
sidx_d: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx_d: sizet = sizet(i) * 17
|
||||
if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0:
|
||||
midx_d: t.CSizeT = t.CSizeT(i) * 64
|
||||
midx_d: sizet = sizet(i) * 64
|
||||
if string.strcmp(StubMerger._sha1_store_mod + midx_d, mod_name) == 0:
|
||||
stdlib.free(mod_name)
|
||||
return 0
|
||||
# 写入 SHA1
|
||||
idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
|
||||
idx_a: sizet = sizet(StubMerger._sha1_store_count) * 17
|
||||
string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1)
|
||||
# 写入模块名
|
||||
idx_m: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
|
||||
mn_len: t.CSizeT = string.strlen(mod_name)
|
||||
idx_m: sizet = sizet(StubMerger._sha1_store_count) * 64
|
||||
mn_len: sizet = string.strlen(mod_name)
|
||||
if mn_len < 64:
|
||||
string.strcpy(StubMerger._sha1_store_mod + idx_m, mod_name)
|
||||
else:
|
||||
@@ -194,15 +194,15 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int:
|
||||
StubMerger._sha1_store_mod[idx_m + 63] = '\0'
|
||||
stdlib.free(mod_name)
|
||||
# 写入相对路径
|
||||
idx_r: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
rp_len: t.CSizeT = string.strlen(rel_path)
|
||||
idx_r: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
rp_len: sizet = string.strlen(rel_path)
|
||||
if rp_len < StubMerger.MAX_REL_PATH_LEN:
|
||||
string.strcpy(StubMerger._sha1_store_rel + idx_r, rel_path)
|
||||
else:
|
||||
string.strncpy(StubMerger._sha1_store_rel + idx_r, rel_path, StubMerger.MAX_REL_PATH_LEN - 1)
|
||||
StubMerger._sha1_store_rel[idx_r + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
|
||||
# App 源文件不属于任何 includes 目录:IncDir 留空(Phase2 回退 includes_dir 参数)
|
||||
idx_inc_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
idx_inc_a: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
StubMerger._sha1_store_incdir[idx_inc_a] = '\0'
|
||||
StubMerger._sha1_store_count += 1
|
||||
return 0
|
||||
@@ -244,34 +244,34 @@ def AddIncludeToSha1MapStore(sha1: str, rel_path: str, inc_dir: str, mod_name: s
|
||||
return 1
|
||||
# 去重:SHA1 与模块名都相同才跳过(对齐 AppendToSha1MapStore)
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
sidx_d: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx_d: sizet = sizet(i) * 17
|
||||
if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0:
|
||||
midx_d: t.CSizeT = t.CSizeT(i) * 64
|
||||
midx_d: sizet = sizet(i) * 64
|
||||
if string.strcmp(StubMerger._sha1_store_mod + midx_d, mod_name) == 0:
|
||||
return 0
|
||||
# 写 SHA1
|
||||
idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
|
||||
idx_a: sizet = sizet(StubMerger._sha1_store_count) * 17
|
||||
string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1)
|
||||
# 写模块名
|
||||
idx_m: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
|
||||
mn_len: t.CSizeT = string.strlen(mod_name)
|
||||
idx_m: sizet = sizet(StubMerger._sha1_store_count) * 64
|
||||
mn_len: sizet = string.strlen(mod_name)
|
||||
if mn_len < 64:
|
||||
string.strcpy(StubMerger._sha1_store_mod + idx_m, mod_name)
|
||||
else:
|
||||
string.strncpy(StubMerger._sha1_store_mod + idx_m, mod_name, 63)
|
||||
StubMerger._sha1_store_mod[idx_m + 63] = '\0'
|
||||
# 写相对路径
|
||||
idx_r: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
rp_len: t.CSizeT = string.strlen(rel_path)
|
||||
idx_r: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
|
||||
rp_len: sizet = string.strlen(rel_path)
|
||||
if rp_len < StubMerger.MAX_REL_PATH_LEN:
|
||||
string.strcpy(StubMerger._sha1_store_rel + idx_r, rel_path)
|
||||
else:
|
||||
string.strncpy(StubMerger._sha1_store_rel + idx_r, rel_path, StubMerger.MAX_REL_PATH_LEN - 1)
|
||||
StubMerger._sha1_store_rel[idx_r + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
|
||||
# 写所属 includes 根目录(非空 = includes 条目;App 条目留空)
|
||||
idx_inc: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
idx_inc: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
|
||||
if inc_dir is not None:
|
||||
icd_len: t.CSizeT = string.strlen(inc_dir)
|
||||
icd_len: sizet = string.strlen(inc_dir)
|
||||
if icd_len < StubMerger.MAX_INC_DIR_LEN:
|
||||
string.strcpy(StubMerger._sha1_store_incdir + idx_inc, inc_dir)
|
||||
else:
|
||||
@@ -317,34 +317,34 @@ def LookupSha1ByModNameSuffix(mod_suffix: str) -> str:
|
||||
return None
|
||||
if StubMerger._sha1_store_count <= 0:
|
||||
return None
|
||||
suffix_len_sf: t.CSizeT = string.strlen(mod_suffix)
|
||||
suffix_len_sf: sizet = string.strlen(mod_suffix)
|
||||
if suffix_len_sf == 0:
|
||||
return None
|
||||
i_sf: int
|
||||
for i_sf in range(StubMerger._sha1_store_count):
|
||||
idx_sf: t.CSizeT = t.CSizeT(i_sf) * 64
|
||||
idx_sf: sizet = sizet(i_sf) * 64
|
||||
mod_name_sf: str = StubMerger._sha1_store_mod + idx_sf
|
||||
mod_len_sf: t.CSizeT = string.strlen(mod_name_sf)
|
||||
mod_len_sf: sizet = string.strlen(mod_name_sf)
|
||||
if mod_len_sf == 0:
|
||||
continue
|
||||
# 精确匹配
|
||||
if mod_len_sf == suffix_len_sf:
|
||||
if string.strcmp(mod_name_sf, mod_suffix) == 0:
|
||||
sidx_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||||
sidx_sf: sizet = sizet(i_sf) * 17
|
||||
return StubMerger._sha1_store_arr + sidx_sf
|
||||
# 后缀匹配:mod_name 以 "." + mod_suffix 结尾
|
||||
if mod_len_sf > suffix_len_sf:
|
||||
if mod_name_sf[mod_len_sf - suffix_len_sf - 1] == '.':
|
||||
cmp_start_sf: str = mod_name_sf + mod_len_sf - suffix_len_sf
|
||||
if string.strcmp(cmp_start_sf, mod_suffix) == 0:
|
||||
sidx2_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||||
sidx2_sf: sizet = sizet(i_sf) * 17
|
||||
return StubMerger._sha1_store_arr + sidx2_sf
|
||||
# 反向后缀匹配:mod_suffix 以 "." + mod_name 结尾
|
||||
if suffix_len_sf > mod_len_sf:
|
||||
if mod_suffix[suffix_len_sf - mod_len_sf - 1] == '.':
|
||||
cmp_start_rev_sf: str = mod_suffix + suffix_len_sf - mod_len_sf
|
||||
if string.strcmp(cmp_start_rev_sf, mod_name_sf) == 0:
|
||||
sidx_rev_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||||
sidx_rev_sf: sizet = sizet(i_sf) * 17
|
||||
return StubMerger._sha1_store_arr + sidx_rev_sf
|
||||
return None
|
||||
# ============================================================
|
||||
@@ -361,11 +361,11 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
|
||||
"""从 from_imports 别名映射解析模块 SHA1(改名别名 import X as Y 场景)"""
|
||||
if from_imports is None or alias is None:
|
||||
return None
|
||||
alias_len: t.CSizeT = string.strlen(alias)
|
||||
alias_len: sizet = string.strlen(alias)
|
||||
if alias_len == 0:
|
||||
return None
|
||||
total_len: t.CSizeT = string.strlen(from_imports)
|
||||
ci: t.CSizeT = 0
|
||||
total_len: sizet = string.strlen(from_imports)
|
||||
ci: sizet = 0
|
||||
while ci < total_len:
|
||||
# 跳过前导空格
|
||||
while ci < total_len and from_imports[ci] == ' ':
|
||||
@@ -373,14 +373,14 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
|
||||
if ci >= total_len:
|
||||
break
|
||||
# 条目起点 ci,找 ':'(local_name 结束)
|
||||
colon: t.CSizeT = ci
|
||||
colon: sizet = ci
|
||||
while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ':
|
||||
colon += 1
|
||||
local_len: t.CSizeT = colon - ci
|
||||
local_len: sizet = colon - ci
|
||||
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
|
||||
# 比较 local_name == alias
|
||||
match: int = 1
|
||||
li: t.CSizeT = 0
|
||||
li: sizet = 0
|
||||
while li < alias_len:
|
||||
if from_imports[ci + li] != alias[li]:
|
||||
match = 0
|
||||
@@ -388,8 +388,8 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
|
||||
li += 1
|
||||
if match == 1:
|
||||
# 提取 module(colon+1 到下一个 ':' 或空格)
|
||||
m_start: t.CSizeT = colon + 1
|
||||
m_end: t.CSizeT = m_start
|
||||
m_start: sizet = colon + 1
|
||||
m_end: sizet = m_start
|
||||
while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ':
|
||||
m_end += 1
|
||||
if m_end > m_start:
|
||||
@@ -419,11 +419,11 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
|
||||
"""从 from_imports 别名映射解析模块真名(import X as Y → Y:X)"""
|
||||
if from_imports is None or alias is None:
|
||||
return None
|
||||
alias_len: t.CSizeT = string.strlen(alias)
|
||||
alias_len: sizet = string.strlen(alias)
|
||||
if alias_len == 0:
|
||||
return None
|
||||
total_len: t.CSizeT = string.strlen(from_imports)
|
||||
ci: t.CSizeT = 0
|
||||
total_len: sizet = string.strlen(from_imports)
|
||||
ci: sizet = 0
|
||||
while ci < total_len:
|
||||
# 跳过前导空格
|
||||
while ci < total_len and from_imports[ci] == ' ':
|
||||
@@ -431,14 +431,14 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
|
||||
if ci >= total_len:
|
||||
break
|
||||
# 条目起点 ci,找 ':'(local_name 结束)
|
||||
colon: t.CSizeT = ci
|
||||
colon: sizet = ci
|
||||
while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ':
|
||||
colon += 1
|
||||
local_len: t.CSizeT = colon - ci
|
||||
local_len: sizet = colon - ci
|
||||
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
|
||||
# 比较 local_name == alias
|
||||
match: int = 1
|
||||
li: t.CSizeT = 0
|
||||
li: sizet = 0
|
||||
while li < alias_len:
|
||||
if from_imports[ci + li] != alias[li]:
|
||||
match = 0
|
||||
@@ -446,8 +446,8 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
|
||||
li += 1
|
||||
if match == 1:
|
||||
# 提取 module(colon+1 到下一个 ':' 或空格)
|
||||
m_start: t.CSizeT = colon + 1
|
||||
m_end: t.CSizeT = m_start
|
||||
m_start: sizet = colon + 1
|
||||
m_end: sizet = m_start
|
||||
while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ':
|
||||
m_end += 1
|
||||
if m_end > m_start:
|
||||
@@ -491,16 +491,16 @@ def PopulateIncludesDeps(sha1: str, deps_str: str) -> int:
|
||||
return 1
|
||||
# 去重:若 SHA1 已存在则跳过
|
||||
for i in range(StubMerger._includes_deps_count):
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx: sizet = sizet(i) * 17
|
||||
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
|
||||
return 0
|
||||
# 写入 SHA1
|
||||
idx: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * 17
|
||||
idx: sizet = sizet(StubMerger._includes_deps_count) * 17
|
||||
string.strcpy(StubMerger._includes_deps_sha1 + idx, sha1)
|
||||
# 写入依赖字符串
|
||||
idx2: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * StubMerger.MAX_DEPS_STR_LEN
|
||||
idx2: sizet = sizet(StubMerger._includes_deps_count) * StubMerger.MAX_DEPS_STR_LEN
|
||||
if deps_str is not None:
|
||||
dl: t.CSizeT = string.strlen(deps_str)
|
||||
dl: sizet = string.strlen(deps_str)
|
||||
if dl < StubMerger.MAX_DEPS_STR_LEN:
|
||||
string.strcpy(StubMerger._includes_deps_str + idx2, deps_str)
|
||||
else:
|
||||
@@ -525,9 +525,9 @@ def LookupIncludesDeps(sha1: str) -> str:
|
||||
if StubMerger._includes_deps_count <= 0:
|
||||
return None
|
||||
for i in range(StubMerger._includes_deps_count):
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx: sizet = sizet(i) * 17
|
||||
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
|
||||
idx2: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_DEPS_STR_LEN
|
||||
idx2: sizet = sizet(i) * StubMerger.MAX_DEPS_STR_LEN
|
||||
return StubMerger._includes_deps_str + idx2
|
||||
return None
|
||||
def GetSha1StoreArrPtr() -> bytes:
|
||||
@@ -590,8 +590,8 @@ def LookupSha1RelPath(sha1: str) -> str:
|
||||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_rel is None:
|
||||
return None
|
||||
for i in range(StubMerger._sha1_store_count):
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
sidx: sizet = sizet(i) * 17
|
||||
if string.strcmp(StubMerger._sha1_store_arr + sidx, sha1) == 0:
|
||||
ridx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_REL_PATH_LEN
|
||||
ridx: sizet = sizet(i) * StubMerger.MAX_REL_PATH_LEN
|
||||
return StubMerger._sha1_store_rel + ridx
|
||||
return None
|
||||
@@ -57,13 +57,13 @@ import lib.Stub.StubMerger as StubMerger
|
||||
def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
|
||||
store_mod_arr: bytes, reachable_set: bytes,
|
||||
reachable_count: int,
|
||||
sorted_idx: t.CSizeT | t.CPtr) -> int:
|
||||
sorted_idx: sizet | t.CPtr) -> 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: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
queue: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
rel_idx: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
indegree: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
queue: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
rel_idx: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
|
||||
if indegree is None or queue is None or rel_idx is None:
|
||||
if indegree is not None:
|
||||
stdlib.free(indegree)
|
||||
@@ -87,7 +87,7 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
|
||||
rel_count += 1
|
||||
else:
|
||||
for i_t in range(store_count):
|
||||
if StubMergerCollect._is_in_sha1_set(store_sha1_arr + t.CSizeT(i_t) * 17, reachable_set, reachable_count) != 0:
|
||||
if StubMergerCollect._is_in_sha1_set(store_sha1_arr + sizet(i_t) * 17, reachable_set, reachable_count) != 0:
|
||||
rel_idx[rel_count] = i_t
|
||||
rel_count += 1
|
||||
# 诊断:可达 store 索引数(rel_count=0 → topo_count=0 → PhaseB+ 循环不执行)
|
||||
@@ -96,16 +96,16 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
|
||||
i_r: int
|
||||
for i_r in range(rel_count):
|
||||
si: int = rel_idx[i_r]
|
||||
deps_si: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + t.CSizeT(si) * 17)
|
||||
deps_si: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + sizet(si) * 17)
|
||||
if deps_si is None:
|
||||
continue
|
||||
dl_si: t.CSizeT = string.strlen(deps_si)
|
||||
dpos: t.CSizeT = 0
|
||||
dl_si: sizet = string.strlen(deps_si)
|
||||
dpos: sizet = 0
|
||||
while dpos < dl_si:
|
||||
dstart: t.CSizeT = dpos
|
||||
dstart: sizet = dpos
|
||||
while dpos < dl_si and deps_si[dpos] != ' ':
|
||||
dpos += 1
|
||||
dlen: t.CSizeT = dpos - dstart
|
||||
dlen: sizet = dpos - dstart
|
||||
if dpos < dl_si:
|
||||
dpos += 1
|
||||
if dlen == 0:
|
||||
@@ -139,23 +139,23 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
|
||||
sorted_idx[out_count] = m
|
||||
out_count += 1
|
||||
# 对依赖 m 的可达模块减入度
|
||||
mod_m: str = store_mod_arr + t.CSizeT(m) * 64
|
||||
mod_m_len: t.CSizeT = string.strlen(mod_m)
|
||||
mod_m: str = store_mod_arr + sizet(m) * 64
|
||||
mod_m_len: sizet = string.strlen(mod_m)
|
||||
for i_r in range(rel_count):
|
||||
si3: int = rel_idx[i_r]
|
||||
if indegree[si3] == 0:
|
||||
continue
|
||||
deps_si3: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + t.CSizeT(si3) * 17)
|
||||
deps_si3: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + sizet(si3) * 17)
|
||||
if deps_si3 is None:
|
||||
continue
|
||||
dl_si3: t.CSizeT = string.strlen(deps_si3)
|
||||
dpos3: t.CSizeT = 0
|
||||
dl_si3: sizet = string.strlen(deps_si3)
|
||||
dpos3: sizet = 0
|
||||
found_dep: int = 0
|
||||
while dpos3 < dl_si3 and found_dep == 0:
|
||||
dstart3: t.CSizeT = dpos3
|
||||
dstart3: sizet = dpos3
|
||||
while dpos3 < dl_si3 and deps_si3[dpos3] != ' ':
|
||||
dpos3 += 1
|
||||
dlen3: t.CSizeT = dpos3 - dstart3
|
||||
dlen3: sizet = dpos3 - dstart3
|
||||
if dpos3 < dl_si3:
|
||||
dpos3 += 1
|
||||
if dlen3 == 0:
|
||||
|
||||
Reference in new issue
Block a user