refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件)

This commit is contained in:
TermiNexus committed 2026-10-05 07:14:14 +08:00
1 parent 4a685d478f
commit f2ef1bb240
67 files changed
+1140 -3775

No files matched your search

+49 -121
View File
@@ -188,12 +188,7 @@ def _tb_basename_is_traceback(file_path: str) -> int:
# Args: mb 内存池;file_path 源文件路径;sha1_val 文件内容的 SHA1 前16字符(用于函数名混淆);current_package 当前文件所属包名(用于解析相对导入),None 表示顶级模块;declare_only 0=全量翻译(默认),1=仅注册 struct/enum/union(不翻译方法体);temp_dir temp 目录路径(非 None 时在翻译前生成 .vpi 存根文件)
# Returns: Translator 对象(None 失败)
# ============================================================
def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str,
sha1_val: str,
current_package: str = None,
declare_only: int = 0,
temp_dir: str = None,
pre_allow_dep_inject: int = 0) -> rawptr[HandlesTranslator.Translator]:
def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, sha1_val: str, current_package: str = None, declare_only: int = 0, temp_dir: str = None, pre_allow_dep_inject: int = 0) -> rawptr[HandlesTranslator.Translator]:
"""翻译文件,返回 Translator 对象(调用者负责 dump_ir),None 失败
current_package: 当前文件所属包名(用于解析相对导入),None 表示顶级模块
@@ -501,16 +496,13 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
p2_olen: sizet = len(p2_asan) + len(compile_input) + 192
p2_opt_cmd = _mbuddy.alloc(p2_olen)
if p2_opt_cmd is not None:
viperlib.snprintf(p2_opt_cmd, p2_olen,
"opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s",
p2_asan, compile_input)
viperlib.snprintf(p2_opt_cmd, p2_olen, "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", p2_asan, compile_input)
compile_input = p2_asan
llc_fp: str = _llc_frame_ptr_flag()
p2_clen: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp) + len(obj_path) + len(compile_input) + 64
p2_cmd: bytes = _mbuddy.alloc(p2_clen)
if p2_cmd is not None:
viperlib.snprintf(p2_cmd, p2_clen, "%s %s%s -o %s %s",
cc_cmd, cc_flags, llc_fp, obj_path, compile_input)
viperlib.snprintf(p2_cmd, p2_clen, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp, obj_path, compile_input)
if p2_opt_cmd is not None: _phase2_write_cmd(p2_opt_cmd)
if p2_cmd is not None: _phase2_write_cmd(p2_cmd)
return 0
@@ -521,9 +513,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
opt_cmd_len: sizet = len(asan_path) + len(compile_input) + 192
opt_cmd: bytes = _mbuddy.alloc(opt_cmd_len)
if opt_cmd is None: return 1
viperlib.snprintf(opt_cmd, opt_cmd_len,
"opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s",
asan_path, compile_input)
viperlib.snprintf(opt_cmd, opt_cmd_len, "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", asan_path, compile_input)
opt_ret: int = stdlib.system(opt_cmd)
if opt_ret != 0:
VLogger.error(f"opt ASan 插桩失败 (module={module_name})", "ASAN")
@@ -535,8 +525,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
cmd_len: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp2) + len(obj_path) + len(compile_input) + 64
cmd: bytes = _mbuddy.alloc(cmd_len)
if cmd is None: return 1
viperlib.snprintf(cmd, cmd_len, "%s %s%s -o %s %s",
cc_cmd, cc_flags, llc_fp2, obj_path, compile_input)
viperlib.snprintf(cmd, cmd_len, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp2, obj_path, compile_input)
# 用 CreateProcessA 直启 llc(避开 cmd/c 在 asan 下挂起),子进程继承父控制台:
# stdout|stderr 直接显示;失败时打印模块 sha1 + 退出码 + 完整命令(退出码同步返回)
@@ -586,8 +575,7 @@ class LlcTask:
FailStage: int # worker 写:失败发生在哪一步
def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str,
module_name: str, cc_cmd: str, cc_flags: str) -> int:
def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str) -> int:
"""填充 llc 任务(全部 stdlib.malloc,线程运行期不被回收),0 成功"""
if task is None or ir_path is None or output_dir is None or module_name is None: return 1
string.memset(task, 0, LlcTask.__sizeof__())
@@ -615,8 +603,7 @@ def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str,
mt_len: sizet = len(MLIR_TRANSLATE_CMD) + len(mlir_opt_out) + len(ll_local_path) + 40
task.MlirTranslateCmd = stdlib.malloc(mt_len)
if task.MlirTranslateCmd is None: return 1
viperlib.snprintf(task.MlirTranslateCmd, mt_len, "%s --mlir-to-llvmir %s -o %s",
MLIR_TRANSLATE_CMD, mlir_opt_out, ll_local_path)
viperlib.snprintf(task.MlirTranslateCmd, mt_len, "%s --mlir-to-llvmir %s -o %s", MLIR_TRANSLATE_CMD, mlir_opt_out, ll_local_path)
compile_input = ll_local_path
# ASan 模式:opt 插桩命令(worker 先跑 MLIR 降级/opt 再跑 llc,故 LlcCmd 的输入
# 必须指向 asan_path;失败即置 Result)
@@ -626,18 +613,14 @@ def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str,
opt_len: sizet = len(asan_path) + len(compile_input) + 192
task.OptCmd = stdlib.malloc(opt_len)
if task.OptCmd is None: return 1
viperlib.snprintf(task.OptCmd, opt_len,
"opt -passes=forceattrs,asan -force-attribute=sanitize_address"
" -asan-globals=false -o %s %s",
asan_path, compile_input)
viperlib.snprintf(task.OptCmd, opt_len, "opt -passes=forceattrs,asan -force-attribute=sanitize_address" " -asan-globals=false -o %s %s", asan_path, compile_input)
compile_input = asan_path
# llc 命令(输入 = compile_input:非 ASan 为 .ll,ASan 为 .asan.ll)
llc_fp3: str = _llc_frame_ptr_flag()
cmd_len: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp3) + len(obj_path) + len(compile_input) + 64
task.LlcCmd = stdlib.malloc(cmd_len)
if task.LlcCmd is None: return 1
viperlib.snprintf(task.LlcCmd, cmd_len, "%s %s%s -o %s %s",
cc_cmd, cc_flags, llc_fp3, obj_path, compile_input)
viperlib.snprintf(task.LlcCmd, cmd_len, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp3, obj_path, compile_input)
return 0
@@ -716,9 +699,7 @@ def _run_cmd_wait(cmd: str) -> int:
si.cb = win32process.STARTUPINFOA.__sizeof__()
# create_flags=0:子进程继承父控制台(输出直接显示,同 system 语义);
# si.dwFlags 保持 memset 后的 0(不置 STARTF_USESTDHANDLES、不设 std 句柄)
ok: int = win32process.CreateProcessA(
t.CPtr(0), cmd_line, t.CPtr(0), t.CPtr(0), 1, 0,
t.CPtr(0), t.CPtr(0), t.CPtr(&si), t.CPtr(&pi))
ok: int = win32process.CreateProcessA(t.CPtr(0), cmd_line, t.CPtr(0), t.CPtr(0), 1, 0, t.CPtr(0), t.CPtr(0), t.CPtr(&si), t.CPtr(&pi))
# CreateProcessA 失败诊断:GetLastError 必须在返回后立即取(此后 stdlib.free/
# CloseHandle/SetConsoleTextAttribute 等都会覆盖它)。用 warning 不用 error——
# VLogger.error 会 sys.exit(1),而本函数可能在 worker 线程里执行;warning 只走
@@ -847,8 +828,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
return ret
def _CollectObjFilesImpl(base_dir: str, bd_len: sizet,
out_buf: bytes, out_pos: sizet, out_size: sizet) -> sizet:
def _CollectObjFilesImpl(base_dir: str, bd_len: sizet, out_buf: bytes, out_pos: sizet, out_size: sizet) -> sizet:
"""递归扫描 base_dir,收集 .obj 文件路径到 out_buf,返回新的 out_pos
支持切片子目录(如 dir/43/{sha1}.obj)。
@@ -954,14 +934,12 @@ def _append_host_export_implib(linker_flags: str, implib_path: str) -> str:
if buf is None:
VLogger.warning("宿主导出:import lib 参数缓冲分配失败(片段将无法导入宿主符号)", "link")
return linker_flags
viperlib.snprintf(buf, string.strlen(linker_flags) + extra,
"%s -Wl,--out-implib=%s", linker_flags, implib_path)
viperlib.snprintf(buf, string.strlen(linker_flags) + extra, "%s -Wl,--out-implib=%s", linker_flags, implib_path)
VLogger.info(f"宿主导出:产出 import lib {implib_path}", "link")
return buf
def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_flags: str, linker_output: str,
includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
"""调用 clang++ 链接 .obj 为 .exe
Args:
@@ -1019,32 +997,22 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
merged_sl: str = _mbuddy.alloc(len(static_libs) + len(linker_dynamic_libs) + 2)
if merged_sl is not None:
if len(static_libs) > 0:
viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2,
"%s %s", static_libs, linker_dynamic_libs)
viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, "%s %s", static_libs, linker_dynamic_libs)
else:
viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2,
"%s", linker_dynamic_libs)
viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, "%s", linker_dynamic_libs)
static_libs = merged_sl
sl_len: sizet = len(static_libs)
cmd_len: sizet = len(linker_cmd) + len(obj_path) + len(use_flags) + len(output_dir) + len(linker_output) + extra_len + sl_len + 128
cmd: bytes = _mbuddy.alloc(cmd_len)
if cmd is None: return 1
if sl_len > 0 and extra_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s/%s %s",
linker_cmd, obj_path, extra_objs, static_libs,
output_dir, linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s/%s %s", linker_cmd, obj_path, extra_objs, static_libs, output_dir, linker_output, use_flags)
elif sl_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s",
linker_cmd, obj_path, static_libs,
output_dir, linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", linker_cmd, obj_path, static_libs, output_dir, linker_output, use_flags)
elif extra_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s",
linker_cmd, obj_path, extra_objs,
output_dir, linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", linker_cmd, obj_path, extra_objs, output_dir, linker_output, use_flags)
else:
viperlib.snprintf(cmd, cmd_len, "%s %s -o %s/%s %s",
linker_cmd, obj_path, output_dir, linker_output,
use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s -o %s/%s %s", linker_cmd, obj_path, output_dir, linker_output, use_flags)
# --phase2command 模式:不执行链接,命令写入 bat
if _phase2_cmd_path is not None:
@@ -1067,8 +1035,7 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
return 0
def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
triple: str) -> int:
def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, triple: str) -> int:
"""用 llvm-mc 汇编 .s 源文件为 .obj(切片路径)
裸机项目(VKernel 等)含 .s 汇编文件(如 Kernel/intr/isr.s 定义
@@ -1093,8 +1060,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
cmd_len: sizet = len("llvm-mc -triple=") + len(trip) + len(" -filetype=obj -o ") + len(obj_path) + len(asm_path) + 64
cmd: bytes = _mbuddy.alloc(cmd_len)
if cmd is None: return 1
viperlib.snprintf(cmd, cmd_len, "llvm-mc -triple=%s -filetype=obj -o %s %s",
trip, obj_path, asm_path)
viperlib.snprintf(cmd, cmd_len, "llvm-mc -triple=%s -filetype=obj -o %s %s", trip, obj_path, asm_path)
# --phase2command 模式:命令写入 bat(与 llc/链接一致)
if _phase2_cmd_path is not None:
@@ -1113,9 +1079,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
return 0
def compile_module_to_obj(ir_buf: bytes, ir_len: sizet,
temp_dir: str, output_dir: str, module_name: str,
cc_cmd: str, cc_flags: str) -> int:
def compile_module_to_obj(ir_buf: bytes, ir_len: sizet, temp_dir: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str) -> int:
"""编译 IR 到 .obj(不链接)
Args:
@@ -1149,9 +1113,7 @@ def compile_module_to_obj(ir_buf: bytes, ir_len: sizet,
return 0
def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet,
linker_cmd: str, linker_flags: str, linker_output: str,
includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
"""链接多个 .obj 文件为 .exe
Args:
@@ -1241,11 +1203,9 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet,
merged_sl2: str = _mbuddy.alloc(len(static_libs2) + len(linker_dynamic_libs) + 2)
if merged_sl2 is not None:
if len(static_libs2) > 0:
viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2,
"%s %s", static_libs2, linker_dynamic_libs)
viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, "%s %s", static_libs2, linker_dynamic_libs)
else:
viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2,
"%s", linker_dynamic_libs)
viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, "%s", linker_dynamic_libs)
static_libs2 = merged_sl2
sl2_len: sizet = len(static_libs2)
cmd_len: sizet = len(linker_cmd) + obj_paths_len + len(use_flags) + len(linker_output) + extra_len + sl2_len + 128
@@ -1253,20 +1213,13 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet,
if cmd is None: return 1
# linker.static_libs 显式静态链接文件位于 .obj 之后、-o 之前
if sl2_len > 0 and extra_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s %s",
linker_cmd, obj_paths, extra_objs, static_libs2,
linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s %s", linker_cmd, obj_paths, extra_objs, static_libs2, linker_output, use_flags)
elif sl2_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s",
linker_cmd, obj_paths, static_libs2,
linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", linker_cmd, obj_paths, static_libs2, linker_output, use_flags)
elif extra_len > 0:
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s",
linker_cmd, obj_paths, extra_objs,
linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", linker_cmd, obj_paths, extra_objs, linker_output, use_flags)
else:
viperlib.snprintf(cmd, cmd_len, "%s %s -o %s %s",
linker_cmd, obj_paths, linker_output, use_flags)
viperlib.snprintf(cmd, cmd_len, "%s %s -o %s %s", linker_cmd, obj_paths, linker_output, use_flags)
# 用 subprocess.run 捕获 clang++ 的 stdout/stderr 输出
# 之前用 stdlib.system() 无法捕获具体错误(undefined reference 等),
@@ -1616,8 +1569,7 @@ def _tb_file_rec(files: bytes, count: int, idx: int) -> int:
return -1
def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int,
dirs: bytes, dcount: int, frec: int) -> str:
def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int, dirs: bytes, dcount: int, frec: int) -> str:
"""Resolve a file-table entry to a path (absolute name wins, else dir join)."""
roff: sizet = sizet(frec) * TB_FILE_SIZE
cached: uint64 = _tb_rd_u64(files, roff + 24)
@@ -1637,8 +1589,7 @@ def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int,
return path
def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int,
rec_size: int, new_cap: int) -> bytes:
def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int, rec_size: int, new_cap: int) -> bytes:
nb: bytes = mb.alloc(sizet(new_cap) * sizet(rec_size))
if nb is None: return None
string.memcpy(nb, buf, sizet(old_cap) * sizet(rec_size))
@@ -1646,8 +1597,7 @@ def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int,
return nb
def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*,
addr: uint64, path: str, line: int, fname: str = None) -> int:
def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*, addr: uint64, path: str, line: int, fname: str = None) -> int:
if d is None: return 1
if d.RowCount >= d.RowCap:
ncap: int = d.RowCap * 2
@@ -1669,8 +1619,7 @@ def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*,
return 0
def _tb_emit_func(mb: memhub.MemBuddy*, d: TbDump*,
low: uint64, high: uint64, name: str) -> int:
def _tb_emit_func(mb: memhub.MemBuddy*, d: TbDump*, low: uint64, high: uint64, name: str) -> int:
if d is None: return 1
if d.FuncCount >= d.FuncCap:
ncap: int = d.FuncCap * 2
@@ -2097,8 +2046,7 @@ def _tb_cp_init(mb: memhub.MemBuddy*) -> TbCallParse*:
return cp
def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*,
caller: str, callee: str, file: str, line: int) -> int:
def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*, caller: str, callee: str, file: str, line: int) -> int:
if cp.CrN >= cp.CrCap:
ncap: int = cp.CrCap * 2
nb: bytes = _tb_grow_rec(mb, cp.Cr, cp.CrCap, TB_CR_SIZE, ncap)
@@ -2117,8 +2065,7 @@ def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*,
return 0
def _tb_cp_add_fr(mb: memhub.MemBuddy*, cp: TbCallParse*,
sym: str, file: str, defline: int) -> int:
def _tb_cp_add_fr(mb: memhub.MemBuddy*, cp: TbCallParse*, sym: str, file: str, defline: int) -> int:
if cp.FrN >= cp.FrCap:
ncap: int = cp.FrCap * 2
nb: bytes = _tb_grow_rec(mb, cp.Fr, cp.FrCap, TB_FR_SIZE, ncap)
@@ -2153,8 +2100,7 @@ def _tb_read_whole(mb: memhub.MemBuddy*, path: str) -> str:
return buf
def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet,
cp: TbCallParse*) -> int:
def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, cp: TbCallParse*) -> int:
"""解析 `F\t<sym>\t<defline>\t<file>`。"""
p: sizet = a
while p < b and _tb_cc(s, p) != 9: p += 1
@@ -2175,8 +2121,7 @@ def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet,
return _tb_cp_add_fr(mb, cp, sym, file, defline)
def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet,
cp: TbCallParse*) -> int:
def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, cp: TbCallParse*) -> int:
"""解析 `C\t<caller>\t<callee>\t<line>\t<file>`。"""
p: sizet = a
while p < b and _tb_cc(s, p) != 9: p += 1
@@ -2202,8 +2147,7 @@ def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet,
return _tb_cp_add_cr(mb, cp, caller, callee, file, line)
def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str,
cp: TbCallParse*) -> int:
def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str, cp: TbCallParse*) -> int:
whole: str = _tb_read_whole(mb, path)
if whole is None:
VLogger.error(f"--traceback: 读取 .vpcall 失败:{path},终止编译", "TRACEBACK")
@@ -2269,9 +2213,7 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int:
return 0
def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*,
cp: TbCallParse*, img_lo: uint64,
caller: str, callee: str, ret_va: uint64) -> int:
def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, caller: str, callee: str, ret_va: uint64) -> int:
"""按 (caller,callee) 的下一条未消费 C 记录为返回地址生成一条行记录。"""
if caller is None or callee is None or cp.Grp is None or ret_va < img_lo: return 0
slot: int = _tb_grp_get(cp.Grp, cp.GrpCap, caller, callee, 0)
@@ -2288,9 +2230,7 @@ def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*,
return _tb_emit_row(mb, d, ret_va, file, line, caller)
def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*,
cp: TbCallParse*, img_lo: uint64,
addr: uint64, sym: str) -> int:
def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, addr: uint64, sym: str) -> int:
"""为 objdump 标签 `sym` 生成函数入口兜底行(文件/定义行取自 F 记录)。"""
if sym is None or cp.Fr is None or cp.FrN <= 0 or addr < img_lo: return 0
i: int = 0
@@ -2336,8 +2276,7 @@ def _tb_run_objdump(mb: memhub.MemBuddy*, exe_path: str) -> str:
return dump
def _tb_scan_objdump(mb: memhub.MemBuddy*, dump: str, img_lo: uint64,
d: TbDump*, cp: TbCallParse*) -> int:
def _tb_scan_objdump(mb: memhub.MemBuddy*, dump: str, img_lo: uint64, d: TbDump*, cp: TbCallParse*) -> int:
"""解析 `llvm-objdump -d` 文本,匹配 C/F 记录并把我方行写入 d。"""
dlen: sizet = string.strlen(dump)
pos: sizet = 0
@@ -2499,12 +2438,9 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
continue
if kept != i:
_tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE, a - img_lo)
_tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FILE,
_tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE))
_tb_wr_u32(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_LINE,
uint64(_tb_rd_u32(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_LINE)))
_tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FUNC,
_tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FUNC))
_tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FILE, _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE))
_tb_wr_u32(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_LINE, uint64(_tb_rd_u32(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_LINE)))
_tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FUNC, _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FUNC))
else: _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE, a - img_lo)
kept += 1
i += 1
@@ -2518,8 +2454,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
sj: int = si2
while sj > 0:
if _tb_rd_u64(d.RowBuf, sizet(sj - 1) * TB_ROW_SIZE) <= _tb_rd_u64(tmp, 0): break
string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE,
d.RowBuf + sizet(sj - 1) * TB_ROW_SIZE, TB_ROW_SIZE)
string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE, d.RowBuf + sizet(sj - 1) * TB_ROW_SIZE, TB_ROW_SIZE)
sj -= 1
string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE, tmp, TB_ROW_SIZE)
si2 += 1
@@ -2568,8 +2503,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
if hi_rva > size_of_image: hi_rva = size_of_image
_tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE, lo_rva)
_tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 8, hi_rva)
_tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 16,
_tb_rd_u64(d.FuncBuf, sizet(fi) * TB_FUNC_SIZE + 16))
_tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 16, _tb_rd_u64(d.FuncBuf, sizet(fi) * TB_FUNC_SIZE + 16))
fkept += 1
fi += 1
ftmp: bytes = mb.alloc(TB_FUNC_SIZE)
@@ -2582,8 +2516,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
fk: int = fj
while fk > 0:
if _tb_rd_u64(d.FuncBuf, sizet(fk - 1) * TB_FUNC_SIZE) <= _tb_rd_u64(ftmp, 0): break
string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE,
d.FuncBuf + sizet(fk - 1) * TB_FUNC_SIZE, TB_FUNC_SIZE)
string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE, d.FuncBuf + sizet(fk - 1) * TB_FUNC_SIZE, TB_FUNC_SIZE)
fk -= 1
string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE, ftmp, TB_FUNC_SIZE)
fj += 1
@@ -2714,11 +2647,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
return 0
def run_pipeline(ir_buf: bytes, ir_len: sizet,
temp_dir: str, output_dir: str, module_name: str,
cc_cmd: str, cc_flags: str,
linker_cmd: str, linker_flags: str, linker_output: str,
includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> BuildResult*:
def run_pipeline(ir_buf: bytes, ir_len: sizet, temp_dir: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> BuildResult*:
"""执行完整编译管线
Args:
@@ -2767,8 +2696,7 @@ def run_pipeline(ir_buf: bytes, ir_len: sizet,
return result
# Step 3: clang++ 链接 .obj → .exe(附加 includes.binary 预编译 .obj 与 static_libs/dynamic_libs)
ret = link_obj_to_exe(output_dir, module_name, linker_cmd, linker_flags, linker_output,
includes_binary_dir, linker_static_libs, linker_dynamic_libs)
ret = link_obj_to_exe(output_dir, module_name, linker_cmd, linker_flags, linker_output, includes_binary_dir, linker_static_libs, linker_dynamic_libs)
if ret != 0:
result.Success = 0
result.ErrorMsg = "链接失败"
+10 -36
View File
@@ -36,8 +36,7 @@ import lib.core.Gen.DebugInfoGen as DebugInfoGen
# 注入 _list/_dict 前检查被注入模块自身的依赖是否已含当前模块,命中(如 memhub↔_list)则跳过注入——
# 否则 Phase A 多遍收敛死锁("无法完成翻译");去掉环边后 _list 仍因当前模块被其依赖而处于闭包,list 类仍由 Phase1b 注册。
# ============================================================
def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry],
mod_name: str) -> int:
def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry], mod_name: str) -> int:
"""注入 mod_name 到当前模块前检查是否成环,返回 1=成环需跳过注入"""
if entry is None or entry.RelPath is None or mod_name is None: return 0
inj_sha1: str = StubMergerStore.LookupSha1ByModName(mod_name)
@@ -202,8 +201,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
# Args: mb 内存池;includes_dir includes 根目录(仅用于失败诊断,路径以 store 为准)
# Returns: ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None
# ============================================================
def _BuildReachableResult(mb: memhub.MemBuddy*,
includes_dir: str) -> rawptr[IncludesScanner.ScanResult]:
def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[IncludesScanner.ScanResult]:
"""从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表"""
if mb is None: return None
store_count: sizet = sizet(StubMerger._sha1_store_count)
@@ -277,8 +275,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy*,
# Args: mb 内存池;includes_dir includes 目录路径;temp_dir 临时目录(保存 stub);log 日志器
# Returns: 0 成功,非 0 失败
# ============================================================
def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
log: rawptr[VLogger.Logger]) -> int:
def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawptr[VLogger.Logger]) -> int:
"""Phase1: 扫描 includes 目录,按需翻译并生成 stub"""
if includes_dir is None or temp_dir is None:
VLogger.error("includes_dir 或 temp_dir 为空,无法运行 Phase1", "Phase1")
@@ -310,8 +307,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
reachable_set = stdlib.malloc(StubMerger.MAX_INCLUDES_SHA1 * 17)
if reachable_set is not None:
string.memset(reachable_set, 0, StubMerger.MAX_INCLUDES_SHA1 * 17)
reachable_count = StubMergerBuild._BuildReachableSha1Set(
mb, Config.SourceDir, temp_dir, reachable_set, None, includes_dir)
reachable_count = StubMergerBuild._BuildReachableSha1Set(mb, Config.SourceDir, temp_dir, reachable_set, None, includes_dir)
if reachable_count < 0:
VLogger.error("可达集合构建失败(依赖图扫描失败),终止编译", "Phase1")
return 1
@@ -387,14 +383,8 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
p1_base_addr: uint64 = uint64(mb.base)
p1_usable_addr: uint64 = uint64(mb.usable)
p1_chkbase_addr: uint64 = uint64(mb.chk_base)
VLogger.info(
f"[取证] mb={p1_mb_addr} base={p1_base_addr} usable={p1_usable_addr} "
f"usable_size={mb.usable_size} max_order={mb.max_order} self_check={p1_sc} "
f"detection={mb.detection}", "Phase1")
VLogger.info(
f"[取证] chk_base={p1_chkbase_addr} chk_depth={mb.chk_depth} "
f"chk_cap={mb.chk_cap} free_lists[clamp={p1_mo}]={p1_fl_head}",
"Phase1")
VLogger.info(f"[取证] mb={p1_mb_addr} base={p1_base_addr} usable={p1_usable_addr} " f"usable_size={mb.usable_size} max_order={mb.max_order} self_check={p1_sc} " f"detection={mb.detection}", "Phase1")
VLogger.info(f"[取证] chk_base={p1_chkbase_addr} chk_depth={mb.chk_depth} " f"chk_cap={mb.chk_cap} free_lists[clamp={p1_mo}]={p1_fl_head}", "Phase1")
p1_sz_cn: sizet = sizet(Phase1.MAX_CLASSES * Phase1.CLASS_NAME_LEN)
p1_sz_ds: sizet = sizet(Phase1.MAX_CLASSES * Phase1.SHA1_LEN)
p1_sz_tp: sizet = sizet(4 * Phase1.MAX_FILE_DEPS)
@@ -405,13 +395,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
p1_o_bx: 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"[取证] 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 只说明该阶空、仍可由更高阶拆分;若 alloc 失败而 dump_stats 的 free>0 才是元数据损坏铁证,"
f"任一 order>max_order={mb.max_order} 则是 size 异常)",
"Phase1")
VLogger.info(f"[取证] 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 只说明该阶空、仍可由更高阶拆分;若 alloc 失败而 dump_stats 的 free>0 才是元数据损坏铁证," f"任一 order>max_order={mb.max_order} 则是 size 异常)", "Phase1")
# 预扫描类继承关系,构建拓扑顺序(用扁平字节数组,避免结构体 str 指针 NULL 崩溃)
class_names_buf: bytes = mb.alloc(Phase1.MAX_CLASSES * Phase1.CLASS_NAME_LEN)
@@ -440,20 +424,11 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
if generic_file_indices is not None: string.memset(generic_file_indices, 0, 4 * Phase1.MAX_FILE_DEPS)
if generic_file_count_box is not None: string.memset(generic_file_count_box, 0, 4)
class_count_scanned: int = Phase1Scan._ScanClassInheritance(
mb, result, reachable_set, reachable_count,
use_reachable, sha1_set, set_count,
class_names_buf, parent_names_buf, def_sha1s_buf,
generic_file_indices, generic_file_count_box)
class_count_scanned: int = Phase1Scan._ScanClassInheritance(mb, result, reachable_set, reachable_count, use_reachable, sha1_set, set_count, class_names_buf, parent_names_buf, def_sha1s_buf, generic_file_indices, generic_file_count_box)
if class_count_scanned > 0:
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)
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)
if tc_ptr is not None: topo_count = tc_ptr[0]
@@ -949,8 +924,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str,
if vpi_exists_1b == 0:
pyi_buf: bytes = stdlib.malloc(Phase1.PYI_BUF_SIZE)
if pyi_buf is not None:
pyi_pos: sizet = StubConverter._GeneratePyiFromAst(
mb, tree, entry.Path, pyi_buf, Phase1.PYI_BUF_SIZE)
pyi_pos: sizet = StubConverter._GeneratePyiFromAst(mb, tree, entry.Path, pyi_buf, Phase1.PYI_BUF_SIZE)
if pyi_pos > 0:
pf_1b: rawptr[fileio.File] = fileio.File(vpi_path_1b, fileio.MODE.W)
if not pf_1b.closed:
+9 -32
View File
@@ -53,16 +53,7 @@ import lib.core.Gen.GenApi as GenApi
# parent_names_buf 父类名扁平数组(每个 Phase1.CLASS_NAME_LEN 字节,无父类填 '\0');def_sha1s_buf 定义 SHA1 扁平数组(每个 Phase1.SHA1_LEN 字节)
# Returns: 收集到的类数量,-1 失败
# ============================================================
def _ScanClassInheritance(mb: memhub.MemBuddy*,
result: rawptr[IncludesScanner.ScanResult],
reachable_set: str, reachable_count: int,
use_reachable: int,
sha1_set: str, set_count: int,
class_names_buf: bytes,
parent_names_buf: bytes,
def_sha1s_buf: bytes,
generic_file_indices: t.CPtr,
generic_file_count_box: t.CPtr) -> int:
def _ScanClassInheritance(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, sha1_set: str, set_count: int, class_names_buf: bytes, parent_names_buf: bytes, def_sha1s_buf: bytes, generic_file_indices: t.CPtr, generic_file_count_box: t.CPtr) -> int:
"""预扫描 includes 文件,收集类继承关系"""
if result is None: return -1
# class_names_buf/parent_names_buf/def_sha1s_buf 由调用方 mb.alloc 分配(Phase1Main 预扫描前),本函数把其地址直接作为 strcpy 目的缓冲;
@@ -208,12 +199,8 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int:
# 跳过空白
while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1
# 读类名标识符
if p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'):
while p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
or(buf[p] >= 'A' and buf[p] <= 'Z')
or(buf[p] >= '0' and buf[p] <= '9')
or buf[p] == '_'):
if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'):
while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or(buf[p] >= '0' and buf[p] <= '9') or buf[p] == '_'):
p += 1
# 类名后非空白是 '[' → 泛型类
while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1
@@ -245,12 +232,8 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int:
# 跳过空白
while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1
# 读函数名标识符
if p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'):
while p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
or(buf[p] >= 'A' and buf[p] <= 'Z')
or(buf[p] >= '0' and buf[p] <= '9')
or buf[p] == '_'):
if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'):
while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or(buf[p] >= '0' and buf[p] <= '9') or buf[p] == '_'):
p += 1
# 函数名后非空白是 '[' → 泛型函数
while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1
@@ -266,8 +249,7 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int:
# _find_generic_template 遍历悬空内存 strcmp 崩溃。本函数先文本扫描(_BufHasGenericClassMarker,不 parse)筛选出含泛型类的文件,
# 仅对命中文件用**永久池(perm_pool)**解析(模板节点与表直接进 perm_pool,跨 mark 永久存活、不占主 pool);重复注册由 _register_generic_template 内部查重跳过。
# ============================================================
def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
result: rawptr[IncludesScanner.ScanResult]) -> int:
def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult]) -> int:
"""预注册全部 includes 文件的泛型类模板,返回处理到的泛型类数量"""
if result is None or mb is None: return 0
perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool
@@ -276,8 +258,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
handled_count: int = 0
for i in range(result.Count):
entry_addr_pg: uint64 = uint64(result.Entries) + i * p1e_size
entry_pg: rawptr[IncludesScanner.FileEntry] = (
rawptr[IncludesScanner.FileEntry])(entry_addr_pg)
entry_pg: rawptr[IncludesScanner.FileEntry] = (rawptr[IncludesScanner.FileEntry])(entry_addr_pg)
if entry_pg is None or entry_pg.Sha1 is None: continue
# 读取文件
file_path_pg: str = entry_pg.Path
@@ -348,8 +329,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
# Args: class_names_buf 类名扁平数组;def_sha1s_buf 定义 SHA1 扁平数组;class_count 类数量;class_name 要查找的类名
# Returns: SHA1 字符串指针(指向 def_sha1s_buf 内部偏移),None 未找到
# ============================================================
def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes,
class_count: int, class_name: str) -> str:
def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes, class_count: int, class_name: str) -> str:
"""查找类名对应的定义文件 SHA1"""
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):
@@ -385,10 +365,7 @@ def _AnnIsContainer(ann: ast.AST*) -> int:
return 0
def _ScanTreeForContainers(node: ast.AST*,
need_list_box: t.CPtr,
need_dict_box: t.CPtr,
depth: int = 0):
def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr, depth: int = 0):
"""递归扫描 AST(字段 + 语句块),检测 list/dict 容器使用"""
# 递归深度守卫:AST 损坏成自引用环(字段/children 回指祖先)时无限
# 递归直至栈耗尽(每个 includes 文件 parse 后必执行)。fail-fast 终止。
+3 -13
View File
@@ -45,15 +45,7 @@ import lib.Phase.Phase1 as Phase1
# class_count 类数量;out_order 输出拓扑顺序的文件索引数组(调用者分配,int 数组);out_count 输出文件数量
# Returns: 0 成功,-1 失败
# ============================================================
def _TopoSortFiles(mb: memhub.MemBuddy*,
result: rawptr[IncludesScanner.ScanResult],
reachable_set: str, reachable_count: int,
use_reachable: int,
sha1_set: str, set_count: int,
class_names_buf: bytes, parent_names_buf: bytes,
def_sha1s_buf: bytes, class_count: int,
out_order: t.CPtr, out_count: t.CPtr,
temp_dir: str, td_len_ts: sizet) -> int:
def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, sha1_set: str, set_count: int, class_names_buf: bytes, parent_names_buf: bytes, def_sha1s_buf: bytes, class_count: int, out_order: t.CPtr, out_count: t.CPtr, temp_dir: str, td_len_ts: sizet) -> int:
"""根据类继承关系对文件进行拓扑排序"""
if result is None or out_order is None or out_count is None: return -1
@@ -155,8 +147,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*,
mod_arr_ts: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64)
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)
map_count_ts = StubMergerIR._BuildIncludesSha1Map(temp_dir, td_len_ts, sha1_arr_ts, mod_arr_ts)
for fi_imp in range(file_count):
if map_count_ts <= 0: break
fsha1_imp: str = file_sha1s_buf + fi_imp * Phase1.SHA1_LEN
@@ -174,8 +165,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*,
if dname_imp is None: continue
string.strncpy(dname_imp, deps_imp + dstart_imp, dlen_imp)
dname_imp[dlen_imp] = '\0'
dsha1_imp: str = StubMergerIR._FindSha1ByModName(
sha1_arr_ts, mod_arr_ts, map_count_ts, dname_imp)
dsha1_imp: str = StubMergerIR._FindSha1ByModName(sha1_arr_ts, mod_arr_ts, map_count_ts, dname_imp)
stdlib.free(dname_imp)
if dsha1_imp is None: continue
# 找依赖文件在列表中的索引(跳过自身)
+20 -61
View File
@@ -50,11 +50,7 @@ class SrcFileEntry:
# Args: mb 内存池;dir_path 当前扫描目录;entries SrcFileEntry 数组;entry_size 单个条目大小(SrcFileEntry.__sizeof__());file_count 当前已收集的文件数;max_files 最大文件数
# Returns: 新的 file_count
# ============================================================
def _ScanDirForPyFiles(mb: memhub.MemBuddy*,
dir_path: str,
entries: SrcFileEntry*,
entry_size: sizet,
file_count: int, max_files: int) -> int:
def _ScanDirForPyFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry*, entry_size: sizet, file_count: int, max_files: int) -> int:
"""递归扫描目录,收集 .vp/.py 文件到 entries,返回新的 file_count"""
if dir_path is None or entries is None: return file_count
if file_count >= max_files: return file_count
@@ -143,11 +139,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy*,
# Kernel/intr/isr.s 定义 isr0/syscall_entry/_per_cpu 等符号)。
# TPV 不对 .s 翻译,直接用 llvm-mc 汇编为 .obj 参与链接。
# ============================================================
def _ScanDirForAsmFiles(mb: memhub.MemBuddy*,
dir_path: str,
entries: SrcFileEntry*,
entry_size: sizet,
file_count: int, max_files: int) -> int:
def _ScanDirForAsmFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry*, entry_size: sizet, file_count: int, max_files: int) -> int:
"""递归扫描目录,收集 .s 汇编文件到 entries,返回新的 file_count"""
if dir_path is None or entries is None: return file_count
if file_count >= max_files: return file_count
@@ -231,10 +223,7 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy*,
# 才首次注册,reset_to(mark2) 会回收表与节点 → 后续查重/特化遍历悬空内存崩溃;App 文件数量少,mark2 前预注册的 AST 驻留内存可忽略。
# 重复注册由 _register_generic_template 查重跳过。
# ============================================================
def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*,
entries: SrcFileEntry*,
file_count: int,
entry_size: sizet) -> int:
def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*, entries: SrcFileEntry*, file_count: int, entry_size: sizet) -> int:
"""mark2 前预注册 App 源文件的泛型类模板,返回处理到的泛型类数量"""
if mb is None or entries is None or file_count <= 0: return 0
handled: int = 0
@@ -429,8 +418,7 @@ def _PhaseAResolveDepSha1(mod_name: str) -> str:
return StubMergerStore.LookupSha1ByModNameSuffix(mod_name)
def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str,
depth: int, prefix: bytes) -> None:
def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str, depth: int, prefix: bytes) -> None:
"""递归打印依赖子图;[MISS]=缺 text.ll(下钻整链),[OK]=就绪(仅探测 1 层)"""
deps: bytes = None
if sha1 is not None: deps = _PhaseADiagDepsLookup(sha1)
@@ -532,8 +520,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) ->
if miss[0] != 0: stdio.printf("[PhaseA-Fail] pending reason: %s\n", miss)
stdlib.free(miss)
stdio.fflush(None)
stdio.printf("[PhaseA-Fail] dep graph ([MISS]=missing text.ll, [OK]=ready, depth<=%d):\n",
PA_GRAPH_DEPTH_MAX)
stdio.printf("[PhaseA-Fail] dep graph ([MISS]=missing text.ll, [OK]=ready, depth<=%d):\n", PA_GRAPH_DEPTH_MAX)
stdio.fflush(None)
root_prefix: bytes = stdlib.malloc(1)
if root_prefix is not None:
@@ -543,17 +530,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) ->
stdio.fflush(None)
def RunMultiFileProject(mb: memhub.MemBuddy*,
source_dir: str, temp_dir: str, output_dir: str,
cc_cmd: str, cc_flags: str,
linker_cmd: str, linker_flags: str, linker_output: str,
includes_binary_dir: str,
includes_dir: str,
do_phase1: int, do_phase2: int,
log: rawptr[VLogger.Logger],
args: rawptr[argparse.ParsedArgs],
linker_static_libs: str = None,
linker_dynamic_libs: str = None) -> int:
def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, output_dir: str, cc_cmd: str, cc_flags: str, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, includes_dir: str, do_phase1: int, do_phase2: int, log: rawptr[VLogger.Logger], args: rawptr[argparse.ParsedArgs], linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
"""多文件项目编译
Returns: 0 成功,非 0 失败
@@ -615,8 +592,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
if rs_05 is None: VLogger.error("reachable_set 分配失败,无法填充 Sha1Store", "project")
else:
string.memset(rs_05, 0, StubMerger.MAX_INCLUDES_SHA1 * 17)
rc_05: int = StubMergerBuild._BuildReachableSha1Set(
mb, source_dir, temp_dir, rs_05, None, includes_dir)
rc_05: int = StubMergerBuild._BuildReachableSha1Set(mb, source_dir, temp_dir, rs_05, None, includes_dir)
if rc_05 < 0: VLogger.error("依赖图扫描失败,无法填充 Sha1Store", "project")
elif rc_05 > 0: VLogger.info(f"Phase2 依赖图按需填充 Sha1Store: {rc_05} 个", "project")
stdlib.free(rs_05)
@@ -740,8 +716,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
continue
pyi_buf_vp2: bytes = stdlib.malloc(PYI_BUF_SIZE_P2)
if pyi_buf_vp2 is not None:
pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst(
mb, tree_vp2, ent_vp2.Path, pyi_buf_vp2, PYI_BUF_SIZE_P2)
pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst(mb, tree_vp2, ent_vp2.Path, pyi_buf_vp2, PYI_BUF_SIZE_P2)
if pyi_pos_vp2 > 0:
pyi_path_vp2: str = StubMergerCollect._sliced_path(temp_dir, td_len_vpa, ent_vp2.Sha1, "vpi")
if pyi_path_vp2 is not None:
@@ -815,11 +790,9 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
incdir_len_pre: sizet = string.strlen(incdir_pre)
full_path_pre: bytes = stdlib.malloc(incdir_len_pre + rel_len_pre + 2)
if full_path_pre is None: continue
viperlib.snprintf(full_path_pre, incdir_len_pre + rel_len_pre + 2,
"%s/%s", incdir_pre, inc_rel_pre)
viperlib.snprintf(full_path_pre, incdir_len_pre + rel_len_pre + 2, "%s/%s", incdir_pre, inc_rel_pre)
pkg_inc_pre: str = GenApi.compute_package_from_relpath(mb, inc_rel_pre)
tr_inc_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(
mb, full_path_pre, inc_sha1_pre, pkg_inc_pre, 1)
tr_inc_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, full_path_pre, inc_sha1_pre, pkg_inc_pre, 1)
stdlib.free(full_path_pre)
if tr_inc_pre is not None:
# 记录本文件依赖(供收敛失败依赖图诊断;stdlib 表跨 reset 存活)
@@ -828,8 +801,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
if inc_fail_flags is not None: inc_fail_flags[si_inc] = 0
# 依赖填充只在第一遍执行(PopulateIncludesDeps 内部有去重)
# 注意:必须在 reset_to(mark2) 之前调用——内部深拷贝到 stdlib
if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None and StubMergerStore.PopulateIncludesDeps(
inc_sha1_pre, tr_inc_pre._imported_modules) == 0:
if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None and StubMergerStore.PopulateIncludesDeps(inc_sha1_pre, tr_inc_pre._imported_modules) == 0:
deps_filled_pre = deps_filled_pre + 1
# OOM 清理:回收本 includes 文件预注册翻译的瞬时数据
# (AST/tokens/lexer/IR/Handler);struct 注册表条目 stdlib 分配不受影响
@@ -866,8 +838,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
# 使类字段注解在预注册期即与阶段 A 同上下文(否则包重导出类
# list[ast.ClassDef*] 的票名前缀会在预注册期被冻结成包前缀,与阶段 A
# 解析出的真定义前缀分裂 → 结构体布局不兼容,见 Translator 字段说明)。
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(
mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1)
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1)
if tr_pre is None: VLogger.error(f"预注册失败: {ent_pre.Path}", "PhaseA")
# OOM 清理:回收本 App 文件预注册翻译的瞬时数据
mb.reset_to(mark2)
@@ -1134,8 +1105,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
VLogger.error("llc 输入路径构造失败", "PhaseB")
sys.exit(1)
tslot: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__())
if BuildPipeline.init_llc_task(tslot, llc_ir_path, output_dir, ent.Sha1,
cc_cmd, cc_flags) != 0:
if BuildPipeline.init_llc_task(tslot, llc_ir_path, output_dir, ent.Sha1, cc_cmd, cc_flags) != 0:
VLogger.error(f"llc 任务构造失败: {ent.Path}", "PhaseB")
sys.exit(1)
# 计时点 3:llc 任务构造完成
@@ -1172,8 +1142,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
stdlib.free(obj_path_sliced)
# 并行执行全部 llc(分批 LLC_MAX_THREADS 线程)
ret_p: int = BuildPipeline.run_llc_parallel(llc_tasks, llc_task_count,
BuildPipeline.LLC_MAX_THREADS)
ret_p: int = BuildPipeline.run_llc_parallel(llc_tasks, llc_task_count, BuildPipeline.LLC_MAX_THREADS)
if ret_p != 0:
VLogger.error("llc 编译失败,终止编译", "PhaseB")
sys.exit(1)
@@ -1194,8 +1163,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
ea_as: uint64 = uint64(asm_entries) + ai_as * entry_size
ent_as: SrcFileEntry* = (SrcFileEntry*)(ea_as)
if ent_as is None or ent_as.Path is None or ent_as.Sha1 is None: continue
aret_as: int = BuildPipeline.asm_to_obj(
ent_as.Path, ent_as.Sha1, output_dir, Config.TargetTriple)
aret_as: int = BuildPipeline.asm_to_obj(ent_as.Path, ent_as.Sha1, output_dir, Config.TargetTriple)
if aret_as != 0:
VLogger.error(f"llvm-mc 汇编失败,终止编译: {ent_as.Path}", "PhaseB")
sys.exit(1)
@@ -1245,8 +1213,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
reachable_count: int = 0
if reachable_set is not None:
string.memset(reachable_set, 0, REACHABLE_SET_SIZE)
reachable_count = StubMergerBuild._BuildReachableSha1Set(
mb, source_dir, temp_dir, reachable_set, app_deps_buf, includes_dir)
reachable_count = StubMergerBuild._BuildReachableSha1Set(mb, source_dir, temp_dir, reachable_set, app_deps_buf, includes_dir)
VLogger.info(f"可达 includes SHA1: {reachable_count} 个", "PhaseB+")
# fast-fail: 可达集合构建失败(依赖未找到),永不回退,直接终止
if reachable_count < 0:
@@ -1268,8 +1235,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
store_mod_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64)
store_count_mi: int = 0
if store_sha1_arr_mi is not None and store_mod_arr_mi is not None:
store_count_mi = StubMergerIR._BuildIncludesSha1Map(
temp_dir, td_len_pb, store_sha1_arr_mi, store_mod_arr_mi)
store_count_mi = StubMergerIR._BuildIncludesSha1Map(temp_dir, td_len_pb, store_sha1_arr_mi, store_mod_arr_mi)
store_rel_arr_mi: bytes = StubMergerStore.GetSha1StoreRelArrPtr()
store_incdir_arr_mi: bytes = StubMergerStore.GetSha1StoreIncdirArrPtr()
if store_count_mi > 0:
@@ -1282,9 +1248,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
VLogger.error("拓扑排序索引分配失败,终止编译", "PhaseB+")
topo_count = 0
else:
topo_count = StubMergerTopo.BuildTopoSortedIndices(
store_count_mi, store_sha1_arr_mi, store_mod_arr_mi,
reachable_set, reachable_count, topo_idx)
topo_count = StubMergerTopo.BuildTopoSortedIndices(store_count_mi, store_sha1_arr_mi, store_mod_arr_mi, reachable_set, reachable_count, topo_idx)
for si_mi in range(topo_count):
# 当前条目(拓扑序索引,仅含可达模块)
@@ -1450,9 +1414,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
continue
# 编译为 .obj(输出到 includes_binary_dir,与存在性检查和链接收集一致)
inc_cret_mi: int = BuildPipeline.compile_module_to_obj(
inc_combined_mi, inc_combined_len_mi, temp_dir, includes_binary_dir, inc_sha1_mi,
cc_cmd, cc_flags)
inc_cret_mi: int = BuildPipeline.compile_module_to_obj(inc_combined_mi, inc_combined_len_mi, temp_dir, includes_binary_dir, inc_sha1_mi, cc_cmd, cc_flags)
stdlib.free(inc_combined_mi)
if inc_cret_mi != 0:
@@ -1594,10 +1556,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
reachable_set = None
# 按图链接:不传 includes_binary_dir(传 None),避免全量收集
lret: int = BuildPipeline.link_objs_to_exe(
final_obj_paths, obj_paths_len,
linker_cmd, linker_flags, exe_path,
None, linker_static_libs, linker_dynamic_libs)
lret: int = BuildPipeline.link_objs_to_exe(final_obj_paths, obj_paths_len, linker_cmd, linker_flags, exe_path, None, linker_static_libs, linker_dynamic_libs)
if lret == 0:
VLogger.success(f"输出: {exe_path}", "PhaseC")