fix(gen): 修 REnum match case 静默丢弃与 CDefine 负 64 位常量截断,补 void 注解放行、移植类型定义前移
- MatchGenMixin: 2a 路径查变体 tag 改用裸类名(注解书写形态带模块前缀,与变体表裸名注册口径不一致致 tag=-1、case 被静默丢弃、match 全走 default),并在 build_switch 前硬校验 应提交 case 数==sw_count,不再静默丢 - ExprGenCdef: _const_int_for_cdefine 补 value < -2147483648 下限判据,修正 (0xA5A5A5A5<<32)|0xA5A5A5A5 等负 64 位模式被物化为 i32(写入 inttoptr 零扩展 vs 比较 sext 不一致,致 MemBuddy canary 假阳性 rc=6) - FuncGenDef/ClassGenVTable: 掉尾检查新增注解级 void 判据(t.CVoid/裸名 CVoid/None),不再因 REnum match 退化误判 void 函数缺 return - StubMergerBuild: 移植 TPC 的 类型定义前移 遍,满足 llc 对 by-value 具名类型需先定义的要求(invalid type for function argument) - main.vp/Phase1Main.vp/project.vpj: 新增 --detection-deep 深诊断开关与 canary 哨兵、ASan 静态库声明
This commit is contained in:
1 parent
60100fa6af
commit
31df298341
8 files changed
+345
-6
No files matched your search
@@ -1231,6 +1231,141 @@ def _BuildReachableSha1Set(mb: rowptr[memhub.MemBuddy], source_dir: str,
|
||||
VLogger.debug(f"可达 SHA1: {reachable_count} 个", "Reachable")
|
||||
return reachable_count
|
||||
|
||||
# ============================================================
|
||||
# 类型定义前移(llc: "invalid type for function argument")
|
||||
#
|
||||
# 来源:TransPyC/lib/Projectrans/Phase2Translator.py:3056-3081(TPC 同语义实现,
|
||||
# 注释原文即 llc 的该要求)。触发条件:by-value 结构体参数引用的具名类型必须在
|
||||
# declare 点之前定义,否则 llc 报 invalid type for function argument。
|
||||
#
|
||||
# 与 TPC 的差异(唯一一处):TPC 额外做一次同名去重(seen_type_names_inc)。
|
||||
# 本侧合并阶段 _seen_types(本文件 L1646-1667)已按类型名保证"活跃定义唯一",
|
||||
# 重复行不会进入 out_buf,故本遍是纯置换(长度不变),天然幂等且行内容逐字不变。
|
||||
# ============================================================
|
||||
def _IsTypeDefLine(buf: bytes, ls: sizet, le: sizet) -> int:
|
||||
"""buf[ls, le)(不含换行)是否为 `%name = type ...` 类型定义行
|
||||
|
||||
对齐 TPC L3064 的 `stripped.startswith('%') and '= type' in stripped`,
|
||||
但把裸子串判定收紧为词判定:'= type' 也会出现在函数体字符串常量里
|
||||
(如 c"= type\\00"),裸子串判定会把普通指令行当类型定义搬走 → 破坏 IR。
|
||||
"""
|
||||
k: sizet = ls
|
||||
while k < le and (buf[k] == ' ' or buf[k] == '\t'):
|
||||
k += 1
|
||||
if k >= le or buf[k] != '%':
|
||||
return 0
|
||||
j: sizet = k
|
||||
while j + 6 <= le:
|
||||
if string.strncmp(buf + j, "= type", 6) == 0:
|
||||
if j + 6 == le:
|
||||
return 1
|
||||
e: char = buf[j + 6]
|
||||
# 'type' 后只能是空白 / '{' / '<'(= type { ... } / opaque / <{...}>)
|
||||
if e == ' ' or e == '\t' or e == '{' or e == '<':
|
||||
return 1
|
||||
j += 1
|
||||
return 0
|
||||
|
||||
|
||||
def _IsIrHeaderLine(buf: bytes, ls: sizet, le: sizet) -> int:
|
||||
"""buf[ls, le)(不含换行)是否属于 ll header(类型定义插在其后)
|
||||
|
||||
对齐 TPC L3076 的 header 判据:空行 / ';' 注释 / 'target ' /
|
||||
'source_filename' / '!' 元数据(行首空白先跳过,等价 TPC 的 stripped)。
|
||||
"""
|
||||
k: sizet = ls
|
||||
while k < le and (buf[k] == ' ' or buf[k] == '\t' or buf[k] == '\r'):
|
||||
k += 1
|
||||
if k >= le:
|
||||
return 1
|
||||
if buf[k] == ';' or buf[k] == '!':
|
||||
return 1
|
||||
if le - k >= 7 and string.strncmp(buf + k, "target ", 7) == 0:
|
||||
return 1
|
||||
if le - k >= 15 and string.strncmp(buf + k, "source_filename", 15) == 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def HoistTypeDefsBeforeDeclares(buf: bytes, length: sizet) -> sizet:
|
||||
"""把所有 `%name = type ...` 行上移到 IR header 之后(见上方注释)
|
||||
|
||||
纯文本行级重排:行内容逐字不变、类型定义之间相对顺序不变、非类型定义行
|
||||
相对顺序不变;插入点与 TPC 一致(header 之后第一行;若首个非 header 行
|
||||
就在文件首行或无 header 行,按 TPC 同规则追加末尾)。
|
||||
幂等:已是"定义在 header 之后"时结果与输入逐字节相同。
|
||||
返回重排后的长度(有类型定义行时恒为 length)。
|
||||
"""
|
||||
if buf is None or length == 0:
|
||||
return length
|
||||
# 1. 统计类型定义行总长(整行含换行)
|
||||
types_len: sizet = 0
|
||||
p: sizet = 0
|
||||
while p < length:
|
||||
le: sizet = p
|
||||
while le < length and buf[le] != '\n':
|
||||
le += 1
|
||||
step: sizet = le - p
|
||||
if le < length:
|
||||
step += 1
|
||||
if _IsTypeDefLine(buf, p, le) != 0:
|
||||
types_len += step
|
||||
p += step
|
||||
if types_len == 0:
|
||||
return length
|
||||
tmp: bytes = stdlib.malloc(types_len + 1)
|
||||
if tmp is None:
|
||||
# VLogger.error 直接终止进程(不静默降级为"未前移")
|
||||
VLogger.error("类型定义前移暂存缓冲分配失败", "StubMerger")
|
||||
return length
|
||||
# 2. 类型定义行抽到 tmp、其余行原地压缩(只删行不增行,w <= p 恒成立)
|
||||
tmp_pos: sizet = 0
|
||||
w: sizet = 0
|
||||
p = 0
|
||||
while p < length:
|
||||
le = p
|
||||
while le < length and buf[le] != '\n':
|
||||
le += 1
|
||||
step = le - p
|
||||
if le < length:
|
||||
step += 1
|
||||
if _IsTypeDefLine(buf, p, le) != 0:
|
||||
string.memmove(tmp + tmp_pos, buf + p, step)
|
||||
tmp_pos += step
|
||||
else:
|
||||
if w != p:
|
||||
string.memmove(buf + w, buf + p, step)
|
||||
w += step
|
||||
p += step
|
||||
tmp[tmp_pos] = '\0'
|
||||
# 3. 求插入点:过滤后文本里 header 之后的首行起始偏移
|
||||
ins: sizet = 0
|
||||
hit: int = 0
|
||||
q: sizet = 0
|
||||
while q < w:
|
||||
qe: sizet = q
|
||||
while qe < w and buf[qe] != '\n':
|
||||
qe += 1
|
||||
if _IsIrHeaderLine(buf, q, qe) == 0:
|
||||
ins = q
|
||||
hit = 1
|
||||
break
|
||||
if qe >= w:
|
||||
break
|
||||
q = qe + 1
|
||||
if hit == 0 or ins == 0:
|
||||
# 对齐 TPC L3079-3080:insert_pos == len(other_lines)
|
||||
ins = w
|
||||
# 4. 腾出 tmp_pos 字节空隙并拷入(长度不变;右移用 memmove 保证重叠安全)
|
||||
tail: sizet = w - ins
|
||||
if tail > 0:
|
||||
string.memmove(buf + ins + tmp_pos, buf + ins, tail)
|
||||
string.memmove(buf + ins, tmp, tmp_pos)
|
||||
new_len: sizet = w + tmp_pos
|
||||
buf[new_len] = '\0'
|
||||
stdlib.free(tmp)
|
||||
return new_len
|
||||
|
||||
# ============================================================
|
||||
# BuildCombinedIR - 组合本地 stub + 依赖 stubs + 本地 text → 完整 IR
|
||||
#
|
||||
@@ -1674,6 +1809,13 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
|
||||
if mod_arr is not None:
|
||||
stdlib.free(mod_arr)
|
||||
|
||||
# 类型定义前移:llc 要求 by-value 结构体参数引用的具名类型在 declare 点之前
|
||||
# 定义(否则 "invalid type for function argument")。TPC 侧同一遍见
|
||||
# TransPyC/lib/Projectrans/Phase2Translator.py:3056-3081。
|
||||
# 落点说明:Phase2 的 write_ir_to_file 是逐字节写本缓冲区(BuildPipeline.vp
|
||||
# L289-314,无任何文本加工),故在此完成即覆盖 llc 的全部输入,无需在
|
||||
# Phase2 再复制一份 4MB 缓冲区重排。
|
||||
out_pos = HoistTypeDefsBeforeDeclares(out_buf, out_pos)
|
||||
return out_pos
|
||||
# ============================================================
|
||||
# LoadDepVpiIntoModule - 加载依赖模块的 .vpi 文件,注入 declare 到当前模块
|
||||
|
||||
Reference in new issue
Block a user