From b7e4861e6c23e6c4ab2ff60a417f51ff6921cae9 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 3 Oct 2026 21:51:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpv):=20vpi=20=E8=BF=94=E5=9B=9E=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E7=BA=AF=20marker=EF=BC=88t.State=20=E7=AD=89?= =?UTF-8?q?=EF=BC=89=E8=A7=A3=E6=9E=90=E4=B8=BA=20void=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=20void=20=E8=B0=83=E7=94=A8=E8=A2=AB=E5=BD=93=20i32?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调用侧 `_resolve_vpi_ret_annot_str` 只把 `t.CVoid` 映射为 void,纯 `t.State` (存储类装饰器标记)会解析失败返回 None → 调用侧回退外部函数白名单默认 i32。 现场(MLIRLiteTest):`includes/stdlib.vp` 的 `extern def exit(status: int)` 在 stdlib 的 vpi 中是 `def exit(status: int) -> t.State: pass`,于是生成 %6 = llvm.call @exit(%c3) : (i32) -> i32 而模块声明是 `llvm.func @exit(%status: i32)`(void),mlir-opt 报 'llvm.call' op calling function with void result must not produce values 修复:在 `_resolve_vpi_ret_annot_str` 增加"纯 marker 注解 → void"分支,与 declare 注入路径 `_inject_module_declare` 的 is_pure_marker_rt 判据同口径。 仅**纯** marker(`t.State` / `t.CExtern` / `t.CExport`,可带 t./c. 前缀) 才归 void;`HANDLE | t.State` 等含真实类型的注解仍由段循环返回真实类型。 --- App/lib/Stub/StubGen/VpiReader.vp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 82ed0a6..cdaf662 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -1542,6 +1542,32 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, return None return mlirlite.Struct(pool, tup_head_t, tup_count_t, None) + # 纯 marker 注解(`t.State` / `t.CExtern` / `t.CExport` 单独出现,可带 t./c. + # 前缀)→ void:这些是存储类装饰器标记,不是真实返回类型,与 declare 注入 + # 路径(_inject_module_declare 的 is_pure_marker_rt)**同口径**。 + # 缺此分支时 `extern def exit(status: int)` 的 vpi 注解 `t.State` 在本函数 + # 解析为 None → 调用侧回退外部函数白名单默认 i32 → 生成 + # `%N = call i32 @exit(...)` 而模块声明 `llvm.func @exit(...)`(void), + # mlir-opt 报 "calling function with void result must not produce values"。 + # 注意仅**纯** marker 才归 void;`HANDLE | t.State`(FindFirstFileA)含真实 + # 类型,其段循环会以 first_ty 返回真实类型,不得在此误判。 + marker_len: sizet = string.strlen(ret_annot) + mk_s: sizet = 0 + while mk_s < marker_len and ret_annot[mk_s] == ' ': + mk_s += 1 + mk_e: sizet = marker_len + while mk_e > mk_s and ret_annot[mk_e - 1] == ' ': + mk_e -= 1 + mk_off_m: sizet = 0 + if mk_e - mk_s >= 2 and (ret_annot[mk_s] == 't' or ret_annot[mk_s] == 'c') \ + and ret_annot[mk_s + 1] == '.': + mk_off_m = 2 + mk_nlen: sizet = mk_e - mk_s - mk_off_m + if (mk_nlen == 5 and string.strncmp(ret_annot + mk_s + mk_off_m, "State", 5) == 0) \ + or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExtern", 7) == 0) \ + or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExport", 7) == 0): + return mlirlite.Void(pool) + has_cptr: int = 0 has_cvoid: int = 0 first_ty: mlirlite.LLVMType* = None