依据 T97 决定性结果,修复了 CVoid 严格验证,other_ty 有效性验证,fallback 不依赖 kind() 实现
This commit is contained in:
1 parent
f440bda421
commit
c876df7907
2 files changed
+85
-2
No files matched your search
@@ -152,8 +152,25 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
ast._lexer_init(lx, vpi_buf, pool)
|
ast._lexer_init(lx, vpi_buf, pool)
|
||||||
tokens: ast.Token | t.CPtr = ast.tokenize(lx)
|
tokens: ast.Token | t.CPtr = ast.tokenize(lx)
|
||||||
tree: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens)
|
tree: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens)
|
||||||
stdlib.free(vpi_buf)
|
# vpi_buf 延迟释放:AST 字符串字段可能引用 vpi_buf 内部(token 零拷贝),
|
||||||
|
# 提前 free 会导致 Name.id/Attribute.attr 等悬空 → 后续解析返回错误类型。
|
||||||
|
# 在 ParseVpiIntoModule 末尾统一释放。
|
||||||
|
# [DBG-T96] 临时诊断:定位 vpi AST 有效性(定位后移除)
|
||||||
|
k96: int = -1
|
||||||
|
if tree is not None:
|
||||||
|
k96 = tree.kind()
|
||||||
|
stdio.printf("[DBG-T96] vpi tree kind=%d children=", k96)
|
||||||
|
if tree is not None and tree.children is not None:
|
||||||
|
n96: t.CSizeT = tree.children.__len__()
|
||||||
|
stdio.printf("%d\n", n96)
|
||||||
|
if n96 > 0:
|
||||||
|
c96: ast.AST | t.CPtr = tree.children.get(0)
|
||||||
|
if c96 is not None:
|
||||||
|
stdio.printf("[DBG-T96] child0 kind=%d\n", c96.kind())
|
||||||
|
else:
|
||||||
|
stdio.printf("0\n")
|
||||||
if tree is None:
|
if tree is None:
|
||||||
|
stdlib.free(vpi_buf)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# 提取源模块 SHA1(用于函数名混淆,在 AST 解析成功后提取避免提前返回时泄漏)
|
# 提取源模块 SHA1(用于函数名混淆,在 AST 解析成功后提取避免提前返回时泄漏)
|
||||||
@@ -234,6 +251,8 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
# 释放 SHA1 缓冲区(_extract_sha1_from_path 用 stdlib.malloc 分配)
|
# 释放 SHA1 缓冲区(_extract_sha1_from_path 用 stdlib.malloc 分配)
|
||||||
if src_sha1 is not None:
|
if src_sha1 is not None:
|
||||||
stdlib.free(src_sha1)
|
stdlib.free(src_sha1)
|
||||||
|
# vpi_buf 延迟到全部 tree 处理完成后释放(见解析处注释)
|
||||||
|
stdlib.free(vpi_buf)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@@ -420,6 +439,26 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
if ret_ty is None:
|
if ret_ty is None:
|
||||||
ret_ty = i32_ty
|
ret_ty = i32_ty
|
||||||
|
|
||||||
|
# [DBG-T97] 临时诊断:定位 args.get_str 类型退化(定位后移除)
|
||||||
|
if string.strcmp(m_fd.name, "parse_args") == 0:
|
||||||
|
vis97: int = HandlesStruct.is_struct_visible("ParsedArgs")
|
||||||
|
gst97: t.CChar | t.CPtr = stdlib.malloc(128)
|
||||||
|
if gst97 is not None:
|
||||||
|
gty97: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type("ParsedArgs")
|
||||||
|
if gty97 is not None:
|
||||||
|
llvmlite.TypePrint(gst97, 128, gty97, pool)
|
||||||
|
else:
|
||||||
|
viperlib.snprintf(gst97, 128, "NULL")
|
||||||
|
ot97: t.CChar | t.CPtr = stdlib.malloc(128)
|
||||||
|
if ot97 is not None:
|
||||||
|
if ret_ty is not None:
|
||||||
|
llvmlite.TypePrint(ot97, 128, ret_ty, pool)
|
||||||
|
else:
|
||||||
|
viperlib.snprintf(ot97, 128, "NULL")
|
||||||
|
stdio.printf("[DBG-T97] vis=%d gst=%s ret=%s\n", vis97, gst97, ot97)
|
||||||
|
stdlib.free(ot97)
|
||||||
|
stdlib.free(gst97)
|
||||||
|
|
||||||
# 创建 declare
|
# 创建 declare
|
||||||
func: llvmlite.Function | t.CPtr = llvmlite.create_declare(
|
func: llvmlite.Function | t.CPtr = llvmlite.create_declare(
|
||||||
pool, mod, mangled_name, ret_ty)
|
pool, mod, mangled_name, ret_ty)
|
||||||
|
|||||||
@@ -1550,12 +1550,56 @@ def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
if left_is_cptr != 0:
|
if left_is_cptr != 0:
|
||||||
other_node = bop.right
|
other_node = bop.right
|
||||||
# 检测另一边是否是 t.CVoid (void* = i8*)
|
# 检测另一边是否是 t.CVoid (void* = i8*)
|
||||||
other_is_cvoid: int = _is_cvoid_marker(other_node, imported_modules)
|
# 严格验证完整形式(Attribute(t.CVoid) 的 value 是 Name("t"),
|
||||||
|
# 或裸名 CVoid 且 t 已导入),防止解析异常节点被误判为 CVoid。
|
||||||
|
other_is_cvoid: int = 0
|
||||||
|
if other_node is not None:
|
||||||
|
if other_node.kind() == ast.ASTKind.Attribute:
|
||||||
|
oat2: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(other_node)
|
||||||
|
if oat2.attr is not None and string.strcmp(oat2.attr, "CVoid") == 0:
|
||||||
|
if oat2.value is not None and oat2.value.kind() == ast.ASTKind.Name:
|
||||||
|
ov2: ast.Name | t.CPtr = (ast.Name | t.CPtr)(oat2.value)
|
||||||
|
if ov2.id is not None and string.strcmp(ov2.id, "t") == 0:
|
||||||
|
other_is_cvoid = 1
|
||||||
|
elif other_node.kind() == ast.ASTKind.Name:
|
||||||
|
onm2: ast.Name | t.CPtr = (ast.Name | t.CPtr)(other_node)
|
||||||
|
if onm2.id is not None and string.strcmp(onm2.id, "CVoid") == 0:
|
||||||
|
if HandlesImports.is_module_imported(imported_modules, "t") != 0:
|
||||||
|
other_is_cvoid = 1
|
||||||
if other_is_cvoid != 0:
|
if other_is_cvoid != 0:
|
||||||
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||||
other_ty: llvmlite.LLVMType | t.CPtr = resolve_annotation_type(
|
other_ty: llvmlite.LLVMType | t.CPtr = resolve_annotation_type(
|
||||||
pool, other_node, imported_modules, from_imports, trans)
|
pool, other_node, imported_modules, from_imports, trans)
|
||||||
|
# other_ty 必须是已注册的结构体类型才算有效:
|
||||||
|
# X | t.CPtr 的 X 是类名,解析结果应为 struct 类型。
|
||||||
|
# 若节点异常导致解析出基础类型/垃圾(如 Int8 → Ptr(i8)),
|
||||||
|
# 不应直接返回,需走下方回退按类名查全局表。
|
||||||
|
# (str | t.CPtr 解析为 Ptr(i8) 非 struct,回退 get_struct_type
|
||||||
|
# 查不到 str → 仍返回 Ptr(i8),结果一致,不受影响。)
|
||||||
|
if other_ty is not None:
|
||||||
|
if HandlesStruct.find_struct_by_type(other_ty) is not None:
|
||||||
|
return llvmlite.Ptr(pool, other_ty)
|
||||||
|
other_ty = None
|
||||||
if other_ty is None:
|
if other_ty is None:
|
||||||
|
# 严格模式(App 文件)下裸类名不可见时,回退到全局
|
||||||
|
# struct 注册表按类名查找。X | t.CPtr 是明确的指针包装
|
||||||
|
# 注解(如 vpi stub 的 "ParsedArgs | t.CPtr"),X 已注册
|
||||||
|
# 时不应静默退化为 i8*——i8* 会让方法返回值的无注解变量
|
||||||
|
# (如 args = parser.parse_args())类型退化,后续 obj.method
|
||||||
|
# get_class_name_by_type 查不到类名,误报
|
||||||
|
# "跨模块调用 'args.get_str' 找不到模块 SHA1"。
|
||||||
|
# 不检查 kind():vpi 解析的节点在后续处理中可能已损坏
|
||||||
|
# (kind() 读取异常),直接按 Name 布局读取 id,
|
||||||
|
# 由 get_struct_type 兜底校验(无效类名返回 None)。
|
||||||
|
other_cls_nm: str = None
|
||||||
|
if other_node is not None:
|
||||||
|
other_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(other_node)
|
||||||
|
if other_nm.id is not None:
|
||||||
|
other_cls_nm = other_nm.id
|
||||||
|
if other_cls_nm is not None:
|
||||||
|
other_cls_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type(other_cls_nm)
|
||||||
|
if other_cls_ty is not None:
|
||||||
|
return llvmlite.Ptr(pool, other_cls_ty)
|
||||||
# CPtr 单独使用或其他无效类型 → i8*
|
# CPtr 单独使用或其他无效类型 → i8*
|
||||||
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||||
return llvmlite.Ptr(pool, other_ty)
|
return llvmlite.Ptr(pool, other_ty)
|
||||||
|
|||||||
Reference in new issue
Block a user