diff --git a/App/lib/Stub/StubGen/Converter.vp b/App/lib/Stub/StubGen/Converter.vp index f8754a1..7d076bf 100644 --- a/App/lib/Stub/StubGen/Converter.vp +++ b/App/lib/Stub/StubGen/Converter.vp @@ -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 diff --git a/App/lib/core/Gen/Func/FuncGenBase.vp b/App/lib/core/Gen/Func/FuncGenBase.vp index 3f5cb16..8bef4e3 100644 --- a/App/lib/core/Gen/Func/FuncGenBase.vp +++ b/App/lib/core/Gen/Func/FuncGenBase.vp @@ -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 函数(简单版本,仅声明) # ============================================================ diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index ba04b92..73682be 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -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: