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

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

No files matched your search

+17 -17
View File
@@ -124,7 +124,7 @@ def WriteCallSidecar(temp_dir: str, sha1: str, text: str) -> int:
if vpath is None:
VLogger.error(f"--traceback: .vpcall 路径构造失败(sha1={sha1}),终止编译", "TRACEBACK")
return 1
vf: rawptr[fileio.File] = fileio.File(vpath, fileio.MODE.W)
vf: fileio.File* = fileio.File(vpath, fileio.MODE.W)
if vf.closed:
VLogger.error(f"--traceback: 写出 .vpcall 失败(无法打开 {vpath}),终止编译", "TRACEBACK")
stdlib.free(vpath)
@@ -146,10 +146,10 @@ def _tb_basename_is_traceback(file_path: str) -> int:
# TranslateFileGetTrans - translate one file and return a Translator (caller dumps IR).
# File -> AST -> .vpi -> LLVM IR; includes use loose scoping, user files strict (local + imports).
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) -> HandlesTranslator.Translator*:
"""Translate one file and return a Translator (caller dumps IR); None on failure."""
if file_path is None: return None
f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R)
f: fileio.File* = fileio.File(file_path, fileio.MODE.R)
if f.closed: return None
# read_all's capacity includes the terminator (reads cap-1 bytes max) and silently
# truncates longer files; reject by size first, else parsing gets confusing syntax errors.
@@ -195,13 +195,13 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, sha1_val: str, c
td_len_vpi: sizet = len(temp_dir)
pyi_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_vpi, sha1_val, "vpi")
if pyi_path is not None:
pf: rawptr[fileio.File] = fileio.File(pyi_path, fileio.MODE.W)
pf: fileio.File* = fileio.File(pyi_path, fileio.MODE.W)
if not pf.closed:
pf.write(pyi_buf, pyi_pos)
pf.close()
stdlib.free(pyi_path)
stdlib.free(pyi_buf)
tr: rawptr[HandlesTranslator.Translator] = mb.alloc(HandlesTranslator.Translator.__sizeof__())
tr: HandlesTranslator.Translator* = mb.alloc(HandlesTranslator.Translator.__sizeof__())
tr.__before_init__()
tr.__init__()
tr.ModuleSha1 = sha1_val
@@ -212,7 +212,7 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, sha1_val: str, c
tr._pre_allow_dep_inject = pre_allow_dep_inject
# P2: reuse the global gen singleton (created by App/main.vp); create it as a fallback
# when unregistered (defensive for direct-call paths).
gen: rawptr[GenGenerator.Generator] = GenGenerator._g_gen
gen: GenGenerator.Generator* = GenGenerator._g_gen
if gen is None:
gen = mb.alloc(GenGenerator.Generator.__sizeof__())
if gen is None:
@@ -344,7 +344,7 @@ def write_ir_to_file(ir_buf: bytes, ir_len: sizet, output_dir: str, module_name:
if path is None: return 1
# open the file for writing
f: rawptr[fileio.File] = fileio.File(path, fileio.MODE.W)
f: fileio.File* = fileio.File(path, fileio.MODE.W)
if f.closed: return 1
written: int64 = f.write(ir_buf, ir_len)
@@ -543,7 +543,7 @@ def _phase2_write_cmd(cmd: str) -> None:
"""--phase2command mode: append the command to the bat file without executing it."""
global _phase2_bat_init
if _phase2_cmd_path is None or cmd is None: return
f: rawptr[fileio.File] = fileio.File(_phase2_cmd_path, fileio.MODE.A)
f: fileio.File* = fileio.File(_phase2_cmd_path, fileio.MODE.A)
if f.closed:
VLogger.error("phase2command: bat 打开失败", "phase2cmd")
return
@@ -662,7 +662,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
# spawn this batch
for j in range(batch_n):
tsk: LlcTask* = (LlcTask*)(uint64(tasks) + sizet(batch_start + j) * slot_size)
th: rawptr[vthreading.Thread] = vthreading.Thread(_llc_task_worker, t.CPtr(tsk))
th: vthreading.Thread* = vthreading.Thread(_llc_task_worker, t.CPtr(tsk))
th.start()
# Read the handle right after start() (the Thread object's stack slot may be
# reused; reading self.handle at join could see a cleared/overwritten value).
@@ -844,7 +844,7 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
_phase2_write_cmd(cmd)
return 0
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
result: subprocess.CompletedProcess* = subprocess.run(cmd, True, True)
if result is None:
VLogger.error("subprocess.run 返回 None", "link")
return 1
@@ -877,7 +877,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, triple: str) -> in
_phase2_write_cmd(cmd)
return 0
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
result: subprocess.CompletedProcess* = subprocess.run(cmd, True, True)
if result is None:
VLogger.error("llvm-mc subprocess.run 返回 None", "asm")
return 1
@@ -1006,7 +1006,7 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, linker_cmd: str, link
if _phase2_cmd_path is not None:
_phase2_write_cmd(cmd)
return 0
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
result: subprocess.CompletedProcess* = subprocess.run(cmd, True, True)
if result is None:
VLogger.error("subprocess.run 返回 None", "link")
return 1
@@ -1418,7 +1418,7 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*:
"""Read (ImageBase, SizeOfImage, .text RVA) from the PE headers."""
lay: TbPeLayout* = TbPeLayout()
if lay is None: return None
f: rawptr[fileio.File] = fileio.File(exe_path, fileio.MODE.R)
f: fileio.File* = fileio.File(exe_path, fileio.MODE.R)
if f.closed: return lay
HEAD: sizet = 4096
head: bytes = mb.alloc(HEAD)
@@ -1811,7 +1811,7 @@ def _tb_cp_add_fr(mb: memhub.MemBuddy*, cp: TbCallParse*, sym: str, file: str, d
def _tb_read_whole(mb: memhub.MemBuddy*, path: str) -> str:
"""Read the whole file into a NUL-terminated string; None on failure."""
f: rawptr[fileio.File] = fileio.File(path, fileio.MODE.R)
f: fileio.File* = fileio.File(path, fileio.MODE.R)
if f.closed: return None
sz: LONGLONG = f.size()
if sz < 0:
@@ -1984,7 +1984,7 @@ def _tb_run_objdump(mb: memhub.MemBuddy*, exe_path: str) -> str:
VLogger.error("--traceback: objdump 命令缓冲分配失败,终止编译", "TRACEBACK")
return None
viperlib.snprintf(cmd, cl, "llvm-objdump -d \"%s\"", exe_path)
res: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
res: subprocess.CompletedProcess* = subprocess.run(cmd, True, True)
if res is None or res.returncode != 0:
rc: int = -1
if res is not None: rc = res.returncode
@@ -2109,7 +2109,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
VLogger.error("--traceback: dwarfdump 命令缓冲分配失败,终止编译", "TRACEBACK")
return 1
viperlib.snprintf(cmd, cmd_len, "llvm-dwarfdump --debug-line --debug-info \"%s\"", exe_path)
res: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
res: subprocess.CompletedProcess* = subprocess.run(cmd, True, True)
if res is None or res.returncode != 0:
rc: int = -1
if res is not None: rc = res.returncode
@@ -2351,7 +2351,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
VLogger.error("--traceback: 旁文件路径缓冲分配失败,终止编译", "TRACEBACK")
return 1
viperlib.snprintf(map_path, map_len, "%s.stackmap", exe_path)
mf: rawptr[fileio.File] = fileio.File(map_path, fileio.MODE.W)
mf: fileio.File* = fileio.File(map_path, fileio.MODE.W)
if mf.closed:
VLogger.error(f"--traceback: 写出旁文件失败(无法打开 {map_path}),终止编译", "TRACEBACK")
return 1
+29 -29
View File
@@ -32,7 +32,7 @@ import lib.core.Gen.DebugInfoGen as DebugInfoGen
# _InjectedCreatesCycle - cycle check before auto-injecting a container module
# (_list/_dict); a hit (e.g. memhub<->_list) skips injection to avoid a Phase A deadlock.
def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry], mod_name: str) -> int:
def _InjectedCreatesCycle(entry: IncludesScanner.FileEntry*, mod_name: str) -> int:
"""Return 1 if injecting mod_name into the current module would create a cycle"""
if entry is None or entry.RelPath is None or mod_name is None: return 0
inj_sha1: str = StubMergerStore.LookupSha1ByModName(mod_name)
@@ -120,7 +120,7 @@ def _RewriteDepsTxt(temp_dir: str, sha1: str, deps_str: str) -> None:
td_len: sizet = string.strlen(temp_dir)
dpath: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "deps.txt")
if dpath is None: return
df: rawptr[fileio.File] = fileio.File(dpath, fileio.MODE.W)
df: fileio.File* = fileio.File(dpath, fileio.MODE.W)
if not df.closed:
dl: sizet = string.strlen(deps_str)
if dl > 0: df.write(deps_str, dl)
@@ -179,12 +179,12 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
# _BuildReachableResult - rebuild the reachable FileEntry list from the Sha1Store.
# Only incdir-nonempty (includes) entries enter result; App entries would cause duplicate symbols.
def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[IncludesScanner.ScanResult]:
def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> IncludesScanner.ScanResult*:
"""Build the reachable FileEntry list from the Sha1Store (reachable includes only)"""
if mb is None: return None
store_count: sizet = sizet(StubMerger._sha1_store_count)
if store_count <= 0 or StubMerger._sha1_store_arr is None: return None
result: rawptr[IncludesScanner.ScanResult] = IncludesScanner.create_scan_result(mb)
result: IncludesScanner.ScanResult* = IncludesScanner.create_scan_result(mb)
if result is None: return None
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
i: sizet
@@ -195,7 +195,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[Inc
iidx: sizet = sizet(i) * StubMerger.MAX_INC_DIR_LEN
if StubMerger._sha1_store_incdir[iidx] == '\0': continue
eaddr: uint64 = uint64(result.Entries) + uint64(result.Count) * entry_size
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](eaddr)
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(eaddr)
if entry is None: continue
# Deep-copy SHA1 (store slot is 17 bytes)
sha1_buf: bytes = stdlib.malloc(17)
@@ -244,7 +244,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[Inc
# ============================================================
# RunPhase1 - scan the includes dir; translate and split stubs only when missing.
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: VLogger.Logger*) -> int:
"""Phase1: scan the includes directory and translate/generate stubs on demand"""
if includes_dir is None or temp_dir is None:
VLogger.error("includes_dir 或 temp_dir 为空,无法运行 Phase1", "Phase1")
@@ -296,7 +296,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# Build the reachable FileEntry list from the Sha1Store; 1a/1b-pre/1b iterate result
# (non-empty incdir = includes). use_reachable filtering is idempotent.
result: rawptr[IncludesScanner.ScanResult] = _BuildReachableResult(mb, includes_dir)
result: IncludesScanner.ScanResult* = _BuildReachableResult(mb, includes_dir)
if result is None:
VLogger.error("可达 FileEntry 列表构建失败,终止编译", "Phase1")
return 1
@@ -399,7 +399,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# ============================================================
# Phase 1a-pre-generic-all: pre-register all includes' generic templates before mark1.
full_scan_g: rawptr[IncludesScanner.ScanResult] = IncludesScanner.scan_includes(mb, includes_dir)
full_scan_g: IncludesScanner.ScanResult* = IncludesScanner.scan_includes(mb, includes_dir)
if full_scan_g is not None: Phase1Scan._PreRegisterAllGenericTemplates(mb, full_scan_g)
else: Phase1Scan._PreRegisterAllGenericTemplates(mb, result)
@@ -422,7 +422,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
if od_ptr is not None: file_idx = od_ptr[0]
entry_addr_r: uint64 = uint64(result.Entries) + file_idx * entry_size
entry_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr_r)
entry_r: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr_r)
if entry_r is None:
p1a_fl += 1
continue
@@ -448,7 +448,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# Read file contents
file_path_r: str = entry_r.Path
f_r: rawptr[fileio.File] = fileio.File(file_path_r, fileio.MODE.R)
f_r: fileio.File* = fileio.File(file_path_r, fileio.MODE.R)
if f_r.closed:
p1a_fl += 1
continue
@@ -492,7 +492,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
t_fa1: uint64 = w32.win32base.GetTickCount64()
# Create Translator with _declare_only=1 (register struct/enum/union)
tr_r: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
tr_r: HandlesTranslator.Translator* = HandlesTranslator.Translator()
if tr_r is None:
stdlib.free(src_buf_r)
p1a_fl += 1
@@ -563,7 +563,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
t_pv0: uint64 = w32.win32base.GetTickCount64()
for i_pv in range(result.Count):
entry_addr_pv: uint64 = uint64(result.Entries) + i_pv * entry_size
entry_pv: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr_pv)
entry_pv: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr_pv)
if entry_pv is None or entry_pv.Sha1 is None:
p1bpre_failed += 1
continue
@@ -578,7 +578,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
p1bpre_failed += 1
VLogger.error(f"[Phase 1b-pre] {entry_pv.Path} | vpi 路径生成失败", "Phase1")
continue
vf_pv: rawptr[fileio.File] = fileio.File(vpi_path_pv, fileio.MODE.R)
vf_pv: fileio.File* = fileio.File(vpi_path_pv, fileio.MODE.R)
if not vf_pv.closed:
vf_pv.close()
stdlib.free(vpi_path_pv)
@@ -586,7 +586,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
stdlib.free(vpi_path_pv)
# Read the file, parse the AST, generate the vpi
file_path_pv: str = entry_pv.Path
f_pv: rawptr[fileio.File] = fileio.File(file_path_pv, fileio.MODE.R)
f_pv: fileio.File* = fileio.File(file_path_pv, fileio.MODE.R)
if f_pv.closed:
p1bpre_failed += 1
VLogger.error(f"[Phase 1b-pre] {file_path_pv} | 无法打开源文件", "Phase1")
@@ -634,7 +634,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
if pyi_pos_pv > 0:
pyi_path_pv: str = StubMergerCollect._sliced_path(temp_dir, dir_len_pv, sha1_pv, "vpi")
if pyi_path_pv is not None:
pf_pv: rawptr[fileio.File] = fileio.File(pyi_path_pv, fileio.MODE.W)
pf_pv: fileio.File* = fileio.File(pyi_path_pv, fileio.MODE.W)
if not pf_pv.closed:
pf_pv.write(pyi_buf_pv, pyi_pos_pv)
pf_pv.close()
@@ -681,7 +681,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
od_ptr_b: t.CPtr = (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: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr)
if entry is None:
failed += 1
continue
@@ -714,7 +714,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
force_translate: int = 0
vpi_path_1b: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "vpi")
if vpi_path_1b is not None:
vf_1b: rawptr[fileio.File] = fileio.File(vpi_path_1b, fileio.MODE.R)
vf_1b: fileio.File* = fileio.File(vpi_path_1b, fileio.MODE.R)
if not vf_1b.closed:
vbuf_1b: bytes = stdlib.malloc(1048576)
if vbuf_1b is not None:
@@ -743,13 +743,13 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
VLogger.info(f"含 class 定义,强制翻译: {rp}(sha1={sha1})", "Phase1")
else:
# Skip already-existing stubs (on-demand translation)
sf: rawptr[fileio.File] = fileio.File(stub_path, fileio.MODE.R)
sf: fileio.File* = fileio.File(stub_path, fileio.MODE.R)
if not sf.closed:
sf.close()
# Check that text.ll exists too (vtable scan needs it)
text_path: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "text.ll")
if text_path is not None:
tf: rawptr[fileio.File] = fileio.File(text_path, fileio.MODE.R)
tf: fileio.File* = fileio.File(text_path, fileio.MODE.R)
if not tf.closed:
tf.close()
# The sidecar ({sha1}.meta) and online FULL artifact ({sha1}.full.ll) must also exist;
@@ -757,7 +757,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
meta_path_1b: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "meta")
meta_ok_1b: int = 0
if meta_path_1b is not None:
mf_chk: rawptr[fileio.File] = fileio.File(meta_path_1b, fileio.MODE.R)
mf_chk: fileio.File* = fileio.File(meta_path_1b, fileio.MODE.R)
if not mf_chk.closed:
mf_chk.close()
meta_ok_1b = 1
@@ -765,7 +765,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
full_path_1b: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "full.ll")
full_ok_1b: int = 0
if full_path_1b is not None:
ff_chk: rawptr[fileio.File] = fileio.File(full_path_1b, fileio.MODE.R)
ff_chk: fileio.File* = fileio.File(full_path_1b, fileio.MODE.R)
if not ff_chk.closed:
ff_chk.close()
full_ok_1b = 1
@@ -790,7 +790,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# Read file contents
file_path: str = entry.Path
f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R)
f: fileio.File* = fileio.File(file_path, fileio.MODE.R)
if f is None:
VLogger.error(f"无法打开(f=None): {file_path}", "Phase1")
failed += 1
@@ -850,7 +850,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# is only a fallback when the vpi is missing.
vpi_path_1b: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "vpi")
if vpi_path_1b is not None:
vf_1b: rawptr[fileio.File] = fileio.File(vpi_path_1b, fileio.MODE.R)
vf_1b: fileio.File* = fileio.File(vpi_path_1b, fileio.MODE.R)
vpi_exists_1b: int = 0
if not vf_1b.closed:
vf_1b.close()
@@ -860,7 +860,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
if pyi_buf is not None:
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)
pf_1b: fileio.File* = fileio.File(vpi_path_1b, fileio.MODE.W)
if not pf_1b.closed:
pf_1b.write(pyi_buf, pyi_pos)
pf_1b.close()
@@ -868,7 +868,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
stdlib.free(vpi_path_1b)
# Translate AST -> LLVM IR
tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
tr: HandlesTranslator.Translator* = HandlesTranslator.Translator()
if tr is None:
stdlib.free(src_buf)
failed += 1
@@ -934,7 +934,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
dir_len_p1: sizet = string.strlen(temp_dir)
stub_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "stub.ll")
if stub_path_p1 is not None:
sf_p1: rawptr[fileio.File] = fileio.File(stub_path_p1, fileio.MODE.W)
sf_p1: fileio.File* = fileio.File(stub_path_p1, fileio.MODE.W)
if not sf_p1.closed:
sf_p1.write(stub_buf, stub_len)
sf_p1.close()
@@ -955,7 +955,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# save text.ll
text_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "text.ll")
if text_path_p1 is not None:
tf_p1: rawptr[fileio.File] = fileio.File(text_path_p1, fileio.MODE.W)
tf_p1: fileio.File* = fileio.File(text_path_p1, fileio.MODE.W)
if not tf_p1.closed:
tf_p1.write(text_buf, text_len)
tf_p1.close()
@@ -973,7 +973,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
full_len_p1: sizet = string.strlen(full_buf_p1)
full_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "full.ll")
if full_path_p1 is not None:
ff_p1: rawptr[fileio.File] = fileio.File(full_path_p1, fileio.MODE.W)
ff_p1: fileio.File* = fileio.File(full_path_p1, fileio.MODE.W)
if not ff_p1.closed:
ff_p1.write(full_buf_p1, full_len_p1)
ff_p1.close()
@@ -995,7 +995,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawpt
# save dependencies(_imported_modules) for Phase B
deps_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "deps.txt")
if deps_path_p1 is not None:
df_p1: rawptr[fileio.File] = fileio.File(deps_path_p1, fileio.MODE.W)
df_p1: fileio.File* = fileio.File(deps_path_p1, fileio.MODE.W)
if not df_p1.closed:
if tr._imported_modules is not None:
dl: sizet = string.strlen(tr._imported_modules)
+11 -11
View File
@@ -40,7 +40,7 @@ import lib.core.Gen.GenApi as GenApi
# _ScanClassInheritance - pre-scan includes files, parse ASTs and collect ClassDef
# names/parent names into flat byte arrays; returns the class count (-1 on failure).
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: 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:
"""Pre-scan includes files and collect class inheritance info."""
if result is None: return -1
# The three flat buffers are mb.alloc'ed by the caller; a NULL buffer would make
@@ -55,7 +55,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.S
# info (keeping all ASTs alive until mark1 would OOM the 1GB main pool).
scan_mark: sizet = mb.mark()
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr)
if entry is None or entry.Sha1 is None: continue
sha1_e: str = entry.Sha1
@@ -69,7 +69,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.S
# read the file
file_path: str = entry.Path
f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R)
f: fileio.File* = fileio.File(file_path, fileio.MODE.R)
if f.closed: continue
# read_all's capacity includes the terminator (reads at most cap-1 bytes); longer files are truncated
@@ -219,7 +219,7 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int:
return 0
# _PreRegisterAllGenericTemplates - pre-register includes generic templates before
# mark1 so the lazy tables survive later resets; parses only marker-matched files.
def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult]) -> int:
def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: IncludesScanner.ScanResult*) -> int:
"""Pre-register generic templates from all includes files and return the count."""
if result is None or mb is None: return 0
perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool
@@ -228,11 +228,11 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: rawptr[Include
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: IncludesScanner.FileEntry* = (IncludesScanner.FileEntry*)(entry_addr_pg)
if entry_pg is None or entry_pg.Sha1 is None: continue
# read the file
file_path_pg: str = entry_pg.Path
f_pg: rawptr[fileio.File] = fileio.File(file_path_pg, fileio.MODE.R)
f_pg: fileio.File* = fileio.File(file_path_pg, fileio.MODE.R)
if f_pg.closed: continue
# read_all's capacity includes the terminator (reads at most cap-1 bytes); longer files are truncated
if f_pg.size() >= Phase1.SRC_BUF_SIZE:
@@ -355,7 +355,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
nk_s: sizet = len(cl_kws_s)
i_k2: sizet
for i_k2 in range(nk_s):
kw_s: rawptr[ast.Keyword] = rawptr[ast.Keyword](cl_kws_s.get(i_k2))
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:
asn_s: ast.Assign* = ast.Assign*(node)
@@ -402,13 +402,13 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
uop_s: ast.UnaryOp* = ast.UnaryOp*(node)
_ScanTreeForContainers(uop_s.operand, need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Expr:
ex_s: rawptr[ast.Expr] = rawptr[ast.Expr](node)
ex_s: ast.Expr* = ast.Expr*(node)
_ScanTreeForContainers(ex_s.value, need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Return:
rt_s: rawptr[ast.Return] = rawptr[ast.Return](node)
rt_s: ast.Return* = ast.Return*(node)
_ScanTreeForContainers(rt_s.value, need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Compare:
cp_s: rawptr[ast.Compare] = rawptr[ast.Compare](node)
cp_s: ast.Compare* = ast.Compare*(node)
_ScanTreeForContainers(cp_s.left, need_list_box, need_dict_box, depth + 1)
cps_s: list[ast.AST*]* = cp_s.comparators
if cps_s is not None:
@@ -416,7 +416,7 @@ def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box:
i_c2: sizet
for i_c2 in range(nc_s): _ScanTreeForContainers(cps_s.get(i_c2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.BoolOp:
bo_s: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node)
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)
+4 -4
View File
@@ -32,7 +32,7 @@ import lib.Phase.Phase1 as Phase1
# _TopoSortFiles - topologically sort files by class inheritance (Kahn).
# Builds a "file SHA1 -> dependency SHA1 set" map, computes in-degrees (parent-file first), then outputs the order; returns 0 or -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: 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:
"""Topologically sort files by class inheritance and import dependencies."""
if result is None or out_order is None or out_count is None: return -1
@@ -64,7 +64,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResu
# sha1 -> file_index map (simple linear search; file count is small)
for i in range(result.Count):
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
entry: IncludesScanner.FileEntry* = IncludesScanner.FileEntry*(entry_addr)
if entry is None or entry.Sha1 is None: continue
sha1_e: str = entry.Sha1
@@ -206,7 +206,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResu
target_sha1: str = file_sha1s_buf + fi * Phase1.SHA1_LEN
for ri in range(result.Count):
ea_r: uint64 = uint64(result.Entries) + ri * entry_size
ent_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea_r)
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
@@ -287,7 +287,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResu
target_sha1_2: str = file_sha1s_buf + fi_a2 * Phase1.SHA1_LEN
for ri in range(result.Count):
ea_r2: uint64 = uint64(result.Entries) + ri * entry_size
ent_r2: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea_r2)
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
+26 -26
View File
@@ -218,7 +218,7 @@ def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*, entries: SrcFileEntry*
ent_pa: SrcFileEntry* = (SrcFileEntry*)(ea_pa)
if ent_pa is None or ent_pa.Path is None or ent_pa.Sha1 is None: continue
# Read the file
f_pa: rawptr[fileio.File] = fileio.File(ent_pa.Path, fileio.MODE.R)
f_pa: fileio.File* = fileio.File(ent_pa.Path, fileio.MODE.R)
if f_pa.closed: continue
# read_all's capacity includes the terminator (reads at most cap-1 bytes); longer files are truncated
if f_pa.size() >= SRC_BUF_SIZE:
@@ -382,7 +382,7 @@ def _PhaseATextLLExists(temp_dir: str, td_len: sizet, sha1: str) -> int:
if temp_dir is None or td_len == 0 or sha1 is None or string.strlen(sha1) < 2: return 0
tpath: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "text.ll")
if tpath is None: return 0
tf: rawptr[fileio.File] = fileio.File(tpath, fileio.MODE.R)
tf: fileio.File* = fileio.File(tpath, fileio.MODE.R)
exists: int = 0
if not tf.closed:
tf.close()
@@ -407,7 +407,7 @@ def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str, depth: int, prefix:
# Fallback: read {temp_dir}/{prefix}/{sha1}.deps.txt (Phase1 already wrote it for includes)
dpath: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "deps.txt")
if dpath is not None:
df: rawptr[fileio.File] = fileio.File(dpath, fileio.MODE.R)
df: fileio.File* = fileio.File(dpath, fileio.MODE.R)
if not df.closed:
deps = stdlib.malloc(PA_DEPS_MAX_STR)
if deps is not None:
@@ -508,7 +508,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: VLogger.Logger*, args: argparse.ParsedArgs*, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int:
"""Compile a multi-file project; return 0 on success, non-zero on failure"""
if source_dir is None:
VLogger.error("source_dir 为空", "project")
@@ -576,7 +576,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
map_path_am: bytes = stdlib.malloc(td_len_am + 32)
if map_path_am is not None:
viperlib.snprintf(map_path_am, td_len_am + 32, "%s/_sha1_map.txt", temp_dir)
mf: rawptr[fileio.File] = fileio.File(map_path_am, fileio.MODE.A)
mf: fileio.File* = fileio.File(map_path_am, fileio.MODE.A)
line_am: bytes = stdlib.malloc(512)
# First fill the in-memory store (no file I/O), then write _sha1_map.txt
app_filled: int = 0
@@ -627,7 +627,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
vpi_failed_p2 += 1
VLogger.error(f"[Phase A-pre-vpi] {ent_vp2.Path} | vpi 路径生成失败", "PhaseA")
continue
vf_vp2: rawptr[fileio.File] = fileio.File(vpi_path_vp2, fileio.MODE.R)
vf_vp2: fileio.File* = fileio.File(vpi_path_vp2, fileio.MODE.R)
if not vf_vp2.closed:
vf_vp2.close()
stdlib.free(vpi_path_vp2)
@@ -635,7 +635,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
stdlib.free(vpi_path_vp2)
# Read the source -> parse the AST -> generate the vpi (rel_path = ent_vp2.Path: vpi content does
# not depend on it; it is only used for fatal_error attribution, pointing at this source file)
f_vp2: rawptr[fileio.File] = fileio.File(ent_vp2.Path, fileio.MODE.R)
f_vp2: fileio.File* = fileio.File(ent_vp2.Path, fileio.MODE.R)
if f_vp2.closed:
vpi_failed_p2 += 1
VLogger.error(f"[Phase A-pre-vpi] {ent_vp2.Path} | 无法打开源文件", "PhaseA")
@@ -683,7 +683,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
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:
pf_vp2: rawptr[fileio.File] = fileio.File(pyi_path_vp2, fileio.MODE.W)
pf_vp2: fileio.File* = fileio.File(pyi_path_vp2, fileio.MODE.W)
if not pf_vp2.closed:
pf_vp2.write(pyi_buf_vp2, pyi_pos_vp2)
pf_vp2.close()
@@ -750,7 +750,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
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)
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: 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:
# Record this file's deps (for convergence diagnostics; stdlib table survives reset)
@@ -793,7 +793,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
pkg_pre = GenApi.compute_package_from_relpath(mb, rel_path_pre)
# App pre-registration passes pre_allow_dep_inject=1: imports and dep vpi injection happen at
# declaration time so field annotations share Phase A's context (else struct layouts diverge).
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1)
tr_pre: 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 cleanup: free this App file's transient pre-registration data
mb.reset_to(mark2)
@@ -846,7 +846,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
if string.strlen(ent.Path) > src_dir_len_pa + 1:
rel_path_pa: str = ent.Path + src_dir_len_pa + 1
pkg_pa = GenApi.compute_package_from_relpath(mb, rel_path_pa)
tr_a: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent.Path, ent.Sha1, pkg_pa, 0, temp_dir)
tr_a: HandlesTranslator.Translator* = BuildPipeline.TranslateFileGetTrans(mb, ent.Path, ent.Sha1, pkg_pa, 0, temp_dir)
# Timing point 1: translate returned
t_pa1: uint64 = w32.win32base.GetTickCount64()
if tr_a is None:
@@ -894,7 +894,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
# Save stub.ll (sliced path: temp_dir/{sha1 prefix}/{sha1}.stub.ll)
stub_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "stub.ll")
if stub_path_a is not None:
sf_a: rawptr[fileio.File] = fileio.File(stub_path_a, fileio.MODE.W)
sf_a: fileio.File* = fileio.File(stub_path_a, fileio.MODE.W)
if not sf_a.closed:
sf_a.write(stub_buf_a, stub_len_a)
sf_a.close()
@@ -910,7 +910,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
# Save text.ll (sliced path)
text_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "text.ll")
if text_path_a is not None:
tf_a: rawptr[fileio.File] = fileio.File(text_path_a, fileio.MODE.W)
tf_a: fileio.File* = fileio.File(text_path_a, fileio.MODE.W)
if not tf_a.closed:
tf_a.write(text_buf_a, text_len_a)
tf_a.close()
@@ -927,7 +927,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
full_len_a: sizet = string.strlen(full_buf_a)
full_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "full.ll")
if full_path_a is not None:
ffa: rawptr[fileio.File] = fileio.File(full_path_a, fileio.MODE.W)
ffa: fileio.File* = fileio.File(full_path_a, fileio.MODE.W)
if not ffa.closed:
ffa.write(full_buf_a, full_len_a)
ffa.close()
@@ -944,7 +944,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
# Save dependencies (_imported_modules) for Phase B (sliced path)
deps_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "deps.txt")
if deps_path_a is not None:
df_a: rawptr[fileio.File] = fileio.File(deps_path_a, fileio.MODE.W)
df_a: fileio.File* = fileio.File(deps_path_a, fileio.MODE.W)
if not df_a.closed:
if tr_a._imported_modules is not None:
dl_a: sizet = string.strlen(tr_a._imported_modules)
@@ -1057,7 +1057,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
if llc_ir_path is None:
VLogger.error("llc 输入路径构造失败", "PhaseB")
sys.exit(1)
tslot: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__())
tslot: BuildPipeline.LlcTask* = 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:
VLogger.error(f"llc 任务构造失败: {ent.Path}", "PhaseB")
sys.exit(1)
@@ -1103,7 +1103,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
# Free the llc tasks (command strings + records)
ti: int = 0
while ti < llc_task_count:
tfree: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(ti) * BuildPipeline.LlcTask.__sizeof__())
tfree: BuildPipeline.LlcTask* = BuildPipeline.LlcTask*(uint64(llc_tasks) + sizet(ti) * BuildPipeline.LlcTask.__sizeof__())
BuildPipeline.free_llc_task(tfree)
ti += 1
stdlib.free(llc_tasks)
@@ -1270,7 +1270,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
if string.strlen(src_fp_mi) > inc_dir_len_mi + 1:
inc_rel_mi2: str = src_fp_mi + inc_dir_len_mi + 1
inc_pkg_mi = GenApi.compute_package_from_relpath(mb, inc_rel_mi2)
tr_mi: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, src_fp_mi, inc_sha1_mi, inc_pkg_mi)
tr_mi: HandlesTranslator.Translator* = BuildPipeline.TranslateFileGetTrans(mb, src_fp_mi, inc_sha1_mi, inc_pkg_mi)
if tr_mi is not None:
# PBP IR buffer: same as PHASE_A_IR_SIZE (parser.vp's text.ll >1MB truncation root cause)
PBP_IR_SIZE: sizet = 8388608
@@ -1283,7 +1283,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
inc_stub_len: sizet = string.strlen(inc_stub_buf)
inc_stub_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "stub.ll")
if inc_stub_path is not None:
isf: rawptr[fileio.File] = fileio.File(inc_stub_path, fileio.MODE.W)
isf: fileio.File* = fileio.File(inc_stub_path, fileio.MODE.W)
if not isf.closed:
isf.write(inc_stub_buf, inc_stub_len)
isf.close()
@@ -1296,7 +1296,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
inc_text_len: sizet = string.strlen(inc_text_buf)
inc_text_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
if inc_text_path is not None:
itf: rawptr[fileio.File] = fileio.File(inc_text_path, fileio.MODE.W)
itf: fileio.File* = fileio.File(inc_text_path, fileio.MODE.W)
if not itf.closed:
itf.write(inc_text_buf, inc_text_len)
itf.close()
@@ -1311,7 +1311,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
inc_full_len: sizet = string.strlen(inc_full_buf)
inc_full_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "full.ll")
if inc_full_path is not None:
ifff: rawptr[fileio.File] = fileio.File(inc_full_path, fileio.MODE.W)
ifff: fileio.File* = fileio.File(inc_full_path, fileio.MODE.W)
if not ifff.closed:
ifff.write(inc_full_buf, inc_full_len)
ifff.close()
@@ -1338,19 +1338,19 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
diag_stub_ex: int = 0
diag_text_ex: int = 0
if diag_full is not None:
df_diag_f: rawptr[fileio.File] = fileio.File(diag_full, fileio.MODE.R)
df_diag_f: fileio.File* = fileio.File(diag_full, fileio.MODE.R)
if not df_diag_f.closed:
diag_full_ex = 1
df_diag_f.close()
stdlib.free(diag_full)
if diag_stub is not None:
df_diag_s: rawptr[fileio.File] = fileio.File(diag_stub, fileio.MODE.R)
df_diag_s: fileio.File* = fileio.File(diag_stub, fileio.MODE.R)
if not df_diag_s.closed:
diag_stub_ex = 1
df_diag_s.close()
stdlib.free(diag_stub)
if diag_text is not None:
df_diag_t: rawptr[fileio.File] = fileio.File(diag_text, fileio.MODE.R)
df_diag_t: fileio.File* = fileio.File(diag_text, fileio.MODE.R)
if not df_diag_t.closed:
diag_text_ex = 1
df_diag_t.close()
@@ -1466,7 +1466,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
obj_path_pc: str = StubMergerCollect._sliced_path(includes_binary_dir, ibd_len_pc, rsha1_pc, "obj")
if obj_path_pc is not None:
# Check whether the .obj file exists
cf_pc: rawptr[fileio.File] = fileio.File(obj_path_pc, fileio.MODE.R)
cf_pc: fileio.File* = fileio.File(obj_path_pc, fileio.MODE.R)
if not cf_pc.closed:
cf_pc.close()
# The .obj exists; append to final_obj_paths
@@ -1514,7 +1514,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, ou
VLogger.info("phase2command 模式:跳过 --run(exe 尚未链接)", "phase2cmd")
elif args.get_bool("run"):
VLogger.info(f"执行: {exe_path}", "run")
rp: rawptr[subprocess.CompletedProcess] = subprocess.run(exe_path, False, False)
rp: subprocess.CompletedProcess* = subprocess.run(exe_path, False, False)
if rp is not None: VLogger.info(f"退出码: {rp.returncode}", "run")
else:
VLogger.error("链接失败", "PhaseC")