This commit is contained in:
2026-07-30 13:34:26 +08:00
parent a2cc28a6ab
commit f79c8ca643
43 changed files with 1690 additions and 1016 deletions

View File

@@ -73,7 +73,9 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
sha1_set: str, set_count: int,
class_names_buf: bytes,
parent_names_buf: bytes,
def_sha1s_buf: bytes) -> int:
def_sha1s_buf: bytes,
generic_file_indices: t.CPtr,
generic_file_count_box: t.CPtr) -> int:
"""预扫描 includes 文件,收集类继承关系"""
if result is None or class_names_buf is None or parent_names_buf is None or def_sha1s_buf is None:
return -1
@@ -88,6 +90,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
continue
sha1_e: str = entry.Sha1
file_has_generic: int = 0
# 按需翻译过滤
in_set: int = 0
@@ -147,6 +150,22 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
if cd is None or cd.name is None:
continue
# 检测泛型类(有 type_params记录文件索引以供 Phase 1a 预注册
if file_has_generic == 0:
tp_scan: list[str] | t.CPtr = cd.type_params
if tp_scan is not None:
file_has_generic = 1
if generic_file_count_box is not None:
gfc_ptr_scan: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(generic_file_count_box, t.CPtr))
if gfc_ptr_scan is not None:
gfc_scan: int = gfc_ptr_scan[0]
if gfc_scan < MAX_FILE_DEPS and generic_file_indices is not None:
gi_addr_scan: t.CUInt64T = t.CUInt64T(generic_file_indices) + gfc_scan * 4
gi_ptr_scan: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(gi_addr_scan, t.CPtr))
if gi_ptr_scan is not None:
gi_ptr_scan[0] = i
gfc_ptr_scan[0] = gfc_scan + 1
if class_count >= MAX_CLASSES:
break
@@ -513,14 +532,15 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
string.strcpy(sha1_set + set_count * 17, se_ent.Sha1)
set_count += 1
# 先填充全局 SHA1 映射存储器(即使 set_count==0 也填充,确保 Phase2 能获取 includes 条目)
# 注意PopulateSha1MapStore 会先 free 旧存储器再重新分配
StubMerger.PopulateSha1MapStore(result)
# 写入 _sha1_map.txt人类可读输出程序内部不读取机器分析使用 PopulateSha1MapStore 内存存储器)
StubMerger.WriteIncludesSha1Map(mb, temp_dir, result, None, 0)
if set_count <= 0:
VLogger.warning("扫描结果无有效 SHA1跳过 Phase1项目可能无 includes 依赖)", "Phase1")
stdlib.free(sha1_set)
return 0
# 写入 _sha1_map.txt人类可读输出程序内部不读取机器分析使用 PopulateSha1MapStore 内存存储器)
StubMerger.WriteIncludesSha1Map(mb, temp_dir, result, None, 0)
# 填充全局 SHA1 映射存储器(内存中,不依赖 _sha1_map.txt 文件)
StubMerger.PopulateSha1MapStore(result)
# 构建模块 SHA1 映射(供跨模块函数调用名混淆使用)
td_len_p1map: t.CSizeT = string.strlen(temp_dir)
p1_sha1_arr: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 17)
@@ -621,6 +641,8 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
p1a_registered += 1
# 生成 .deps.txt记录依赖模块名供依赖图按需翻译使用
# 同时填充内存依赖存储器PopulateIncludesDeps供 _BuildReachableSha1Set
# 直接从内存读取,不依赖 .deps.txt 过程文件
td_len_a: t.CSizeT = string.strlen(temp_dir)
deps_path_a: str = StubMerger._sliced_path(temp_dir, td_len_a, sha1_a, "deps.txt")
if deps_path_a is not None:
@@ -631,6 +653,9 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
df_a.write(tr_a._imported_modules, dl_a)
df_a.close()
stdlib.free(deps_path_a)
# 填充内存依赖存储器(供 _BuildReachableSha1Set 使用,不读 .deps.txt
if tr_a._imported_modules is not None:
StubMerger.PopulateIncludesDeps(sha1_a, tr_a._imported_modules)
# 释放 Translator 的 C malloc 资源
if tr_a._global_names is not None:
@@ -689,6 +714,12 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
def_sha1s_buf: bytes = mb.alloc(MAX_CLASSES * SHA1_LEN)
topo_order: t.CPtr = mb.alloc(4 * MAX_FILE_DEPS)
topo_count_box: t.CPtr = mb.alloc(4)
generic_file_indices: t.CPtr = mb.alloc(4 * MAX_FILE_DEPS)
generic_file_count_box: t.CPtr = mb.alloc(4)
if generic_file_indices is not None:
string.memset(generic_file_indices, 0, 4 * MAX_FILE_DEPS)
if generic_file_count_box is not None:
string.memset(generic_file_count_box, 0, 4)
topo_count: int = 0
if class_names_buf is not None and parent_names_buf is not None and def_sha1s_buf is not None and topo_order is not None and topo_count_box is not None:
@@ -697,11 +728,16 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
string.memset(def_sha1s_buf, 0, MAX_CLASSES * SHA1_LEN)
string.memset(topo_order, 0, 4 * MAX_FILE_DEPS)
string.memset(topo_count_box, 0, 4)
if generic_file_indices is not None:
string.memset(generic_file_indices, 0, 4 * MAX_FILE_DEPS)
if generic_file_count_box is not None:
string.memset(generic_file_count_box, 0, 4)
class_count_scanned: int = _ScanClassInheritance(
mb, result, reachable_set, reachable_count,
use_reachable, sha1_set, set_count,
class_names_buf, parent_names_buf, def_sha1s_buf)
class_names_buf, parent_names_buf, def_sha1s_buf,
generic_file_indices, generic_file_count_box)
if class_count_scanned > 0:
ret_topo: int = _TopoSortFiles(
@@ -726,6 +762,87 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
VLogger.warning("类继承预扫描无结果,回退到字母序", "Phase1")
topo_count = 0
# ============================================================
# Phase 1a-pre-generic: 预注册所有泛型类模板
#
# 在 Phase 1astruct 注册)之前执行,确保所有泛型类模板
#(如 GSListNode[T]、GSList[T])已注册。这样当其他文件的
# 结构体字段使用 GSListNode[Value] 等特化类型时,模板能被找到。
# ============================================================
generic_file_count: int = 0
if generic_file_count_box is not None:
gfc_box_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(generic_file_count_box, t.CPtr))
if gfc_box_ptr is not None:
generic_file_count = gfc_box_ptr[0]
if generic_file_count > 0 and generic_file_indices is not None:
fb_gpre: t.CChar | t.CPtr = VLogger.fmt_buf()
if fb_gpre is not None:
viperlib.snprintf(fb_gpre, 1024, "预注册 %d 个泛型类模板文件", generic_file_count)
VLogger.info(fb_gpre, "Phase1")
for gi in range(generic_file_count):
gi_addr_p: t.CUInt64T = t.CUInt64T(generic_file_indices) + gi * 4
gi_ptr_p: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(gi_addr_p, t.CPtr))
if gi_ptr_p is None:
continue
file_idx_gen: int = gi_ptr_p[0]
gen_entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + file_idx_gen * entry_size
gen_entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(gen_entry_addr, t.CPtr))
if gen_entry is None or gen_entry.Sha1 is None:
continue
gen_path: str = gen_entry.Path
gen_f: fileio.File | t.CPtr = fileio.File(gen_path, fileio.MODE.R)
if gen_f.closed:
continue
gen_src: bytes = stdlib.malloc(SRC_BUF_SIZE)
if gen_src is None:
gen_f.close()
continue
gen_br: LONG = gen_f.read_all(gen_src, SRC_BUF_SIZE)
gen_f.close()
if gen_br <= 0:
stdlib.free(gen_src)
continue
if gen_br < SRC_BUF_SIZE:
gen_src[gen_br] = 0
else:
gen_src[SRC_BUF_SIZE - 1] = 0
gen_lx: ast.Lexer | t.CPtr = ast.new_lexer(mb)
if gen_lx is None:
stdlib.free(gen_src)
continue
ast._lexer_init(gen_lx, gen_src, mb)
gen_tokens: ast.Token | t.CPtr = ast.tokenize(gen_lx)
gen_tree: ast.AST | t.CPtr = ast.parse_tokens(mb, gen_tokens)
if gen_tree is None:
stdlib.free(gen_src)
continue
gen_tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
if gen_tr is None:
stdlib.free(gen_src)
continue
gen_tr.ModuleSha1 = gen_entry.Sha1
gen_tr._declare_only = 1
gen_tr.CurrentPackage = HandlesImports.compute_package_from_relpath(mb, gen_entry.RelPath)
HandlesType.set_current_file(gen_path)
HandlesType.set_current_module_sha1(gen_entry.Sha1)
HandlesType.clear_cdefine_constants()
HandlesStruct.reset_visible_structs(mb, 0)
gen_tr.translate(gen_tree)
if gen_tr._global_names is not None:
stdlib.free(gen_tr._global_names)
if gen_tr._nonlocal_names is not None:
stdlib.free(gen_tr._nonlocal_names)
stdlib.free(gen_src)
# 遍历文件:优先使用拓扑顺序,回退到字母序
iter_count: int = topo_count if topo_count > 0 else result.Count
for i in range(iter_count):
@@ -834,6 +951,10 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
mb.free(topo_order)
if topo_count_box is not None:
mb.free(topo_count_box)
if generic_file_indices is not None:
mb.free(generic_file_indices)
if generic_file_count_box is not None:
mb.free(generic_file_count_box)
# ============================================================
# Phase 1b: 全量翻译struct 已注册,走 existing 路径翻译方法体)