自举实验失败,C1 编译 Test 成功,暂未达到自举收敛点
This commit is contained in:
@@ -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 1a(struct 注册)之前执行,确保所有泛型类模板
|
||||
#(如 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 路径翻译方法体)
|
||||
|
||||
Reference in New Issue
Block a user