refactor(return): 移除 @c.CReturn 处理,改为遇到即 fatal_error(只保留 -> tuple[...])

FuncGenBase:整体删除 _resolve_creturn_ret_ty,新增 RejectCReturnDecorator(兼容 @c.CReturn(...) 与裸 @c.CReturn 两形态;命中即 TypeGenErr.fatal_error,报文指向 -> tuple[ty1, ty2, ...])

FuncGenDef:前向声明与定义两处调用点改为调用 RejectCReturnDecorator,删除随之失效的注释;周围类型解析主干(-> 注解、State/CExport、无注解 fail-fast)逐字未动

Converter:删除 _PyiCreturnArgs 与其“无 -> 注解则合成 -> tuple[...]”的调用点,改为 _PyiRejectCReturnDecorator(vpi 中仍带 @c.CReturn 即报错,提示用 --clean 重新生成该 .vpi)

注:TPV.vp.txt 是生成的单文件打包产物,需重新生成(本次未手改)
This commit is contained in:
TermiNexus committed 2026-09-28 13:57:05 +08:00
1 parent d06c4d2c0e
commit dfae2f090c
3 files changed
+55 -78

No files matched your search

+24 -27
View File
@@ -502,30 +502,38 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
# ============================================================
# _PyiCreturnArgs - 从装饰器列表提取 @c.CReturn(...) 的实参列表
# _PyiRejectCReturnDecorator - 装饰器列表里出现 @c.CReturn 即编译期报错
#
# 定义侧把 @c.CReturn(a, b, c) 展开为聚合返回类型 {a, b, c},vpi 里该函数却只有装饰器行、无 `->` 注解,stub declare 会退化成 i32;
# 据此合成 `-> tuple[a, b, c]`(tuple 分支同样打包成 Struct),使 stub declare 与 define 的返回类型一致。
# 返回 None = 装饰器列表里没有 CReturn。
# @c.CReturn 已移除:多返回值统一用返回注解 `-> tuple[ty1, ty2, ...]`
# (既有 tuple → struct 通路保留)。vpi 里仍带该装饰器意味着存根过旧,
# fail-fast 提示重新生成,不静默忽略。返回 0 = 装饰器列表里没有 CReturn。
# ============================================================
def _PyiCreturnArgs(decorators: list[ast.AST*]*) -> list[ast.AST*]*:
"""在装饰器列表里找 @c.CReturn(...),返回其实参列表;未找到返回 None"""
def _PyiRejectCReturnDecorator(node: ast.AST*,
decorators: list[ast.AST*]*) -> int:
"""装饰器列表里出现 @c.CReturn 即 fatal_error(返回 0 = 无该装饰器)"""
if decorators is None:
return None
return 0
dn: sizet = len(decorators)
di: sizet = 0
while di < dn:
dnode: ast.AST* = decorators.get(di)
di += 1
if dnode is None or dnode.kind() != ast.ASTKind.Call:
if dnode is None:
continue
dcall: ast.Call* = ast.Call*(dnode)
if dcall.func is None or dcall.func.kind() != ast.ASTKind.Attribute:
# 兼容 @c.CReturn(...)(Call(func=Attribute))与裸 @c.CReturn(Attribute)两形态
dattr: ast.Attribute* = None
if dnode.kind() == ast.ASTKind.Call:
dcall: ast.Call* = ast.Call*(dnode)
if dcall.func is not None and dcall.func.kind() == ast.ASTKind.Attribute:
dattr = ast.Attribute*(dcall.func)
elif dnode.kind() == ast.ASTKind.Attribute:
dattr = ast.Attribute*(dnode)
if dattr is None or dattr.attr is None:
continue
dat: ast.Attribute* = ast.Attribute*(dcall.func)
if dat.attr is not None and string.strcmp(dat.attr, "CReturn") == 0:
return dcall.args
return None
if string.strcmp(dattr.attr, "CReturn") == 0:
GenApi.fatal_error(node, "vpi 中仍带 `@c.CReturn`(已移除):请用返回注解 `-> tuple[ty1, ty2, ...]` 重新生成该 .vpi(可加 --clean)", "TypeError")
return 1
return 0
# ============================================================
@@ -620,19 +628,8 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
pos = _PyiEmit(buf, buf_size, pos, " -> ")
pos = _PyiTypeStr(buf, buf_size, pos, fn.returns)
else:
# 无 `->` 注解但带 @c.CReturn(...):合成 " -> tuple[a, b, c]"(N11)
cre_args: list[ast.AST*]* = _PyiCreturnArgs(fn.decorator_list)
if cre_args is not None:
cre_n: sizet = len(cre_args)
if cre_n > 0:
pos = _PyiEmit(buf, buf_size, pos, " -> tuple[")
cre_i: sizet = 0
while cre_i < cre_n:
if cre_i > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
pos = _PyiTypeStr(buf, buf_size, pos, cre_args.get(cre_i))
cre_i += 1
pos = _PyiEmit(buf, buf_size, pos, "]")
# 无 `->` 注解时若带 @c.CReturn(...):该装饰器已移除,fail-fast 提示重生成 vpi
_PyiRejectCReturnDecorator(fn, fn.decorator_list)
pos = _PyiEmit(buf, buf_size, pos, ": pass\n")
return pos
+27 -41
View File
@@ -296,49 +296,35 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase):
return 1
return 0
# ============================================================
# _resolve_creturn_ret_ty - @c.CReturn(ty1, ty2, ...) → 多返回 struct 类型
# RejectCReturnDecorator - @c.CReturn 装饰器已移除,遇到即编译期报错
#
# 对齐 TPC DeclarationGenerator:CReturn 声明函数返回多个值(如
# GetMemoryStats @c.CReturn(uint64, uint64, uint64) →
# {i64, i64, i64})。pre_scan 前向声明与 translate_function_def 定义
# 两阶段必须一致,否则 declare i32 + define {i64,i64,i64} → llc
# "ret doesn't match function result type"。
# 多返回值唯一入口是返回注解 `-> tuple[ty1, ty2, ...]`(tuple → struct 通路
# 逐字保留)。任何装饰器形态出现 CReturn 一律 fail-fast,不静默忽略。
# 供 FuncGenDef(pre_scan 前向声明 / translate_function_def 定义两阶段)复用;
# Converter 为模块级函数,同报文另写一份(见 StubGen/Converter.vp)。
# 无 CReturn 返回 0。
# ============================================================
def _resolve_creturn_ret_ty(self, pool: memhub.MemBuddy*,
fd: ast.FunctionDef*,
imported_modules: str,
from_imports: str,
trans: HT.Translator*) -> llvmlite.LLVMType*:
"""解析 @c.CReturn 装饰器为 struct 返回类型;无 CReturn 返回 None"""
if fd is None or fd.decorator_list is None: return None
cr_head: llvmlite.Function* = None
cr_last: llvmlite.Function* = None
cr_count: int = 0
cr_dn: sizet = len(fd.decorator_list)
for cdi in range(cr_dn):
deco_cr: ast.AST* = fd.decorator_list.get(cdi)
if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call: continue
deco_call_cr: ast.Call* = ast.Call*(deco_cr)
if deco_call_cr.func is None or deco_call_cr.func.kind() != ast.ASTKind.Attribute: continue
deco_fa_cr: ast.Attribute* = ast.Attribute*(deco_call_cr.func)
if deco_fa_cr.attr is None or string.strcmp(deco_fa_cr.attr, "CReturn") != 0: continue
cr_args: list[ast.AST*]* = deco_call_cr.args
if cr_args is None: continue
cr_an: sizet = len(cr_args)
for cai in range(cr_an):
cr_aty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, cr_args.get(cai), imported_modules, from_imports, trans, 0)
if cr_aty is None: continue
cr_pn: llvmlite.Function* = llvmlite.new_param_node(pool, cr_aty)
if cr_pn is not None:
if cr_head is None:
cr_head = cr_pn
else:
cr_last.Next = cr_pn
cr_last = cr_pn
cr_count += 1
if cr_head is not None and cr_count > 0:
return llvmlite.Struct(pool, cr_head, cr_count, None)
return None
def RejectCReturnDecorator(self, node: ast.AST*,
decorators: list[ast.AST*]*) -> int:
"""装饰器列表里出现 @c.CReturn 即 fatal_error(返回 0 = 无该装饰器)"""
if decorators is None: return 0
rcr_dn: sizet = len(decorators)
for rcr_i in range(rcr_dn):
rcr_deco: ast.AST* = decorators.get(rcr_i)
if rcr_deco is None: continue
# 兼容 @c.CReturn(...)(Call(func=Attribute))与裸 @c.CReturn(Attribute)两形态
rcr_attr: ast.Attribute* = None
if rcr_deco.kind() == ast.ASTKind.Call:
rcr_call: ast.Call* = ast.Call*(rcr_deco)
if rcr_call.func is not None and rcr_call.func.kind() == ast.ASTKind.Attribute:
rcr_attr = ast.Attribute*(rcr_call.func)
elif rcr_deco.kind() == ast.ASTKind.Attribute:
rcr_attr = ast.Attribute*(rcr_deco)
if rcr_attr is None or rcr_attr.attr is None: continue
if string.strcmp(rcr_attr.attr, "CReturn") == 0:
self.Gen.TypeGenErr.fatal_error(node, "`@c.CReturn` 已移除:请改用返回注解 `-> tuple[ty1, ty2, ...]`(多返回值打包为 struct 返回)", "TypeError")
return 1
return 0
# ============================================================
# 创建 LLVM 函数(简单版本,仅声明)
# ============================================================
+4 -10
View File
@@ -122,11 +122,9 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
if ret_ty is None and fd.returns is not None:
if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0:
ret_ty = llvmlite.Void(pool)
# @c.CReturn(ty1, ...) → 多返回 struct(前向声明必须与定义一致,
# 否则 declare i32 + define {i64,i64,i64} → llc "value doesn't
# match function result type"——GetMemoryStats 根因)
# @c.CReturn 装饰器已移除:遇到即编译期报错(多返回值改用 -> tuple[...])
if ret_ty is None:
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans)
self.Gen.FuncGenBase.RejectCReturnDecorator(fd, fd.decorator_list)
if ret_ty is None and fd.returns is not None:
# 有返回注解但解析失败:编译期报错,不静默回退 i32。
# (i32 回退曾导致掉尾检查强制 return i32 / 跨模块调用返回类型错位,
@@ -336,13 +334,9 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0:
ret_ty = llvmlite.Void(pool)
# @c.CReturn(ty1, ty2, ...) 装饰器 → 多返回 struct 类型
# (GetMemoryStats 根因:TPC DeclarationGenerator 处理 CReturn 为
# '{i64, i64, i64}',TPV pre_scan 前向声明阶段未实现 → 无注解函数
# declare 成 i32 → 定义阶段 ret {i64,i64,i64} 与 i32 不匹配。
# 公共方法 _resolve_creturn_ret_ty 保证声明/定义两阶段一致)
# @c.CReturn 装饰器已移除:遇到即编译期报错(多返回值改用 -> tuple[...])
if ret_ty is None:
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans)
self.Gen.FuncGenBase.RejectCReturnDecorator(fd, fd.decorator_list)
# 如果仍然为 None,扫描 return 语句推断(至少返回 i32)
if ret_ty is None: