refactor: rawptr[T] -> T*(R14)+ 修 REnum 前向占位未就地填充

R14:rawptr[X] -> X*(56 文件 / 834 行改动);保留 6 处 rawptr[t.CPtr](存纯裸指针的规范例外)。 修复:class X(t.REnum) 的变体字段写成自引用 X* 时,字段解析在变体扫描期经 ensure_forward_class 建了一个 opaque 前向占位;末尾 register_struct 按 Ty 指针去重会再建第二个同名 entry,而 find_struct 取首个(占位,0 字段)→ X.__sizeof__() == 0,报「已注册但大小为 0(字段链表未填充)」。改为注册前若命中同模块前向占位则就地填充(与 ensure_forward_class 文档口径一致)。TPC 无此问题,属 TPV 侧缺口。 验证:自举三重重编 SUCCESS;全量 77/77 顺序回归通过(修复前卡在 LLvmLiteTest)。
This commit is contained in:
TermiNexus committed 2026-10-05 17:38:28 +08:00
1 parent aeb4e8e54c
commit cd55a7e214
56 files changed
+834 -822

No files matched your search

+2 -2
View File
@@ -241,7 +241,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
# Compare: comparison expressions (MAX_SIZE > 512 / val == 1).
# == != < <= > >= match TPC; unknown ops emit " ? ".
if k == ast.ASTKind.Compare:
cmp_t: rawptr[ast.Compare] = rawptr[ast.Compare](annot)
cmp_t: ast.Compare* = ast.Compare*(annot)
pos = _PyiTypeStr(buf, buf_size, pos, cmp_t.left, depth + 1)
ops_ct: list[int]* = (list[int]*)(cmp_t.ops)
cmps_ct: list[ast.AST*]* = cmp_t.comparators
@@ -264,7 +264,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
# BoolOp: boolean ops (ENABLED and MAX_SIZE > 0 / A or B).
# Matches TPC: and -> " and ", or -> " or ".
if k == ast.ASTKind.BoolOp:
bool_t: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](annot)
bool_t: ast.BoolOp* = ast.BoolOp*(annot)
vals_bt: list[ast.AST*]* = bool_t.values
if vals_bt is not None:
vn_bt: sizet = len(vals_bt)
+35 -35
View File
@@ -809,7 +809,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
vpi_path[td_len + 3] = '/'
string.strcpy(vpi_path + td_len + 4, src_sha1)
string.strcpy(vpi_path + td_len + 4 + sha1_len, ".vpi")
f: rawptr[fileio.File] = fileio.File(vpi_path, fileio.MODE.R)
f: fileio.File* = fileio.File(vpi_path, fileio.MODE.R)
if f.closed:
stdlib.free(vpi_path)
return 0
@@ -879,7 +879,7 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
vpi_path[td_len + 3] = '/'
string.strcpy(vpi_path + td_len + 4, src_sha1)
string.strcpy(vpi_path + td_len + 4 + sha1_len, ".vpi")
f: rawptr[fileio.File] = fileio.File(vpi_path, fileio.MODE.R)
f: fileio.File* = fileio.File(vpi_path, fileio.MODE.R)
if f.closed:
stdlib.free(vpi_path)
return 0
@@ -1450,7 +1450,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, import_mods: str, temp
vpi_path_r[td_len + 3] = '/'
string.strcpy(vpi_path_r + td_len + 4, sha1_r)
string.strcpy(vpi_path_r + td_len + 4 + 16, ".vpi")
f_r: rawptr[fileio.File] = fileio.File(vpi_path_r, fileio.MODE.R)
f_r: fileio.File* = fileio.File(vpi_path_r, fileio.MODE.R)
if f_r.closed:
stdlib.free(vpi_path_r)
continue
@@ -1570,7 +1570,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, v
if pool is None or mod is None or vpi_path is None or trans is None: return 0
# 1. read the .vpi file
f: rawptr[fileio.File] = fileio.File(vpi_path, fileio.MODE.R)
f: fileio.File* = fileio.File(vpi_path, fileio.MODE.R)
if f.closed: return 0
vpi_buf: bytes = stdlib.malloc(VPI_READ_BUF_SIZE)
if vpi_buf is None:
@@ -1934,7 +1934,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*,
if path_i is None: return 0
if sub_len_i > 0: viperlib.snprintf(path_i, path_len_i, "%s/%s/%s.vpi", temp_dir, sub_i, dep_sha1)
else: viperlib.snprintf(path_i, path_len_i, "%s/%s.vpi", temp_dir, dep_sha1)
vf_i: rawptr[fileio.File] = fileio.File(path_i, fileio.MODE.R)
vf_i: fileio.File* = fileio.File(path_i, fileio.MODE.R)
if vf_i.closed:
stdlib.free(path_i)
return 0
@@ -2058,7 +2058,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModul
# REPL (ReplStubLayoutMode): if this class is already driven by the {sha1}.meta path, yield to it:
# mark visible if registered, defer if the base is pending, skip if the layout is untrusted.
if ReplStubLayoutMode != 0:
se: rawptr[ReplStubClass] = _repl_stub_find(_repl_stub_key(pool, src_sha1, real_name))
se: ReplStubClass* = _repl_stub_find(_repl_stub_key(pool, src_sha1, real_name))
if se is not None and se.State != _REPL_SS_EMPTY:
if se.State == _REPL_SS_PENDING: _repl_stub_try(se, mod)
if se.State == _REPL_SS_OK: GenApi.add_visible_struct(pool, real_name)
@@ -2117,11 +2117,11 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModul
# the source module hit an empty struct and raise InternalCompilerError, so do not register.
if field_count == 0: return 0
# 4. build the ParamNode list
first_node_c: rawptr[mlirlite.ParamNode] = None
prev_node_c: rawptr[mlirlite.ParamNode] = None
first_node_c: mlirlite.ParamNode* = None
prev_node_c: mlirlite.ParamNode* = None
for fi_c in range(field_count):
fty_c: mlirlite.LLVMType* = (mlirlite.LLVMType*)(field_types_buf[fi_c])
pnode_c: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
pnode_c: mlirlite.ParamNode* = pool.alloc(mlirlite.ParamNode.__sizeof__())
if pnode_c is None: continue
string.memset(pnode_c, 0, mlirlite.ParamNode.__sizeof__())
pnode_c.Ty = fty_c
@@ -2153,7 +2153,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModul
# fill_fwd) so register_struct's Ty-pointer dedup works and the StructTable does not overflow.
if fill_fwd_c != 0 and existing_c is not None and existing_c.Ty is not None:
fwd_name_c: str = mlirlite.get_struct_name(existing_c.Ty)
fwd_fields_c: rawptr[mlirlite.ParamNode] = mlirlite.get_struct_fields(struct_ty_c)
fwd_fields_c: mlirlite.ParamNode* = mlirlite.get_struct_fields(struct_ty_c)
fwd_fc_c: int = mlirlite.get_struct_fcount(struct_ty_c)
*existing_c.Ty = mlirlite.LLVMType.Struct(fwd_fields_c, fwd_fc_c, fwd_name_c)
struct_ty_c = existing_c.Ty
@@ -2701,7 +2701,7 @@ def _repl_stub_path(sha1: str, ext: str) -> str:
def _repl_stub_readtext(path: str) -> str:
"""Read stub text (stdlib.malloc, caller frees); None if missing or over the size cap."""
if path is None: return None
f: rawptr[fileio.File] = fileio.File(path, fileio.MODE.R)
f: fileio.File* = fileio.File(path, fileio.MODE.R)
if f is None or f.closed: return None
sz: sizet = f.size()
if sz <= 0 or sz >= _REPL_STUB_TXT_CAP:
@@ -2808,39 +2808,39 @@ def ReplStubLayoutBegin(temp_dir: str) -> int:
return 0
def _repl_stub_at(i: int) -> rawptr[ReplStubClass]:
def _repl_stub_at(i: int) -> ReplStubClass*:
"""Return the i-th class-table entry, or None."""
if ReplStubTable is None or i < 0 or i >= ReplStubCount: return None
addr: sizet = ReplStubTable[i]
if addr == 0: return None
return rawptr[ReplStubClass](uint64(addr))
return ReplStubClass*(uint64(addr))
def _repl_stub_find(key: str) -> rawptr[ReplStubClass]:
def _repl_stub_find(key: str) -> ReplStubClass*:
"""Look up a class-table entry by "<sha1>.<class name>"; None if not found."""
if key is None: return None
i: int
for i in range(ReplStubCount):
e: rawptr[ReplStubClass] = _repl_stub_at(i)
e: ReplStubClass* = _repl_stub_at(i)
if e is None or e.Key is None: continue
if string.strcmp(e.Key, key) == 0: return e
return None
def _repl_stub_find_base(e: rawptr[ReplStubClass], bi: int) -> rawptr[ReplStubClass]:
def _repl_stub_find_base(e: ReplStubClass*, bi: int) -> ReplStubClass*:
"""Find a base-class entry: same-module SHA1 exact match first, then first bare-name match."""
if e is None or e.Bases is None or bi < 0 or bi >= e.BaseCount: return None
pname: str = rawptr(e.Bases[bi])
if pname is None: return None
i: int
for i in range(ReplStubCount):
pe: rawptr[ReplStubClass] = _repl_stub_at(i)
pe: ReplStubClass* = _repl_stub_at(i)
if pe is None or pe.ClassName is None: continue
if string.strcmp(pe.ClassName, pname) != 0: continue
if e.Sha1 is not None and pe.Sha1 is not None:
if string.strcmp(pe.Sha1, e.Sha1) == 0: return pe
for i in range(ReplStubCount):
pe2: rawptr[ReplStubClass] = _repl_stub_at(i)
pe2: ReplStubClass* = _repl_stub_at(i)
if pe2 is None or pe2.ClassName is None: continue
if string.strcmp(pe2.ClassName, pname) == 0: return pe2
return None
@@ -2883,7 +2883,7 @@ def _repl_stub_deco_flags(deco_list: list[ast.AST*]*) -> int:
return flags
def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int, first: rawptr[ReplStubClass]) -> int:
def _repl_stub_is_virtual(e: ReplStubClass*, mi: int, first: ReplStubClass*) -> int:
"""Return whether this class's mi-th method goes into the vtable."""
if e is None or e.MethodFlags is None or mi < 0 or mi >= e.MethodCount: return 0
mf: int = int(e.MethodFlags[mi])
@@ -2896,7 +2896,7 @@ def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int, first: rawptr[ReplS
return 0
def _repl_stub_warn_refuse(e: rawptr[ReplStubClass], why: str, a: int, b: int) -> None:
def _repl_stub_warn_refuse(e: ReplStubClass*, why: str, a: int, b: int) -> None:
"""Warn on a criterion rejection: stub field count a differs from flattened+vtable inference b."""
global ReplStubWarnLeft, ReplStubRefused
ReplStubRefused += 1
@@ -2905,7 +2905,7 @@ def _repl_stub_warn_refuse(e: rawptr[ReplStubClass], why: str, a: int, b: int) -
stdio.printf("includes 类布局: %s.%s 布局不可信 ⇒ 明确拒绝(原因=判据拒绝:%s;" "存根字段数=%d ≠ 展平字段数+虚表位=%d)。该类字段访问被明确拒绝" "(方法调用不受影响)\n", e.Sha1, e.ClassName, why, a, b)
def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None:
def _repl_stub_warn_nodata(e: ReplStubClass*, cause: int) -> None:
"""Warn on a missing-data refusal: no comparison was possible, so print the data sources instead."""
global ReplStubWarnLeft, ReplStubRefused
global ReplStubRefusedNoStub, ReplStubRefusedNoClass
@@ -2928,7 +2928,7 @@ def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None:
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" "meta %s.meta 存在但其中没有键 %s 的 `STRUCT … FIELDS n / OPAQUE` 记录;" "meta 字段数=未找到 / 推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问" "被拒绝(方法调用不受影响);若该类确实定义于该模块,说明 meta 陈旧/" "不完整,请重建\n", e.Sha1, e.ClassName, e.Sha1, e.Key)
def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) -> None:
def _repl_stub_warn_parent(e: ReplStubClass*, detail: str, pname: str) -> None:
"""Warn on an upstream-no-data refusal: the base layout is unavailable or unregistered."""
global ReplStubWarnLeft, ReplStubRefused, ReplStubRefusedParent
ReplStubRefused += 1
@@ -2938,7 +2938,7 @@ def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) ->
stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『上游无数据』:%s," "父类=%s;父类字段与虚表位无法展平 ⇒ 本类未做字段数比较)。该类字段访问" "被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname)
def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
def _repl_stub_try(e: ReplStubClass*, mod: mlirlite.LLVMModule*) -> int:
"""Validate and register the full layout from the stub: 1=registered / 0=base pending / -1=refused."""
global ReplStubOk, ReplStubVtOk, ReplStubWarnLeft
if e is None: return -1
@@ -2952,7 +2952,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
# (1) base classes must be ready (not ready -> defer; refused -> this layout is untrusted)
bi: int
for bi in range(e.BaseCount):
pe: rawptr[ReplStubClass] = _repl_stub_find_base(e, bi)
pe: ReplStubClass* = _repl_stub_find_base(e, bi)
if pe is None: return 0
if pe.State == _REPL_SS_PENDING: return 0
if pe.State == _REPL_SS_REFUSED:
@@ -2965,7 +2965,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
e.State = _REPL_SS_REFUSED
_repl_stub_warn_parent(e, "父类的字段类型未全部解析(其字段数不完整)", pe.ClassName)
return -1
first: rawptr[ReplStubClass] = None
first: ReplStubClass* = None
if e.BaseCount > 0: first = _repl_stub_find_base(e, 0)
# (2) HasVTable (transcribed from ClassGenBase._detect_vtable_status)
hv: int = 0
@@ -2978,7 +2978,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
# (3) field flattening (base fields first + own fields, deduped by short name, first wins)
cn: int = 0
for bi in range(e.BaseCount):
pe: rawptr[ReplStubClass] = _repl_stub_find_base(e, bi)
pe: ReplStubClass* = _repl_stub_find_base(e, bi)
fi: int
for fi in range(pe.Count):
if cn >= _REPL_STUB_FIELD_MAX: break
@@ -3009,7 +3009,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
vn: int = 0
if hv == 1:
for bi in range(e.BaseCount):
pe: rawptr[ReplStubClass] = _repl_stub_find_base(e, bi)
pe: ReplStubClass* = _repl_stub_find_base(e, bi)
vi: int
for vi in range(pe.VtCount):
if vn >= _REPL_STUB_VT_MAX: break
@@ -3041,10 +3041,10 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
total: int = cn + hv
i8_ptr: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
if i8_ptr is None: return 0
first_node: rawptr[mlirlite.ParamNode] = None
prev_node: rawptr[mlirlite.ParamNode] = None
first_node: mlirlite.ParamNode* = None
prev_node: mlirlite.ParamNode* = None
if hv == 1:
nd0: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
nd0: mlirlite.ParamNode* = pool.alloc(mlirlite.ParamNode.__sizeof__())
if nd0 is None: return 0
string.memset(nd0, 0, mlirlite.ParamNode.__sizeof__())
nd0.Ty = i8_ptr
@@ -3054,7 +3054,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
for fi2 in range(cn):
fty: mlirlite.LLVMType* = (mlirlite.LLVMType*)(e.Types[fi2])
if fty is None: continue
nd: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
nd: mlirlite.ParamNode* = pool.alloc(mlirlite.ParamNode.__sizeof__())
if nd is None: continue
string.memset(nd, 0, mlirlite.ParamNode.__sizeof__())
nd.Ty = fty
@@ -3116,7 +3116,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cd:
key: str = _repl_stub_key(pool, sha1, cd.name)
if key is None: return 0
if _repl_stub_find(key) is not None: return 0
e: rawptr[ReplStubClass] = pool.alloc(ReplStubClass.__sizeof__())
e: ReplStubClass* = pool.alloc(ReplStubClass.__sizeof__())
if e is None: return 0
string.memset(e, 0, ReplStubClass.__sizeof__())
e.Key = key
@@ -3287,21 +3287,21 @@ def ReplStubLayoutFinish() -> int:
prog: int = 0
i: int
for i in range(ReplStubCount):
e: rawptr[ReplStubClass] = _repl_stub_at(i)
e: ReplStubClass* = _repl_stub_at(i)
if e is None or e.State != _REPL_SS_PENDING: continue
if _repl_stub_try(e, None) != 0: prog += 1
if prog == 0: break
# still not ready -> the base was never registered (missing stub/refused): explicitly refuse
i2: int
for i2 in range(ReplStubCount):
e2: rawptr[ReplStubClass] = _repl_stub_at(i2)
e2: ReplStubClass* = _repl_stub_at(i2)
if e2 is None or e2.State != _REPL_SS_PENDING: continue
e2.State = _REPL_SS_REFUSED
# find the still-unready base class name (to identify the upstream)
pbad: str = "(未定位)"
bi2: int
for bi2 in range(e2.BaseCount):
peb: rawptr[ReplStubClass] = _repl_stub_find_base(e2, bi2)
peb: ReplStubClass* = _repl_stub_find_base(e2, bi2)
if peb is not None and peb.State == _REPL_SS_OK: continue
if peb is not None and peb.ClassName is not None: pbad = peb.ClassName
break
+8 -8
View File
@@ -97,11 +97,11 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str,
# 1. App scan (skipped when app_deps is non-empty; use the caller-provided initial queue directly)
if app_deps is None or app_deps[0] == '\0':
VLogger.info("App 扫描:解析 source_dir 的 import 依赖", "Reachable")
scan_res_r: rawptr[IncludesScanner.ScanResult] = IncludesScanner.scan_includes(mb, source_dir)
scan_res_r: IncludesScanner.ScanResult* = IncludesScanner.scan_includes(mb, source_dir)
if scan_res_r is not None:
es_r: sizet = IncludesScanner.FileEntry.__sizeof__()
for e_i_r in range(scan_res_r.Count):
e_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r)
e_r: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r)
if e_r is None or e_r.Path is None: continue
# File-level mark: reclaim the AST right after parsing (keeping all App ASTs resident would OOM)
app_mark: sizet = mb.mark()
@@ -116,7 +116,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str,
tokens: ast.Token* = ast.tokenize(lx)
tree = ast.parse_tokens(mb, tokens)
if tree is not None:
tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
tr: HandlesTranslator.Translator* = HandlesTranslator.Translator()
if tr is not None:
tr._declare_only = 2
# Source package name from RelPath (relative to source_dir, supports subdirs),
@@ -397,7 +397,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str,
stdlib.free(wl_pos)
mb.reset_to(scan_mark_r)
return -1
tr_r2: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
tr_r2: HandlesTranslator.Translator* = HandlesTranslator.Translator()
if tr_r2 is None:
stdlib.free(abs_path)
stdlib.free(rel_path)
@@ -448,7 +448,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str,
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: rawptr[fileio.File] = fileio.File(deps_path_w, fileio.MODE.W)
df_w: fileio.File* = fileio.File(deps_path_w, fileio.MODE.W)
if not df_w.closed:
dl_w: sizet = string.strlen(deps_r2)
if dl_w > 0: df_w.write(deps_r2, dl_w)
@@ -500,7 +500,7 @@ def LoadFullIR(temp_dir: str, sha1: str, out_buf: bytes, out_size: sizet) -> siz
td_len: sizet = string.strlen(temp_dir)
p: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "full.ll")
if p is None: return 0
f: rawptr[fileio.File] = fileio.File(p, fileio.MODE.R)
f: fileio.File* = fileio.File(p, fileio.MODE.R)
stdlib.free(p)
out_buf[0] = '\0'
if f.closed: return 0
@@ -516,7 +516,7 @@ def LoadFullIR(temp_dir: str, sha1: str, out_buf: bytes, out_size: sizet) -> siz
# LoadDepVpiIntoModule - load dependency modules' .vpi files and inject their declares into the current module.
# Call after Import handling and before translate_children; returns the number of successfully loaded .vpi files.
def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, imported_modules: str, from_imports: str, temp_dir: str, trans: rawptr[HandlesTranslator.Translator]) -> int:
def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, imported_modules: str, from_imports: str, temp_dir: str, trans: HandlesTranslator.Translator*) -> int:
"""Load dependency modules' .vpi files and inject their declares into the current module."""
if pool is None or mod is None or temp_dir is None or trans is None: return 0
if imported_modules is None: return 0
@@ -564,7 +564,7 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, impo
vpi_path: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1_val, "vpi")
if vpi_path is not None:
# Check that the .vpi file exists (is readable)
vf: rawptr[fileio.File] = fileio.File(vpi_path, fileio.MODE.R)
vf: fileio.File* = fileio.File(vpi_path, fileio.MODE.R)
if not vf.closed:
vf.close()
# Parse the .vpi via VpiReader and inject declares (the error context frame is kept by the caller HandlesTranslator)
+3 -3
View File
@@ -87,7 +87,7 @@ def _is_in_sha1_set(sha1: str, sha1_set: str, set_count: int) -> int:
return 0
# WriteIncludesSha1Map - write includes scan results to _sha1_map.txt (human-readable debug output only).
# Internally the in-memory store filled by PopulateSha1MapStore is used; returns 0 on success, non-zero on failure.
def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawptr[IncludesScanner.ScanResult], filter_set: str, filter_count: int) -> int:
def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: IncludesScanner.ScanResult*, filter_set: str, filter_count: int) -> int:
"""Write the includes scan result to _sha1_map.txt (human-readable debug output)."""
if temp_dir is None or scan_result is None: return 1
@@ -98,7 +98,7 @@ def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawpt
viperlib.snprintf(map_path, dir_len + 32, "%s/_sha1_map.txt", temp_dir)
# Open the file for writing (CREATE_ALWAYS)
f: rawptr[fileio.File] = fileio.File(map_path, fileio.MODE.W)
f: fileio.File* = fileio.File(map_path, fileio.MODE.W)
if f.closed: return 1
# Write each include entry: {sha1}:includes/{rel_path}\n
@@ -111,7 +111,7 @@ def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawpt
written_count: int = 0
for i in range(scan_result.Count):
ea_w: uint64 = uint64(scan_result.Entries) + i * entry_size_w
ent_w: rawptr[IncludesScanner.FileEntry] = (rawptr[IncludesScanner.FileEntry])(ea_w)
ent_w: IncludesScanner.FileEntry* = (IncludesScanner.FileEntry*)(ea_w)
if ent_w is None or ent_w.Sha1 is None or ent_w.RelPath is None: continue
# When a filter set is provided, write only its entries
if filter_set is not None and filter_count > 0:
+2 -2
View File
@@ -126,7 +126,7 @@ def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*, name: str, asname:
# PopulateSha1MapStore - build sha1 -> module_name map from ScanResult.Entries into the global store.
# Memory via stdlib.malloc (global, not freed with mbuddy). Returns entry count, -1 on failure.
def PopulateSha1MapStore(scan_result: rawptr[IncludesScanner.ScanResult]) -> int:
def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult*) -> int:
"""Populate the global SHA1 store from a scan result; returns the entry count or -1"""
if scan_result is None: return -1
# free the old store
@@ -149,7 +149,7 @@ def PopulateSha1MapStore(scan_result: rawptr[IncludesScanner.ScanResult]) -> int
for i in range(scan_result.Count):
if StubMerger._sha1_store_count >= StubMerger.MAX_INCLUDES: VLogger.error("includes SHA1 存储超上限,终止", "StubMerger")
ea: uint64 = uint64(scan_result.Entries) + i * entry_size_p
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea)
ent: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(ea)
if ent is None or ent.Sha1 is None or ent.RelPath is None:
p_bad += 1
continue