chore: 全仓同步 w32→win32 模块改名与 range(int(...)) 显式收窄适配

This commit is contained in:
TermiNexus committed 2026-10-12 20:59:11 +08:00
1 parent ea2af739dd
commit d206abf3e1
49 files changed
+16545 -16495

No files matched your search

+34 -34
View File
@@ -4,8 +4,8 @@ import string
import stdlib
import memhub
import viperlib
import w32.fileio as fileio
import w32.win32base
import win32.fileio as fileio
import win32.win32base
import ast
import mlirlite
import lib.core.VLogger as VLogger
@@ -133,7 +133,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
if StubMerger._includes_deps_sha1 is None or StubMerger._includes_deps_str is None: return 0
cnt: sizet = StubMerger._includes_deps_count
ci: sizet
for ci in range(cnt):
for ci in range(int(cnt)):
sha1_m: str = StubMerger._includes_deps_sha1 + sizet(ci) * 17
deps_m: str = StubMerger._includes_deps_str + sizet(ci) * StubMerger.MAX_DEPS_STR_LEN
if sha1_m is None or deps_m is None: continue
@@ -195,7 +195,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> IncludesSc
if result is None: return None
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
i: sizet
for i in range(store_count):
for i in range(int(store_count)):
sidx: sizet = sizet(i) * 17
if StubMerger._sha1_store_arr[sidx] == '\0': continue
# Only includes entries (non-empty incdir); App entries do not enter result
@@ -274,7 +274,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
# On-demand dependency scan (App-first): seed the queue from App imports, then BFS-resolve
# reachable includes only (read + SHA1 + import parse); unreferenced ones are never read.
t_scan0: uint64 = w32.win32base.GetTickCount64()
t_scan0: uint64 = win32.win32base.GetTickCount64()
reachable_set: str = None
reachable_count: int = 0
use_reachable: int = 0
@@ -298,7 +298,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
else:
VLogger.warning("SourceDir unavailable; cannot build the dependency graph; skipping Phase1", "Phase1")
return 0
t_scan1: uint64 = w32.win32base.GetTickCount64()
t_scan1: uint64 = win32.win32base.GetTickCount64()
VLogger.info(f"dependency-graph scan total time: {t_scan1 - t_scan0} ms (reachable {reachable_count} includes)", "Phase1")
# Build the reachable FileEntry list from the Sha1Store; 1a/1b-pre/1b iterate result
@@ -354,10 +354,10 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
p1_sz_ds: sizet = sizet(Phase1.MAX_CLASSES * Phase1.SHA1_LEN)
p1_sz_tp: sizet = sizet(4 * Phase1.MAX_FILE_DEPS)
p1_sz_bx: sizet = sizet(4)
p1_o_cn: int = mb._order_for_size(p1_sz_cn + 16)
p1_o_ds: int = mb._order_for_size(p1_sz_ds + 16)
p1_o_tp: int = mb._order_for_size(p1_sz_tp + 16)
p1_o_bx: int = mb._order_for_size(p1_sz_bx + 16)
p1_o_cn: int = int(mb._order_for_size(p1_sz_cn + 16))
p1_o_ds: int = int(mb._order_for_size(p1_sz_ds + 16))
p1_o_tp: int = int(mb._order_for_size(p1_sz_tp + 16))
p1_o_bx: int = int(mb._order_for_size(p1_sz_bx + 16))
p1_fl_cn: uint64 = uint64(mb.free_lists[p1_o_cn])
p1_fl_ds: uint64 = uint64(mb.free_lists[p1_o_ds])
VLogger.info(f"[EVIDENCE] order(class_names {p1_sz_cn}B+16)={p1_o_cn} fl={p1_fl_cn} " f"order(def_sha1s {p1_sz_ds}B+16)={p1_o_ds} fl={p1_fl_ds} " f"order(topo {p1_sz_tp}B+16)={p1_o_tp} order(box {p1_sz_bx}B+16)={p1_o_bx} " f"(fl==0 only means that order is empty and can still be split by a higher order; if alloc fails while dump_stats shows free>0 that is the definitive proof of metadata corruption; " f"any order>max_order={mb.max_order} means an abnormal size)", "Phase1")
@@ -394,7 +394,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
td_len_ts_call: sizet = string.strlen(temp_dir)
ret_topo: int = Phase1Topo._TopoSortFiles(mb, result, reachable_set, reachable_count, use_reachable, sha1_set, set_count, class_names_buf, parent_names_buf, def_sha1s_buf, class_count_scanned, topo_order, topo_count_box, temp_dir, td_len_ts_call)
if ret_topo == 0:
tc_ptr: t.CPtr = (int*)(topo_count_box)
tc_ptr: int* = (int*)(topo_count_box)
if tc_ptr is not None: topo_count = tc_ptr[0]
VLogger.info(f"topological sort: {class_count_scanned} classes, {topo_count} files processed in dependency order", "Phase1")
else:
@@ -415,17 +415,17 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
GenApi.set_stdlib_alloc(1)
# Iterate files: topo order preferred, falling back to alphabetical
iter_count: int = topo_count if topo_count > 0 else result.Count
iter_count: int = int(topo_count if topo_count > 0 else result.Count)
# 1a total-time start (struct/enum/union registration)
t_a0: uint64 = w32.win32base.GetTickCount64()
for i in range(iter_count):
t_a0: uint64 = win32.win32base.GetTickCount64()
for i in range(int(iter_count)):
# Per-file mark: free this file's AST after translating (registered data is in perm_pool)
p1a_mark: sizet = mb.mark()
# Get the file index: topo order or alphabetical
file_idx: int = i
file_idx: int = int(i)
if topo_count > 0:
od_addr: uint64 = uint64(topo_order) + i * 4
od_ptr: t.CPtr = (int*)(t.CPtr(od_addr))
od_ptr: int* = (int*)(t.CPtr(od_addr))
if od_ptr is not None: file_idx = od_ptr[0]
entry_addr_r: uint64 = uint64(result.Entries) + file_idx * entry_size
@@ -451,7 +451,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
continue
# Per-file timer start (read + parse, to locate 1a stalls)
t_fa0: uint64 = w32.win32base.GetTickCount64()
t_fa0: uint64 = win32.win32base.GetTickCount64()
# Read file contents
file_path_r: str = entry_r.Path
@@ -496,7 +496,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
continue
# Timer 1: read + parse done
t_fa1: uint64 = w32.win32base.GetTickCount64()
t_fa1: uint64 = win32.win32base.GetTickCount64()
# Create Translator with _declare_only=1 (register struct/enum/union)
tr_r: HandlesTranslator.Translator* = HandlesTranslator.Translator()
@@ -515,7 +515,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
GenApi.reset_visible_structs(mb, 0)
ret_r: int = tr_r.translate(tree_r)
# Timer 2: translate(declare=1) returned
t_fa2: uint64 = w32.win32base.GetTickCount64()
t_fa2: uint64 = win32.win32base.GetTickCount64()
if ret_r != 0: p1a_fl += 1
else: p1a_reg += 1
@@ -540,7 +540,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
mb.reset_to(p1a_mark)
# 1a total time (struct/enum/union registration, incl. per-file read+parse+declaration)
t_a1: uint64 = w32.win32base.GetTickCount64()
t_a1: uint64 = win32.win32base.GetTickCount64()
VLogger.info(f"1a total time: {t_a1-t_a0} ms (registering struct/enum, reg={p1a_reg} skp={p1a_skp})", "Phase1")
if p1a_fl > 0:
@@ -567,8 +567,8 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
p1bpre_failed: int = 0
dir_len_pv: sizet = string.strlen(temp_dir)
# 1b-pre total-time start (vpi pre-generation)
t_pv0: uint64 = w32.win32base.GetTickCount64()
for i_pv in range(result.Count):
t_pv0: uint64 = win32.win32base.GetTickCount64()
for i_pv in range(int(result.Count)):
entry_addr_pv: uint64 = uint64(result.Entries) + i_pv * entry_size
entry_pv: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr_pv)
if entry_pv is None or entry_pv.Sha1 is None:
@@ -663,7 +663,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
mb.reset_to(mark1)
# 1b-pre total time (vpi pre-generation)
t_pv1: uint64 = w32.win32base.GetTickCount64()
t_pv1: uint64 = win32.win32base.GetTickCount64()
VLogger.info(f"1b-pre total time: {t_pv1-t_pv0} ms (vpi pre-generation)", "Phase1")
if p1bpre_failed > 0:
@@ -676,16 +676,16 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
skipped: int = 0
failed: int = 0
# 1b total-time start (full translation)
t_b0: uint64 = w32.win32base.GetTickCount64()
t_b0: uint64 = win32.win32base.GetTickCount64()
loop_n_b: int = result.Count
loop_n_b: int = int(result.Count)
if topo_count > 0: loop_n_b = topo_count
for i in range(loop_n_b):
for i in range(int(loop_n_b)):
# Get the entry (topo: file_idx from topo_order, else the scan index)
file_idx_b: int = i
file_idx_b: int = int(i)
if topo_count > 0:
od_addr_b: uint64 = uint64(topo_order) + sizet(i) * 4
od_ptr_b: t.CPtr = (int*)(od_addr_b)
od_ptr_b: int* = (int*)(od_addr_b)
if od_ptr_b is not None: file_idx_b = od_ptr_b[0]
entry_addr: uint64 = uint64(result.Entries) + sizet(file_idx_b) * entry_size
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr)
@@ -793,7 +793,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
stdlib.free(stub_path)
# Per-file timer start: read (parse/translate/dump segments, matching Phase2 instrumentation)
t_f0: uint64 = w32.win32base.GetTickCount64()
t_f0: uint64 = win32.win32base.GetTickCount64()
# Read file contents
file_path: str = entry.Path
@@ -847,7 +847,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
continue
# Timer 1: read + lexer/tokenize/parse done
t_f1: uint64 = w32.win32base.GetTickCount64()
t_f1: uint64 = win32.win32base.GetTickCount64()
# Register CTypedef by scanning source text: AST string fields (attr/id) point into src_buf
# and dangle across phases (reading attr faults), so match "NAME: t.CTypedef = TYPE" lines.
@@ -901,7 +901,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
ret: int = tr.translate(tree)
# Timer 2: translate returned
t_f2: uint64 = w32.win32base.GetTickCount64()
t_f2: uint64 = win32.win32base.GetTickCount64()
# Diagnostic: translate returned normally (if it hangs inside, this line is not printed,
# distinguishing an internal hang from a later dump hang).
if ret == 0: VLogger.info(f"translation complete (translate returned): {file_path}", "Phase1")
@@ -996,7 +996,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
stdlib.free(vpcall_text_p1)
# Timer 3: dump (stub+text) done; print the per-file three-segment timing
t_f3: uint64 = w32.win32base.GetTickCount64()
t_f3: uint64 = win32.win32base.GetTickCount64()
VLogger.info(f"[{i+1}/{loop_n_b}] translating: {file_path} (parse={t_f1-t_f0} ms, translate={t_f2-t_f1} ms, dump={t_f3-t_f2} ms, total={t_f3-t_f0} ms)", "Phase1")
# save dependencies(_imported_modules) for Phase B
@@ -1023,14 +1023,14 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: VLogg
# tables moved to stdlib). Memory sentinels locate overruns deterministically.
chk_rc: int = mb.check_alive_blocks(mark1)
if chk_rc != 0: VLogger.error(f"memory corruption (live block header, rc={chk_rc}): {file_path}", "Phase1")
# Out-of-bounds writes are the crash root cause (unrelated to reclamation/UAF, confirmed
# Out-of-bounds writes are the crash root cause (unrelated to reclamation/UAF, confirmed
# by A/B tests); reset_to plus the tail canary pins the offending file.
mb.reset_to(mark1)
sc_rc: int = mb.self_check()
if sc_rc != 0: VLogger.error(f"memory corruption (free list, rc={sc_rc}): {file_path}", "Phase1")
# 1b total time (full translation + dump)
t_b1: uint64 = w32.win32base.GetTickCount64()
t_b1: uint64 = win32.win32base.GetTickCount64()
VLogger.info(f"1b total time: {t_b1-t_b0} ms (full translation, trans={translated} skip={skipped} fail={failed})", "Phase1")
# Release the topo-sort resources used by Phase 1b
+19 -19
View File
@@ -5,9 +5,9 @@ import stdlib
import memhub
import viperlib
import sys
import w32.fileio as fileio
import w32.win32file
import w32.win32base
import win32.fileio as fileio
import win32.win32file
import win32.win32base
import ast
import mlirlite
import lib.core.VLogger as VLogger
@@ -50,7 +50,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResu
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
class_count: int = 0
for i in range(result.Count):
for i in range(int(result.Count)):
# Per-file mark: reclaim this file's AST right after collecting inheritance
# info (keeping all ASTs alive until mark1 would OOM the 1GB main pool).
scan_mark: sizet = mb.mark()
@@ -106,7 +106,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResu
ch: list[ast.AST*]* = tree.children
if ch is not None:
cn: sizet = len(ch)
for ci in range(cn):
for ci in range(int(cn)):
child: ast.AST* = ch.get(ci)
if child is None: continue
kd: int = child.kind()
@@ -121,12 +121,12 @@ def _ScanClassInheritance(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResu
if tp_scan is not None:
file_has_generic = 1
if generic_file_count_box is not None:
gfc_ptr_scan: t.CPtr = (int*)(generic_file_count_box)
gfc_ptr_scan: int* = (int*)(generic_file_count_box)
if gfc_ptr_scan is not None:
gfc_scan: int = gfc_ptr_scan[0]
if gfc_scan < Phase1.MAX_FILE_DEPS and generic_file_indices is not None:
gi_addr_scan: uint64 = uint64(generic_file_indices) + gfc_scan * 4
gi_ptr_scan: t.CPtr = (int*)(gi_addr_scan)
gi_ptr_scan: int* = (int*)(gi_addr_scan)
if gi_ptr_scan is not None: gi_ptr_scan[0] = i
gfc_ptr_scan[0] = gfc_scan + 1
@@ -226,7 +226,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: IncludesScanne
if perm is None: return 0
p1e_size: sizet = IncludesScanner.FileEntry.__sizeof__()
handled_count: int = 0
for i in range(result.Count):
for i in range(int(result.Count)):
entry_addr_pg: uint64 = uint64(result.Entries) + i * p1e_size
entry_pg: IncludesScanner.FileEntry* = (IncludesScanner.FileEntry*)(entry_addr_pg)
if entry_pg is None or entry_pg.Sha1 is None: continue
@@ -269,7 +269,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: IncludesScanne
ch_pg: list[ast.AST*]* = tree_pg.children
if ch_pg is not None:
cn_pg: sizet = len(ch_pg)
for ci_pg in range(cn_pg):
for ci_pg in range(int(cn_pg)):
child_pg: ast.AST* = ch_pg.get(ci_pg)
if child_pg is None: continue
ck_pg: int = child_pg.kind()
@@ -298,7 +298,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: IncludesScanne
def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes, class_count: int, class_name: str) -> str:
"""Find a class name's defining file SHA1 in the flat arrays."""
if class_names_buf is None or def_sha1s_buf is None or class_name is None: return None
for i in range(class_count):
for i in range(int(class_count)):
name_ptr: str = class_names_buf + i * Phase1.CLASS_NAME_LEN
if string.strcmp(name_ptr, class_name) == 0: return def_sha1s_buf + i * Phase1.SHA1_LEN
return None
@@ -349,12 +349,12 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if cl_args_s is not None:
na_s: sizet = len(cl_args_s)
i_a2: sizet
for i_a2 in range(na_s): _ScanTreeForContainers(cl_args_s.get(i_a2), need_list_box, need_dict_box, depth + 1)
for i_a2 in range(int(na_s)): _ScanTreeForContainers(cl_args_s.get(i_a2), need_list_box, need_dict_box, depth + 1)
cl_kws_s: list[ast.AST*]* = cl_s2.keywords
if cl_kws_s is not None:
nk_s: sizet = len(cl_kws_s)
i_k2: sizet
for i_k2 in range(nk_s):
for i_k2 in range(int(nk_s)):
kw_s: ast.Keyword* = ast.Keyword*(cl_kws_s.get(i_k2))
if kw_s is not None: _ScanTreeForContainers(kw_s.value, need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Assign:
@@ -364,7 +364,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if tgts_s is not None:
nt_s: sizet = len(tgts_s)
i_t2: sizet
for i_t2 in range(nt_s): _ScanTreeForContainers(tgts_s.get(i_t2), need_list_box, need_dict_box, depth + 1)
for i_t2 in range(int(nt_s)): _ScanTreeForContainers(tgts_s.get(i_t2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.AnnAssign:
aa_s2: ast.AnnAssign* = ast.AnnAssign*(node)
_ScanTreeForContainers(aa_s2.annotation, need_list_box, need_dict_box, depth + 1)
@@ -378,7 +378,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if fa_s is not None:
nf_s: sizet = len(fa_s)
i_f2: sizet
for i_f2 in range(nf_s):
for i_f2 in range(int(nf_s)):
arg_s: ast.Arg* = ast.Arg*(fa_s.get(i_f2))
if arg_s is not None: _ScanTreeForContainers(arg_s.annotation, need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.ClassDef:
@@ -387,7 +387,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if bases_s is not None:
nb_s: sizet = len(bases_s)
i_b2: sizet
for i_b2 in range(nb_s): _ScanTreeForContainers(bases_s.get(i_b2), need_list_box, need_dict_box, depth + 1)
for i_b2 in range(int(nb_s)): _ScanTreeForContainers(bases_s.get(i_b2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Attribute:
at_s: ast.Attribute* = ast.Attribute*(node)
_ScanTreeForContainers(at_s.value, need_list_box, need_dict_box, depth + 1)
@@ -397,7 +397,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if elts_s is not None:
ne_s: sizet = len(elts_s)
i_e2: sizet
for i_e2 in range(ne_s): _ScanTreeForContainers(elts_s.get(i_e2), need_list_box, need_dict_box, depth + 1)
for i_e2 in range(int(ne_s)): _ScanTreeForContainers(elts_s.get(i_e2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.UnaryOp:
uop_s: ast.UnaryOp* = ast.UnaryOp*(node)
_ScanTreeForContainers(uop_s.operand, need_list_box, need_dict_box, depth + 1)
@@ -414,18 +414,18 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
if cps_s is not None:
nc_s: sizet = len(cps_s)
i_c2: sizet
for i_c2 in range(nc_s): _ScanTreeForContainers(cps_s.get(i_c2), need_list_box, need_dict_box, depth + 1)
for i_c2 in range(int(nc_s)): _ScanTreeForContainers(cps_s.get(i_c2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.BoolOp:
bo_s: ast.BoolOp* = ast.BoolOp*(node)
bvs_s: list[ast.AST*]* = bo_s.values
if bvs_s is not None:
nv_s: sizet = len(bvs_s)
i_v2: sizet
for i_v2 in range(nv_s): _ScanTreeForContainers(bvs_s.get(i_v2), need_list_box, need_dict_box, depth + 1)
for i_v2 in range(int(nv_s)): _ScanTreeForContainers(bvs_s.get(i_v2), need_list_box, need_dict_box, depth + 1)
# `[...]`/`{}` literals do not trigger _list/_dict imports (compile-time constant lists, array init);
# recurse into statement-block children.
if node.children is not None:
ch_s: list[ast.AST*]* = node.children
n_s: sizet = len(ch_s)
ci_s: sizet
for ci_s in range(n_s): _ScanTreeForContainers(ch_s.get(ci_s), need_list_box, need_dict_box, depth + 1)
for ci_s in range(int(n_s)): _ScanTreeForContainers(ch_s.get(ci_s), need_list_box, need_dict_box, depth + 1)
+40 -40
View File
@@ -4,9 +4,9 @@ import string
import stdlib
import memhub
import viperlib
import w32.fileio as fileio
import w32.win32file
import w32.win32base
import win32.fileio as fileio
import win32.win32file
import win32.win32base
import ast
import mlirlite
import lib.core.VLogger as VLogger
@@ -62,7 +62,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
file_count: int = 0
# sha1 -> file_index map (simple linear search; file count is small)
for i in range(result.Count):
for i in range(int(result.Count)):
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr)
if entry is None or entry.Sha1 is None: continue
@@ -83,7 +83,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
file_count += 1
# 2. Build dependency edges: for each class, find the parent's defining file and add a child->parent edge
for ci in range(class_count):
for ci in range(int(class_count)):
# Read parent class name (offset = ci * Phase1.CLASS_NAME_LEN)
parent_ptr: str = parent_names_buf + ci * Phase1.CLASS_NAME_LEN
if parent_ptr[0] == '\0': continue
@@ -100,19 +100,19 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
if string.strcmp(parent_sha1, child_def_sha1) == 0: continue
# Find the child file's index and add the parent file SHA1 to its dependency list
for fi in range(file_count):
for fi in range(int(file_count)):
fsha1: str = file_sha1s_buf + fi * Phase1.SHA1_LEN
if string.strcmp(fsha1, child_def_sha1) != 0: continue
# Read the current dependency count
cnt_addr: uint64 = uint64(file_dep_counts) + fi * 4
cnt_ptr: t.CPtr = (int*)(cnt_addr)
cnt_ptr: int* = (int*)(cnt_addr)
if cnt_ptr is None: break
cur_cnt: int = cnt_ptr[0]
# Check whether the dependency is already present (dedupe)
already: int = 0
for di in range(cur_cnt):
for di in range(int(cur_cnt)):
dep_slot: str = file_deps_buf + fi * Phase1.MAX_DEP_EDGES * Phase1.SHA1_LEN + di * Phase1.SHA1_LEN
if string.strcmp(dep_slot, parent_sha1) == 0:
already = 1
@@ -132,7 +132,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
map_count_ts: int = 0
if sha1_arr_ts is not None and mod_arr_ts is not None:
map_count_ts = StubMergerIR._BuildIncludesSha1Map(temp_dir, td_len_ts, sha1_arr_ts, mod_arr_ts)
for fi_imp in range(file_count):
for fi_imp in range(int(file_count)):
if map_count_ts <= 0: break
fsha1_imp: str = file_sha1s_buf + fi_imp * Phase1.SHA1_LEN
deps_imp: str = StubMergerStore.LookupIncludesDeps(fsha1_imp)
@@ -153,16 +153,16 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
stdlib.free(dname_imp)
if dsha1_imp is None: continue
# Find the dependency file's index in the list (skip self)
for fj_imp in range(file_count):
for fj_imp in range(int(file_count)):
if string.strcmp(file_sha1s_buf + fj_imp * Phase1.SHA1_LEN, dsha1_imp) != 0: continue
if fj_imp == fi_imp: break
# Dedupe and add the edge: fi_imp depends on fj_imp (InDegree[fi_imp]++)
cnt_addr_imp: uint64 = uint64(file_dep_counts) + fi_imp * 4
cnt_ptr_imp: t.CPtr = (int*)(cnt_addr_imp)
cnt_ptr_imp: int* = (int*)(cnt_addr_imp)
if cnt_ptr_imp is None: break
cur_cnt_imp: int = cnt_ptr_imp[0]
already_imp: int = 0
for di_imp in range(cur_cnt_imp):
for di_imp in range(int(cur_cnt_imp)):
dep_slot_imp: str = file_deps_buf + fi_imp * Phase1.MAX_DEP_EDGES * Phase1.SHA1_LEN + di_imp * Phase1.SHA1_LEN
if string.strcmp(dep_slot_imp, dsha1_imp) == 0:
already_imp = 1
@@ -179,11 +179,11 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
# 3. Kahn: InDegree = DepCount (number of parent files depended on).
# Process zero-dependency files first, then decrement the in-degree of dependents.
for fi in range(file_count):
for fi in range(int(file_count)):
cnt_addr3: uint64 = uint64(file_dep_counts) + fi * 4
cnt_ptr3: t.CPtr = (int*)(cnt_addr3)
cnt_ptr3: int* = (int*)(cnt_addr3)
ind_addr3: uint64 = uint64(file_indegrees) + fi * 4
ind_ptr3: t.CPtr = (int*)(ind_addr3)
ind_ptr3: int* = (int*)(ind_addr3)
if cnt_ptr3 is not None and ind_ptr3 is not None: ind_ptr3[0] = cnt_ptr3[0]
# 4. Topological sort output
@@ -191,27 +191,27 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
changed: int = 1
while changed != 0:
changed = 0
for fi in range(file_count):
for fi in range(int(file_count)):
# Check processed flag
proc_addr4: uint64 = uint64(file_processed) + fi * 4
proc_ptr4: t.CPtr = (int*)(proc_addr4)
proc_ptr4: int* = (int*)(proc_addr4)
if proc_ptr4 is None or proc_ptr4[0] != 0: continue
# Check in-degree
ind_addr4: uint64 = uint64(file_indegrees) + fi * 4
ind_ptr4: t.CPtr = (int*)(ind_addr4)
ind_ptr4: int* = (int*)(ind_addr4)
if ind_ptr4 is None or ind_ptr4[0] > 0: continue
# In-degree 0: can be processed
# Find the matching result.Entries index
target_sha1: str = file_sha1s_buf + fi * Phase1.SHA1_LEN
for ri in range(result.Count):
for ri in range(int(result.Count)):
ea_r: uint64 = uint64(result.Entries) + ri * entry_size
ent_r: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(ea_r)
if ent_r is not None and ent_r.Sha1 is not None:
if string.strcmp(ent_r.Sha1, target_sha1) == 0:
# Write into the output index array
out_idx_addr: uint64 = uint64(out_order) + out_idx * 4
out_int_ptr: t.CPtr = (int*)(out_idx_addr)
out_int_ptr: int* = (int*)(out_idx_addr)
if out_int_ptr is not None: out_int_ptr[0] = ri
out_idx += 1
break
@@ -221,56 +221,56 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
changed = 1
# Decrement the in-degree of files that depend on this one
for fj in range(file_count):
for fj in range(int(file_count)):
proc_addr5: uint64 = uint64(file_processed) + fj * 4
proc_ptr5: t.CPtr = (int*)(proc_addr5)
proc_ptr5: int* = (int*)(proc_addr5)
if proc_ptr5 is None or proc_ptr5[0] != 0: continue
# Read fj's dependency count
cnt_addr5: uint64 = uint64(file_dep_counts) + fj * 4
cnt_ptr5: t.CPtr = (int*)(cnt_addr5)
cnt_ptr5: int* = (int*)(cnt_addr5)
if cnt_ptr5 is None: continue
fj_dep_cnt: int = cnt_ptr5[0]
for di in range(fj_dep_cnt):
for di in range(int(fj_dep_cnt)):
dep_slot5: str = file_deps_buf + fj * Phase1.MAX_DEP_EDGES * Phase1.SHA1_LEN + di * Phase1.SHA1_LEN
if string.strcmp(dep_slot5, target_sha1) == 0:
ind_addr5: uint64 = uint64(file_indegrees) + fj * 4
ind_ptr5: t.CPtr = (int*)(ind_addr5)
ind_ptr5: int* = (int*)(ind_addr5)
if ind_ptr5 is not None: ind_ptr5[0] = ind_ptr5[0] - 1
break
# Handle cycles: within a cycle emit the more-depended-upon files first.
# On-demand container injection (e.g. string -> _list) plus real imports form pseudo-cycles Kahn cannot fully drain; scan order would translate dependents first -> unregistered cross-module vtable TypeStr.
if out_idx < file_count:
rem_idx: t.CPtr = stdlib.malloc(4 * file_count)
rem_depcnt: t.CPtr = stdlib.malloc(4 * file_count)
rem_idx: int* = (int*)(stdlib.malloc(4 * file_count))
rem_depcnt: int* = (int*)(stdlib.malloc(4 * file_count))
rem_count: int = 0
if rem_idx is not None and rem_depcnt is not None:
for fi in range(file_count):
for fi in range(int(file_count)):
proc_addr7: uint64 = uint64(file_processed) + fi * 4
proc_ptr7: t.CPtr = (int*)(proc_addr7)
proc_ptr7: int* = (int*)(proc_addr7)
if proc_ptr7 is not None and proc_ptr7[0] == 0:
rem_idx[rem_count] = fi
rem_depcnt[rem_count] = 0
rem_count += 1
# Compute each remaining file's dependents count (among the remaining files)
for i_a in range(rem_count):
for i_a in range(int(rem_count)):
fi_a: int = rem_idx[i_a]
target_sha1_a: str = file_sha1s_buf + fi_a * Phase1.SHA1_LEN
for i_b in range(rem_count):
for i_b in range(int(rem_count)):
fi_b: int = rem_idx[i_b]
if fi_b == fi_a: continue
cnt_addr_b: uint64 = uint64(file_dep_counts) + fi_b * 4
cnt_ptr_b: t.CPtr = (int*)(cnt_addr_b)
cnt_ptr_b: int* = (int*)(cnt_addr_b)
if cnt_ptr_b is None: continue
cnt_b: int = cnt_ptr_b[0]
for di_b in range(cnt_b):
for di_b in range(int(cnt_b)):
dep_slot_b: str = file_deps_buf + fi_b * Phase1.MAX_DEP_EDGES * Phase1.SHA1_LEN + di_b * Phase1.SHA1_LEN
if string.strcmp(dep_slot_b, target_sha1_a) == 0:
rem_depcnt[i_a] = rem_depcnt[i_a] + 1
break
# Bubble sort descending (more dependents first)
for i_a in range(rem_count):
for j_a in range(rem_count - 1):
for i_a in range(int(rem_count)):
for j_a in range(int(rem_count - 1)):
if rem_depcnt[j_a] < rem_depcnt[j_a + 1]:
tmp_i: int = rem_idx[j_a]
rem_idx[j_a] = rem_idx[j_a + 1]
@@ -279,19 +279,19 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
rem_depcnt[j_a] = rem_depcnt[j_a + 1]
rem_depcnt[j_a + 1] = tmp_d
# Emit the remaining files in order
for i_a in range(rem_count):
for i_a in range(int(rem_count)):
fi_a2: int = rem_idx[i_a]
proc_addr8: uint64 = uint64(file_processed) + fi_a2 * 4
proc_ptr8: t.CPtr = (int*)(proc_addr8)
proc_ptr8: int* = (int*)(proc_addr8)
if proc_ptr8 is None or proc_ptr8[0] != 0: continue
target_sha1_2: str = file_sha1s_buf + fi_a2 * Phase1.SHA1_LEN
for ri in range(result.Count):
for ri in range(int(result.Count)):
ea_r2: uint64 = uint64(result.Entries) + ri * entry_size
ent_r2: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(ea_r2)
if ent_r2 is not None and ent_r2.Sha1 is not None:
if string.strcmp(ent_r2.Sha1, target_sha1_2) == 0:
out_idx_addr2: uint64 = uint64(out_order) + out_idx * 4
out_int_ptr2: t.CPtr = (int*)(out_idx_addr2)
out_int_ptr2: int* = (int*)(out_idx_addr2)
if out_int_ptr2 is not None: out_int_ptr2[0] = ri
out_idx += 1
break
@@ -300,7 +300,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*, re
stdlib.free(rem_depcnt)
# Write the output count
out_count_ptr: t.CPtr = (int*)(out_count)
out_count_ptr: int* = (int*)(out_count)
if out_count_ptr is not None: out_count_ptr[0] = out_idx
# Free the flat arrays
File diff suppressed because it is too large. Load diff