fix(TPV): 浮点 CDefine 注册多方案绕开 pool 覆写与跨模块 double 传递问题 - 查表/str_val/源文件重读+atof_out 输出参数; PRE-TR/PRE-ML/REG-SRC 定位插桩; 记录浮点节点构造值表
This commit is contained in:
1 parent
24d3de4b72
commit
92ba3af752
4 files changed
+174
-3
No files matched your search
@@ -5,6 +5,8 @@ import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesVar as HandlesVar
|
||||
@@ -137,18 +139,142 @@ def _register_cdefine_from_value(pool: memhub.MemBuddy | t.CPtr,
|
||||
if val_node is not None and val_node.kind() == ast.ASTKind.Constant:
|
||||
cn_fp: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(val_node)
|
||||
if cn_fp.const_kind == ast.CONST_FLOAT:
|
||||
# 源文件重读恢复(最可靠:AST 节点 float_val 可能被 pool 操作覆写,
|
||||
# 源文件文本不受影响;用输出参数绕开跨模块 double 返回值传递 bug)
|
||||
use_val: double = cn_fp.float_val
|
||||
rec_d: t.CDouble = 0.0
|
||||
if _recover_cdefine_float(name, t.CPtr(c.Addr(rec_d))) != 0:
|
||||
use_val = rec_d
|
||||
# CDEF-DBG: 打印 float_val 读取(定位浮点 CDefine 值错误)
|
||||
fb_cd: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb_cd is not None:
|
||||
viperlib.snprintf(fb_cd, 1024, "REG-SRC: %s kind=%d const_kind=%d int_val=%lld float_val=%.17g ptr=%p",
|
||||
name, val_node.kind(), cn_fp.const_kind, cn_fp.int_val, cn_fp.float_val, t.CSizeT(cn_fp))
|
||||
viperlib.snprintf(fb_cd, 1024, "REG-SRC: %s kind=%d const_kind=%d float_val=%.17g rec=%.17g use=%.17g ptr=%p",
|
||||
name, val_node.kind(), cn_fp.const_kind, cn_fp.float_val,
|
||||
rec_d, use_val, t.CSizeT(cn_fp))
|
||||
VLogger.info(fb_cd, "CDEF-DBG")
|
||||
HandlesType.register_cdefine_double(pool, name, cn_fp.float_val)
|
||||
HandlesType.register_cdefine_double(pool, name, use_val)
|
||||
return
|
||||
val_fp: int = extract_cdefine_int_value(val_node)
|
||||
HandlesType.register_cdefine_constant(pool, name, val_fp)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 源文件重读恢复 CDefine 浮点值
|
||||
#
|
||||
# 背景:AST 节点的 float_val/str_val 字段可能被 pool 分配操作覆写
|
||||
# (MemBuddy 内存冲突),导致注册的浮点 CDefine 值错误(llc ret i32 0)。
|
||||
# 本函数直接读源文件找 "NAME: t.CDefine = value" 行,atof 解析 value——
|
||||
# 源文件文本不受 pool 影响,是最可靠的恢复路径。
|
||||
# ============================================================
|
||||
_g_recover_found: int = 0
|
||||
|
||||
|
||||
def _recover_found() -> int:
|
||||
"""检查最近一次 _recover_cdefine_float 是否成功"""
|
||||
return _g_recover_found
|
||||
|
||||
|
||||
def _recover_cdefine_float(name: str, out: t.CDouble | t.CPtr) -> int:
|
||||
"""从当前模块源文件恢复浮点 CDefine 值,写入 out[0],成功返回 1
|
||||
|
||||
用输出参数传递 double,避免 TPV 跨模块 double 返回值传递 bug。
|
||||
"""
|
||||
global _g_recover_found
|
||||
_g_recover_found = 0
|
||||
fp: str = HandlesType.get_current_file()
|
||||
if fp is None or name is None or out is None:
|
||||
return 0
|
||||
f: fileio.File | t.CPtr = fileio.File(fp, fileio.MODE.R)
|
||||
if f.closed:
|
||||
return 0
|
||||
BUF_SZ: t.CSizeT = 1048576
|
||||
buf: bytes = stdlib.malloc(BUF_SZ)
|
||||
if buf is None:
|
||||
f.close()
|
||||
return 0
|
||||
nrd: LONG = f.read_all(buf, BUF_SZ)
|
||||
f.close()
|
||||
if nrd <= 0:
|
||||
stdlib.free(buf)
|
||||
return 0
|
||||
if nrd < BUF_SZ:
|
||||
buf[nrd] = 0
|
||||
else:
|
||||
buf[BUF_SZ - 1] = 0
|
||||
|
||||
name_len: t.CSizeT = string.strlen(name)
|
||||
total_len: t.CSizeT = string.strlen(buf)
|
||||
pos: t.CSizeT = 0
|
||||
while pos < total_len:
|
||||
line_start: t.CSizeT = pos
|
||||
while pos < total_len and buf[pos] != '\n':
|
||||
pos += 1
|
||||
line_len: t.CSizeT = pos - line_start
|
||||
if pos < total_len:
|
||||
pos += 1
|
||||
|
||||
# 匹配 "name:"
|
||||
if line_len < name_len + 1:
|
||||
continue
|
||||
match_ok: int = 1
|
||||
ki: t.CSizeT
|
||||
for ki in range(name_len):
|
||||
if buf[line_start + ki] != name[ki]:
|
||||
match_ok = 0
|
||||
break
|
||||
if match_ok == 0:
|
||||
continue
|
||||
if buf[line_start + name_len] != ':':
|
||||
continue
|
||||
|
||||
# 行内包含 "t.CDefine"
|
||||
has_cd: int = 0
|
||||
ci: t.CSizeT = line_start + name_len + 1
|
||||
while ci + 8 <= line_start + line_len:
|
||||
if (buf[ci] == 't' and buf[ci + 1] == '.' and buf[ci + 2] == 'C' and
|
||||
buf[ci + 3] == 'D' and buf[ci + 4] == 'e' and buf[ci + 5] == 'f' and
|
||||
buf[ci + 6] == 'i' and buf[ci + 7] == 'n' and buf[ci + 8] == 'e'):
|
||||
has_cd = 1
|
||||
break
|
||||
ci += 1
|
||||
if has_cd == 0:
|
||||
continue
|
||||
|
||||
# 找 '='
|
||||
eq: t.CSizeT = line_start
|
||||
while eq < line_start + line_len and buf[eq] != '=':
|
||||
eq += 1
|
||||
if eq >= line_start + line_len:
|
||||
continue
|
||||
eq += 1
|
||||
while eq < line_start + line_len and buf[eq] == ' ':
|
||||
eq += 1
|
||||
val_start: t.CSizeT = eq
|
||||
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' \
|
||||
and buf[eq] != '#' and buf[eq] != '\r' and buf[eq] != '\n':
|
||||
eq += 1
|
||||
if eq == val_start:
|
||||
continue
|
||||
|
||||
val_txt: str = stdlib.malloc(eq - val_start + 1)
|
||||
if val_txt is None:
|
||||
stdlib.free(buf)
|
||||
return 0
|
||||
vi: t.CSizeT
|
||||
for vi in range(eq - val_start):
|
||||
val_txt[vi] = buf[val_start + vi]
|
||||
val_txt[eq - val_start] = 0
|
||||
stdlib.free(buf)
|
||||
# 用 atof_out(输出参数)绕开跨模块 double 返回值传递 bug
|
||||
if string.atof_out(val_txt, out) != 0:
|
||||
_g_recover_found = 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
stdlib.free(buf)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _annotation_contains_name - 递归检查注解中是否包含指定名称
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user