fix(phasec): 可达模块 .obj 缺失误杀恢复,纯声明模块跳过
Phase B+ 对纯声明模块(text.ll 无 define 行,如 stdio.vp 全 pass) 按设计不生成 .obj,但 Phase C 遍历可达模块时无条件要求 .obj 存在, 导致误杀。新增 StubMerger.IsDeclOnlyModule 判断(与 Phase B+ 内联 逻辑一致),.obj 缺失时声明文件静默跳过,实现文件缺失仍 fail-fast。
This commit is contained in:
1 parent
c9de06e76d
commit
b4c01808bf
2 files changed
+63
-4
No files matched your search
@@ -980,6 +980,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
# 不再全量收集 includes.binary 下的所有 .obj
|
||||
if reachable_set is not None and reachable_count > 0:
|
||||
ibd_len_pc: t.CSizeT = string.strlen(includes_binary_dir)
|
||||
td_len_pc: t.CSizeT = string.strlen(temp_dir)
|
||||
ri_pc: int
|
||||
for ri_pc in range(reachable_count):
|
||||
rsha1_pc: str = reachable_set + t.CSizeT(ri_pc) * 17
|
||||
@@ -1001,10 +1002,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
fop_pos += op_len_pc
|
||||
final_obj_paths[fop_pos] = '\0'
|
||||
else:
|
||||
fb_pc: str = VLogger.fmt_buf()
|
||||
if fb_pc is not None:
|
||||
viperlib.snprintf(fb_pc, 1024, "可达模块 .obj 缺失: %s", obj_path_pc)
|
||||
VLogger.error(fb_pc, "PhaseC")
|
||||
# .obj 缺失:纯声明模块(text.ll 无 define 行,如 stdio.vp 全 pass)
|
||||
# 无需 .obj,静默跳过;实现文件缺失才是编译产物异常(fail-fast)
|
||||
if StubMerger.IsDeclOnlyModule(temp_dir, td_len_pc, rsha1_pc) != 1:
|
||||
fb_pc: str = VLogger.fmt_buf()
|
||||
if fb_pc is not None:
|
||||
viperlib.snprintf(fb_pc, 1024, "可达模块 .obj 缺失: %s", obj_path_pc)
|
||||
VLogger.error(fb_pc, "PhaseC")
|
||||
stdlib.free(obj_path_pc)
|
||||
|
||||
final_obj_paths[fop_pos] = '\0'
|
||||
|
||||
@@ -729,6 +729,61 @@ def LookupSha1RelPath(sha1: str) -> str:
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# IsDeclOnlyModule - 判断模块是否为纯声明文件
|
||||
#
|
||||
# 读取 {temp_dir}/{sha1}.text.ll,扫描是否含 "define " 行:
|
||||
# 返回 1 = 纯声明(无函数体,如 stdio.vp 全 pass),无需 .obj
|
||||
# 返回 0 = 实现文件(含 define 函数体)
|
||||
# 返回 -1 = text.ll 不存在/无法判断
|
||||
#
|
||||
# 与 Phase B+(Phase2.vp 编译缺失 includes 时)的内联判断逻辑一致,
|
||||
# 供 Phase C 链接时区分"声明文件无需 .obj"与"实现文件缺失"。
|
||||
# ============================================================
|
||||
def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
|
||||
"""判断模块是否为纯声明文件(text.ll 无 define 行)"""
|
||||
if temp_dir is None or sha1 is None:
|
||||
return -1
|
||||
tpath: str = _sliced_path(temp_dir, td_len, sha1, "text.ll")
|
||||
if tpath is None:
|
||||
return -1
|
||||
tf_d: fileio.File | t.CPtr = fileio.File(tpath, fileio.MODE.R)
|
||||
stdlib.free(tpath)
|
||||
if tf_d.closed:
|
||||
return -1
|
||||
tbuf_d: bytes = stdlib.malloc(STUB_READ_BUF_SIZE)
|
||||
tbr_d: t.CInt64T = 0
|
||||
if tbuf_d is not None:
|
||||
tbr_d = tf_d.read_all(tbuf_d, STUB_READ_BUF_SIZE)
|
||||
tf_d.close()
|
||||
if tbuf_d is None:
|
||||
return -1
|
||||
if tbr_d <= 0:
|
||||
# 空 text.ll:无函数体,纯声明
|
||||
stdlib.free(tbuf_d)
|
||||
return 1
|
||||
if tbr_d < STUB_READ_BUF_SIZE:
|
||||
tbuf_d[tbr_d] = '\0'
|
||||
else:
|
||||
tbuf_d[STUB_READ_BUF_SIZE - 1] = '\0'
|
||||
# 逐行扫描:找 "define " 行即为实现文件
|
||||
tpos_d: t.CSizeT = 0
|
||||
while tpos_d < tbr_d:
|
||||
tls_d: t.CSizeT = tpos_d
|
||||
while tpos_d < tbr_d:
|
||||
if tbuf_d[tpos_d] == '\n':
|
||||
break
|
||||
tpos_d += 1
|
||||
tll_d: t.CSizeT = tpos_d - tls_d
|
||||
if tpos_d < tbr_d:
|
||||
tpos_d += 1
|
||||
if tll_d >= 7 and string.strncmp(tbuf_d + tls_d, "define ", 7) == 0:
|
||||
stdlib.free(tbuf_d)
|
||||
return 0
|
||||
stdlib.free(tbuf_d)
|
||||
return 1
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _IsFuncDeclaredOrDefined - 检查 out_buf 中是否已有函数的 declare/define
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user