From a7af34bd7eb6c447ef7be9f4914ebfcba63fa2da Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 23 Sep 2026 17:41:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9A=84=E8=A1=A8=E8=BE=BE=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E6=9C=80=E5=90=8E=E5=8F=AF=E7=94=A8=E7=89=88=E6=9C=AC?= =?UTF-8?q?=EF=BC=8Cmlirlite=20=E5=B7=B2=E5=9F=BA=E6=9C=AC=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/AssignGenMixin.vp | 485 +++++++-------------- App/lib/core/Gen/AsyncGenMixin.vp | 504 ++++++++-------------- App/lib/core/Gen/Class/ClassGenBase.vp | 76 ++-- App/lib/core/Gen/Class/ClassGenDef.vp | 92 ++-- App/lib/core/Gen/Class/ClassGenEnum.vp | 199 +++------ App/lib/core/Gen/Class/ClassGenGeneric.vp | 59 +-- App/lib/core/Gen/Class/ClassGenMixin.vp | 6 +- App/lib/core/Gen/Class/ClassGenVTable.vp | 164 +++---- App/lib/core/Gen/Expr/ExprGenBase.vp | 152 +++---- App/lib/core/Gen/Expr/ExprGenCdef.vp | 22 +- App/lib/core/Gen/Expr/ExprGenCls.vp | 171 +++----- App/lib/core/Gen/Expr/ExprGenConst.vp | 38 +- App/lib/core/Gen/Expr/ExprGenFstr.vp | 123 ++---- App/lib/core/Gen/Expr/ExprGenMixin.vp | 88 ++-- App/lib/core/Gen/Expr/ExprGenName.vp | 420 ++++++------------ App/lib/core/Gen/Expr/ExprGenOps.vp | 211 +++------ App/lib/core/Gen/Func/FuncGenBase.vp | 235 ++++------ App/lib/core/Gen/Func/FuncGenDef.vp | 292 ++++--------- App/lib/core/Gen/Func/FuncGenMixin.vp | 368 +++++----------- App/lib/core/Gen/ImportsGenMixin.vp | 27 +- App/lib/core/Gen/MatchGenMixin.vp | 239 ++++------ App/lib/core/Gen/Stmt/StmtGenCifMixin.vp | 312 +++++--------- App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp | 48 +-- App/lib/core/Gen/Stmt/StmtGenMixin.vp | 136 ++---- App/lib/core/Gen/StructGenMixin.vp | 28 +- App/lib/core/Gen/Translator.vp | 25 +- App/lib/core/Gen/TranslatorGenMixin.vp | 115 ++--- App/lib/core/Gen/Type/TypeGenBase.vp | 40 +- App/lib/core/Gen/Type/TypeGenCDef.vp | 35 +- App/lib/core/Gen/Type/TypeGenCType.vp | 23 +- App/lib/core/Gen/Type/TypeGenErr.vp | 21 +- App/lib/core/Gen/Type/TypeGenMixin.vp | 7 +- App/lib/core/Gen/Type/TypeGenResolve.vp | 163 +++---- App/lib/core/Gen/Type/TypeSpec.vp | 249 +++++------ App/lib/core/Gen/VarGenMixin.vp | 192 +++------ App/lib/core/Repl.vp | 46 +- 36 files changed, 1755 insertions(+), 3656 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index a6b8b81..7a07469 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -468,8 +468,7 @@ novirtual class AssignGenMixin: bits: int = self._define_annot_bits(pool, annot) wmin: int = self.define_min_width(value) if self._int_text_exceeds_64(text) != 0: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {text} 超出 64 位" f"(本语言最宽的整数类型为 64 位,按有符号/无符号两种解释的可存储范围为 " f"-9223372036854775808..18446744073709551615,不存在更宽的整数类型 ⇒ 需要扩容)。" @@ -497,8 +496,7 @@ novirtual class AssignGenMixin: elif bits == 64: return if value < lo or value > hi: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {value} 不可存储。" f"最小可容纳宽度 W_min: {wmin} 位;声明类型位宽 {bits} 位," f"该声明可存储范围: {lo}..{hi}。" @@ -541,8 +539,7 @@ novirtual class AssignGenMixin: wmin: int = self.define_min_width(cdef_val) if bits >= wmin: return - self.Gen.TypeGenErr.fatal_error( - value_node, + self.Gen.TypeGenErr.fatal_error(value_node, f"[TPV] define 常量使用处宽度不足: 常量 '{rn.id}' 的实际值 {cdef_val} " f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," f"但使用处(变量声明注解)只提供 {bits} 位。" @@ -1095,28 +1092,24 @@ novirtual class AssignGenMixin: if sv_s is not None: n_s: sizet = string.strlen(sv_s) if sizet(arr_count) < n_s: - self.Gen.TypeGenErr.fatal_error( - list_node, + self.Gen.TypeGenErr.fatal_error(list_node, f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", "OverflowError") bi_s: sizet = 0 while bi_s < n_s: bidx_s: llvmlite.Value* = llvmlite.const_int32(pool, bi_s) - bp_s: llvmlite.Value* = llvmlite.build_gep_array( - builder, arr_ty, elem_ty, array_alloca, bidx_s) + bp_s: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, bidx_s) if bp_s is None: break bvv: llvmlite.Value* = llvmlite.const_int32(pool, sv_s[bi_s]) - bsv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, bvv, elem_ty, e0_s) + bsv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, bvv, elem_ty, e0_s) llvmlite.build_store(builder, bsv, bp_s) bi_s += 1 return 0 # 元素数超过声明长度 → fail-fast(否则会生成 idx>=N 的越界 GEP 写) if arr_count > 0 and sizet(arr_count) < elts_count: - self.Gen.TypeGenErr.fatal_error( - list_node, + self.Gen.TypeGenErr.fatal_error(list_node, f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许越界写入", "OverflowError") @@ -1163,8 +1156,7 @@ novirtual class AssignGenMixin: if list_node is not None: src_line = list_node.lineno src_col = list_node.col_offset - self.Gen.TypeGenErr.fatal_error( - list_node, + self.Gen.TypeGenErr.fatal_error(list_node, f"全局数组初始化遇到空 AST 元素:{ctx_dbg}第 {i} 个元素为裸空指针(0)," f"但列表元素计数为 {elts_count}(元素与计数不一致)。" f"上层某处产生了空 AST 元素(列表字面量节点 {src_line}:{src_col} 的第 {i} 槽未被填充)," @@ -1191,8 +1183,7 @@ novirtual class AssignGenMixin: if list_node is not None: vt_line = list_node.lineno vt_col = list_node.col_offset - self.Gen.TypeGenErr.fatal_error( - list_node, + self.Gen.TypeGenErr.fatal_error(list_node, f"全局数组初始化遇到【对象无效】的 AST 元素(vptr 为 0):{ctx_vt}" f"第 {i} 个元素指针非 0(地址 {uint64(elem_node)})但其对象首字(vtable 指针)为 0," f"对它的任何虚调用(kind()/dump()/…) 都会在 `load [0+slot]` 处读地址 0。" @@ -1202,8 +1193,7 @@ novirtual class AssignGenMixin: "ValueError", vt_col) return 1 idx_val: llvmlite.Value* = llvmlite.const_int32(pool, i) - elem_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, arr_ty, elem_ty, array_alloca, idx_val) + elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, idx_val) if elem_ptr is None: continue # 内层嵌套数组:元素类型是数组且元素节点是列表字面量 → 递归数组初始化 @@ -1217,8 +1207,7 @@ novirtual class AssignGenMixin: if inner_arr != 0: self._init_global_array_from_list(builder, pool, mod, elem_ptr, elem_node, trans, owner_ctx) continue - elem_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, elem_node, None, 0, trans) + elem_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node, None, 0, trans) if elem_val is None: # 元素翻译失败:直接报错终止(fail-fast),暴露上游根因 self.Gen.TypeGenErr.fatal_error(elem_node, "全局数组初始化元素翻译失败", "TypeError") @@ -1227,8 +1216,7 @@ novirtual class AssignGenMixin: # 写成 `is not None` 会被折成常量 true(IR 见上方 1146-1156 注释)。 store_val: llvmlite.Value* = elem_val if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee != 0: - store_val = self.Gen.ExprGenBase.coerce_to_type( - builder, elem_val, elem_ptr.Ty.Pointee, elem_node) + store_val = self.Gen.ExprGenBase.coerce_to_type(builder, elem_val, elem_ptr.Ty.Pointee, elem_node) llvmlite.build_store(builder, store_val, elem_ptr) return 0 @@ -1362,8 +1350,7 @@ novirtual class AssignGenMixin: def const_assign_fail(self, node: ast.AST*, kind: str, name: str, src_name: str) -> int: """const 目标被写入 → 立即 fail-fast(不降级为警告、不静默继续)。""" - self.Gen.TypeGenErr.fatal_error( - node, self.const_assign_msg(kind, name, src_name), "TypeError") + self.Gen.TypeGenErr.fatal_error(node, self.const_assign_msg(kind, name, src_name), "TypeError") return 0 def translate_augassign(self, trans: HT.Translator*, @@ -1392,14 +1379,12 @@ novirtual class AssignGenMixin: # const 字段:+= 与 TPC 的 `obj.f = ...` 同一条 fail-fast(字段赋值) at_ca: ast.Attribute* = ast.Attribute*(target) if at_ca is not None and at_ca.attr is not None: - if self.Gen.ExprGenAttr.attr_field_is_const( - pool, trans, target) != 0: + if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, target) != 0: self.const_assign_fail(target, "字段赋值", at_ca.attr, self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, target)) # 1. 获取字段指针 - field_ptr: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, target, trans) + field_ptr: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, target, trans) if field_ptr is None: # fail-fast: 属性指针解析失败 self.Gen.TypeGenErr.fatal_error(target, "attribute ptr is None", "TypeError") @@ -1417,25 +1402,21 @@ novirtual class AssignGenMixin: # 字段 += 的 load/store 亦带 volatile(两来源取或)。 at_aug: ast.Attribute* = ast.Attribute*(target) if at_aug is not None: - if self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, at_aug.value) != 0: + if self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, at_aug.value) != 0: vol_fa = 1 - cur_val: llvmlite.Value* = llvmlite.build_load( - builder, target_ty, field_ptr, vol_fa) + cur_val: llvmlite.Value* = llvmlite.build_load(builder, target_ty, field_ptr, vol_fa) if cur_val is None: # fail-fast: 属性当前值加载失败 self.Gen.TypeGenErr.fatal_error(target, "无法加载 attribute 当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aug.value, None, 0, trans) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aug.value, None, 0, trans) if rhs_val is None: # fail-fast: RHS 翻译失败 self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError") # 4. 应用二元运算 - result: llvmlite.Value* = self._apply_aug_op( - pool, builder, aug.op, cur_val, rhs_val, node, trans, target) + result: llvmlite.Value* = self._apply_aug_op(pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: attribute 二元运算失败 self.Gen.TypeGenErr.fatal_error(target, f"attribute 二元运算失败 op={aug.op}", "TypeError") @@ -1470,15 +1451,12 @@ novirtual class AssignGenMixin: elif sub_ca.value.kind() == ast.ASTKind.Attribute: at_ca2: ast.Attribute* = ast.Attribute*(sub_ca.value) if at_ca2.attr is not None: - if self.Gen.ExprGenAttr.attr_field_is_const( - pool, trans, sub_ca.value) != 0: + if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, sub_ca.value) != 0: self.const_assign_fail(target, "的元素赋值", at_ca2.attr, - self.Gen.ExprGenAttr.attr_field_decl_src( - pool, trans, sub_ca.value)) + self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_ca.value)) # 1. 获取元素指针 - elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( - builder, pool, mod, target, trans) + elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, target, trans) if elem_ptr is None: # fail-fast: 下标指针解析失败 self.Gen.TypeGenErr.fatal_error(target, "subscript ptr is None", "TypeError") @@ -1495,24 +1473,20 @@ novirtual class AssignGenMixin: vol_sa: int = 0 sub_aug: ast.Subscript* = ast.Subscript*(target) if sub_aug is not None: - vol_sa = self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, sub_aug.value) - cur_val: llvmlite.Value* = llvmlite.build_load( - builder, target_ty, elem_ptr, vol_sa) + vol_sa = self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, sub_aug.value) + cur_val: llvmlite.Value* = llvmlite.build_load(builder, target_ty, elem_ptr, vol_sa) if cur_val is None: # fail-fast: 元素当前值加载失败 self.Gen.TypeGenErr.fatal_error(target, "无法加载 subscript 元素当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aug.value, None, 0, trans) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aug.value, None, 0, trans) if rhs_val is None: # fail-fast: RHS 翻译失败 self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError") # 4. 应用二元运算 - result: llvmlite.Value* = self._apply_aug_op( - pool, builder, aug.op, cur_val, rhs_val, node, trans, target) + result: llvmlite.Value* = self._apply_aug_op(pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: subscript 二元运算失败 self.Gen.TypeGenErr.fatal_error(target, f"subscript 二元运算失败 op={aug.op}", "TypeError") @@ -1527,16 +1501,14 @@ novirtual class AssignGenMixin: if tk != ast.ASTKind.Name: # fail-fast: 不支持的 AugAssign 目标类型 - self.Gen.TypeGenErr.fatal_error( - target, "AugAssign 目标类型不支持,仅支持 Name/Attribute/Subscript", "TypeError") + self.Gen.TypeGenErr.fatal_error(target, "AugAssign 目标类型不支持,仅支持 Name/Attribute/Subscript", "TypeError") nm: ast.Name* = ast.Name*(target) if nm is None or nm.id is None: return 0 # const 变量:+= 立即 fail-fast(与 TPC HandlesAugAssign 同判据/同报文) - ve_aug: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + ve_aug: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if self.Gen.VarGen.var_is_const(ve_aug) != 0: self.const_assign_fail(target, "增量赋值", nm.id, self.Gen.VarGen.var_annot_class_name(ve_aug)) @@ -1548,8 +1520,7 @@ novirtual class AssignGenMixin: # 按普通局部变量路径处理(不写会话槽)。 if trans.ReplCtx is not None \ and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0: - if self.Gen.VarGen.repl_try_augassign( - trans, nm.id, aug.op, aug.value, node) != 0: + if self.Gen.VarGen.repl_try_augassign(trans, nm.id, aug.op, aug.value, node) != 0: return 0 pool: memhub.MemBuddy* = trans.Pool @@ -1564,8 +1535,7 @@ novirtual class AssignGenMixin: scope_type = 2 # t.CVolatile 变量:+= 的 load 与 store 均带 volatile 限定符 - vol_aa: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_aa: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) # 2. 加载当前值 cur_val: llvmlite.Value* = None @@ -1601,20 +1571,17 @@ novirtual class AssignGenMixin: self.Gen.TypeGenErr.fatal_error(target, f"无法加载目标变量 '{nm.id}' 的当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aug.value, None, 0, trans) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aug.value, None, 0, trans) if rhs_val is None: # fail-fast: RHS 翻译失败 self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError") # 4. 类型对齐 + 应用二元运算 # 注意: AugAssign 不走运算符重载(语义上需要 __iadd__ 而非 __add__) - result: llvmlite.Value* = self._apply_aug_op( - pool, builder, aug.op, cur_val, rhs_val, node, trans, target) + result: llvmlite.Value* = self._apply_aug_op(pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: 二元运算失败 - self.Gen.TypeGenErr.fatal_error( - target, + self.Gen.TypeGenErr.fatal_error(target, f"对变量 '{nm.id}' 应用二元运算失败 op={aug.op}", "TypeError") @@ -1630,8 +1597,7 @@ novirtual class AssignGenMixin: llvmlite.build_store(builder, result, target_alloca, vol_aa) elif scope_type == 2: # nonlocal 变量 - nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( - trans, nm.id) + nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(trans, nm.id) if nl_ptr is not None: llvmlite.build_store(builder, result, nl_ptr) else: @@ -1831,8 +1797,7 @@ novirtual class AssignGenMixin: return 0 # 检查是否已存在 - existing: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, nm.id) + existing: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) if existing is not None: return 0 @@ -1851,8 +1816,7 @@ novirtual class AssignGenMixin: # i32→AST* 截断指针 → StmtGenMixin._translate_stmt_impl 读垃圾节点崩溃。 # 与 Handle 路径共用 _prespecialize_generic_annotation,保证两处解析一致。 self._prespecialize_generic_annotation(trans, pool, annot) - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, annot, trans._imported_modules, trans._from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, annot, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: var_ty = resolved # 单参 t.CArray[elem_ty] + 列表字面量 → 静态数组(与 Handle 推断一致)。 @@ -1863,48 +1827,36 @@ novirtual class AssignGenMixin: self._fail_on_degenerated_generic_annotation(aa, nm.id, annot, var_ty) else: # fast-fail: 注解类型解析失败,Python traceback 立即终止(不静默回退 i32) - self.Gen.TypeGenErr.fatal_error( - aa, - self._build_ann_fail_msg(pool, annot, nm.id), - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, self._build_ann_fail_msg(pool, annot, nm.id), "TypeError") else: # fail-fast: AnnAssign 必须有 annotation,缺少时立即终止(禁止兜底 i32) - self.Gen.TypeGenErr.fatal_error( - aa, - f"AnnAssign 缺少类型注解,变量名: {nm.id}", - "SyntaxError") + self.Gen.TypeGenErr.fatal_error(aa, f"AnnAssign 缺少类型注解,变量名: {nm.id}", "SyntaxError") # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, trans.Module, var_ty) alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, var_ty) if alloca is not None: - if self.Gen.VarGen.define_var( - trans.SymTab, nm.id, alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, nm.id, alloca) == 0: # 存储原始类型注解的类名(方法调用检测时 Ptr(i8) 回退按类名查结构体)。 # 传 pool:泛型 Subscript 返回 mangled 特化名;pool=None 只得裸模板名, # 模板未注册时属性访问会报"类未注册"。 if annot is not None: - cls_nm_ps: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - annot, trans._imported_modules, pool, trans._from_imports) + cls_nm_ps: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(annot, trans._imported_modules, pool, trans._from_imports) if cls_nm_ps is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, nm.id, cls_nm_ps) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, nm.id, cls_nm_ps) # 检查是否为 bytes|t.CPtr 或 str|t.CPtr(i8** 语义,8 字节步长) if self._is_ptr_element_annotation(annot) != 0: - self.Gen.VarGen.set_var_ptr_element( - trans.SymTab, nm.id) + self.Gen.VarGen.set_var_ptr_element(trans.SymTab, nm.id) # const 对象(注解含 t.CConst 且声明类型非指针):整个作用域内 # 禁止对该变量名赋值/增量赋值/元素赋值。判据与 TPC 的 # BaseGen._IsConstObject 逐条一致(见 Debugger/type-descriptors.md)。 - if self.Gen.TypeGenErr.is_const_object_marker( - annot, var_ty) != 0: + if self.Gen.TypeGenErr.is_const_object_marker(annot, var_ty) != 0: self.Gen.VarGen.set_var_const(trans.SymTab, nm.id) # t.CVolatile:声明期即标记该变量的 load/store 带 volatile。 # 覆盖「无初值声明」`x: t.CVolatile | T`(有初值路径 # translate_annassign 亦会登记,幂等)。动机:volatile 禁优化器 # 把忙等循环的重复 load 提升/消除,不能依赖优化器保序。 - if self.Gen.TypeGenErr.has_decorator_marker( - annot, "CVolatile", 0) != 0: + if self.Gen.TypeGenErr.has_decorator_marker(annot, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile(trans.SymTab, nm.id) # rawptr[t.CVolatile | T](volatile 指针指向物,等价 C 的 # volatile T*):解引用(p[i]/p.field/c.Deref(p))的 load/store @@ -1950,12 +1902,10 @@ novirtual class AssignGenMixin: template_cd: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(sub_nm.id) if template_cd is None: return 0 - type_args_ps: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice( - pool, spec_annot.slice, trans._from_imports) + type_args_ps: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, spec_annot.slice, trans._from_imports) if type_args_ps is None or len(type_args_ps) == 0: return 0 - self.Gen.ClassGenGeneric._specialize_generic_class( - trans, sub_nm.id, type_args_ps) + self.Gen.ClassGenGeneric._specialize_generic_class(trans, sub_nm.id, type_args_ps) return 1 # ============================================================ @@ -2015,8 +1965,7 @@ novirtual class AssignGenMixin: vt_short_ff: str = vt_nm_ff + vt_pf_ff if vt_pf_ff != 0 else vt_nm_ff if string.strchr(vt_short_ff, '[') is not None: return 0 # 带类型实参:未退化 - self.Gen.TypeGenErr.fatal_error( - aa, + self.Gen.TypeGenErr.fatal_error(aa, f"变量 '{var_name}' 的泛型注解 '{base_nm_ff.id}[...]' 解析成了裸基类 " f"'{vt_nm_ff}*'(丢失类型实参);后续 .get()/.set() 会按错误元素类型" f"特化(如 list[int].get 返回 i32)→ inttoptr 截断指针崩溃。" @@ -2076,8 +2025,7 @@ novirtual class AssignGenMixin: rp_e: rawptr[GenTypes.ReplVarEntry] = \ self.Gen.VarGen.repl_ensure_entry(trans, nm.id, aa) if rp_e is not None: - self.Gen.VarGen.repl_try_annassign( - trans, nm.id, aa.annotation, aa.value, aa) + self.Gen.VarGen.repl_try_annassign(trans, nm.id, aa.annotation, aa.value, aa) return 0 pool: memhub.MemBuddy* = trans.Pool @@ -2092,38 +2040,32 @@ novirtual class AssignGenMixin: # 误分派(返回 i32 → inttoptr 截断)。此处为循环体内重声明同名变量、 # 不复用预扫描 alloca 的路径(详见 _prespecialize_generic_annotation)。 self._prespecialize_generic_annotation(trans, pool, annot) - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, annot, trans._imported_modules, trans._from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, annot, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: var_ty = resolved else: # fast-fail: 注解类型解析失败,Python traceback 立即终止(不静默回退 i32) - self.Gen.TypeGenErr.fatal_error( - aa, + self.Gen.TypeGenErr.fatal_error(aa, self._build_ann_fail_msg(pool, annot, nm.id), "TypeError") else: # fail-fast: AnnAssign 必须有 annotation,缺少时立即终止(禁止兜底 i32) - self.Gen.TypeGenErr.fatal_error( - aa, + self.Gen.TypeGenErr.fatal_error(aa, f"AnnAssign 缺少类型注解,变量名: {nm.id}", "SyntaxError") # t.Callable 函数指针:注册返回类型签名(供函数指针间接调用精确返回类型) - callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret( - pool, annot, trans._imported_modules, trans._from_imports, trans) + callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot, trans._imported_modules, trans._from_imports, trans) if callable_ret is not None: # 返回值:0=成功/同名同类型幂等命中;非 0 已在 register_func_ptr_sig # 内部 fatal_error(表满/同名不同类型/表分配失败)终止编译。此处分支 # 仅为防御——报错通道异常时不带着未登记的签名继续翻译。 - if self.Gen.CallGenLeafKit.register_func_ptr_sig( - pool, nm.id, callable_ret, aa) != 0: + if self.Gen.CallGenLeafKit.register_func_ptr_sig(pool, nm.id, callable_ret, aa) != 0: return 0 # global 变量:写入模块作用域中的全局变量 if GenApi.is_global_name(trans, nm.id) != 0: - mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm.id) + mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) if mod_alloca is not None and aa.value is not None: # P1-A(上下文位宽传播):把目标变量的类型作为 target_ty 传入, # 使整数字面量按目标位宽直接物化(如 uint64 目标 → i64 const), @@ -2139,8 +2081,7 @@ novirtual class AssignGenMixin: # 会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aa.value, + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, aa_glob_ty, "模块级全局") if rhs_val is not None: # 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象 @@ -2163,8 +2104,7 @@ novirtual class AssignGenMixin: if rhs_inner_aa is not None and rhs_inner_aa.kind() == llvmlite.LLVMType.Struct \ and self._stg_ty_equal(pool, stg_ty_aa, rhs_inner_aa) != 0: llvmlite.build_store(builder, stg_ref_aa, mod_alloca) - stg_obj_val_aa: llvmlite.Value* = llvmlite.build_load( - builder, stg_ty_aa, rhs_val) + stg_obj_val_aa: llvmlite.Value* = llvmlite.build_load(builder, stg_ty_aa, rhs_val) if stg_obj_val_aa is not None: llvmlite.build_store(builder, stg_obj_val_aa, stg_ref_aa) # 清除赋值上下文(防残留):与主分支清空时机同款—— @@ -2178,8 +2118,7 @@ novirtual class AssignGenMixin: if target_ty is not None: rhs_val = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, target_ty, node, trans) # t.CVolatile(global 声明)全局:初始化 store 带 volatile 限定符 - vol_gaa: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_gaa: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) llvmlite.build_store(builder, rhs_val, mod_alloca, vol_gaa) # 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 / # 本 global 分支 / 下方 mod_glob 分支 / 下方 nonlocal 分支)必须同步清除, @@ -2194,8 +2133,7 @@ novirtual class AssignGenMixin: # P1-A:先把 nonlocal 槽位指针取出(原先在 RHS 翻译之后),以便把 # 槽位类型作为 target_ty 传入;槽位/类型缺失时直接返回,不再发射 # 无用的 RHS 死值。 - nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( - trans, nm.id) + nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(trans, nm.id) # 从 nl_ptr 的类型推断 nonlocal 变量实际类型, # 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏) nl_target_ty: llvmlite.LLVMType* = None @@ -2208,23 +2146,19 @@ novirtual class AssignGenMixin: # `nonlocal s: Stack[int] = Stack()` 的类型实参推断会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aa.value, + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, nl_target_ty, "闭包变量(nonlocal)") if rhs_val is not None: if nl_ptr is not None: if nl_target_ty is None: # fast-fail: nl_ptr 类型信息丢失,无法安全 store - VLogger.error( - f"nonlocal 变量类型信息丢失,无法写入: {nm.id}", - "HandlesAnnAssign") + VLogger.error(f"nonlocal 变量类型信息丢失,无法写入: {nm.id}", "HandlesAnnAssign") # 清除赋值上下文(防残留):与主分支清空时机同款—— # 提前 return 前必须清,否则泄漏到后续语句 trans.CurAssignAnnot = None trans.CurAssignNode = None return 0 - rhs_coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, nl_target_ty, node) + rhs_coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, nl_target_ty, node) llvmlite.build_store(builder, rhs_coerced, nl_ptr) # 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 / # global / mod_glob / 本 nonlocal 分支)必须同步清除,否则残留注解会 @@ -2237,16 +2171,14 @@ novirtual class AssignGenMixin: # Python 语义:仅模块级代码(Current == Root)时修改全局变量; # 函数内无 global 声明时应创建局部变量(走后面的 get_or_create_sym 路径)。 if self.Gen.VarGen.is_module_scope(trans.SymTab) != 0: - mod_glob: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm.id) + mod_glob: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) else: mod_glob = None if mod_glob is not None: if aa.value is not None: # 列表字面量 → 逐元素 GEP + store 初始化数组 if aa.value.kind() == ast.ASTKind.List: - self._init_global_array_from_list( - builder, pool, mod, mod_glob, aa.value, trans) + self._init_global_array_from_list(builder, pool, mod, mod_glob, aa.value, trans) else: # P1-A:模块级全局目标类型作为 target_ty(同上方 global 分支) mg_val_ty: llvmlite.LLVMType* = None @@ -2258,9 +2190,7 @@ novirtual class AssignGenMixin: # global / 本 mod_glob 分支 / 上方 nonlocal 分支)必须同步。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val_mg: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aa.value, - None, 0, trans, mg_val_ty, "模块级全局") + rhs_val_mg: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, mg_val_ty, "模块级全局") if rhs_val_mg is not None: # 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象 stg_ref_mg: llvmlite.Value* = None @@ -2282,8 +2212,7 @@ novirtual class AssignGenMixin: if rhs_inner_mg is not None and rhs_inner_mg.kind() == llvmlite.LLVMType.Struct \ and self._stg_ty_equal(pool, stg_ty_mg, rhs_inner_mg) != 0: llvmlite.build_store(builder, stg_ref_mg, mod_glob) - stg_obj_val_mg: llvmlite.Value* = llvmlite.build_load( - builder, stg_ty_mg, rhs_val_mg) + stg_obj_val_mg: llvmlite.Value* = llvmlite.build_load(builder, stg_ty_mg, rhs_val_mg) if stg_obj_val_mg is not None: llvmlite.build_store(builder, stg_obj_val_mg, stg_ref_mg) # 清除赋值上下文(防残留):与主分支清空时机同款, @@ -2297,8 +2226,7 @@ novirtual class AssignGenMixin: if target_ty_mg is not None: rhs_val_mg = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val_mg, target_ty_mg, node) # t.CVolatile 模块级全局:初始化 store 带 volatile 限定符 - vol_mga: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_mga: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) llvmlite.build_store(builder, rhs_val_mg, mod_glob, vol_mga) # 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 / # 上方 global 分支 / 本 mod_glob 分支 / 上方 nonlocal 分支)必须同步清除, @@ -2316,14 +2244,10 @@ novirtual class AssignGenMixin: # 普通局部变量 # 创建 alloca - alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym( - trans.SymTab, pool, builder, nm.id, var_ty) + alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym(trans.SymTab, pool, builder, nm.id, var_ty) if alloca is None: # fail-fast: 存储创建失败,立即终止(禁止静默跳过) - self.Gen.TypeGenErr.fatal_error( - aa, - f"无法为变量 {nm.id} 创建存储", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"无法为变量 {nm.id} 创建存储", "TypeError") # 复用到的 alloca 类型必须与本次注解解析类型一致:get_or_create_sym 只用 # 「名字 + 作用域」复用(ty 不参与判定,见 VarGenMixin),可能命中类型不同的 # 旧 alloca(同名重声明 / 退化 alloca,如裸 list* 对上 list[ast.ASTptr]*)。 @@ -2348,8 +2272,7 @@ novirtual class AssignGenMixin: if string.strchr(av_short, '[') is None: av_tpl: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(av_short) if av_tpl is not None: - self.Gen.TypeGenErr.fatal_error( - aa, + self.Gen.TypeGenErr.fatal_error(aa, f"变量 '{nm.id}' 复用到的存储类型为裸泛型基类 '{av_nm_d}*'" f"(丢了类型实参),与注解解析类型 '{vt_nm_d}*' 不一致;" f"禁止静默混用——方法调用会按错误元素类型特化并截断指针", @@ -2376,30 +2299,22 @@ novirtual class AssignGenMixin: fd_meta_name = pool.alloc(256) if fd_meta_name is not None: viperlib.snprintf(fd_meta_name, 256, "%s__meta__", nm.id) - fd_meta_alloca = self.Gen.VarGen.get_or_create_sym( - trans.SymTab, pool, builder, fd_meta_name, fd_str_ty) + fd_meta_alloca = self.Gen.VarGen.get_or_create_sym(trans.SymTab, pool, builder, fd_meta_name, fd_str_ty) if fd_meta_alloca is None: # fail-fast: 影子存储创建失败,立即终止 - self.Gen.TypeGenErr.fatal_error( - aa, - f"无法为 str 影子变量 {fd_meta_name} 创建存储", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"无法为 str 影子变量 {fd_meta_name} 创建存储", "TypeError") # 存储原始类型注解的类名(方法调用检测时,Ptr(i8) 回退到类名查找结构体) # 传 pool:泛型 Subscript 返回 mangled name(对齐 L401 同根因修复) if annot is not None: - cls_nm_hd: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - annot, trans._imported_modules, pool, trans._from_imports) + cls_nm_hd: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(annot, trans._imported_modules, pool, trans._from_imports) if cls_nm_hd is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, nm.id, cls_nm_hd) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, nm.id, cls_nm_hd) # 检查是否为 bytes|t.CPtr 或 str|t.CPtr(i8** 语义,8 字节步长) if self._is_ptr_element_annotation(annot) != 0: - self.Gen.VarGen.set_var_ptr_element( - trans.SymTab, nm.id) + self.Gen.VarGen.set_var_ptr_element(trans.SymTab, nm.id) new_vars: int = 0 - existing: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, nm.id) + existing: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) if existing is None: new_vars = 1 @@ -2437,12 +2352,10 @@ novirtual class AssignGenMixin: if self.Gen.ExprGenBase.is_array_type(pt_l) != 0: local_arr_ty = pt_l if local_arr_ty is not None: - zero_arr: llvmlite.Value* = llvmlite.ConstZero( - pool, local_arr_ty) + zero_arr: llvmlite.Value* = llvmlite.ConstZero(pool, local_arr_ty) if zero_arr is not None: llvmlite.build_store(builder, zero_arr, alloca) - self._init_global_array_from_list( - builder, pool, mod, alloca, aa.value, trans) + self._init_global_array_from_list(builder, pool, mod, alloca, aa.value, trans) else: # 供裸名泛型构造从注解推断类型实参(消费者见 CallGenCtor.vp 的 # CurAssignNode 判定:`s: Stack[int] = Stack()` 用注解里的 int 特化)。 @@ -2456,9 +2369,7 @@ novirtual class AssignGenMixin: lv_target_ty: llvmlite.LLVMType* = None if alloca.Ty is not None: lv_target_ty = alloca.Ty.Pointee - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, aa.value, - None, 0, trans, lv_target_ty, "局部变量注解") + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, lv_target_ty, "局部变量注解") if rhs_val is not None: # 注解退化修复(对齐 TPC 从构造结果推断类型):无实参泛型模板注解 # 会让 alloca 退化为 Ptr(i8),而 rhs 构造返回精确结构体指针 → 用 rhs @@ -2523,11 +2434,9 @@ novirtual class AssignGenMixin: if alloca_pt is not None and \ uint64(alloca_pt) != uint64(precise_rhs_ty) \ and rb_is_bare_generic == 0: - new_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry( - builder, precise_rhs_ty) + new_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, precise_rhs_ty) if new_alloca is not None: - v_entry_rb: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + v_entry_rb: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if v_entry_rb is not None: v_entry_rb.Alloca = new_alloca alloca = new_alloca @@ -2543,17 +2452,14 @@ novirtual class AssignGenMixin: if aa.annotation is not None and nm.id is not None: # const 对象局部变量:登记 VarEntry.IsConst(与 prescan 幂等)。 # 用 alloca 的值类型(target_ty)判指针性,判据同 TPC。 - if self.Gen.TypeGenErr.is_const_object_marker( - aa.annotation, target_ty) != 0: + if self.Gen.TypeGenErr.is_const_object_marker(aa.annotation, target_ty) != 0: self.Gen.VarGen.set_var_const(trans.SymTab, nm.id) - if self.Gen.TypeGenErr.has_decorator_marker( - aa.annotation, "CVolatile", 0) != 0: + if self.Gen.TypeGenErr.has_decorator_marker(aa.annotation, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile(trans.SymTab, nm.id) vol_laa = 1 # rawptr[t.CVolatile | T](volatile 指针指向物):登记 # PointeeVolatile;本 store 写的是指针变量自身,不影响。 - if self.Gen.TypeGenErr.has_pointee_volatile_marker( - aa.annotation) != 0: + if self.Gen.TypeGenErr.has_pointee_volatile_marker(aa.annotation) != 0: self.Gen.VarGen.set_var_pointee_volatile(trans.SymTab, nm.id) llvmlite.build_store(builder, rhs_val, alloca, vol_laa) # FakeDuck: 初始化影子结构体 __data__ 字段 = 初始字符串指针 @@ -2563,9 +2469,7 @@ novirtual class AssignGenMixin: self.Gen.StructGen.lookup_field(fd_str_ty, "__data__") if fd_data_fe is not None: fd_data_ptr: llvmlite.Value* = \ - llvmlite.build_gep_struct( - builder, fd_str_ty, fd_data_fe.Ty, - fd_meta_alloca, fd_data_fe.Index) + llvmlite.build_gep_struct(builder, fd_str_ty, fd_data_fe.Ty, fd_meta_alloca, fd_data_fe.Index) if fd_data_ptr is not None: llvmlite.build_store(builder, rhs_val, fd_data_ptr) # 清除赋值上下文(防残留):CurAssignAnnot/CurAssignNode 只在该 @@ -2582,18 +2486,15 @@ novirtual class AssignGenMixin: fd_buddy_fe: GenTypes.FieldEntry* = \ self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__") if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None: - fd_null: llvmlite.Value* = llvmlite.ConstNull( - pool, fd_buddy_fe.Ty, "null") + fd_null: llvmlite.Value* = llvmlite.ConstNull(pool, fd_buddy_fe.Ty, "null") fd_buddy_ptr: llvmlite.Value* = \ - llvmlite.build_gep_struct( - builder, fd_str_ty, fd_buddy_fe.Ty, + llvmlite.build_gep_struct(builder, fd_str_ty, fd_buddy_fe.Ty, fd_meta_alloca, fd_buddy_fe.Index) if fd_buddy_ptr is not None and fd_null is not None: llvmlite.build_store(builder, fd_null, fd_buddy_ptr) # FakeDuck: with 上下文自动注入 requires 字段(如 __mbuddy__)。 # 跨 Mixin 经 self.Gen 调用 CallGenFd._inject_requires_fields。 - self.Gen.CallGenFd._inject_requires_fields( - trans, pool, builder, mod, fd_meta_alloca, "_str") + self.Gen.CallGenFd._inject_requires_fields(trans, pool, builder, mod, fd_meta_alloca, "_str") return 0 @@ -2634,8 +2535,7 @@ novirtual class AssignGenMixin: nm_c: ast.Name* = ast.Name*(tgt_c) if nm_c.id is None: continue - ve_c: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_c.id) + ve_c: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_c.id) if self.Gen.VarGen.var_is_const(ve_c) != 0: self.const_assign_fail(tgt_c, "赋值", nm_c.id, self.Gen.VarGen.var_annot_class_name(ve_c)) @@ -2654,8 +2554,7 @@ novirtual class AssignGenMixin: nm_c2: ast.Name* = ast.Name*(sub_c.value) if nm_c2.id is None: continue - ve_c2: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_c2.id) + ve_c2: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_c2.id) if self.Gen.VarGen.var_is_const(ve_c2) != 0: self.const_assign_fail(tgt_c, "的元素赋值", nm_c2.id, self.Gen.VarGen.var_annot_class_name(ve_c2)) @@ -2663,11 +2562,9 @@ novirtual class AssignGenMixin: at_c2: ast.Attribute* = ast.Attribute*(sub_c.value) if at_c2.attr is None: continue - if self.Gen.ExprGenAttr.attr_field_is_const( - pool, trans, sub_c.value) != 0: + if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, sub_c.value) != 0: self.const_assign_fail(tgt_c, "的元素赋值", at_c2.attr, - self.Gen.ExprGenAttr.attr_field_decl_src( - pool, trans, sub_c.value)) + self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_c.value)) # 翻译 RHS 值 # 无注解赋值无目标类型可推断,清空 CurAssignAnnot/CurAssignNode @@ -2684,11 +2581,9 @@ novirtual class AssignGenMixin: if asg_t0 is not None and asg_t0.kind() == ast.ASTKind.Name: asg_nm0: ast.Name* = ast.Name*(asg_t0) if asg_nm0.id is not None: - asg_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, asg_nm0.id) + asg_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, asg_nm0.id) if asg_slot is None: - asg_slot = self.Gen.VarGen.lookup_module_var( - trans.SymTab, asg_nm0.id) + asg_slot = self.Gen.VarGen.lookup_module_var(trans.SymTab, asg_nm0.id) if asg_slot is not None and asg_slot.Ty is not None: asg_target_ty = asg_slot.Ty.Pointee elif trans.ReplCtx is not None \ @@ -2701,8 +2596,7 @@ novirtual class AssignGenMixin: if asg_re is not None \ and asg_re.Kind != GenTypes.REPL_KIND_UNTYPED: asg_target_ty = self.Gen.VarGen.repl_slot_ty(pool, asg_re) - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, asgn.value, None, 0, trans, asg_target_ty) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, asgn.value, None, 0, trans, asg_target_ty) if rhs_val is None: # 增强错误信息:包含文件名 + lineno + AST 节点详情,便于定位 if asgn.value is not None: @@ -2794,22 +2688,18 @@ novirtual class AssignGenMixin: tgt_nm2: ast.Name* = ast.Name*(tgt_elt) if tgt_nm2.id is None: continue - fp2: llvmlite.Value* = llvmlite.build_gep_struct( - builder, rhs_val.Ty, fty, tmp_s, fti) + fp2: llvmlite.Value* = llvmlite.build_gep_struct(builder, rhs_val.Ty, fty, tmp_s, fti) if fp2 is None: continue fv2: llvmlite.Value* = llvmlite.build_load(builder, fty, fp2) - tgt_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, tgt_nm2.id) + tgt_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, tgt_nm2.id) if tgt_alloca is None: - tgt_alloca = self.Gen.VarGen.get_or_create_sym( - trans.SymTab, pool, builder, tgt_nm2.id, fty) + tgt_alloca = self.Gen.VarGen.get_or_create_sym(trans.SymTab, pool, builder, tgt_nm2.id, fty) if tgt_alloca is None: continue sval: llvmlite.Value* = fv2 if tgt_alloca.Ty is not None and tgt_alloca.Ty.Pointee != 0: - sval = self.Gen.ExprGenBase.coerce_to_type( - builder, fv2, tgt_alloca.Ty.Pointee, node, trans) + sval = self.Gen.ExprGenBase.coerce_to_type(builder, fv2, tgt_alloca.Ty.Pointee, node, trans) llvmlite.build_store(builder, sval, tgt_alloca) case _: pass @@ -2819,41 +2709,34 @@ novirtual class AssignGenMixin: if tk == ast.ASTKind.Subscript: # 检查是否是 list[T] 类型的 Subscript(泛型类不注册 struct) # list 的 subscript 赋值走 __setitem__ 内联路径 - list_obj: llvmlite.Value* = self.Gen.ExprGenName.is_list_subscript( - target, trans) + list_obj: llvmlite.Value* = self.Gen.ExprGenName.is_list_subscript(target, trans) if list_obj is not None: # list[T] 类型: 内联生成 __setitem__ 逻辑 sub_node: ast.Subscript* = ast.Subscript*(target) if sub_node is not None and sub_node.slice is not None: - list_idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_node.slice, None, 0, trans) + list_idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_node.slice, None, 0, trans) if list_idx_val is None: # fail-fast: list 下标翻译失败,立即终止 self.Gen.TypeGenErr.fatal_error(target, "list 下标翻译失败", "TypeError") - self.Gen.ExprGenName.list_setitem_inline( - builder, pool, list_obj, list_idx_val, rhs_val, target) + self.Gen.ExprGenName.list_setitem_inline(builder, pool, list_obj, list_idx_val, rhs_val, target) continue # 普通 Subscript 赋值 - elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( - builder, pool, mod, target, trans) + elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, target, trans) if elem_ptr is not None: store_val: llvmlite.Value* = rhs_val # fail-fast:rawptr[T] 元素为对象 T、而 RHS 是指向 T 的指针时, # 下游 coerce_to_type 会静默 load 整对象再按 sizeof(T) 存储 # (写 sizeof(T) 而非 8 字节指针)。数组槽(t.CArray[T,N])除外。 - self._reject_whole_object_copy_into_ptr_slot( - pool, trans, target, elem_ptr, rhs_val) + self._reject_whole_object_copy_into_ptr_slot(pool, trans, target, elem_ptr, rhs_val) # 守卫短路:elem 类型完整才做类型转换 if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee != 0: - store_val = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, elem_ptr.Ty.Pointee, node, trans) + store_val = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, elem_ptr.Ty.Pointee, node, trans) # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):p[i] = v # 的 store 带 volatile。仅基址可解析到条目时为 1(否则文本不变)。 vol_sw: int = 0 sub_wr: ast.Subscript* = ast.Subscript*(target) if sub_wr is not None: - vol_sw = self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, sub_wr.value) + vol_sw = self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, sub_wr.value) llvmlite.build_store(builder, store_val, elem_ptr, vol_sw) continue # get_subscript_ptr 返回 None: 尝试 __setitem__ 运算符重载 @@ -2864,39 +2747,33 @@ novirtual class AssignGenMixin: if sub_asgn.value.kind() == ast.ASTKind.Name: sub_nm: ast.Name* = ast.Name*(sub_asgn.value) if sub_nm.id is not None: - sub_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, sub_nm.id) + sub_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, sub_nm.id) if sub_alloca is not None and sub_alloca.Ty is not None \ and sub_alloca.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0: sub_pointee: llvmlite.LLVMType* = sub_alloca.Ty.Pointee cls_nm_set: str = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee) - obj_val_set: llvmlite.Value* = llvmlite.build_load( - builder, sub_pointee, sub_alloca) + obj_val_set: llvmlite.Value* = llvmlite.build_load(builder, sub_pointee, sub_alloca) # 指针类型变量 (X|t.CPtr): sub_pointee 是 Ptr(Struct), # 需 load 获取 Ptr(Struct) 再检查 inner struct if cls_nm_set is None and obj_val_set is not None \ and self.Gen.ExprGenBase.is_ptr_type(sub_pointee) != 0 \ and sub_pointee.Pointee != 0: - cls_nm_set = self.Gen.StructGen.get_class_name_by_type( - pool, sub_pointee.Pointee) + cls_nm_set = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee.Pointee) if cls_nm_set is not None and obj_val_set is not None: - key_val_set: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_asgn.slice, None, 0, trans) + key_val_set: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.slice, None, 0, trans) if key_val_set is not None: arg_vals_set: sizet* = pool.alloc(16) if arg_vals_set is not None: arg_vals_set[0] = sizet(key_val_set) arg_vals_set[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_set, "__setitem__", + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_set, "__setitem__", obj_val_set, arg_vals_set, 2, trans) setitem_done = 1 elif sub_asgn.value.kind() == ast.ASTKind.Attribute: # self._ht[key] = val → self._ht.__setitem__(key, val) # 通过 get_attribute_ptr 获取字段指针,再调用 __setitem__ - field_ptr_set: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, sub_asgn.value, trans) + field_ptr_set: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, sub_asgn.value, trans) if field_ptr_set is not None and field_ptr_set.Ty is not None \ and field_ptr_set.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0: @@ -2908,48 +2785,39 @@ novirtual class AssignGenMixin: if cls_nm_attr is None \ and self.Gen.ExprGenBase.is_ptr_type(field_pointee_set) != 0 \ and field_pointee_set.Pointee != 0: - cls_nm_attr = self.Gen.StructGen.get_class_name_by_type( - pool, field_pointee_set.Pointee) + cls_nm_attr = self.Gen.StructGen.get_class_name_by_type(pool, field_pointee_set.Pointee) if cls_nm_attr is not None: - obj_val_attr = llvmlite.build_load( - builder, field_pointee_set, field_ptr_set) + obj_val_attr = llvmlite.build_load(builder, field_pointee_set, field_ptr_set) if cls_nm_attr is not None and obj_val_attr is not None: - key_val_attr: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_asgn.slice, None, 0, trans) + key_val_attr: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.slice, None, 0, trans) if key_val_attr is not None: arg_vals_attr: sizet* = pool.alloc(16) if arg_vals_attr is not None: arg_vals_attr[0] = sizet(key_val_attr) arg_vals_attr[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_attr, "__setitem__", + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_attr, "__setitem__", obj_val_attr, arg_vals_attr, 2, trans) setitem_done = 1 if setitem_done == 0: # 通用 fallback: 翻译 sub.value 并尝试 __setitem__ 或直接 GEP+store # 处理 Name/Attribute 之外的节点以及 SymTab 查找失败的情况 if sub_asgn is not None and sub_asgn.value is not None: - obj_val_gen: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_asgn.value, None, 0, trans) - key_val_gen: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_asgn.slice, None, 0, trans) + obj_val_gen: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.value, None, 0, trans) + key_val_gen: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.slice, None, 0, trans) if obj_val_gen is not None and key_val_gen is not None \ and obj_val_gen.Ty is not None: # 内联 _get_custom_struct_cls_nm 逻辑(避免依赖新函数) - cls_nm_gen: str = self.Gen.StructGen.get_class_name_by_type( - pool, obj_val_gen.Ty) + cls_nm_gen: str = self.Gen.StructGen.get_class_name_by_type(pool, obj_val_gen.Ty) if cls_nm_gen is None and self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \ and obj_val_gen.Ty.Pointee != 0: - cls_nm_gen = self.Gen.StructGen.get_class_name_by_type( - pool, obj_val_gen.Ty.Pointee) + cls_nm_gen = self.Gen.StructGen.get_class_name_by_type(pool, obj_val_gen.Ty.Pointee) if cls_nm_gen is not None: # 自定义结构体: 调用 __setitem__ arg_vals_gen: sizet* = pool.alloc(16) if arg_vals_gen is not None: arg_vals_gen[0] = sizet(key_val_gen) arg_vals_gen[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_gen, "__setitem__", + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_gen, "__setitem__", obj_val_gen, arg_vals_gen, 2, trans) setitem_done = 1 elif self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \ @@ -2961,16 +2829,13 @@ novirtual class AssignGenMixin: elem_ptr_gen: llvmlite.Value* = None match elem_gen: case llvmlite.LLVMType.Array(arr_elem_gen, _): - elem_ptr_gen = llvmlite.build_gep_array( - builder, elem_gen, arr_elem_gen, + elem_ptr_gen = llvmlite.build_gep_array(builder, elem_gen, arr_elem_gen, obj_val_gen, key_val_gen) case _: - elem_ptr_gen = llvmlite.build_gep( - builder, elem_gen, obj_val_gen, key_val_gen) + elem_ptr_gen = llvmlite.build_gep(builder, elem_gen, obj_val_gen, key_val_gen) if elem_ptr_gen is not None and elem_ptr_gen.Ty is not None: if elem_ptr_gen.Ty.Pointee != 0: - store_val_gen = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, elem_ptr_gen.Ty.Pointee, node) + store_val_gen = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, elem_ptr_gen.Ty.Pointee, node) llvmlite.build_store(builder, store_val_gen, elem_ptr_gen) setitem_done = 1 if setitem_done == 0: @@ -2982,8 +2847,7 @@ novirtual class AssignGenMixin: # property setter 拦截: obj.attr = v 且 attr 是 @x.setter 方法时, # 生成 call Class.attr$set(obj, v),跳过字段存储 # 注意参数顺序:_try_property_setter(pool, builder, mod, ...)。 - if self.Gen.CallGenProp._try_property_setter( - pool, builder, mod, target, rhs_val, trans) == 1: + if self.Gen.CallGenProp._try_property_setter(pool, builder, mod, target, rhs_val, trans) == 1: continue # FakeDuck: 影子结构体属性写入 (str 变量的 per-instance 字段) # a.__data__ = v → GEP {a}__meta__[field] 并 store @@ -2998,8 +2862,7 @@ novirtual class AssignGenMixin: fd_meta_w: str = pool.alloc(256) if fd_meta_w is not None: viperlib.snprintf(fd_meta_w, 256, "%s__meta__", fd_obj_nm.id) - fd_meta_vw: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, fd_meta_w) + fd_meta_vw: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, fd_meta_w) if fd_meta_vw is not None: fd_sty_w: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type("_str") @@ -3008,39 +2871,32 @@ novirtual class AssignGenMixin: self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr) if fd_fe_w is not None and fd_fe_w.Ty is not None: fd_fp_w: llvmlite.Value* = \ - llvmlite.build_gep_struct( - builder, fd_sty_w, fd_fe_w.Ty, + llvmlite.build_gep_struct(builder, fd_sty_w, fd_fe_w.Ty, fd_meta_vw, fd_fe_w.Index) if fd_fp_w is not None: sv_fd: llvmlite.Value* = \ - self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, fd_fe_w.Ty, node) + self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, fd_fe_w.Ty, node) llvmlite.build_store(builder, sv_fd, fd_fp_w) continue # VTABLE 直接写入:obj.method = func(serial0_file.open = serial0_open) # vtable 方法不是数据字段(FieldEntry),get_attribute_ptr 查不到会 # fatal_error;此处对齐 TPC HandlesAssign.py L905-949 的写时复制, # 检测到 vtable 方法时直接生成槽位写入并跳过字段路径。 - if self.Gen.CallGenVt._write_vtable_attr( - builder, pool, mod, target, rhs_val, trans) == 1: + if self.Gen.CallGenVt._write_vtable_attr(builder, pool, mod, target, rhs_val, trans) == 1: continue - field_ptr: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, target, trans) + field_ptr: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, target, trans) if field_ptr is not None: # 获取字段类型,对 rhs_val 进行类型转换(如 i32 → i64) store_val: llvmlite.Value* = rhs_val if field_ptr.Ty is not None and field_ptr.Ty.Pointee != 0: - store_val = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, field_ptr.Ty.Pointee, node, trans) + store_val = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, field_ptr.Ty.Pointee, node, trans) # t.CVolatile 字段:store 带 volatile 限定符 - vol_fw: int = self.Gen.ExprGenAttr.attr_field_is_volatile( - pool, trans, target) + vol_fw: int = self.Gen.ExprGenAttr.attr_field_is_volatile(pool, trans, target) # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):p.field = v # 的 store 亦带 volatile(两来源取或)。 at_wr: ast.Attribute* = ast.Attribute*(target) if at_wr is not None: - if self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, at_wr.value) != 0: + if self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, at_wr.value) != 0: vol_fw = 1 llvmlite.build_store(builder, store_val, field_ptr, vol_fw) continue @@ -3071,14 +2927,10 @@ novirtual class AssignGenMixin: continue # global 变量:写入模块作用域中的全局变量 if GenApi.is_global_name(trans, nm.id) != 0: - mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm.id) + mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) if mod_alloca is None: # fail-fast: global 变量未注册,无法赋值 - self.Gen.TypeGenErr.fatal_error( - target, - f"global 变量 '{nm.id}' 未注册,无法赋值", - "NameError") + self.Gen.TypeGenErr.fatal_error(target, f"global 变量 '{nm.id}' 未注册,无法赋值", "NameError") # 对象类全局(裸类名注解 → 静态 storage):对象构造/赋值 → 引用绑定 # 到 storage + 复制对象到 storage;否则 store 栈 alloca 指针悬垂, # 或模块级构造初始化器被丢弃后全局保持 NULL(见 TranslatorGenMixin)。 @@ -3103,8 +2955,7 @@ novirtual class AssignGenMixin: # 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂) llvmlite.build_store(builder, stg_ref_as, mod_alloca) # 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效) - stg_obj_val_as: llvmlite.Value* = llvmlite.build_load( - builder, stg_ty_as, rhs_val) + stg_obj_val_as: llvmlite.Value* = llvmlite.build_load(builder, stg_ty_as, rhs_val) if stg_obj_val_as is not None: llvmlite.build_store(builder, stg_obj_val_as, stg_ref_as) continue @@ -3116,21 +2967,16 @@ novirtual class AssignGenMixin: # t.CVolatile 全局:store 带 volatile 限定符 vol_gas: int = 0 if nm.id is not None: - vol_gas = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_gas = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) llvmlite.build_store(builder, rhs_val, mod_alloca, vol_gas) continue # nonlocal 变量:通过闭包 env 写入 if GenApi.is_nonlocal_name(trans, nm.id) != 0: - nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( - trans, nm.id) + nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(trans, nm.id) if nl_ptr is None: # fail-fast: nonlocal 变量指针解析失败 - self.Gen.TypeGenErr.fatal_error( - target, - f"nonlocal 变量 '{nm.id}' 指针解析失败", - "NameError") + self.Gen.TypeGenErr.fatal_error(target, f"nonlocal 变量 '{nm.id}' 指针解析失败", "NameError") # 从 nl_ptr 的类型推断 nonlocal 变量实际类型, # 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏) nl_target_ty: llvmlite.LLVMType* = None @@ -3138,12 +2984,8 @@ novirtual class AssignGenMixin: nl_target_ty = nl_ptr.Ty.Pointee if nl_target_ty is None: # fail-fast: nl_ptr 类型信息丢失,无法安全 store - self.Gen.TypeGenErr.fatal_error( - target, - f"nonlocal 变量 '{nm.id}' 类型信息丢失,无法写入", - "TypeError") - rhs_coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, nl_target_ty, node, trans) + self.Gen.TypeGenErr.fatal_error(target, f"nonlocal 变量 '{nm.id}' 类型信息丢失,无法写入", "TypeError") + rhs_coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, nl_target_ty, node, trans) llvmlite.build_store(builder, rhs_coerced, nl_ptr) continue @@ -3157,38 +2999,32 @@ novirtual class AssignGenMixin: rp_entry: rawptr[GenTypes.ReplVarEntry] = \ self.Gen.VarGen.repl_ensure_entry(trans, nm.id, target) if rp_entry is not None: - self.Gen.VarGen.repl_try_assign( - trans, nm.id, rhs_val, asgn.value, node) + self.Gen.VarGen.repl_try_assign(trans, nm.id, rhs_val, asgn.value, node) continue # 拦截:函数内对模块级全局变量赋值但没 global 声明 # 否则静默创建局部变量遮蔽全局,全局保持 null 导致运行时崩溃 # (_mbuddy = mb 缺 global 声明即此类 bug:Int32 解引用 null 崩溃) if self.Gen.VarGen.is_module_scope(trans.SymTab) == 0: - mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm.id) + mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) if mod_gv is not None: self.Gen.TypeGenErr.fatal_error(target, f"变量 '{nm.id}' 是模块级全局变量,函数内赋值需用 global 声明(否则创建局部变量遮蔽全局,导致全局保持 null 崩溃)", "SyntaxError") # 普通局部变量 - alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym( - trans.SymTab, pool, builder, nm.id, rhs_val.Ty) + alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym(trans.SymTab, pool, builder, nm.id, rhs_val.Ty) if alloca is not None: # 无注解赋值:从 RHS 表达式推断类名设置变量注解 # (联合类型 X|t.CPtr 简化为 Ptr(i8),属性访问按需过滤需要 # AnnotClassName 才能定位结构体字段) cls_inf: str = self._infer_rhs_annot(pool, mod, asgn.value, trans, rhs_val) if cls_inf is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, nm.id, cls_inf) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, nm.id, cls_inf) # 按 alloca 类型对值进行转换(如 double → float) store_val: llvmlite.Value* = rhs_val if alloca.Ty is not None and alloca.Ty.Pointee != 0: - store_val = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, alloca.Ty.Pointee, node, trans) + store_val = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, alloca.Ty.Pointee, node, trans) # t.CVolatile 局部变量:store 带 volatile 限定符 - vol_las: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_las: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) llvmlite.build_store(builder, store_val, alloca, vol_las) # lambda 表达式赋给变量:注册为闭包变量名, # 调用分派(is_closure_name)才走闭包间接调用路径; @@ -3197,16 +3033,12 @@ novirtual class AssignGenMixin: if asgn.value is not None \ and asgn.value.kind() == ast.ASTKind.Lambda: self.Gen.CallGenLeafKit.register_closure_name(nm.id) - existing: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, nm.id) + existing: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) if existing is None: new_vars += 1 else: # fail-fast: 变量存储创建失败,立即终止 - self.Gen.TypeGenErr.fatal_error( - target, - f"变量 '{nm.id}' 存储创建失败", - "TypeError") + self.Gen.TypeGenErr.fatal_error(target, f"变量 '{nm.id}' 存储创建失败", "TypeError") return new_vars @@ -3288,8 +3120,7 @@ novirtual class AssignGenMixin: if target is not None: col_s_wo = target.col_offset + 1 col_e_wo = target.end_col_offset + 1 - self.Gen.TypeGenErr.fatal_error( - target, + self.Gen.TypeGenErr.fatal_error(target, f"下标赋值的左值元素是对象 '{elem_nm_wo}'({elem_sz_wo} 字节)," f"右值却是指向 '{rhs_nm_wo}' 的指针:编译器会静默生成整对象拷贝" f"(load {elem_nm_wo} + store {elem_nm_wo},写 {elem_sz_wo} 字节)," @@ -3355,20 +3186,16 @@ novirtual class AssignGenMixin: if ca.value.kind() == ast.ASTKind.Name: mod_nm_rhs: ast.Name* = ast.Name*(ca.value) if mod_nm_rhs.id is not None: - mod_sha1_rhs: str = self.Gen.CallGenBase._lookup_module_sha1( - mod_nm_rhs.id) + mod_sha1_rhs: str = self.Gen.CallGenBase._lookup_module_sha1(mod_nm_rhs.id) if mod_sha1_rhs is not None: temp_dir_rhs: str = None if self.Gen.CallGenBase.TempDir is not None: temp_dir_rhs = self.Gen.CallGenBase.TempDir if temp_dir_rhs is not None: - VpiReader._ensure_vpi_ret_annot_loaded( - mod_sha1_rhs, temp_dir_rhs) - annot_rhs: str = VpiReader._lookup_vpi_ret_annot( - mod_sha1_rhs, None, ca.attr) + VpiReader._ensure_vpi_ret_annot_loaded(mod_sha1_rhs, temp_dir_rhs) + annot_rhs: str = VpiReader._lookup_vpi_ret_annot(mod_sha1_rhs, None, ca.attr) if annot_rhs is not None: - ret_cls_rhs: str = self._extract_annot_class_name( - pool, annot_rhs) + ret_cls_rhs: str = self._extract_annot_class_name(pool, annot_rhs) if ret_cls_rhs is not None: return ret_cls_rhs return None @@ -3385,8 +3212,7 @@ novirtual class AssignGenMixin: temp_dir = self.Gen.CallGenBase.TempDir if temp_dir is not None: VpiReader._ensure_vpi_ret_annot_loaded(cls_sha1, temp_dir) - annot_ret: str = VpiReader._lookup_vpi_ret_annot( - cls_sha1, obj_cls, ca.attr) + annot_ret: str = VpiReader._lookup_vpi_ret_annot(cls_sha1, obj_cls, ca.attr) if annot_ret is not None: ret_cls = self._extract_annot_class_name(pool, annot_ret) return ret_cls @@ -3396,8 +3222,7 @@ novirtual class AssignGenMixin: nm: ast.Name* = ast.Name*(node) if nm is None or nm.id is None: return None - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if ve is None: return None return self.Gen.VarGen.var_annot_class_name(ve) diff --git a/App/lib/core/Gen/AsyncGenMixin.vp b/App/lib/core/Gen/AsyncGenMixin.vp index b43a420..be9459b 100644 --- a/App/lib/core/Gen/AsyncGenMixin.vp +++ b/App/lib/core/Gen/AsyncGenMixin.vp @@ -55,8 +55,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): cname_buf: str = pool.alloc(64) if cname_buf is not None: viperlib.snprintf(cname_buf, 64, "create_%s", name) - create_mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, cname_buf, 0) + create_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, cname_buf, 0) if self.Gen.CallGenBase.find_func_in_module(mod, create_mangled) is not None: return 0 @@ -85,8 +84,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_nseg = 1 + trans._coro_await_count # 帧结构体 %Coro_ - frame_ty: llvmlite.LLVMType* = self._build_frame_ty( - pool, mod, trans, name, nparams, nlocals, nextra) + frame_ty: llvmlite.LLVMType* = self._build_frame_ty(pool, mod, trans, name, nparams, nlocals, nextra) if frame_ty is None: return 0 self._register_coro_frame(trans, name, frame_ty) @@ -202,7 +200,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_stmts(trans, whn.orelse) return if sk == ast.ASTKind.For: - fn2: rawptr[ast.For] = rawptr[ast.For](stmt) + fn2: ast.For* = ast.For*(stmt) self._scan_sleep_expr(trans, fn2.iter) self._scan_sleep_stmts(trans, stmt.children) self._scan_sleep_stmts(trans, fn2.orelse) @@ -338,15 +336,13 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_stmts(trans, whn.orelse) return if sk == ast.ASTKind.For: - fn_: rawptr[ast.For] = rawptr[ast.For](stmt) + fn_: ast.For* = ast.For*(stmt) if self._for_deep_await(stmt) != 0: # 含 await:必须是 range-For(M3) if self._is_range_for(stmt) == 0: err_b2: str = trans.Pool.alloc(256) if err_b2 is not None: - viperlib.snprintf( - err_b2, 256, - "[coro-M3] 协程内 For 仅支持 range 迭代(含 await)") + viperlib.snprintf(err_b2, 256, "[coro-M3] 协程内 For 仅支持 range 迭代(含 await)") self.Gen.TypeGenErr.fatal_error(stmt, err_b2, "SyntaxError") return # 填 __f_idx_N / __f_len_N(i32) @@ -502,7 +498,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): """For 语句树(含嵌套 If/While/For/Try/body/orelse)是否含 await""" if stmt is None: return 0 - fn3: rawptr[ast.For] = rawptr[ast.For](stmt) + fn3: ast.For* = ast.For*(stmt) if fn3.iter is not None and self._find_expr_await(fn3.iter) is not None: return 1 if stmt.children is not None: @@ -570,7 +566,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): """range-For:单 Name target + iter 是 range(x) 或 range(a, b),参数无 await""" if stmt is None: return 0 - fn4: rawptr[ast.For] = rawptr[ast.For](stmt) + fn4: ast.For* = ast.For*(stmt) if fn4.target is None or fn4.target.kind() != ast.ASTKind.Name: return 0 if fn4.iter is None or fn4.iter.kind() != ast.ASTKind.Call: @@ -649,7 +645,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._collect_locals_stmts(trans, whn.orelse) return if sk == ast.ASTKind.For: - fn: rawptr[ast.For] = rawptr[ast.For](stmt) + fn: ast.For* = ast.For*(stmt) if self._for_deep_await(stmt) != 0: if fn.target is not None and fn.target.kind() == ast.ASTKind.Name: tn3: ast.Name* = ast.Name*(fn.target) @@ -701,8 +697,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): 参数槽(5+i), 局部槽(5+nparams+i), 额外槽(extra_base+i, 按类型表 1=i32 2=i64)}""" i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) - i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) # 槽基址(供 resume/await 计算槽 index) trans._coro_local_base = 5 + nparams trans._coro_extra_base = trans._coro_local_base + nlocals @@ -719,8 +714,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if tidx < nextra and trans._coro_extra_types is not None: if trans._coro_extra_types[tidx] == 2: fty = i64_ty - pnode: rawptr[llvmlite.ParamNode] = pool.alloc( - llvmlite.ParamNode.__sizeof__()) + pnode: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__()) if pnode is None: continue string.memset(pnode, 0, llvmlite.ParamNode.__sizeof__()) @@ -733,13 +727,11 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): ty_name: str = pool.alloc(128) if ty_name is not None: viperlib.snprintf(ty_name, 128, "Coro_%s", name) - frame_ty: llvmlite.LLVMType* = llvmlite.Struct( - pool, head, total, ty_name) + frame_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, head, total, ty_name) if frame_ty is None: return None llvmlite.module_add_named_type(mod, pool, frame_ty) - self.Gen.StructGen.register_struct( - pool, ty_name, frame_ty, trans.ModuleSha1) + self.Gen.StructGen.register_struct(pool, ty_name, frame_ty, trans.ModuleSha1) return frame_ty # ============================================================ @@ -765,12 +757,10 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): cname_buf2: str = pool.alloc(64) if cname_buf2 is not None: viperlib.snprintf(cname_buf2, 64, "create_%s", name) - mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, cname_buf2, 0) + mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, cname_buf2, 0) if self.Gen.CallGenBase.find_func_in_module(mod, mangled) is not None: return 0 - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled, frame_ptr_ty) + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled, frame_ptr_ty) if func is None: return 0 # 参数(i32,帧槽 5+i)。TPV 无 Python % 格式化(% 是取模), @@ -784,13 +774,10 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # 注册到函数表(裸名 create_) funcs_ptr: GenTypes.FuncEntry* = trans._funcs cur_count: int = trans._func_count - if self.Gen.CallGenLeafKit.add_func_to_table( - funcs_ptr, cur_count, cname_buf2, func, 1024, - None, 0, 0, trans.Pool) == 0: + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, cname_buf2, func, 1024, None, 0, 0, trans.Pool) == 0: trans._func_count = cur_count + 1 - entry: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "entry") + entry: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") if entry is None: return 0 builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) @@ -805,72 +792,54 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): size_val.Next = None # M7 帧池:i64 池头(0 = 空);帧首 8 字节存 next(覆盖 state/done,弹池后统一清零) - pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool( - pool, mod, trans, name) + pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool(pool, mod, trans, name) # GlobalVariable 非 Value 子类:构造 Value 视图(Ty=Ptr(i64), Name="@coro_pool_") pool_ref_name: str = pool.alloc(96) if pool_ref_name is not None: viperlib.snprintf(pool_ref_name, 96, "@coro_pool_%s", name) - pool_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, i64_ptr_ty, pool_ref_name) - pool_head: llvmlite.Value* = llvmlite.build_load( - builder, i64_ty, pool_ref) - if pool_head is None: - return 0 + pool_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i64_ptr_ty, pool_ref_name) + pool_head: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, pool_ref) + if pool_head is None: return 0 zero64: llvmlite.Value* = llvmlite.const_int64(pool, 0) - empty_cond: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, pool_head, zero64) - if empty_cond is None: - return 0 - hit_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "pool.hit") - miss_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "pool.miss") - join_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "pool.join") + empty_cond: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, pool_head, zero64) + if empty_cond is None: return 0 + hit_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "pool.hit") + miss_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "pool.miss") + join_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "pool.join") if hit_bb is None or miss_bb is None or join_bb is None: return 0 llvmlite.build_cond_br(builder, empty_cond, miss_bb, hit_bb) # hit:弹池(帧首 8 字节是 next) llvmlite.position_at_end(builder, hit_bb) - node_next_ptr: llvmlite.Value* = llvmlite.build_inttoptr( - builder, pool_head, i64_ptr_ty) - next_head: llvmlite.Value* = llvmlite.build_load( - builder, i64_ty, node_next_ptr) + node_next_ptr: llvmlite.Value* = llvmlite.build_inttoptr(builder, pool_head, i64_ptr_ty) + next_head: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, node_next_ptr) if next_head is None: return 0 llvmlite.build_store(builder, next_head, pool_ref) - hit_frame: llvmlite.Value* = llvmlite.build_inttoptr( - builder, pool_head, frame_ptr_ty) + hit_frame: llvmlite.Value* = llvmlite.build_inttoptr(builder, pool_head, frame_ptr_ty) if hit_frame is None: return 0 llvmlite.build_br(builder, join_bb) # miss:malloc + 帧首 8 字节置 0(弹池帧的 next 残留清零) llvmlite.position_at_end(builder, miss_bb) - raw: llvmlite.Value* = llvmlite.build_call( - builder, "malloc", size_val, 1, i8_ptr_ty, 0) + raw: llvmlite.Value* = llvmlite.build_call(builder, "malloc", size_val, 1, i8_ptr_ty, 0) if raw is None: return 0 - miss_frame: llvmlite.Value* = llvmlite.build_bitcast( - builder, raw, frame_ptr_ty) + miss_frame: llvmlite.Value* = llvmlite.build_bitcast(builder, raw, frame_ptr_ty) if miss_frame is None: return 0 - miss_head_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, miss_frame, i64_ptr_ty) + miss_head_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, miss_frame, i64_ptr_ty) if miss_head_ptr is not None: llvmlite.build_store(builder, zero64, miss_head_ptr) llvmlite.build_br(builder, join_bb) # join:phi 选帧 + 5 头清零(弹池复用帧必须重置 state/done/ret/exc/msg)+ 参数存槽 llvmlite.position_at_end(builder, join_bb) - inc1: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming( - pool, hit_frame, hit_bb) - inc2: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming( - pool, miss_frame, miss_bb) + inc1: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, hit_frame, hit_bb) + inc2: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, miss_frame, miss_bb) if inc1 is None or inc2 is None: return 0 inc1.Next = inc2 - frame_ref: llvmlite.Value* = llvmlite.build_phi( - builder, frame_ptr_ty, inc1, 2) + frame_ref: llvmlite.Value* = llvmlite.build_phi(builder, frame_ptr_ty, inc1, 2) if frame_ref is None: return 0 zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) @@ -878,26 +847,22 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): si: int = 0 for si in range(5): if si == 4: - mslot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i8_ptr_ty, frame_ref, 4) + mslot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i8_ptr_ty, frame_ref, 4) if mslot is not None: llvmlite.build_store(builder, null_p, mslot) else: - slot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_ref, si) + slot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_ref, si) if slot is not None: llvmlite.build_store(builder, zero, slot) # 参数存帧槽(index 5+i) pj: int = 0 for pj in range(nparams): - pslot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_ref, 5 + pj) + pslot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_ref, 5 + pj) if pslot is not None: arnb: str = pool.alloc(16) if arnb is not None: viperlib.snprintf(arnb, 16, "%%arg%d", pj) - arg_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, i32_ty, arnb) + arg_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i32_ty, arnb) if arg_ref is not None: llvmlite.build_store(builder, arg_ref, pslot) llvmlite.build_ret(builder, frame_ref) @@ -972,22 +937,18 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): rname_buf: str = pool.alloc(64) if rname_buf is not None: viperlib.snprintf(rname_buf, 64, "resume_%s", name) - mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, rname_buf, 0) - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled, i32_ty) + mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, rname_buf, 0) + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled, i32_ty) if func is None: return 0 llvmlite.add_param(pool, func, frame_ptr_ty, "%frame") funcs_ptr: GenTypes.FuncEntry* = trans._funcs cur_count: int = trans._func_count - if self.Gen.CallGenLeafKit.add_func_to_table( - funcs_ptr, cur_count, rname_buf, func, 1024, + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, rname_buf, func, 1024, None, 0, 1, trans.Pool) == 0: trans._func_count = cur_count + 1 - entry: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "entry") + entry: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") if entry is None: return 0 builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) @@ -995,25 +956,18 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return 0 llvmlite.position_at_end(builder, entry) - frame_arg: llvmlite.Value* = llvmlite.SSAValue( - pool, frame_ptr_ty, "%frame") + frame_arg: llvmlite.Value* = llvmlite.SSAValue(pool, frame_ptr_ty, "%frame") if frame_arg is None: return 0 # GEP 5 头槽(M4 exc / M7 msg) - i8_ptr_ty_r: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + i8_ptr_ty_r: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) i64_ty_r: llvmlite.LLVMType* = llvmlite.Int64(pool) - state_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, 0) - done_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, 1) - ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, 2) - exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, 3) - msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i8_ptr_ty_r, frame_arg, 4) + state_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, 0) + done_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, 1) + ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, 2) + exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, 3) + msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i8_ptr_ty_r, frame_arg, 4) # 参数槽 GEP → 注册到符号表(index 5+i) pj: int = 0 @@ -1021,8 +975,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): pname: str = self._read_param_name(trans, pj) if pname is None: continue - pslot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, 5 + pj) + pslot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, 5 + pj) if pslot is not None: self.Gen.VarGen.define_var(trans.SymTab, pname, pslot) @@ -1032,8 +985,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): lname: str = self._read_local_name(trans, li) if lname is None: continue - slot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_arg, + slot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, trans._coro_local_base + li) if slot is not None: self.Gen.VarGen.define_var(trans.SymTab, lname, slot) @@ -1049,8 +1001,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): ety_llvm: llvmlite.LLVMType* = i32_ty if ety == 2: ety_llvm = i64_ty_r - eslot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, ety_llvm, frame_arg, + eslot: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, ety_llvm, frame_arg, trans._coro_extra_base + ei) if eslot is None: continue @@ -1093,10 +1044,8 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.define_var(trans.SymTab, ename, eslot) # state 值 + exit 块 - state_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, state_ptr) - exit_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.exit") + state_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, state_ptr) + exit_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.exit") if exit_bb is None: return 0 @@ -1135,13 +1084,11 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): for si in range(nseg): if bb_name is not None: viperlib.snprintf(bb_name, 32, "state%d", si) - sbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, bb_name) + sbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_name) if sbb is None: continue state_bbs[si] = sizet(sbb) - sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case( - pool, llvmlite.const_int32(pool, si), sbb) + sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(pool, llvmlite.const_int32(pool, si), sbb) if sc is not None: if sw_head is None: sw_head = sc @@ -1171,8 +1118,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # exit 块:load done 返回(0=SUSPEND 1=DONE) llvmlite.position_at_end(builder, exit_bb) - done_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, done_ptr) + done_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, done_ptr) llvmlite.build_ret(builder, done_val) return 0 @@ -1244,8 +1190,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if self._is_await_tail(stmt) != 0: target_name: str = self._get_assign_target_name(stmt) if target_name is not None: - trans._coro_await_slot = self.Gen.VarGen.lookup_var( - trans.SymTab, target_name) + trans._coro_await_slot = self.Gen.VarGen.lookup_var(trans.SymTab, target_name) else: # Expr(await ...):无目标槽(丢弃返回值),防残留旧槽 trans._coro_await_slot = None @@ -1260,9 +1205,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): call_name = "(unknown)" err_buf: str = pool.alloc(256) if err_buf is not None: - viperlib.snprintf( - err_buf, 256, - "[coro-M2] await 目标 '%s' 不是 async 函数", call_name) + viperlib.snprintf(err_buf, 256, "[coro-M2] await 目标 '%s' 不是 async 函数", call_name) self.Gen.TypeGenErr.fatal_error(stmt, err_buf, "SyntaxError") continue # 语句内嵌套 await → 提升为 __await_N @@ -1289,16 +1232,13 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_b, 256, "[coro-M2] if 条件中不支持 await") self.Gen.TypeGenErr.fatal_error(stmt, err_b, "SyntaxError") return - cond: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, ifn.test, None, 0, trans) + cond: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ifn.test, None, 0, trans) if cond is None: return cond1: llvmlite.Value* = self._normalize_cond(builder, pool, cond) func: llvmlite.Function* = trans._cur_func - then_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.then") - merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.end") + then_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.then") + merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.end") has_else: int = 0 if ifn.orelse is not None and len(ifn.orelse) > 0: has_else = 1 @@ -1340,12 +1280,9 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(stmt, err_c, "SyntaxError") return func: llvmlite.Function* = trans._cur_func - cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.wcond") - body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.wbody") - after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.wend") + cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.wcond") + body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.wbody") + after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.wend") if cond_bb is None or body_bb is None or after_bb is None: return # break/continue 目标(M2 单层) @@ -1356,8 +1293,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, cond_bb) # 条件块 llvmlite.position_at_end(builder, cond_bb) - cond: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, whn.test, None, 0, trans) + cond: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, whn.test, None, 0, trans) if cond is None: cond = llvmlite.const_int32(pool, 0) cond1: llvmlite.Value* = self._normalize_cond(builder, pool, cond) @@ -1391,13 +1327,11 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): guard = guard + 1 temp_name: str = pool.alloc(32) if temp_name is not None: - viperlib.snprintf( - temp_name, 32, "__await_%d", trans._coro_hoist_count) + viperlib.snprintf(temp_name, 32, "__await_%d", trans._coro_hoist_count) # 目标槽 = __await_N 帧额外槽(预扫描位置数组,wake/for 槽穿插在前) slot_idx: int = trans._coro_extra_base + trans._coro_await_slots[trans._coro_hoist_count] trans._coro_hoist_count = trans._coro_hoist_count + 1 - slot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, self._lookup_coro_frame_by_trans(trans), + slot: llvmlite.Value* = llvmlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), llvmlite.Int32(pool), trans._coro_frame, slot_idx) trans._coro_await_slot = slot call_name: str = self._extract_await_call_name(aw_node) @@ -1752,23 +1686,19 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if aw_s.value is not None and aw_s.value.kind() == ast.ASTKind.Call: cl_s: ast.Call* = ast.Call*(aw_s.value) if cl_s.args is not None and len(cl_s.args) > 0: - ms_v: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl_s.args.get(0), None, 0, trans) + ms_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl_s.args.get(0), None, 0, trans) if ms_v is not None: ms_val = ms_v # GetTickCount64() + ms(i64) - now_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - mod, "GetTickCount64") + now_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, "GetTickCount64") if now_fn is None: now_fn = llvmlite.create_declare(pool, mod, "GetTickCount64", i64_ty) if now_fn is None: return llvmlite.const_int32(pool, 0) - now_val: llvmlite.Value* = llvmlite.build_call( - builder, "GetTickCount64", None, 0, i64_ty, 0) + now_val: llvmlite.Value* = llvmlite.build_call(builder, "GetTickCount64", None, 0, i64_ty, 0) if now_val is None: return llvmlite.const_int32(pool, 0) - wake_val: llvmlite.Value* = llvmlite.build_add( - builder, now_val, ms_val) + wake_val: llvmlite.Value* = llvmlite.build_add(builder, now_val, ms_val) if wake_val is None: return llvmlite.const_int32(pool, 0) llvmlite.build_store(builder, wake_val, trans._coro_wake_ptr) @@ -1778,8 +1708,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): st_v_s: llvmlite.Value* = llvmlite.const_int32(pool, new_state_s) llvmlite.build_store(builder, st_v_s, trans._coro_state_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) - resume_bb_s: rawptr[llvmlite.BasicBlock] = self._get_state_bb( - trans, new_state_s) + resume_bb_s: rawptr[llvmlite.BasicBlock] = self._get_state_bb(trans, new_state_s) if resume_bb_s is not None: llvmlite.position_at_end(builder, resume_bb_s) return llvmlite.const_int32(pool, 0) @@ -1802,13 +1731,11 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if code != 0: exc_code = llvmlite.const_int32(pool, code) # M7:异常消息(Exception("msg") 首参) - msg_v: llvmlite.Value* = self._resolve_raise_msg( - builder, pool, mod, trans, rz.exc) + msg_v: llvmlite.Value* = self._resolve_raise_msg(builder, pool, mod, trans, rz.exc) if msg_v is not None and trans._coro_msg_ptr is not None: llvmlite.build_store(builder, msg_v, trans._coro_msg_ptr) else: - v: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, rz.exc, None, 0, trans) + v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rz.exc, None, 0, trans) if v is not None: exc_code = v if trans._coro_exc_ptr is not None: @@ -1854,8 +1781,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): cl: ast.Call* = ast.Call*(exc_node) if cl.args is None or len(cl.args) < 1: return None - return self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) + return self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) # ============================================================ # M5-M6:协程内 try/except(多 except 链式匹配 + 类型码 + as e 绑定) @@ -1882,10 +1808,8 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(stmt, err_t, "SyntaxError") return func: llvmlite.Function* = trans._cur_func - except_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.try_except") - merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.try_merge") + except_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.try_except") + merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.try_merge") if except_bb is None or merge_bb is None: return # try 栈 push @@ -1900,8 +1824,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_try_stack_count = trans._coro_try_stack_count - 1 # ---- 异常分发:exc 码依次匹配各 except ---- llvmlite.position_at_end(builder, except_bb) - exc_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, trans._coro_exc_ptr) + exc_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, trans._coro_exc_ptr) # 预建 check/handler/unmatched 块 check_bbs: sizet* = pool.alloc((nhandlers + 1) * 8) handler_bbs: sizet* = pool.alloc(nhandlers * 8) @@ -1920,18 +1843,14 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return viperlib.snprintf(chk_name, 64, "coro.exc_check_%d", hi) viperlib.snprintf(exc_name, 64, "coro.except_%d", hi) - check_bbs[hi + 1] = sizet(llvmlite.create_block( - pool, func, chk_name)) - handler_bbs[hi] = sizet(llvmlite.create_block( - pool, func, exc_name)) - unmatched_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.try_reraise") + check_bbs[hi + 1] = sizet(llvmlite.create_block(pool, func, chk_name)) + handler_bbs[hi] = sizet(llvmlite.create_block(pool, func, exc_name)) + unmatched_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.try_reraise") codes_buf: int | t.CPtr = pool.alloc(256) # 每个 handler:check 链 for hi in range(nhandlers): h_node: ast.AST* = tr.handlers.get(hi) - check_bb: rawptr[llvmlite.BasicBlock] = ( - rawptr[llvmlite.BasicBlock])(check_bbs[hi]) + check_bb: rawptr[llvmlite.BasicBlock] = (rawptr[llvmlite.BasicBlock])(check_bbs[hi]) llvmlite.position_at_end(builder, check_bb) catch_all: int = 0 ncodes: int = 0 @@ -1944,23 +1863,20 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if ename is not None and string.strcmp(ename, "Exception") == 0: catch_all = 1 else: - ncodes = self.Gen.ClassGenBase.collect_descendant_codes( - ename, codes_buf, 64) + ncodes = self.Gen.ClassGenBase.collect_descendant_codes(ename, codes_buf, 64) next_check: rawptr[llvmlite.BasicBlock] = None if hi + 1 < nhandlers: next_check = rawptr[llvmlite.BasicBlock](check_bbs[hi + 1]) else: next_check = unmatched_bb - handler_bb: rawptr[llvmlite.BasicBlock] = ( - rawptr[llvmlite.BasicBlock])(handler_bbs[hi]) + handler_bb: rawptr[llvmlite.BasicBlock] = (rawptr[llvmlite.BasicBlock])(handler_bbs[hi]) if catch_all != 0: llvmlite.build_br(builder, handler_bb) else: match_cond: llvmlite.Value* = None ci: int = 0 for ci in range(ncodes): - eq_v: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, exc_val, + eq_v: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, exc_val, llvmlite.const_int32(pool, codes_buf[ci])) if match_cond is None: match_cond = eq_v @@ -1978,18 +1894,15 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ---- 各 except handler ---- for hi in range(nhandlers): h_node2: ast.AST* = tr.handlers.get(hi) - handler_bb2: rawptr[llvmlite.BasicBlock] = ( - rawptr[llvmlite.BasicBlock])(handler_bbs[hi]) + handler_bb2: rawptr[llvmlite.BasicBlock] = (rawptr[llvmlite.BasicBlock])(handler_bbs[hi]) llvmlite.position_at_end(builder, handler_bb2) if h_node2 is not None: hd2: ast.ExceptHandler* = ast.ExceptHandler*(h_node2) # as e:异常码绑定 e 槽(e 是局部槽,_collect_local_names 收集) if hd2.name is not None and trans._coro_exc_ptr is not None: - e_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, hd2.name) + e_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, hd2.name) if e_slot is not None: - hv: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, trans._coro_exc_ptr) + hv: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, trans._coro_exc_ptr) llvmlite.build_store(builder, hv, e_slot) # 捕获后清帧 exc z_clr: llvmlite.Value* = llvmlite.const_int32(pool, 0) @@ -2033,12 +1946,9 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(stmt, err_f, "SyntaxError") return func: llvmlite.Function* = trans._cur_func - fin_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fin") - fin_exc_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fin_exc") - merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fin_merge") + fin_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fin") + fin_exc_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fin_exc") + merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fin_merge") if fin_bb is None or fin_exc_bb is None or merge_bb is None: return # try 栈 push(异常跳 finally) @@ -2052,8 +1962,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_try_stack_count = trans._coro_try_stack_count - 1 # fin_bb:记录异常标志 + 执行 fbody llvmlite.position_at_end(builder, fin_bb) - was_exc: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, + was_exc: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, llvmlite.build_load(builder, i32_ty, trans._coro_exc_ptr), llvmlite.const_int32(pool, 0)) self._handle_segment(trans, builder, pool, mod, tr.finalbody) @@ -2083,16 +1992,14 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_g, 256, "[coro-M3] 协程内 For 仅支持 range 迭代(含 await)") self.Gen.TypeGenErr.fatal_error(stmt, err_g, "SyntaxError") return - fn: rawptr[ast.For] = rawptr[ast.For](stmt) + fn: ast.For* = ast.For*(stmt) k: int = trans._coro_for_counter trans._coro_for_counter = k + 1 idx_idx: int = trans._coro_extra_base + trans._coro_for_slots[k] len_idx: int = idx_idx + 1 - idx_slot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, self._lookup_coro_frame_by_trans(trans), + idx_slot: llvmlite.Value* = llvmlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, idx_idx) - len_slot: llvmlite.Value* = llvmlite.build_gep_struct( - builder, self._lookup_coro_frame_by_trans(trans), + len_slot: llvmlite.Value* = llvmlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, len_idx) if idx_slot is None or len_slot is None: return @@ -2103,13 +2010,10 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): nargs: int = len(cl.args) if nargs == 1: start_val = llvmlite.const_int32(pool, 0) - end_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) + end_val = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) else: - start_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) - end_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(1), None, 0, trans) + start_val = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) + end_val = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(1), None, 0, trans) if start_val is None: start_val = llvmlite.const_int32(pool, 0) if end_val is None: @@ -2118,12 +2022,9 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_store(builder, end_val, len_slot) # 循环结构 func: llvmlite.Function* = trans._cur_func - cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fcond") - body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fbody") - after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.fend") + cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fcond") + body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fbody") + after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.fend") if cond_bb is None or body_bb is None or after_bb is None: return prev_break: rawptr[llvmlite.BasicBlock] = trans._coro_break_bb @@ -2133,27 +2034,21 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, cond_bb) # 条件块 llvmlite.position_at_end(builder, cond_bb) - idx_v: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, idx_slot) - len_v: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, len_slot) - cmp_v: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_SLT, idx_v, len_v) + idx_v: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_slot) + len_v: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, len_slot) + cmp_v: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, idx_v, len_v) llvmlite.build_cond_br(builder, cmp_v, body_bb, after_bb) # 循环体:target = idx; ; idx += 1 llvmlite.position_at_end(builder, body_bb) if fn.target is not None and fn.target.kind() == ast.ASTKind.Name: tn: ast.Name* = ast.Name*(fn.target) - tgt_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, tn.id) + tgt_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, tn.id) if tgt_slot is not None: - idx_v2: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, idx_slot) + idx_v2: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_slot) llvmlite.build_store(builder, idx_v2, tgt_slot) self._handle_segment(trans, builder, pool, mod, stmt.children) if llvmlite.builder_cur_block_is_terminated(builder) == 0: - idx_v3: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, idx_slot) + idx_v3: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_slot) one_v: llvmlite.Value* = llvmlite.const_int32(pool, 1) nxt_v: llvmlite.Value* = llvmlite.build_add(builder, idx_v3, one_v) llvmlite.build_store(builder, nxt_v, idx_slot) @@ -2178,36 +2073,28 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, async_name) + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) - frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_val, frame_ptr_ty) + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) # 回池:帧首 8 字节存旧池头;池头 = 本帧(i64) - pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool( - pool, mod, trans, async_name) + pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool(pool, mod, trans, async_name) # GlobalVariable 非 Value 子类:构造 Value 视图(Ty=Ptr(i64), Name="@coro_pool_") i64_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i64_ty) pool_ref_name: str = pool.alloc(96) if pool_ref_name is not None: viperlib.snprintf(pool_ref_name, 96, "@coro_pool_%s", async_name) - pool_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, i64_ptr_ty, pool_ref_name) - pool_head: llvmlite.Value* = llvmlite.build_load( - builder, i64_ty, pool_ref) - node_next: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_ptr, i64_ptr_ty) + pool_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i64_ptr_ty, pool_ref_name) + pool_head: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, pool_ref) + node_next: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_ptr, i64_ptr_ty) llvmlite.build_store(builder, pool_head, node_next) - frame_i64: llvmlite.Value* = llvmlite.build_ptrtoint( - builder, frame_ptr, i64_ty) + frame_i64: llvmlite.Value* = llvmlite.build_ptrtoint(builder, frame_ptr, i64_ty) llvmlite.build_store(builder, frame_i64, pool_ref) return llvmlite.const_int32(pool, 0) @@ -2223,21 +2110,17 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, async_name) + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) - frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_val, frame_ptr_ty) + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) - exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_ptr, 3) + exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_ptr, 3) return llvmlite.build_load(builder, i32_ty, exc_ptr) def translate_coro_exception_msg(self, builder: llvmlite.IRBuilder*, @@ -2246,28 +2129,23 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): cl: ast.Call*, trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_exception_msg(帧):返回帧 msg 槽(异常消息指针,null=无)""" - i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, async_name) + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, async_name) if frame_ty is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) - frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), None, 0, trans) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_val, frame_ptr_ty) + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i8_ptr_ty, frame_ptr, 4) + msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i8_ptr_ty, frame_ptr, 4) return llvmlite.build_load(builder, i8_ptr_ty, msg_ptr) def translate_coro_gather(self, builder: llvmlite.IRBuilder*, @@ -2286,40 +2164,32 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): async_name: str = self._var_to_async(trans, arg0) if async_name is None: continue - frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, async_name) + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, async_name) if frame_ty is None: continue frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) - frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg0, None, 0, trans) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg0, None, 0, trans) if frame_val is None: continue - frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_val, frame_ptr_ty) + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_val, frame_ptr_ty) if frame_ptr is None: continue rn_buf: str = pool.alloc(64) if rn_buf is not None: viperlib.snprintf(rn_buf, 64, "resume_%s", async_name) - resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, rn_buf, 0) + resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, rn_buf, 0) if self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None: continue func: llvmlite.Function* = trans._cur_func - loop_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "gather.loop") - after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "gather.after") + loop_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "gather.loop") + after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "gather.after") if loop_bb is None or after_bb is None: continue llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, loop_bb) frame_ptr.Next = None - status: llvmlite.Value* = llvmlite.build_call( - builder, resume_mangled, frame_ptr, 1, i32_ty, 0) - done_cond: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, status, llvmlite.const_int32(pool, 0)) + status: llvmlite.Value* = llvmlite.build_call(builder, resume_mangled, frame_ptr, 1, i32_ty, 0) + done_cond: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, status, llvmlite.const_int32(pool, 0)) llvmlite.build_cond_br(builder, done_cond, after_bb, loop_bb) llvmlite.position_at_end(builder, after_bb) return llvmlite.const_int32(pool, 0) @@ -2352,15 +2222,13 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): 立即 position(预建 case 块),后续语句在恢复块继续翻译 返回子协程 ret 值(i32)。注意 node 是 Await,须先转 ast.Await 再取 value。""" i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) - i8_ptr_ty_a: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + i8_ptr_ty_a: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if node is None or call_name is None or trans is None: return llvmlite.const_int32(pool, 0) # M3:await coro_sleep(ms) —— 挂起到 wake 时刻(帧 wake 槽) if string.strcmp(call_name, "coro_sleep") == 0: return self._emit_await_sleep(builder, pool, mod, trans, node) - child_frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, call_name) + child_frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, call_name) if child_frame_ty is None: return llvmlite.const_int32(pool, 0) child_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, child_frame_ty) @@ -2368,13 +2236,11 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): cc_buf: str = pool.alloc(64) if cc_buf is not None: viperlib.snprintf(cc_buf, 64, "create_%s", call_name) - create_mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, cc_buf, 0) + create_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, cc_buf, 0) rc_buf: str = pool.alloc(64) if rc_buf is not None: viperlib.snprintf(rc_buf, 64, "resume_%s", call_name) - resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, rc_buf, 0) + resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, rc_buf, 0) if self.Gen.CallGenBase.find_func_in_module(mod, create_mangled) is None \ or self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None: # async 函数必须定义在前(前向引用未支持),静默返回 0 @@ -2391,8 +2257,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): nb: sizet = len(cl_a.args) j: sizet = 0 for j in range(nb): - av: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl_a.args.get(j), None, 0, trans) + av: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl_a.args.get(j), None, 0, trans) if av is None: av = llvmlite.const_int32(pool, 0) av.Next = None @@ -2405,41 +2270,31 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): args_count = args_count + 1 # 子协程 create(M2 带参数)+ resume - child: llvmlite.Value* = llvmlite.build_call( - builder, create_mangled, args_head, args_count, child_ptr_ty, 0) + child: llvmlite.Value* = llvmlite.build_call(builder, create_mangled, args_head, args_count, child_ptr_ty, 0) if child is None: return llvmlite.const_int32(pool, 0) child.Next = None llvmlite.build_call(builder, resume_mangled, child, 1, i32_ty, 0) # 子帧 ret 槽 GEP [0,2] load - child_ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, child_frame_ty, i32_ty, child, 2) - child_ret: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, child_ret_ptr) + child_ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, child_frame_ty, i32_ty, child, 2) + child_ret: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, child_ret_ptr) # M4:子帧异常传播——子帧 exc != 0 → 父 exc/msg 槽 + 跳 try except 或终止 - child_exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, child_frame_ty, i32_ty, child, 3) - child_exc: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, child_exc_ptr) + child_exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, child_frame_ty, i32_ty, child, 3) + child_exc: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, child_exc_ptr) zero32_x: llvmlite.Value* = llvmlite.const_int32(pool, 0) - exc_ok_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, trans._cur_func, "coro.ok") - exc_bad_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, trans._cur_func, "coro.exc") + exc_ok_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, trans._cur_func, "coro.ok") + exc_bad_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, trans._cur_func, "coro.exc") if exc_ok_bb is None or exc_bad_bb is None: return llvmlite.const_int32(pool, 0) - exc_cond: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, child_exc, zero32_x) + exc_cond: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, child_exc, zero32_x) llvmlite.build_cond_br(builder, exc_cond, exc_ok_bb, exc_bad_bb) # exc 路径:父帧 exc/msg 槽 + 跳 try 或终止 llvmlite.position_at_end(builder, exc_bad_bb) if trans._coro_exc_ptr is not None: llvmlite.build_store(builder, child_exc, trans._coro_exc_ptr) if trans._coro_msg_ptr is not None: - child_msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, child_frame_ty, i8_ptr_ty_a, child, 4) - child_msg: llvmlite.Value* = llvmlite.build_load( - builder, i8_ptr_ty_a, child_msg_ptr) + child_msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, child_frame_ty, i8_ptr_ty_a, child, 4) + child_msg: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty_a, child_msg_ptr) llvmlite.build_store(builder, child_msg, trans._coro_msg_ptr) if trans._coro_try_stack_count > 0: tbb: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](trans._coro_try_stack[trans._coro_try_stack_count - 1]) @@ -2460,8 +2315,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_store(builder, st_v, trans._coro_state_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) # 恢复块 state{new_state}:立即 position(预建 case 块,后续翻译在此继续) - resume_bb: rawptr[llvmlite.BasicBlock] = self._get_state_bb( - trans, new_state) + resume_bb: rawptr[llvmlite.BasicBlock] = self._get_state_bb(trans, new_state) if resume_bb is not None: llvmlite.position_at_end(builder, resume_bb) return child_ret @@ -2494,19 +2348,16 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): async_name: str = self._lookup_coro_var(trans, nm.id) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( - trans, async_name) + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame(trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) # 帧变量值(i8* / Ptr(帧))→ bitcast 到 Ptr(帧) - frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg0, None, 0, trans) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg0, None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, frame_val, frame_ptr_ty) + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) @@ -2516,27 +2367,21 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): rn_buf: str = pool.alloc(64) if rn_buf is not None: viperlib.snprintf(rn_buf, 64, "resume_%s", async_name) - resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name( - trans, rn_buf, 0) + resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, rn_buf, 0) if self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None: return llvmlite.const_int32(pool, 0) - loop_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.loop") - check_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.check") - after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.after") + loop_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.loop") + check_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.check") + after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.after") if loop_bb is None or check_bb is None or after_bb is None: return llvmlite.const_int32(pool, 0) llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, loop_bb) frame_ptr.Next = None - status: llvmlite.Value* = llvmlite.build_call( - builder, resume_mangled, frame_ptr, 1, i32_ty, 0) + status: llvmlite.Value* = llvmlite.build_call(builder, resume_mangled, frame_ptr, 1, i32_ty, 0) zero_cmp: llvmlite.Value* = llvmlite.const_int32(pool, 0) - done_cond: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, status, zero_cmp) + done_cond: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, status, zero_cmp) llvmlite.build_cond_br(builder, done_cond, after_bb, check_bb) # M3:SUSPEND → wake 轮询(GetTickCount64 >= wake 或 wake==0 继续,否则 Sleep(1)) llvmlite.position_at_end(builder, check_bb) @@ -2545,23 +2390,15 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, loop_bb) else: i64_ty_r2: llvmlite.LLVMType* = llvmlite.Int64(pool) - wake_ptr_r: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i64_ty_r2, frame_ptr, wake_idx_r) - wake_v_r: llvmlite.Value* = llvmlite.build_load( - builder, i64_ty_r2, wake_ptr_r) - now_v_r: llvmlite.Value* = llvmlite.build_call( - builder, "GetTickCount64", None, 0, i64_ty_r2, 0) - not_wake_r: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, wake_v_r, + wake_ptr_r: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i64_ty_r2, frame_ptr, wake_idx_r) + wake_v_r: llvmlite.Value* = llvmlite.build_load(builder, i64_ty_r2, wake_ptr_r) + now_v_r: llvmlite.Value* = llvmlite.build_call(builder, "GetTickCount64", None, 0, i64_ty_r2, 0) + not_wake_r: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, wake_v_r, llvmlite.const_int64(pool, 0)) - due_r: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_UGE, now_v_r, wake_v_r) - cont_r: llvmlite.Value* = llvmlite.build_or( - builder, not_wake_r, due_r) - wsleep_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.wsleep") - wdue_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, "coro.wdue") + due_r: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_UGE, now_v_r, wake_v_r) + cont_r: llvmlite.Value* = llvmlite.build_or(builder, not_wake_r, due_r) + wsleep_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.wsleep") + wdue_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "coro.wdue") llvmlite.build_cond_br(builder, cont_r, wdue_bb, wsleep_bb) llvmlite.position_at_end(builder, wsleep_bb) sleep_one: llvmlite.Value* = llvmlite.const_int32(pool, 1) @@ -2571,10 +2408,8 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.position_at_end(builder, wdue_bb) llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, after_bb) - ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - builder, frame_ty, i32_ty, frame_ptr, 2) - ret_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, ret_ptr) + ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, frame_ty, i32_ty, frame_ptr, 2) + ret_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, ret_ptr) return ret_val # ============================================================ @@ -2712,8 +2547,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): ret_val: llvmlite.Value* = None if rv_node is not None and rv_node.value is not None: if rv_node.value.kind() != ast.ASTKind.Await: - ret_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, rv_node.value, None, 0, trans) + ret_val = self.Gen.ExprGen.translate_value(builder, pool, mod, rv_node.value, None, 0, trans) if ret_val is None: ret_val = llvmlite.const_int32(pool, 0) llvmlite.build_store(builder, ret_val, trans._coro_ret_ptr) diff --git a/App/lib/core/Gen/Class/ClassGenBase.vp b/App/lib/core/Gen/Class/ClassGenBase.vp index 67dbae3..e95e6e4 100644 --- a/App/lib/core/Gen/Class/ClassGenBase.vp +++ b/App/lib/core/Gen/Class/ClassGenBase.vp @@ -16,37 +16,32 @@ import lib.core.Gen.Generator as Generator # 方法元数据/类元数据/装饰器/异常表容量与编码;本地副本避免跨模块 CDefine 查找) # ============================================================ # 方法元数据 flag 位(对齐 TPC HandlesBase _METHOD_META_*) -META_TLS: t.CDefine = 32 +define META_TLS = 32 # 类编译期元数据表容量上限(__provides__/__requires__/__require_must__) -CLASS_META_MAX: t.CDefine = 256 +define CLASS_META_MAX = 256 # 自定义装饰器 wrapper 表容量上限(带 @decor 的函数数) -DECOR_FUNC_MAX: t.CDefine = 64 +define DECOR_FUNC_MAX = 64 # 装饰器表槽内函数名/wrapper 名长度(含 NUL) -DECOR_NAME_LEN: t.CDefine = 128 +define DECOR_NAME_LEN = 128 # 异常类注册表容量上限(class X(Exception) 自定义异常类) -EXCEPTION_MAX: t.CDefine = 64 +define EXCEPTION_MAX = 64 # 异常类表槽内类名/父类名长度(含 NUL) -EXCEPTION_NAME_LEN: t.CDefine = 128 +define EXCEPTION_NAME_LEN = 128 # 内置异常编码(对齐 TPC HandlesBase.py EXCEPTION_CODE_MAP); # KeyError=6 IOError=7 OSError=8 AssertionError=9 Exception=99;用户类从 100 起 -BUILTIN_EH_VALUE_ERROR: t.CDefine = 1 -BUILTIN_EH_RUNTIME_ERROR: t.CDefine = 3 -BUILTIN_EH_EXCEPTION: t.CDefine = 99 -EH_USER_CODE_START: t.CDefine = 100 +define BUILTIN_EH_VALUE_ERROR = 1 +define BUILTIN_EH_RUNTIME_ERROR = 3 +define BUILTIN_EH_EXCEPTION = 99 +define EH_USER_CODE_START = 100 # 方法元数据表容量(原 HandlesClassDef.META_MAX/META_KEY_LEN,阶段 D 拆分遗漏) -META_MAX: t.CDefine = 512 -META_KEY_LEN: t.CDefine = 128 +define META_MAX = 512 +define META_KEY_LEN = 128 # ============================================================ # ClassGenBase - ClassGenMixin 拆分(阶段 D):字段 + 方法元数据/异常/继承检测/装饰器(Meta) -# -# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenBase: +novirtual class ClassGenBase: """字段 + 方法元数据/异常/继承检测/装饰器(Meta)""" # --- 方法元数据表(原 _g_method_meta_keys/_g_method_meta_flags/_g_method_meta_count) --- @@ -100,7 +95,7 @@ class ClassGenBase: DecoratorFuncNames: bytes DecoratorWrapNames: bytes # 装饰器首个常量参数(@repeat(3) 的 3),无参数为 0(每槽 8B,i64) - DecoratorArgs: int64 | t.CPtr + DecoratorArgs: int64* # --- 异常类注册表(try-except,对齐 TPC HandlesClassDef.py L47-61) --- # perm_pool 分配(跨 mark/reset 存活):每槽类名(128B) + 父类名(128B) + 编码(4B) @@ -109,7 +104,7 @@ class ClassGenBase: ExceptionCount: int ExceptionNames: bytes ExceptionParents: bytes - ExceptionCodes: int | t.CPtr + ExceptionCodes: int* # 下一个待分配的异常编码(用户类,从 100 起) NextExceptionCode: int # 递归收集子孙编码用的临时计数(collect_descendant_codes 返回后无效)。 @@ -125,7 +120,7 @@ class ClassGenBase: # --- 泛型模板表(原 HandlesClassDef._generic_class_names/ # _generic_class_nodes/_generic_class_sha1s) --- GenericClassNames: list[str]* - GenericClassNodes: list[ast.ClassDef*] | t.CPtr + GenericClassNodes: list[ast.ClassDef*]* GenericClassSha1s: list[str]* # 泛型模板来源文件路径(与上面三表同序)。特化翻译模板方法体时 node.lineno 是模板 # 文件行号,若 CurrentFile 仍是调用方文件,fatal_error 会把模板行号套到调用方文件上 @@ -165,8 +160,7 @@ class ClassGenBase: # 别名形式: from t import CEnum as en; class Color(en) # 解析别名原始名(en → CEnum)再比较 if trans is not None and trans._from_imports is not None: - alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, nm.id) + alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id) if alias_orig is not None: og_len_ce: sizet = 0 while alias_orig[og_len_ce] != ' ' and alias_orig[og_len_ce] != '\0': @@ -218,8 +212,7 @@ class ClassGenBase: return 1 # 别名形式: from t import CUnion as un; class Data(un) if trans is not None and trans._from_imports is not None: - alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, nm.id) + alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id) if alias_orig is not None: og_len_cu: sizet = 0 while alias_orig[og_len_cu] != ' ' and alias_orig[og_len_cu] != '\0': @@ -271,8 +264,7 @@ class ClassGenBase: return 1 # 别名形式: from t import REnum as ren; class Opt(ren) if trans is not None and trans._from_imports is not None: - alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, nm.id) + alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm.id) if alias_orig is not None: og_len_cr: sizet = 0 while alias_orig[og_len_cr] != ' ' and alias_orig[og_len_cr] != '\0': @@ -556,14 +548,10 @@ class ClassGenBase: if pool is None or func_name is None or wrapper_name is None: return -1 if self.DecoratorFuncNames is None: - self.DecoratorFuncNames = CompilerFactory.factory.PermPool.alloc( - DECOR_FUNC_MAX * DECOR_NAME_LEN) - self.DecoratorWrapNames = CompilerFactory.factory.PermPool.alloc( - DECOR_FUNC_MAX * DECOR_NAME_LEN) - self.DecoratorArgs = CompilerFactory.factory.PermPool.alloc( - DECOR_FUNC_MAX * 8) - if self.DecoratorFuncNames is None or self.DecoratorWrapNames is None \ - or self.DecoratorArgs is None: + self.DecoratorFuncNames = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * DECOR_NAME_LEN) + self.DecoratorWrapNames = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * DECOR_NAME_LEN) + self.DecoratorArgs = CompilerFactory.factory.PermPool.alloc(DECOR_FUNC_MAX * 8) + if self.DecoratorFuncNames is None or self.DecoratorWrapNames is None or self.DecoratorArgs is None: return -1 string.memset(self.DecoratorFuncNames, 0, DECOR_FUNC_MAX * DECOR_NAME_LEN) string.memset(self.DecoratorWrapNames, 0, DECOR_FUNC_MAX * DECOR_NAME_LEN) @@ -986,8 +974,7 @@ class ClassGenBase: """ if base_name is None or trans is None or trans._from_imports is None: return base_name - orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, base_name) + orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, base_name) if orig is not None: # lookup_from_import_original 返回 from_imports 内部指针且未 NUL 结尾 # (如 "CStruct myint:t:CInt CChar:t CPtr:t" 整串直到真正的 NUL)。 @@ -1146,8 +1133,7 @@ class ClassGenBase: # 用 SHA1 感知查找父类,规避跨模块同名找错 is_nvt: int = 0 if trans is not None: - p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - parent_name, trans.ModuleSha1) + p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1) if p_entry is None: # 跨模块父类回退全局查找(父类注册在父模块 SHA1 下,如 linkedlist.LinkedNode), # 与字段展平(1.5 节)的回退保持一致,否则父类 NoVTable 被误判为有虚表 → 子类插 vptr @@ -1171,8 +1157,7 @@ class ClassGenBase: def _detect_vtable_status(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> int: """检测类是否应该启用虚表""" - if cd is None: - return 0 + if cd is None: return 0 # 检查类装饰器 if cd.decorator_list is not None: @@ -1189,8 +1174,7 @@ class ClassGenBase: # 用 SHA1 感知查找父类,规避跨模块同名找错 is_nvt: int = 0 if trans is not None: - p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - parent_name, trans.ModuleSha1) + p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1) if p_entry is None: # 跨模块父类回退全局查找(同 _detect_vtable_status 的回退) p_entry = self.Gen.StructGen.find_struct(parent_name) @@ -1204,10 +1188,8 @@ class ClassGenBase: # 继承链统一虚表:父类有虚表 → 子类启用;父类无虚表 → 子类静态。 # 若父类无 vtable 而子类有,父类方法按无 vptr 布局(self.field@0)操作 # 子类实例(有 vptr@0)会字段错位 → 运行时错误(父类方法读 vptr 当字段)。 - if p_entry is None: - return 1 # 父类信息未知(跨模块/未注册),保守启用虚表 - if p_entry.HasVTable == 1: - return 1 + if p_entry is None: return 1 # 父类信息未知(跨模块/未注册),保守启用虚表 + if p_entry.HasVTable == 1: return 1 return 0 # 默认(无装饰器无继承),检查函数级 @t.CVTable diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index 98618e2..eef3f13 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -16,27 +16,20 @@ from . import ClassGenBase # ============================================================ # ClassGenDef - ClassGenMixin 拆分(阶段 D):translate_class_def 主入口 -# -# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenDef(ClassGenBase.ClassGenBase): +novirtual class ClassGenDef(ClassGenBase.ClassGenBase): """translate_class_def 主入口""" - # ============================================================ + # ============================================================ # translate_class_def — 翻译 class 定义(簇 D) # ============================================================ def translate_class_def(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 class 定义,返回 0""" - if node is None or trans is None: - return 0 + if node is None or trans is None: return 0 cd: ast.ClassDef* = ast.ClassDef*(node) - if cd is None or cd.name is None: - return 0 + if cd is None or cd.name is None: return 0 pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name @@ -85,8 +78,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): return self.Gen.ClassGenBase._register_exception_class_def(trans, cd) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - class_name, trans.ModuleSha1) + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) # 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。 # 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry # (置空 Name + Ty=None,使 find_struct_by_module 不再命中),走下方完整注册路径重建。 @@ -112,8 +104,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # _ensure_field_types_in_module 遍历悬空字段 ParamNode 链表 # 读悬空挂起(G3 LinkedNode.prepend 挂起根因)。DeepCopyType # 递归深拷贝字段链表/子类型/Name 到 stdlib(深度上限+链守卫)。 - ty_deep: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, existing.Ty) + ty_deep: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, existing.Ty) if ty_deep is not None: existing.Ty = ty_deep old_name: str = llvmlite.get_struct_name(existing.Ty) @@ -122,10 +113,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): on_copy: str = CompilerFactory.factory.PermPool.alloc(on_len + 1) if on_copy is not None: string.strcpy(on_copy, old_name) - c.DerefAs(existing.Ty, llvmlite.LLVMType.Struct( - llvmlite.get_struct_fields(existing.Ty), - llvmlite.get_struct_fcount(existing.Ty), - on_copy)) + *existing.Ty = llvmlite.LLVMType.Struct(llvmlite.get_struct_fields(existing.Ty), llvmlite.get_struct_fcount(existing.Ty), on_copy) # Phase B: 将已存在的命名结构体注册到当前模块(输出类型定义行) llvmlite.module_add_named_type(trans.Module, pool, existing.Ty) # B5:existing 路径(Phase B 已注册类)同样需设置 packed/aligned—— @@ -185,8 +173,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # Phase B(declare_only==0)不延迟,避免死锁。 # ============================================================ if trans._declare_only == 1 and parent_name is not None: - parent_check: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - parent_name, trans.ModuleSha1) + parent_check: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(parent_name, trans.ModuleSha1) if parent_check is None: parent_check = self.Gen.StructGen.find_struct(parent_name) if parent_check is None: @@ -237,14 +224,11 @@ class ClassGenDef(ClassGenBase.ClassGenBase): if parents_count > 0 and parents_buf is not None: for pi in range(parents_count): pname_addr: sizet = parents_buf[pi] - if pname_addr == 0: - continue + if pname_addr == 0: continue pname: str = (str | t.CPtr)(pname_addr) - if pname is None: - continue + if pname is None: continue # 用 SHA1 感知查找父类,规避跨模块同名找错 - parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - pname, trans.ModuleSha1) + parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pname, trans.ModuleSha1) if parent_entry is None: # 父类可能定义在另一个模块(不同 SHA1,如 HandlesBase.Mixin), # find_struct_by_module 不回退全局查找,此处手动回退到 find_struct, @@ -259,19 +243,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase): return 0 pfc: int = parent_entry.FieldCount for pfi in range(pfc): - pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( - parent_entry, pfi) - if pfe is None: - continue + pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(parent_entry, pfi) + if pfe is None: continue pfn: str = self.Gen.StructGen.get_field_name_ptr(pfe) - if pfn is None: - continue + if pfn is None: continue # 跳过父类的 vtable 指针字段 - if string.strcmp(pfn, "__vtable__") == 0: - continue + if string.strcmp(pfn, "__vtable__") == 0: continue # 多继承去重:字段名已存在跳过(先声明父类优先) - if self.Gen.ClassGenBase._field_name_exists(field_names_buf, field_count, pfn) != 0: - continue + if self.Gen.ClassGenBase._field_name_exists(field_names_buf, field_count, pfn) != 0: continue if field_count < GenTypes.FIELD_MAX: pft: llvmlite.LLVMType* = self.Gen.StructGen.get_field_type_ptr(pfe) pfd: ast.AST* = self.Gen.StructGen.get_field_default_ptr(pfe) @@ -302,23 +281,19 @@ class ClassGenDef(ClassGenBase.ClassGenBase): cn: sizet = len(children) for ci in range(cn): stmt: ast.AST* = children.get(ci) - if stmt is None: - continue + if stmt is None: continue sk: int = stmt.kind() if sk != ast.ASTKind.AnnAssign: continue # AnnAssign(target=Name(id), annotation=type, value=...) aa: ast.AnnAssign* = ast.AnnAssign*(stmt) - if aa is None or aa.target is None: - continue + if aa is None or aa.target is None: continue # 获取字段名 - if aa.target.kind() != ast.ASTKind.Name: - continue + if aa.target.kind() != ast.ASTKind.Name: continue tgt: ast.Name* = ast.Name*(aa.target) - if tgt.id is None: - continue + if tgt.id is None: continue # 类体 CDefine 常量(任意位置,2026-08-10):注册到全局 CDefine 表。 # 方法内裸名(如 ISINSTANCE_CLASS_MAX)经 translate_name_value 查 @@ -359,16 +334,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase): continue # 解析字段类型 - field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) + field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) # 单参 t.CArray[elem] + 列表字面量 → 静态数组 [N x elem] # (与局部 AnnAssign 路径一致,对齐 TPC ParseListAnnotation 语义): # 否则字段保持 Ptr(elem)(如 t.CArray[str] → i8**), # for x in self.field 会误走指针迭代(元素非整数 → null 终止符 # 检查失败报错)。推断为静态数组后走数组迭代(按长度 N)。 if field_ty is not None: - field_ty = self.Gen.AssignGen._infer_static_array_ty_from_literal( - pool, aa.annotation, aa.value, field_ty) + field_ty = self.Gen.AssignGen._infer_static_array_ty_from_literal(pool, aa.annotation, aa.value, field_ty) if field_ty is None: # BUG 5 方案1修改点1:消除 i32 静默回退 # Phase A-pre(declare_only=1):依赖的类可能尚未注册,延迟到下一遍 @@ -425,8 +398,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 提取原始类型注解的类名(联合类型简化为 Ptr(i8) 时回退查找结构体) # BUG 1 方案3:传 pool 使泛型 Subscript 返回 mangled name(如 "list[ast.AST|t.CPtr]") if aa.annotation is not None: - annot_cn: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - aa.annotation, trans._imported_modules, pool, trans._from_imports) + annot_cn: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(aa.annotation, trans._imported_modules, pool, trans._from_imports) if annot_cn is not None: diag_cn_val: sizet = sizet(annot_cn) field_annot_buf[field_count] = diag_cn_val @@ -434,23 +406,20 @@ class ClassGenDef(ClassGenBase.ClassGenBase): field_annot_buf[field_count] = 0 # t.CVolatile 存储类标记 → 该字段经对象访问的 load/store 带 # volatile(如 Spinlock.locked: t.CVolatile | t.CInt)。 - if self.Gen.TypeGenErr.has_decorator_marker( - aa.annotation, "CVolatile", 0) != 0: + if self.Gen.TypeGenErr.has_decorator_marker(aa.annotation, "CVolatile", 0) != 0: field_volatile_buf[field_count] = 1 else: field_volatile_buf[field_count] = 0 # rawptr[t.CVolatile | T](volatile 指针指向物,等价 C 的 # volatile T*)→ 经该字段解引用(self.ptr[i]/self.ptr.field) # 的 load/store 带 volatile。 - if self.Gen.TypeGenErr.has_pointee_volatile_marker( - aa.annotation) != 0: + if self.Gen.TypeGenErr.has_pointee_volatile_marker(aa.annotation) != 0: field_pointee_volatile_buf[field_count] = 1 else: field_pointee_volatile_buf[field_count] = 0 # const 对象字段(注解含 t.CConst 且字段类型非指针)→ 经对象给该 # 字段赋值 fail-fast。判据与 TPC 的 Gen.field_const_flags 一致。 - if self.Gen.TypeGenErr.is_const_object_marker( - aa.annotation, field_ty) != 0: + if self.Gen.TypeGenErr.is_const_object_marker(aa.annotation, field_ty) != 0: field_const_buf[field_count] = 1 else: field_const_buf[field_count] = 0 @@ -544,8 +513,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 后续文件字段类型引用(resolve → Ptr(entry.Ty))→ opaque 扫描遍历悬空 fields # 崩溃(LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - st_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, struct_ty) + st_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, struct_ty) if st_copy is not None: struct_ty = st_copy type_name = llvmlite.get_struct_name(struct_ty) @@ -556,8 +524,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # B5:@c.Attribute(t.attr.packed) 打包结构体 → 类型定义输出 <{...}> # (LLVM packed struct,无字段填充,GEP 按 packed 布局计算偏移)。 # idt/gdt/elf/fat32 等二进制格式结构体依赖它读写硬件/磁盘布局。 - is_packed_cd: int = self.Gen.ClassGenBase._class_has_tattr( - cd.decorator_list, "packed") + is_packed_cd: int = self.Gen.ClassGenBase._class_has_tattr(cd.decorator_list, "packed") if is_packed_cd != 0: llvmlite.module_set_named_type_packed(trans.Module, pool, struct_ty, 1) @@ -573,8 +540,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # ============================================================ # 3. 注册到 HandlesStruct # ============================================================ - entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct( - pool, class_name, struct_ty, trans.ModuleSha1) + entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, struct_ty, trans.ModuleSha1) if entry is None: VLogger.error(f"failed to register {class_name}", "CLASS") return 0 diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index 1f1d24a..5cf56a5 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -18,20 +18,15 @@ from . import ClassGenBase # 未定义名在常量上下文被 TPV 折叠为 0,会导致枚举成员收集被静默跳过、 # register_enum 永不调用 → 所有 CEnum 注册失败 → 裸名枚举访问 NameError) # ============================================================ -ENUM_MEMBER_MAX_LOCAL: t.CDefine = 128 # 与 StmtGenDeclMixin.ENUM_MEMBER_MAX 一致 -RENUM_CLASS_MAX: t.CDefine = 64 -RENUM_VARIANT_PER_CLASS: t.CDefine = 32 -RENUM_ALIAS_MAX: t.CDefine = 512 +define ENUM_MEMBER_MAX_LOCAL = 128 +define RENUM_ENUM_CLASS_MAX = 64 +define RENUM_ENUM_VARIANT_PER_CLASS = 32 +define RENUM_ENUM_ALIAS_MAX = 512 # ============================================================ # ClassGenEnum - ClassGenMixin 拆分(阶段 D):enum/union/renum 定义与变体表 -# -# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenEnum(ClassGenBase.ClassGenBase): +novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): """enum/union/renum 定义与变体表""" def _resolve_enum_member_type(self, pool: memhub.MemBuddy*, @@ -49,8 +44,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): at: ast.Attribute* = ast.Attribute*(ann_node) if at.attr is None: # [S4 fail-fast] Attribute 缺失成员名(AST 损坏),不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, "枚举成员类型注解 Attribute 缺失成员名", "TypeError") + self.Gen.TypeGenErr.fatal_error(ann_node, "枚举成员类型注解 Attribute 缺失成员名", "TypeError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # t.State → 默认 i32 if string.strcmp(at.attr, "State") == 0: @@ -62,13 +56,10 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if string.strcmp(at.attr, "CBool") == 0: return llvmlite.Int8(pool) # 其他 t.CXxx 类型:统一口径(CTypedef 动态表优先,miss 回退 map_t_type) - ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map( - pool, at.attr, imported_modules, from_imports) - if ty is not None: - return ty + ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, imported_modules, from_imports) + if ty is not None: return ty # [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, f"枚举成员类型注解解析失败: t.{at.attr}", "NameError") + self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: t.{at.attr}", "NameError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # Name 节点: from-import 形式(State / CInt) @@ -76,8 +67,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): nm: ast.Name* = ast.Name*(ann_node) if nm.id is None: # [S4 fail-fast] Name 缺失标识符(AST 损坏),不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, "枚举成员类型注解 Name 缺失标识符", "TypeError") + self.Gen.TypeGenErr.fatal_error(ann_node, "枚举成员类型注解 Name 缺失标识符", "TypeError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) if string.strcmp(nm.id, "State") == 0: return llvmlite.Int32(pool) @@ -97,27 +87,23 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # map_t_type 的 CBool,用于普通变量/形参/字段)。 # 两侧一致:TPC 侧枚举成员 bool 经 t.CBool.Size 亦为 8。 return llvmlite.Int8(pool) - ty2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map( - pool, nm.id, imported_modules, from_imports) + ty2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, nm.id, imported_modules, from_imports) if ty2 is not None: return ty2 # [S4 fail-fast] 有注解但解析失败 → 不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, f"枚举成员类型注解解析失败: {nm.id}", "NameError") + self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {nm.id}", "NameError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # BinOp 节点: t.State | int8(递归查找实际类型) if k == ast.ASTKind.BinOp: bop: ast.BinOp* = ast.BinOp*(ann_node) if bop.op == ast.OpKind.BitOr: - left_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( - pool, bop.left, imported_modules, from_imports) + left_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, bop.left, imported_modules, from_imports) # 跳过 t.State(i32 默认),优先返回具体类型 left_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(left_ty) if left_bits != 0 and not self._is_state_annotation(bop.left): return left_ty - right_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( - pool, bop.right, imported_modules, from_imports) + right_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, bop.right, imported_modules, from_imports) if right_ty is not None and not self._is_state_annotation(bop.right): return right_ty # 两边都是 State 或无法确定,返回较宽的 @@ -126,13 +112,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return left_ty return right_ty # fail-fast:BinOp 但非 BitOr(未知联合运算),不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError") + self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) # fail-fast:未知注解节点 kind,不再静默回退 i32 - self.Gen.TypeGenErr.fatal_error( - ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError") + self.Gen.TypeGenErr.fatal_error(ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) def _is_state_annotation(self, node: ast.AST*) -> int: """检查注解节点是否为 t.State,返回 1=是 / 0=否""" @@ -385,25 +369,18 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 具体整数类型、rawptr[...] 又是 Subscript(非 Name/Attribute/BinOp) # 会在解析里报笼统的"注解解析失败",两者都盖不住"指针成员"这个真因。 if self._enum_member_annotation_is_ptr(aa.annotation) == 1: - self.Gen.TypeGenErr.fatal_error( - aa, - f"枚举成员 '{tgt.id}' 不能是指针类型(枚举值只支持整数成员类型)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"枚举成员 '{tgt.id}' 不能是指针类型(枚举值只支持整数成员类型)", "TypeError") return 0 # 不可达(fatal_error 已退出) # 解析成员类型 - member_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( - pool, aa.annotation, trans._imported_modules, trans._from_imports) + member_ty: llvmlite.LLVMType* = self._resolve_enum_member_type(pool, aa.annotation, trans._imported_modules, trans._from_imports) # [枚举规格 fail-fast] 成员类型必须是整数类型:浮点/void/结构体/ # 数组的位宽均为 0,无法参与"枚举宽度 = 最宽成员类型"的推导, # 静默接受会让寄存器宽度与访问侧常量类型不一致。禁止静默降级。 member_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(member_ty) if member_bits <= 0: - self.Gen.TypeGenErr.fatal_error( - aa, - f"枚举成员 '{tgt.id}' 的类型必须为整数类型(不允许指针/浮点/void/结构体/数组),无法推导枚举宽度", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"枚举成员 '{tgt.id}' 的类型必须为整数类型(不允许指针/浮点/void/结构体/数组),无法推导枚举宽度", "TypeError") return 0 # 不可达(fatal_error 已退出) # 解析成员值 @@ -510,8 +487,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): base_ty = mty # 注册枚举 - entry: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.register_enum( - pool, class_name, base_ty) + entry: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.register_enum(pool, class_name, base_ty) if entry is None: VLogger.error("failed to register {class_name}", "ENUM") return 0 @@ -627,8 +603,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): def _translate_union_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """翻译联合体定义,返回 0""" - if cd is None or cd.name is None or trans is None: - return 0 + if cd is None or cd.name is None or trans is None: return 0 pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name @@ -637,8 +612,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): self.Gen.StructGen.add_visible_struct(pool, class_name) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - class_name, trans.ModuleSha1) + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) if existing is not None: # Phase B: 将已存在的命名结构体注册到当前模块 if existing.Ty is not None: @@ -666,36 +640,27 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): for ci in range(cn): stmt: ast.AST* = children.get(ci) - if stmt is None: - continue + if stmt is None: continue sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: aa: ast.AnnAssign* = ast.AnnAssign*(stmt) - if aa is None or aa.target is None: - continue + if aa is None or aa.target is None: continue # 获取字段名 - if aa.target.kind() != ast.ASTKind.Name: - continue + if aa.target.kind() != ast.ASTKind.Name: continue tgt: ast.Name* = ast.Name*(aa.target) - if tgt.id is None: - continue + if tgt.id is None: continue # 解析字段类型 - field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) + field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) if field_ty is None: # Phase A-pre(declare_only=1):依赖的类可能尚未注册, # 静默 return 1 让多遍收敛机制生效(renum 返回 1=跳过该类) - if trans._declare_only == 1: - return 1 + if trans._declare_only == 1: return 1 # Phase B(declare_only=0):真正的类型解析错误,fast-fail 终止 type_name: str = self.Gen.TypeGenResolve.annotation_to_str(aa.annotation) - self.Gen.TypeGenErr.fatal_error( - aa, - f"'{type_name}' is not defined", - "NameError") + self.Gen.TypeGenErr.fatal_error(aa, f"'{type_name}' is not defined", "NameError") field_ty = llvmlite.Int32(pool) # 计算字段大小,更新 max_size @@ -747,8 +712,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # entry.Ty 悬空 → 后续文件 opaque 扫描跨模块引用遍历悬空 fields 崩溃 # (LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - union_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, union_ty) + union_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, union_ty) if union_copy is not None: union_ty = union_copy @@ -756,8 +720,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): llvmlite.module_add_named_type(trans.Module, pool, union_ty) # 注册到 HandlesStruct(传递 SHA1 在注册时直接设置,避免跨模块同名找错 entry) - entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct( - pool, class_name, union_ty, trans.ModuleSha1) + entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, union_ty, trans.ModuleSha1) if entry is None: VLogger.error(f"failed to register {class_name}", "UNION") return 0 @@ -810,35 +773,20 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if dyn_sz > 0: return dyn_sz # 内置类型 - if string.strcmp(type_name, "int") == 0: - return 4 - if string.strcmp(type_name, "CInt") == 0: - return 4 - if string.strcmp(type_name, "CInt8T") == 0: - return 1 - if string.strcmp(type_name, "CInt16T") == 0: - return 2 - if string.strcmp(type_name, "CInt32T") == 0: - return 4 - if string.strcmp(type_name, "CInt64T") == 0: - return 8 - if string.strcmp(type_name, "CChar") == 0: - return 1 - if string.strcmp(type_name, "CDouble") == 0: - return 8 - if string.strcmp(type_name, "CFloat") == 0: - return 4 - if string.strcmp(type_name, "CPtr") == 0: - return 8 - if string.strcmp(type_name, "CSizeT") == 0: - return 8 - if string.strcmp(type_name, "str") == 0: - return 8 - if string.strcmp(type_name, "bytes") == 0: - return 8 - if string.strcmp(type_name, "bool") == 0: - # bool = t.CBool = i8(1 字节) - return 1 + if string.strcmp(type_name, "int") == 0: return 4 + if string.strcmp(type_name, "CInt") == 0: return 4 + if string.strcmp(type_name, "CInt8T") == 0: return 1 + if string.strcmp(type_name, "CInt16T") == 0: return 2 + if string.strcmp(type_name, "CInt32T") == 0: return 4 + if string.strcmp(type_name, "CInt64T") == 0: return 8 + if string.strcmp(type_name, "CChar") == 0: return 1 + if string.strcmp(type_name, "CDouble") == 0: return 8 + if string.strcmp(type_name, "CFloat") == 0: return 4 + if string.strcmp(type_name, "CPtr") == 0: return 8 + if string.strcmp(type_name, "CSizeT") == 0: return 8 + if string.strcmp(type_name, "str") == 0: return 8 + if string.strcmp(type_name, "bytes") == 0: return 8 + if string.strcmp(type_name, "bool") == 0: return 1 # 已注册的结构体类型 struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(type_name) if struct_ty is not None: @@ -850,8 +798,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): def _translate_renum_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """翻译 REnum 类定义,返回 0""" - if cd is None or cd.name is None or trans is None: - return 0 + if cd is None or cd.name is None or trans is None: return 0 pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name @@ -860,8 +807,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): self.Gen.StructGen.add_visible_struct(pool, class_name) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - class_name, trans.ModuleSha1) + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) if existing is not None: # existing 只保证 struct entry 在,不保证 REnum 语义(变体表)在:struct entry # 由 register_struct 写 StructTable,跨 Phase 存活(perm_pool);而变体表是 gen @@ -885,9 +831,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # [D32 fail-fast] 此前只 warning + return 0:变体表**静默不注册** → # _is_renum_class_name 恒 0、变体构造拿不到 tag(__types.vp L703 # `LLVMType.Metadata()` 被当外部函数根因)。禁止静默跳过。 - self.Gen.TypeGenErr.fatal_error( - cd, f"REnum 类 '{class_name}' 缺少类体(children 为 None),无法注册变体表", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cd, f"REnum 类 '{class_name}' 缺少类体(children 为 None),无法注册变体表", "TypeError") return 0 cn: sizet = len(children) @@ -946,13 +890,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if vnm is not None and vnm.id is not None: mem_ty_l: llvmlite.LLVMType* = None if trans is not None: - mem_ty_l = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, vaa.annotation, - trans._imported_modules, - trans._from_imports, trans, 0) - self._register_renum_field_alias( - pool, class_name, vnm.id, field_idx + 1, - mem_ty_l, variant_cd.name) + mem_ty_l = self.Gen.TypeGenResolve.resolve_annotation_type(pool, vaa.annotation, trans._imported_modules, trans._from_imports, trans, 0) + self._register_renum_field_alias(pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name) field_idx += 1 if field_idx > max_field_count: max_field_count = field_idx @@ -980,9 +919,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if variant_count == 0: # [D32 fail-fast] 同上:变体数为 0 时此前静默 return → 变体表不注册。 # 对 `class X(t.REnum)` 而言变体数必 > 0,为 0 说明 AST 变体类丢失。 - self.Gen.TypeGenErr.fatal_error( - cd, f"REnum 类 '{class_name}' 的变体数为 0(嵌套变体类丢失),无法注册变体表", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cd, f"REnum 类 '{class_name}' 的变体数为 0(嵌套变体类丢失),无法注册变体表", "TypeError") return 0 # 计算每个位置的最大字段大小 @@ -1046,8 +983,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): viperlib.snprintf(renum_name_buf, 64, "%s.%s", trans.ModuleSha1, class_name) renum_type_name = renum_name_buf - renum_ty: llvmlite.LLVMType* = llvmlite.Struct( - pool, first_node, total_positions, renum_type_name) + renum_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, total_positions, renum_type_name) if renum_ty is None: VLogger.error(f"failed to create type for {class_name}", "RENUM") return 0 @@ -1056,8 +992,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 与 entry.Ty 保持同一指针,find_struct_by_type 匹配不失效) # StdlibAlloc=1(Phase2 mark2 后)也必须深拷贝:同 union 的悬空根因。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - renum_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, renum_ty) + renum_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, renum_ty) if renum_copy is not None: renum_ty = renum_copy @@ -1065,8 +1000,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): llvmlite.module_add_named_type(trans.Module, pool, renum_ty) # 注册到 HandlesStruct - entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct( - pool, class_name, renum_ty, trans.ModuleSha1) + entry: GenTypes.StructEntry* = self.Gen.StructGen.register_struct(pool, class_name, renum_ty, trans.ModuleSha1) if entry is None: VLogger.error(f"failed to register {class_name}", "RENUM") return 0 @@ -1152,29 +1086,20 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 与第一遍同规则:有效 AnnAssign 仍占用 payload 槽位 field_idx += 1 continue - mem_ty_l: llvmlite.LLVMType* = \ - self.Gen.TypeGenResolve.resolve_annotation_type( - pool, vaa.annotation, - trans._imported_modules, - trans._from_imports, trans, 0) + mem_ty_l: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, vaa.annotation, trans._imported_modules, trans._from_imports, trans, 0) # 解析成功 → 触发别名表去重路径(类型槽为 0 时回填;非 0 跳过) if mem_ty_l is not None: - self._register_renum_field_alias( - pool, class_name, vnm.id, field_idx + 1, - mem_ty_l, variant_cd.name) + self._register_renum_field_alias(pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name) field_idx += 1 def _register_renum_variants(self, pool: memhub.MemBuddy*, class_name: str, cd: ast.ClassDef*, variant_count: int): """注册 REnum 类的变体名和 tag 值到全局变体表""" - if pool is None or class_name is None or cd is None: - return - if variant_count == 0: - return + if pool is None or class_name is None or cd is None: return + if variant_count == 0: return children: list[ast.AST*]* = cd.children - if children is None: - return + if children is None: return # 懒初始化表(首次注册时分配) # 注意: 必须用 stdlib 分配——这些表在 1b 阶段(mark1 之后)首次分配, @@ -1464,8 +1389,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # _refill_renum_field_types)类型槽为 0 时,本次解析成功则 # 回填真实类型;非 0 槽保持原样(避免重复 DeepCopy 覆盖抖动)。 if self.RenumAliasTy[i] == 0 and field_ty is not None: - ty_copy_rf2: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, field_ty) + ty_copy_rf2: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, field_ty) if ty_copy_rf2 is not None: self.RenumAliasTy[i] = sizet(ty_copy_rf2) return @@ -1492,8 +1416,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 未解析成功(自引用等)存 0,绑定回退槽位类型) self.RenumAliasTy[idx] = 0 if field_ty is not None: - ty_copy_rfa: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, field_ty) + ty_copy_rfa: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, field_ty) if ty_copy_rfa is not None: self.RenumAliasTy[idx] = sizet(ty_copy_rfa) # 变体名同样 strcpy 到 perm_pool(1a reset 后 variant_cd.name 悬空) diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 5c4322b..30f236b 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -15,22 +15,16 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore # 泛型特化递归深度上限(泛型循环套用防护) # 正常嵌套特化深度 ≤ 3(如 list[list[str]]);64 远超合理值,命中即循环。 -# (原 HandlesClassDef/ClassGenMixin 顶层常量,阶段 D 拆分时遗漏,补回) -GENERIC_SPEC_MAX_DEPTH: t.CDefine = 64 +define GENERIC_SPEC_MAX_DEPTH = 64 # 泛型模板表容量上限(与 GenericClassNames 等 pool 表可容纳的模板数对齐; -# 原 ClassGenMixin 顶层常量,阶段 D 拆分时遗漏,补回) -GENERIC_TEMPLATE_MAX: t.CDefine = 512 -# 泛型特化缓存表容量(原 HandlesClassDef.SPEC_CACHE_MAX,阶段 D 拆分遗漏) -SPEC_CACHE_MAX: t.CDefine = 512 +define GENERIC_TEMPLATE_MAX = 512 +# 泛型特化缓存表容量 +define SPEC_CACHE_MAX = 512 # ============================================================ # ClassGenGeneric - 泛型模板注册/特化/克隆 -# -# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesClassDef 委托。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenGeneric(ClassGenBase.ClassGenBase): +novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): """泛型模板注册/特化/克隆""" # ============================================================ @@ -49,20 +43,16 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): 接收 type_params 而非 cd,避免 cd.type_params 属性访问 因跨模块类型推断失败返回 None。 """ - if tp is None: - return 0 + if tp is None: return 0 return 1 def _dup_perm_str(self, s: str) -> str: """深拷贝字符串到永久池(无永久池/分配失败时原样返回入参)""" - if s is None: - return None + if s is None: return None perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool - if perm is None: - return s + if perm is None: return s n: sizet = string.strlen(s) b: str = perm.alloc(n + 1) - if b is None: - return s + if b is None: return s string.strcpy(b, s) return b def _register_generic_template(self, pool: memhub.MemBuddy*, @@ -92,8 +82,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): (同样的类名/节点/ SHA1/文件路径,同样的插入顺序与查重),发射的 IR 与 符号名不受池选择影响 ⇒ 逐字不变。 """ - if cd is None or cd.name is None: - return + if cd is None or cd.name is None: return perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool table_pool: memhub.MemBuddy* = perm if table_pool is None: @@ -104,11 +93,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): self.GenericClassSha1s = list[str](table_pool, 8) self.GenericClassFiles = list[str](table_pool, 8) if self.GenericClassTpParams is None: - if perm is None: - return + if perm is None: return self.GenericClassTpParams = perm.alloc(GENERIC_TEMPLATE_MAX * 8) - if self.GenericClassTpParams is None: - return + if self.GenericClassTpParams is None: return string.memset(self.GenericClassTpParams, 0, GENERIC_TEMPLATE_MAX * 8) # 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败) names_local: list[str]* = self.GenericClassNames @@ -116,16 +103,14 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): i: sizet for i in range(cn): nm: str = names_local.get(i) - if nm is not None and string.strcmp(nm, cd.name) == 0: - return + if nm is not None and string.strcmp(nm, cd.name) == 0: return # type_params stdlib 深拷贝:模板节点的 type_params 是 pool 分配的 tp_names_buf: str = self._copy_type_params_stdlib(cd.type_params) self.GenericClassNames.append(self._dup_perm_str(cd.name)) self.GenericClassNodes.append(cd) self.GenericClassSha1s.append(self._dup_perm_str(module_sha1)) # 同时保存模板来源文件路径(错误定位用,见字段注释) - self.GenericClassFiles.append( - self._dup_perm_str(self.Gen.TypeGenResolve.get_current_file())) + self.GenericClassFiles.append(self._dup_perm_str(self.Gen.TypeGenResolve.get_current_file())) if tp_names_buf is not None and cn < GENERIC_TEMPLATE_MAX: self.GenericClassTpParams[cn] = sizet(tp_names_buf) def _copy_type_params_stdlib(self, tp: list[str]*) -> str: @@ -602,12 +587,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 方法体永不发射 → 特化方法只有 call 无 define → 链接 undefined symbol。 pre_existing.MethodsEmitted = 1 # 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效) - tp_names_pre: list[str]* = self._find_generic_template_tp_params( - pool, class_name) + tp_names_pre: list[str]* = self._find_generic_template_tp_params(pool, class_name) if tp_names_pre is None: tp_names_pre = template_cd.type_params - spec_cd_pre: ast.ClassDef* = self._clone_classdef_for_spec( - pool, template_cd, spec_name, tp_names_pre, type_args) + spec_cd_pre: ast.ClassDef* = self._clone_classdef_for_spec(pool, template_cd, spec_name, tp_names_pre, type_args) if spec_cd_pre is not None: trans.GenericTypeParamNames = tp_names_pre trans.GenericTypeArgs = type_args @@ -681,12 +664,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 5. 拷贝 ClassDef 节点 # 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效) - tp_names: list[str]* = self._find_generic_template_tp_params( - pool, class_name) + tp_names: list[str]* = self._find_generic_template_tp_params(pool, class_name) if tp_names is None: tp_names = template_cd.type_params - spec_cd: ast.ClassDef* = self._clone_classdef_for_spec( - pool, template_cd, spec_name, tp_names, type_args) + spec_cd: ast.ClassDef* = self._clone_classdef_for_spec(pool, template_cd, spec_name, tp_names, type_args) if spec_cd is None: self.GenericSpecDepth -= 1 return None @@ -734,10 +715,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if string.strcmp(class_name, "GSListNode") == 0: result_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(spec_name) if result_entry is not None: - ri: int for ri in range(result_entry.FieldCount): - rfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( - result_entry, ri) + rfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(result_entry, ri) if rfe is not None: rfn: str = self.Gen.StructGen.get_field_name_ptr(rfe) if rfn is None: diff --git a/App/lib/core/Gen/Class/ClassGenMixin.vp b/App/lib/core/Gen/Class/ClassGenMixin.vp index a2968f7..888c4a6 100644 --- a/App/lib/core/Gen/Class/ClassGenMixin.vp +++ b/App/lib/core/Gen/Class/ClassGenMixin.vp @@ -4,10 +4,6 @@ from . import ClassGenBase # ============================================================ # ClassGenMixin - 类定义/继承/泛型/vtable/enum/union/renum -# -# 方法已全部拆至 ClassGenBase/Enum/Generic/VTable/Def,本文件保留类声明。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenMixin(ClassGenBase.ClassGenBase): +novirtual class ClassGenMixin(ClassGenBase.ClassGenBase): """类定义处理 Mixin(阶段 D 拆分后顶层,方法全部在子 Mixin)""" diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index 3c7a1b6..fcb9818 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -17,21 +17,15 @@ import lib.core.Gen.GenApi as GenApi # 方法元数据 flag:TLS(@t.TLS 装饰器,对齐 ClassGenBase 本地常量;本地副本避免跨模块 CDefine 查找) -META_TLS: t.CDefine = 32 -# 虚表方法数上限(原 HandlesClassDef.VTBL_METHOD_MAX,阶段 D 拆分遗漏) -VTBL_METHOD_MAX: t.CDefine = 32 - -SCOPE_FUNCTION: t.CDefine = 1 +define META_TLS = 32 +# 虚表方法数上限 +define VTBL_METHOD_MAX = 32 +define SCOPE_FUNCTION = 1 # ============================================================ # ClassGenVTable - ClassGenMixin 拆分(阶段 D):vtable 收集/生成/方法翻译 -# -# 继承 ClassGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesClassDef 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ClassGenVTable(ClassGenBase.ClassGenBase): +novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): """vtable 收集/生成/方法翻译""" # ============================================================ @@ -45,8 +39,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): dlen: sizet = string.strlen(dst) slen: sizet = string.strlen(src) remain: sizet = dst_size - dlen - if remain <= 0: - return + if remain <= 0: return i: sizet = 0 while i < slen and i + 1 < remain: dst[dlen + i] = src[i] @@ -114,8 +107,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 如果子类覆盖了方法,full_name 用子类的;否则用父类的。 # 用 SHA1 感知查找,规避跨模块同名 find_struct 找错 # ============================================================ - vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - class_name, trans.ModuleSha1) + vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) # 多继承:遍历所有父类(声明顺序),vtable 方法合并(短名去重,先声明父类优先) parent_count: int = self.Gen.StructGen.get_parent_count(class_name) if parent_count > 0: @@ -124,8 +116,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if pname is None: continue # 查找父类 entry(优先同模块 SHA1 匹配) - vt_parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - pname, trans.ModuleSha1) + vt_parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pname, trans.ModuleSha1) if vt_parent_entry is None: # 跨模块继承: 父类在不同模块定义(SHA1 不同),回退到按类名查找 vt_parent_entry = self.Gen.StructGen.find_struct(pname) @@ -204,8 +195,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): method_parent_sha1s[method_count] = 0 else: # 继承未覆盖: 用实际定义类的模块 SHA1(跨模块继承时 mangling 正确) - def_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct( - def_class) + def_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(def_class) if def_entry2 is not None and def_entry2.ModuleSha1 is not None: method_parent_sha1s[method_count] = sizet(def_entry2.ModuleSha1) else: @@ -308,8 +298,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): method_parent_sha1s: sizet* = self.VtParentSha1s method_count: int = self.VtMethodCount # 重新获取 entry(后续存储 VTableMethods 用) - vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - class_name, trans.ModuleSha1) + vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) # 2. 构造 VTable 类型: { i8*, i8*, ..., i8* } i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) @@ -370,8 +359,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): continue func_ty_buf[0] = '\0' if ge is None or ge.Spec is None or TSpec.SpecToLLVMText(ge.Spec, func_ty_buf, 1024) != 0: - self.Gen.TypeGenErr.fatal_error( - cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError") continue # 构造 bitcast 字符串: i8* bitcast (func_ty* @mangled to i8*) @@ -397,8 +385,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): vtable_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vtable_name_buf) # 5. 创建全局变量 - gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable( - pool, vtable_mangled, vtable_ty) + gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, vtable_mangled, vtable_ty) if gv is None: return 0 gv.Initializer = init_buf @@ -636,8 +623,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 推断返回类型 ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: - ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, fd.returns, imported_modules, from_imports, trans, 0) + ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0) if ret_ty is None and fd.returns is not None: # 存储类标记(t.State / t.CExport / t.CExtern)语义为 Void:这类注解 # 不携带真实返回类型(extern/export 语法写成 "<原类型> | t.<标记>", @@ -649,8 +635,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): else: # [S4 fail-fast] 有返回注解但解析失败 → 不再退回 infer_return_type() # (推断可能给出与真实注解不符的类型,静默错到运行期才暴露) - self.Gen.TypeGenErr.fatal_error( - fd, f"方法 '{class_name}.{method_name}' 返回类型注解解析失败", "NameError") + self.Gen.TypeGenErr.fatal_error(fd, f"方法 '{class_name}.{method_name}' 返回类型注解解析失败", "NameError") return 0 if ret_ty is None: # __init__ 和 __before_init__ 返回 void @@ -661,12 +646,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): ret_ty = llvmlite.Ptr(pool, struct_ty) else: param_types_str: str = self.Gen.TypeGenErr.build_param_types_str(pool, fd.args) - ret_ty = self.Gen.TypeGenErr.infer_return_type( - pool, fd.children, param_types_str) + ret_ty = self.Gen.TypeGenErr.infer_return_type(pool, fd.children, param_types_str) # 创建 LLVM 函数 - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled_name, ret_ty) + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_name, ret_ty) if func is None: return 0 @@ -728,14 +711,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if arg is not None and arg.arg is not None: param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg.annotation, imported_modules, from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 # (方法签名与调用点/实现体三方不一致) - self.Gen.TypeGenErr.fatal_error( - arg, f"方法 '{class_name}.{method_name}' 形参 '{arg.arg}' 类型注解解析失败", - "NameError") + self.Gen.TypeGenErr.fatal_error(arg, f"方法 '{class_name}.{method_name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError") return 0 # 裸类形参 → Ptr(struct):按"对象即指针"引用传参。 # 若按 struct 值传参,self.Head = node 会取局部拷贝地址 @@ -783,8 +763,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): tls_m_flag_name: str = pool.alloc(128) if tls_m_flag_name is not None: viperlib.snprintf(tls_m_flag_name, 128, "__tls_init_done_%s", method_name) - tls_m_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int( - pool, mod, tls_m_flag_name, 1, 0) + tls_m_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(pool, mod, tls_m_flag_name, 1, 0) if tls_m_gv is not None: i1_ty_m: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_m is not None: @@ -793,46 +772,37 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): tls_m_rn: str = pool.alloc(64) if tls_m_rn is not None: viperlib.snprintf(tls_m_rn, 64, "@%s", tls_m_flag_name) - tls_m_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, tls_m_ptr_ty, tls_m_rn) + tls_m_ref: llvmlite.Value* = llvmlite.SSAValue(pool, tls_m_ptr_ty, tls_m_rn) if tls_m_ref is not None: - tls_m_ld: llvmlite.Value* = llvmlite.build_load( - func_builder, i1_ty_m, tls_m_ref) + tls_m_ld: llvmlite.Value* = llvmlite.build_load(func_builder, i1_ty_m, tls_m_ref) lc_m: int = trans._label_counter trans._label_counter = lc_m + 1 tls_m_buf: str = pool.alloc(64) if tls_m_buf is not None: viperlib.snprintf(tls_m_buf, 64, "tls.skip.%d", lc_m) - tls_m_skip: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, tls_m_buf) + tls_m_skip: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_m_buf) viperlib.snprintf(tls_m_buf, 64, "tls.cont.%d", lc_m) - tls_m_cont: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, tls_m_buf) + tls_m_cont: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_m_buf) if tls_m_skip is not None and tls_m_cont is not None: - llvmlite.build_cond_br( - func_builder, tls_m_ld, tls_m_skip, tls_m_cont) + llvmlite.build_cond_br(func_builder, tls_m_ld, tls_m_skip, tls_m_cont) llvmlite.position_at_end(func_builder, tls_m_skip) match ret_ty: case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(func_builder) case llvmlite.LLVMType.Int(_): - tlm0: llvmlite.Value* = llvmlite.ConstInt( - pool, ret_ty, 0, "0") + tlm0: llvmlite.Value* = llvmlite.ConstInt(pool, ret_ty, 0, "0") if tlm0 is not None: llvmlite.build_ret(func_builder, tlm0) case llvmlite.LLVMType.Float(_): - tlmf: llvmlite.Value* = llvmlite.ConstFloat( - pool, ret_ty, 0.0) + tlmf: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0) if tlmf is not None: llvmlite.build_ret(func_builder, tlmf) case _: - tlmn: llvmlite.Value* = llvmlite.ConstNull( - pool, ret_ty, "null") + tlmn: llvmlite.Value* = llvmlite.ConstNull(pool, ret_ty, "null") if tlmn is not None: llvmlite.build_ret(func_builder, tlmn) llvmlite.position_at_end(func_builder, tls_m_cont) - tlmo: llvmlite.Value* = llvmlite.ConstInt( - pool, i1_ty_m, 1, "1") + tlmo: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_m, 1, "1") if tlmo is not None: llvmlite.build_store(func_builder, tlmo, tls_m_ref) @@ -878,13 +848,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if arg2 is not None and arg2.arg is not None: param_ty2: llvmlite.LLVMType* = i32_ty if arg2.annotation is not None: - resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg2.annotation, imported_modules, from_imports, trans, 0) + resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg2.annotation, imported_modules, from_imports, trans, 0) if resolved2 is None: # fail-fast:参数有注解但类型解析失败,不再静默保持 i32 - self.Gen.TypeGenErr.fatal_error( - arg2, f"方法 '{class_name}.{method_name}' 参数 '{arg2.arg}' 类型解析失败", - "NameError") + self.Gen.TypeGenErr.fatal_error(arg2, f"方法 '{class_name}.{method_name}' 参数 '{arg2.arg}' 类型解析失败", "NameError") resolved2 = i32_ty # 不可达(fatal_error 已退出) if resolved2 is not None: # 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针) @@ -902,16 +869,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 存储原始类型注解的类名(方法调用检测时,Ptr(i8) 回退到类名查找结构体) # 传 pool:泛型 Subscript 返回 mangled name(对齐 HandlesAnnAssign 修复) if arg2.annotation is not None: - cls_nm_oc: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - arg2.annotation, imported_modules, pool, trans._from_imports) + cls_nm_oc: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg2.annotation, imported_modules, pool, trans._from_imports) if cls_nm_oc is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, arg2.arg, cls_nm_oc) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg2.arg, cls_nm_oc) pname2: str = pool.alloc(32) if pname2 is not None: viperlib.snprintf(pname2, 32, "%%%s", arg2.arg) - param_val: llvmlite.Value* = llvmlite.SSAValue( - pool, param_ty2, pname2) + param_val: llvmlite.Value* = llvmlite.SSAValue(pool, param_ty2, pname2) llvmlite.build_store(func_builder, param_val, alloca) # OOP iter 协议:__next__ 的 stop-flag 参数初始化(store 0)并保存 @@ -922,12 +886,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if i1_ty_sf is not None: i1_ptr_ty_sf: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_sf) if i1_ptr_ty_sf is not None: - flag_ref_sf: llvmlite.Value* = llvmlite.SSAValue( - pool, i1_ptr_ty_sf, "%__stop_iter_flag__") + flag_ref_sf: llvmlite.Value* = llvmlite.SSAValue(pool, i1_ptr_ty_sf, "%__stop_iter_flag__") if flag_ref_sf is not None: trans._stop_iter_flag_ptr = flag_ref_sf - zero_i1_sf: llvmlite.Value* = llvmlite.ConstInt( - pool, i1_ty_sf, 0, "0") + zero_i1_sf: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_sf, 0, "0") if zero_i1_sf is not None: llvmlite.build_store(func_builder, zero_i1_sf, flag_ref_sf) @@ -1013,12 +975,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # TypeGenResolve._is_cvoid_marker(TypeGenResolve.vp:1484) # ③ -> None(CONST_NONE):解析即 Void(TypeGenResolve.vp:1996-1999) if _is_void == 0 and fd.returns is not None: - if self.Gen.TypeGenResolve._is_cvoid_marker( - fd.returns, imported_modules) != 0: + if self.Gen.TypeGenResolve._is_cvoid_marker(fd.returns, imported_modules) != 0: _is_void = 1 elif fd.returns.kind() == ast.ASTKind.Constant: - ret_none_cn_m: ast.Constant* = ( - ast.Constant*)(fd.returns) + ret_none_cn_m: ast.Constant* = (ast.Constant*)(fd.returns) if ret_none_cn_m.const_kind == ast.CONST_NONE: _is_void = 1 if _is_void != 0: @@ -1049,10 +1009,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): rt_name_m = "?" err_fn_m: str = pool.alloc(256) if err_fn_m is not None: - viperlib.snprintf( - err_fn_m, 256, - "方法 '%s' 流程掉出末尾但未显式 return(返回类型 %s)," - "请补显式 return(如 return 0 / return null)", method_name, rt_name_m) + viperlib.snprintf(err_fn_m, 256, "方法 '%s' 流程掉出末尾但未显式 return(返回类型 %s),请补显式 return(如 return 0 / return null)", method_name, rt_name_m) self.Gen.TypeGenErr.fatal_error(fd, err_fn_m, "TypeError") self.Gen.TypeGenErr.fatal_error(fd, "方法流程掉出末尾但未显式 return", "TypeError") else: @@ -1096,18 +1053,15 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 构建函数名: ClassName.__before_init__ full_name_buf: str = pool.alloc(128) - if full_name_buf is None: - return 0 + if full_name_buf is None: return 0 viperlib.snprintf(full_name_buf, 128, "%s.__before_init__", class_name) full_name: str = full_name_buf mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name) # 创建函数 - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled_name, void_ty) - if func is None: - return 0 + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_name, void_ty) + if func is None: return 0 # 注册到函数表 max_funcs: int = 1024 @@ -1123,11 +1077,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 创建 entry 块 + builder entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") - if entry_blk is None: - return 0 + if entry_blk is None: return 0 func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) - if func_builder is None: - return 0 + if func_builder is None: return 0 llvmlite.position_at_end(func_builder, entry_blk) # 注册 self 为 SSA 值 @@ -1181,8 +1133,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): vt_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vt_full_name) # GEP 到 __vtable__ 字段(索引 0) - vt_slot: llvmlite.Value* = llvmlite.build_gep_struct( - func_builder, struct_ty, vt_i8_ptr_ty, self_val, 0) + vt_slot: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, vt_i8_ptr_ty, self_val, 0) if vt_slot is not None: # 创建全局变量引用 Value vt_ref: llvmlite.Value* = llvmlite.new_value(pool) @@ -1200,16 +1151,14 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.value_set_name(vt_ref, vt_ref_name) # bitcast 到 i8* - vt_as_i8: llvmlite.Value* = llvmlite.build_bitcast( - func_builder, vt_ref, vt_i8_ptr_ty) + vt_as_i8: llvmlite.Value* = llvmlite.build_bitcast(func_builder, vt_ref, vt_i8_ptr_ty) if vt_as_i8 is not None: llvmlite.build_store(func_builder, vt_as_i8, vt_slot) # 2. 逐字段 store 默认值(用 bi_entry 直接访问,规避跨模块同名 find_struct 找错) if bi_entry is not None: for fi in range(bi_entry.FieldCount): - fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( - bi_entry, fi) + fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(bi_entry, fi) if fe is None or fe.DefaultVal is None: continue # 静态数组字段 + 列表字面量默认值 → 整体置零 + 逐元素 GEP+store @@ -1219,8 +1168,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 推断为静态数组,此处保证 __before_init__ 填充真实字符串指针。 if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 \ and fe.DefaultVal.kind() == ast.ASTKind.List: - field_ptr_arr: llvmlite.Value* = llvmlite.build_gep_struct( - func_builder, struct_ty, fe.Ty, self_val, fe.Index) + field_ptr_arr: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, fe.Ty, self_val, fe.Index) if field_ptr_arr is not None: zero_arr_f: llvmlite.Value* = llvmlite.ConstZero(pool, fe.Ty) if zero_arr_f is not None: @@ -1232,22 +1180,16 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): arr_ctx: str = pool.alloc(192) if arr_ctx is not None: fname_dbg_v: str = fe.Name - if fname_dbg_v is None: - fname_dbg_v = "?" + if fname_dbg_v is None: fname_dbg_v = "?" viperlib.snprintf(arr_ctx, 192, "类 %s 字段 %s:", class_name, fname_dbg_v) - self.Gen.AssignGen._init_global_array_from_list( - func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans, arr_ctx) + self.Gen.AssignGen._init_global_array_from_list(func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans, arr_ctx) continue # 翻译默认值表达式 - default_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - func_builder, pool, mod, fe.DefaultVal, None, 0, trans) - if default_val is None: - continue + default_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(func_builder, pool, mod, fe.DefaultVal, None, 0, trans) + if default_val is None: continue # GEP 到字段 - field_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - func_builder, struct_ty, fe.Ty, self_val, fe.Index) - if field_ptr is None: - continue + field_ptr: llvmlite.Value* = llvmlite.build_gep_struct(func_builder, struct_ty, fe.Ty, self_val, fe.Index) + if field_ptr is None: continue # 类型转换并 store default_val = self.Gen.ExprGenBase.coerce_to_type(func_builder, default_val, fe.Ty, fe.DefaultVal) llvmlite.build_store(func_builder, default_val, field_ptr) diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 5ac98c3..0be5e0a 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -13,13 +13,8 @@ import lib.core.Gen.Type.TypeSpec as TSpec # ============================================================ # ExprGenBase - ExprGenMixin 拆分(阶段 D):表达式基础工具(类型判断/指针层级/coerce) -# -# 最底层 Base(ExprGenMixin/Const/Fstr/Ops/Cdef/Name/Attr/Cls 均 1 级继承本类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenBase: +novirtual class ExprGenBase: """表达式基础工具(类型判断/指针层级/coerce)""" # --- docstring 登记表字段(__doc__ 魔法属性支持)--- @@ -44,8 +39,7 @@ class ExprGenBase: # ============================================================ def get_func_name(self, func_node: ast.AST*) -> str: """从函数节点提取函数名""" - if func_node is None: - return None + if func_node is None: return None k: int = func_node.kind() if k == ast.ASTKind.Name: nm: ast.Name* = ast.Name*(func_node) @@ -60,13 +54,11 @@ class ExprGenBase: def escape_llvm_string(self, pool: memhub.MemBuddy*, src: str) -> str: """将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """ - if src is None: - return None + if src is None: return None slen: sizet = string.strlen(src) alloc_size: sizet = 4 * slen + 8 buf: str = pool.alloc(alloc_size) - if buf is None: - return None + if buf is None: return None pos: sizet = 0 buf[pos] = 'c' pos += 1 @@ -114,8 +106,7 @@ class ExprGenBase: # ============================================================ def get_llvm_float_bits(self, ty: llvmlite.LLVMType*) -> int: """获取 LLVM 浮点类型的位宽,非浮点类型返回 0""" - if ty is None: - return 0 + if ty is None: return 0 match ty: case llvmlite.LLVMType.Float(bits): return bits @@ -128,8 +119,7 @@ class ExprGenBase: # ============================================================ def is_ptr_type(self, ty: llvmlite.LLVMType*) -> int: """检查 ty 是否是 Ptr 类型,返回 1=是, 0=否""" - if ty is None: - return 0 + if ty is None: return 0 match ty: case llvmlite.LLVMType.Ptr(pointee): return 1 @@ -166,15 +156,11 @@ class ExprGenBase: # ============================================================ def _is_zero_int_literal(self, node: ast.AST*) -> int: """判断节点是否为整数字面量 0,返回 1=是 / 0=否""" - if node is None: - return 0 - if node.kind() != ast.ASTKind.Constant: - return 0 + if node is None: return 0 + if node.kind() != ast.ASTKind.Constant: return 0 cn: ast.Constant* = ast.Constant*(node) - if cn is None or cn.const_kind != ast.CONST_INT: - return 0 - if cn.int_val == 0: - return 1 + if cn is None or cn.const_kind != ast.CONST_INT: return 0 + if cn.int_val == 0: return 1 return 0 # ============================================================ # is_array_type - 检查类型是否为 Array @@ -183,8 +169,7 @@ class ExprGenBase: # ============================================================ def is_array_type(self, ty: llvmlite.LLVMType*) -> int: """检查 ty 是否是 Array 类型,返回 1=是, 0=否""" - if ty is None: - return 0 + if ty is None: return 0 match ty: case llvmlite.LLVMType.Array(_, _): return 1 @@ -245,22 +230,16 @@ class ExprGenBase: trans: HT.Translator*, sub_node: ast.AST*) -> int: """判断下标基座是否为 list[T] 变量(1=是)""" - if sub_node is None or trans is None: - return 0 + if sub_node is None or trans is None: return 0 sub: ast.Subscript* = ast.Subscript*(sub_node) - if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: - return 0 + if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return 0 nm: ast.Name* = ast.Name*(sub.value) - if nm.id is None: - return 0 + if nm.id is None: return 0 alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) - if alloca is None or alloca.Ty is None: - return 0 - if self.is_ptr_type(alloca.Ty) == 0: - return 0 + if alloca is None or alloca.Ty is None: return 0 + if self.is_ptr_type(alloca.Ty) == 0: return 0 pointee: llvmlite.LLVMType* = alloca.Ty.Pointee - if pointee is None: - return 0 + if pointee is None: return 0 match pointee: case llvmlite.LLVMType.Ptr(inner_ty): lsn_ls: str = None @@ -281,22 +260,16 @@ class ExprGenBase: trans: HT.Translator*, sub_node: ast.AST*) -> str: """解析下标基座变量的结构体类名(无则 None)""" - if sub_node is None or trans is None: - return None + if sub_node is None or trans is None: return None sub: ast.Subscript* = ast.Subscript*(sub_node) - if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: - return None + if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return None nm: ast.Name* = ast.Name*(sub.value) - if nm.id is None: - return None + if nm.id is None: return None alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) - if alloca is None or alloca.Ty is None: - return None - if self.is_ptr_type(alloca.Ty) == 0: - return None + if alloca is None or alloca.Ty is None: return None + if self.is_ptr_type(alloca.Ty) == 0: return None pointee: llvmlite.LLVMType* = alloca.Ty.Pointee - if pointee is None: - return None + if pointee is None: return None if self.is_ptr_type(pointee) != 0: inner: llvmlite.LLVMType* = pointee.Pointee if inner is not None: @@ -316,17 +289,13 @@ class ExprGenBase: trans: HT.Translator*, sub_node: ast.AST*) -> int: """下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)""" - if self._is_list_subscript_base(pool, trans, sub_node) != 0: - return 1 + if self._is_list_subscript_base(pool, trans, sub_node) != 0: return 1 cls_ugi: str = self._sub_base_class_name(pool, trans, sub_node) - if cls_ugi is None: - return 0 + if cls_ugi is None: return 0 lookup_ugi: str = pool.alloc(128) - if lookup_ugi is None: - return 0 + if lookup_ugi is None: return 0 viperlib.snprintf(lookup_ugi, 128, "%s.__getitem__", cls_ugi) - if self.Gen.CallGenBase.find_func_in_module(mod, lookup_ugi) is not None: - return 1 + if self.Gen.CallGenBase.find_func_in_module(mod, lookup_ugi) is not None: return 1 return 0 # ============================================================ # _deref_if_ptr_ptr - 如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用 @@ -338,19 +307,14 @@ class ExprGenBase: def _deref_if_ptr_ptr(self, builder: llvmlite.IRBuilder*, obj_ptr: llvmlite.Value*) -> llvmlite.Value*: """如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针""" - if obj_ptr is None or obj_ptr.Ty is None: - return obj_ptr - if self.is_ptr_type(obj_ptr.Ty) == 0: - return obj_ptr + if obj_ptr is None or obj_ptr.Ty is None: return obj_ptr + if self.is_ptr_type(obj_ptr.Ty) == 0: return obj_ptr pointee: llvmlite.LLVMType* = obj_ptr.Ty.Pointee - if pointee is None: - return obj_ptr - if self.is_ptr_type(pointee) == 0: - return obj_ptr + if pointee is None: return obj_ptr + if self.is_ptr_type(pointee) == 0: return obj_ptr # obj_ptr 是 Ptr(Ptr(...)),load 解引用 loaded: llvmlite.Value* = llvmlite.build_load(builder, pointee, obj_ptr) - if loaded is None: - return obj_ptr + if loaded is None: return obj_ptr return loaded # ============================================================ # 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si @@ -369,8 +333,7 @@ class ExprGenBase: node: AST 节点(用于错误定位),可为 None """ - if val is None or target_ty is None: - return val + if val is None or target_ty is None: return val # 函数 → 指针: bitcast(如 CreateThread(..., _thread_alloc_free, ...) 传函数指针) # 函数 Value 的 Ty 是 Func,既不是整数也不是指针,需在整数/浮点转换之前处理 match val.Ty: @@ -397,12 +360,8 @@ class ExprGenBase: # 属标准 C 空指针用法,须放行而非报 CastError。先拓宽到 i64 # (inttoptr 要求同宽,对齐 MatchGenMixin 模式),再 inttoptr 成空指针。 if val.IsConst == 1 and val.IntVal == 0: - return llvmlite.build_inttoptr( - builder, llvmlite.const_int64(builder.Pool, 0), target_ty) - self.Gen.TypeGenErr.fatal_error( - node, - "整数隐式转指针已禁止:必须显式强转为指针(如 t.CPtr(x))才能把整数赋给指针类型", - "CastError") + return llvmlite.build_inttoptr(builder, llvmlite.const_int64(builder.Pool, 0), target_ty) + self.Gen.TypeGenErr.fatal_error(node, "整数隐式转指针已禁止:必须显式强转为指针(如 t.CPtr(x))才能把整数赋给指针类型", "CastError") return val # 指针 → 整数: ptrtoint(当目标明确是整数而非指针时) # 注意: target_bits == 8 时跳过 ptrtoint,走后面的 build_load 解引用首字符 @@ -434,10 +393,7 @@ class ExprGenBase: target_max_u: uint64 = (uint64(1) << target_bits) - 1 if uint64(val.IntVal) > target_max_u: max_print: int64 = int64(target_max_u) - self.Gen.TypeGenErr.fatal_error( - node, - f"窄化截断溢出:常量 {val.IntVal} 超出目标类型 {target_bits} 位范围 [0, {max_print}],赋值将被静默截断", - "OverflowError") + self.Gen.TypeGenErr.fatal_error(node, f"窄化截断溢出:常量 {val.IntVal} 超出目标类型 {target_bits} 位范围 [0, {max_print}],赋值将被静默截断", "OverflowError") return llvmlite.build_trunc(builder, val, target_ty) # 浮点转换 val_fbits: int = self.get_llvm_float_bits(val.Ty) @@ -463,19 +419,16 @@ class ExprGenBase: if self.is_ptr_type(val.Ty) == 0 and self.is_ptr_type(target_ty) != 0: vk_agg: int = val.Ty.kind() if vk_agg == llvmlite.LLVMType.Struct or vk_agg == llvmlite.LLVMType.Array: - tmp_agg: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry( - builder, val.Ty) + tmp_agg: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, val.Ty) if tmp_agg is not None: llvmlite.build_store(builder, val, tmp_agg) match target_ty: case llvmlite.LLVMType.Ptr(pointee_agg): - if self.Gen.AssignGen._stg_ty_equal( - builder.Pool, pointee_agg, val.Ty) != 0: + if self.Gen.AssignGen._stg_ty_equal(builder.Pool, pointee_agg, val.Ty) != 0: return tmp_agg case _: pass - bc_agg: llvmlite.Value* = llvmlite.build_bitcast( - builder, tmp_agg, target_ty) + bc_agg: llvmlite.Value* = llvmlite.build_bitcast(builder, tmp_agg, target_ty) if bc_agg is not None: return bc_agg return tmp_agg @@ -504,8 +457,7 @@ class ExprGenBase: trans 供 _node_type_unsigned 经 SymTab 解析变量注解的符号性(Name/ Subscript 形态必需);省略则仅能识别显式 t.CUIntXXT 强转。 """ - if val is None or val.Ty is None: - return 0 + if val is None or val.Ty is None: return 0 return self.Gen.ExprGenOps.should_zext_widen(pool, val, None, node, trans) # translate_ptr_arith:指针算术 ptr±int,用 getelementptr(按 pointee 元素大小缩放索引,对齐 TPC ExprGen.emit_binary_op / HandlesAugAssign.py);数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0),避免以整个数组为步长 @@ -515,8 +467,7 @@ class ExprGenBase: int_val: llvmlite.Value*, op: int) -> llvmlite.Value*: """指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)""" - if ptr_val is None or int_val is None or ptr_val.Ty is None: - return None + if ptr_val is None or int_val is None or ptr_val.Ty is None: return None # 提取 pointee 类型(非指针 → 不处理返回 None) elem_ty: llvmlite.LLVMType* = None match ptr_val.Ty: @@ -524,19 +475,15 @@ class ExprGenBase: elem_ty = pointee case _: return None - if elem_ty is None: - return None + if elem_ty is None: return None # 索引统一到 i64(对齐 TPC zext 到 i64) i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) idx: llvmlite.Value* = self.coerce_to_type(builder, int_val, i64_ty, None) - if idx is None: - return None + if idx is None: return None # ptr - int → 负索引(LLVM GEP 索引为加法语义) if op == ast.OpKind.Sub: - neg_idx: llvmlite.Value* = llvmlite.build_sub( - builder, llvmlite.const_int64(pool, 0), idx) - if neg_idx is None: - return None + neg_idx: llvmlite.Value* = llvmlite.build_sub(builder, llvmlite.const_int64(pool, 0), idx) + if neg_idx is None: return None idx = neg_idx # 数组 pointee → 先 decay 为元素指针(getelementptr [N x ty], [N x ty]* %p, i32 0, i32 0) if self.is_array_type(elem_ty) != 0: @@ -548,16 +495,13 @@ class ExprGenBase: return None if inner_ty is None: return None - decayed: llvmlite.Value* = llvmlite.build_gep_array( - builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0)) - if decayed is None: - return None + decayed: llvmlite.Value* = llvmlite.build_gep_array(builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0)) + if decayed is None: return None return llvmlite.build_gep(builder, inner_ty, decayed, idx) return llvmlite.build_gep(builder, elem_ty, ptr_val, idx) def InitExprGen(self) -> int: """初始化 ExprGen 族字段(构造时由 Generator 调用)""" - if self is None: - return 1 + if self is None: return 1 self.DocKeys = None self.DocValues = None self.DocCount = 0 diff --git a/App/lib/core/Gen/Expr/ExprGenCdef.vp b/App/lib/core/Gen/Expr/ExprGenCdef.vp index 6ca4087..3cc1b85 100644 --- a/App/lib/core/Gen/Expr/ExprGenCdef.vp +++ b/App/lib/core/Gen/Expr/ExprGenCdef.vp @@ -19,37 +19,27 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore # ============================================================ # ExprGenCdef - ExprGenMixin 拆分(阶段 D):跨模块 CDefine 查找 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenCdef(ExprGenBase.ExprGenBase): +novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): """跨模块 CDefine 查找""" # _build_source_path_from_sha1:通过 SHA1 从 StubMerger 全局存储器构建源 .vp/.py 文件路径(.vpi 未生成时回退读源 .py);rel_path 以 "lib/" 开头 → {Config.SourceDir}/{rel_path},其他 → {Config.IncludesDir}/{rel_path}。返回 stdlib.malloc 分配的路径字符串(调用者负责 free),失败返回 None def _build_source_path_from_sha1(self, sha1: str) -> str: """通过 SHA1 从全局存储器构建源 .py 文件路径""" - if sha1 is None: - return None - if Config.IncludesDir is None: - return None + if sha1 is None: return None + if Config.IncludesDir is None: return None # 从 StubMerger 全局存储器获取相对路径数组 rel_arr_ptr: bytes = StubMergerStore.GetSha1StoreRelArrPtr() count: int = StubMergerStore.GetSha1StoreCount() - if rel_arr_ptr is None or count <= 0: - return None + if rel_arr_ptr is None or count <= 0: return None sha1_arr_ptr: bytes = StubMergerStore.GetSha1StoreArrPtr() - if sha1_arr_ptr is None: - return None + if sha1_arr_ptr is None: return None # 遍历查找匹配的 SHA1 idx_s: int = -1 for i in range(count): sidx: sizet = sizet(i) * 17 cur_sha1: str = sha1_arr_ptr + sidx - if cur_sha1[0] == '\0': - continue + if cur_sha1[0] == '\0': continue if string.strcmp(cur_sha1, sha1) == 0: idx_s = i break diff --git a/App/lib/core/Gen/Expr/ExprGenCls.vp b/App/lib/core/Gen/Expr/ExprGenCls.vp index 48bf1c6..884ea58 100644 --- a/App/lib/core/Gen/Expr/ExprGenCls.vp +++ b/App/lib/core/Gen/Expr/ExprGenCls.vp @@ -16,24 +16,17 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore # ============================================================ -# docstring 登记表容量常量(与 ExprGenMixin 保持一致,本地副本避免 -# 跨模块 CDefine 查找 bug:ExprGenCls(C) 在 ExprGenMixin(M) 之前按 -# 文件序编译时,跨模块 CDefine 全局表未注册 → NameError 未定义) +# docstring 登记表容量常量(与 ExprGenMixin 保持一致,存疑 # ============================================================ -DOC_MAX: t.CDefine = 512 -DOC_KEY_SZ: t.CDefine = 192 -DOC_VAL_SZ: t.CDefine = 4096 +define DOC_MAX = 512 +define DOC_KEY_SZ = 192 +define DOC_VAL_SZ = 4096 # ============================================================ # ExprGenCls - ExprGenMixin 拆分(阶段 D):类名推断/docstring 登记 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenCls(ExprGenBase.ExprGenBase): +novirtual class ExprGenCls(ExprGenBase.ExprGenBase): """类名推断/docstring 登记""" # ============================================================ @@ -48,40 +41,30 @@ class ExprGenCls(ExprGenBase.ExprGenBase): def _extract_docstring_from_body(self, body: list[ast.AST*]*) -> str: """从函数/类体提取 docstring:body[0] 为 Expr(Constant str) 时返回内容""" - if body is None or len(body) == 0: - return None + if body is None or len(body) == 0: return None first: ast.AST* = body.get(0) - if first is None or first.kind() != ast.ASTKind.Expr: - return None + if first is None or first.kind() != ast.ASTKind.Expr: return None ex: rawptr[ast.Expr] = rawptr[ast.Expr](first) - if ex is None or ex.value is None or ex.value.kind() != ast.ASTKind.Constant: - return None + if ex is None or ex.value is None or ex.value.kind() != ast.ASTKind.Constant: return None cn: ast.Constant* = ast.Constant*(ex.value) - if cn is None or cn.const_kind != ast.CONST_STR: - return None + if cn is None or cn.const_kind != ast.CONST_STR: return None return cn.str_val def register_docstring(self, module_sha1: str, symbol: str, doc: str) -> None: """登记 docstring(key="{module_sha1}.{symbol}"),查重幂等""" - if module_sha1 is None or symbol is None or doc is None: - return - if string.strlen(doc) == 0: - return + if module_sha1 is None or symbol is None or doc is None: return + if string.strlen(doc) == 0: return if self.DocKeys is None: self.DocKeys = CompilerFactory.factory.PermPool.alloc(DOC_MAX * DOC_KEY_SZ) self.DocValues = CompilerFactory.factory.PermPool.alloc(DOC_MAX * DOC_VAL_SZ) - if self.DocKeys is None or self.DocValues is None: - return + if self.DocKeys is None or self.DocValues is None: return string.memset(self.DocKeys, 0, DOC_MAX * DOC_KEY_SZ) string.memset(self.DocValues, 0, DOC_MAX * DOC_VAL_SZ) - if self.DocCount >= DOC_MAX: - return + if self.DocCount >= DOC_MAX: return ml: sizet = string.strlen(module_sha1) sl: sizet = string.strlen(symbol) key_buf: bytes = stdlib.malloc(ml + sl + 2) - if key_buf is None: - return + if key_buf is None: return viperlib.snprintf(key_buf, ml + sl + 2, "%s.%s", module_sha1, symbol) - i: int for i in range(self.DocCount): if string.strcmp(self.DocKeys + i * DOC_KEY_SZ, key_buf) == 0: stdlib.free(key_buf) @@ -92,15 +75,12 @@ class ExprGenCls(ExprGenBase.ExprGenBase): stdlib.free(key_buf) def lookup_docstring(self, module_sha1: str, symbol: str) -> str: """查找 docstring 内容(key="{module_sha1}.{symbol}"),未找到返回 None""" - if self.DocKeys is None or module_sha1 is None or symbol is None: - return None + if self.DocKeys is None or module_sha1 is None or symbol is None: return None ml: sizet = string.strlen(module_sha1) sl: sizet = string.strlen(symbol) key_buf: bytes = stdlib.malloc(ml + sl + 2) - if key_buf is None: - return None + if key_buf is None: return None viperlib.snprintf(key_buf, ml + sl + 2, "%s.%s", module_sha1, symbol) - i: int for i in range(self.DocCount): if string.strcmp(self.DocKeys + i * DOC_KEY_SZ, key_buf) == 0: stdlib.free(key_buf) @@ -109,16 +89,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return None def extract_module_docstrings(self, tree: ast.AST*, module_sha1: str) -> None: """扫描模块 AST:登记模块级函数/类/方法的 docstring(幂等)""" - if tree is None or module_sha1 is None: - return + if tree is None or module_sha1 is None: return ch: list[ast.AST*]* = tree.children - if ch is None: - return + if ch is None: return cn: sizet = len(ch) for ci in range(cn): child: ast.AST* = ch.get(ci) - if child is None: - continue + if child is None: continue kd: int = child.kind() if kd == ast.ASTKind.FunctionDef: fd: ast.FunctionDef* = ast.FunctionDef*(child) @@ -129,8 +106,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): self.register_docstring(module_sha1, fd.name, fdoc) elif kd == ast.ASTKind.ClassDef: cd: ast.ClassDef* = ast.ClassDef*(child) - if cd is None or cd.name is None: - continue + if cd is None or cd.name is None: continue cd_body0: list[ast.AST*]* = cd.children cdoc: str = self._extract_docstring_from_body(cd_body0) if cdoc is not None: @@ -141,11 +117,9 @@ class ExprGenCls(ExprGenBase.ExprGenBase): cbn: sizet = len(cd_body) for mi in range(cbn): m: ast.AST* = cd_body.get(mi) - if m is None or m.kind() != ast.ASTKind.FunctionDef: - continue + if m is None or m.kind() != ast.ASTKind.FunctionDef: continue mfd: ast.FunctionDef* = ast.FunctionDef*(m) - if mfd is None or mfd.name is None: - continue + if mfd is None or mfd.name is None: continue mdoc: str = self._extract_docstring_from_body(mfd.children) if mdoc is not None: cl_nl: sizet = string.strlen(cd.name) @@ -161,10 +135,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase): 判定顺序:本地变量(函数变量)→ 结构体类(含跨模块预注册)→ 模块名。 """ - if trans is None or name_id is None or out_mod is None or out_sym is None: - return 0 - if trans.ModuleSha1 is None: - return 0 + if trans is None or name_id is None or out_mod is None or out_sym is None: return 0 + if trans.ModuleSha1 is None: return 0 # 1. 本地变量(函数变量/全局变量) if self.Gen.VarGen.lookup_var(trans.SymTab, name_id) is not None: string.strcpy(out_mod, trans.ModuleSha1) @@ -201,21 +173,17 @@ class ExprGenCls(ExprGenBase.ExprGenBase): remote.RemoteClass.remote_method / LocalClass.local_method 等。 最左 Name 判定:模块名 → 该模块 sha1;变量/类 → 类所属模块 sha1。 """ - if trans is None or at is None or out_mod is None or out_sym is None: - return 0 - if trans.ModuleSha1 is None: - return 0 + if trans is None or at is None or out_mod is None or out_sym is None: return 0 + if trans.ModuleSha1 is None: return 0 # 收集 Attribute 链(最外层 attr 在前) DOC_CHAIN_MAX: int = 8 items: bytes = stdlib.malloc(DOC_CHAIN_MAX * 128) - if items is None: - return 0 + if items is None: return 0 n_items: int = 0 cur: ast.AST* = (ast.AST*)(at) while cur is not None and cur.kind() == ast.ASTKind.Attribute and n_items < DOC_CHAIN_MAX: cat: ast.Attribute* = ast.Attribute*(cur) - if cat.attr is None: - break + if cat.attr is None: break string.strcpy(items + n_items * 128, cat.attr) n_items += 1 cur = cat.value @@ -244,7 +212,6 @@ class ExprGenCls(ExprGenBase.ExprGenBase): stdlib.free(items) return 1 total: sizet = 0 - j: int for j in range(n_items): total += string.strlen(items + j * 128) + 1 sym_buf: bytes = stdlib.malloc(total + 1) @@ -304,27 +271,22 @@ class ExprGenCls(ExprGenBase.ExprGenBase): node: ast.AST*, trans: HT.Translator*) -> str: """从表达式推断结构体类名,无法推断返回 None""" - if node is None or trans is None: - return None + if node is None or trans is None: return None k: int = node.kind() # Call: 类实例化 / 方法调用 if k == ast.ASTKind.Call: cl: ast.Call* = ast.Call*(node) - if cl is None or cl.func is None: - return None + if cl is None or cl.func is None: return None if cl.func.kind() == ast.ASTKind.Name: cand: str = (ast.Name*(cl.func)).id - if cand is None: - return None - if self.Gen.StructGen.find_struct(cand) is not None: - return cand + if cand is None: return None + if self.Gen.StructGen.find_struct(cand) is not None: return cand return None if cl.func.kind() == ast.ASTKind.Attribute: # 方法调用 a.cross(b):vpi 返回注解缓存精确解析返回类名 # (方法可返回非同类对象,如 Transform.world_position → 'Vec3')。 ca: ast.Attribute* = ast.Attribute*(cl.func) - if ca is None or ca.attr is None or ca.value is None: - return None + if ca is None or ca.attr is None or ca.value is None: return None # 模块级函数调用(Module.func()):接收者是已导入模块名而非类对象 if ca.value.kind() == ast.ASTKind.Name: mod_nm2: str = (ast.Name*(ca.value)).id @@ -344,10 +306,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if ret_cls2 is not None: return ret_cls2 obj_cls: str = self.infer_expr_class(pool, mod, ca.value, trans) - if obj_cls is None: - return None - if self._cls_has_dunder(pool, mod, obj_cls, ca.attr) == 0: - return None + if obj_cls is None: return None + if self._cls_has_dunder(pool, mod, obj_cls, ca.attr) == 0: return None cls_sha1: str = self.Gen.StructGen.get_struct_sha1(obj_cls) if cls_sha1 is None and trans.ModuleSha1 is not None: cls_sha1 = trans.ModuleSha1 @@ -359,8 +319,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): temp_dir = self.Gen.CallGenBase.TempDir if temp_dir is not None: VpiReader._ensure_vpi_ret_annot_loaded(cls_sha1, temp_dir) - annot_ret: str = VpiReader._lookup_vpi_ret_annot( - cls_sha1, obj_cls, ca.attr) + annot_ret: str = VpiReader._lookup_vpi_ret_annot(cls_sha1, obj_cls, ca.attr) if annot_ret is not None: ret_cls = self._extract_annot_class_name(pool, annot_ret) return ret_cls @@ -368,15 +327,11 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # Name: 源变量注解 if k == ast.ASTKind.Name: nm: ast.Name* = ast.Name*(node) - if nm is None or nm.id is None: - return None - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) - if ve is None: - return None + if nm is None or nm.id is None: return None + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) + if ve is None: return None acn_n: str = self.Gen.VarGen.var_annot_class_name(ve) - if acn_n is None: - return None + if acn_n is None: return None # 去模块前缀:json.JsonValue → JsonValue。AnnotClassName 可能带 # 模块限定(extract_class_name_from_annotation 的 Attribute 分支返回 # "memhub.MemBuddy" 形式),而 find_struct/_cls_has_dunder/ @@ -389,25 +344,19 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # BinOp/UnaryOp: 运算符重载返回同类对象 if k == ast.ASTKind.BinOp: bop: ast.BinOp* = ast.BinOp*(node) - if bop is None or bop.left is None: - return None + if bop is None or bop.left is None: return None dunder: str = self.Gen.ExprGenOps._binop_to_dunder(bop.op) - if dunder is None: - return None + if dunder is None: return None lhs_cls: str = self.infer_expr_class(pool, mod, bop.left, trans) - if lhs_cls is None or self._cls_has_dunder(pool, mod, lhs_cls, dunder) == 0: - return None + if lhs_cls is None or self._cls_has_dunder(pool, mod, lhs_cls, dunder) == 0: return None return lhs_cls if k == ast.ASTKind.UnaryOp: uop: ast.UnaryOp* = ast.UnaryOp*(node) - if uop is None or uop.operand is None: - return None + if uop is None or uop.operand is None: return None dunder: str = self.Gen.ExprGenOps._unaryop_to_dunder(uop.op) - if dunder is None: - return None + if dunder is None: return None opr_cls: str = self.infer_expr_class(pool, mod, uop.operand, trans) - if opr_cls is None or self._cls_has_dunder(pool, mod, opr_cls, dunder) == 0: - return None + if opr_cls is None or self._cls_has_dunder(pool, mod, opr_cls, dunder) == 0: return None return opr_cls # Attribute: 字段注解类名(属性链递归,如 p = r.origin) if k == ast.ASTKind.Attribute: @@ -420,18 +369,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # SHA1(stub 中声明)即视为存在。仅在确实存在时采用推断类名, # 避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: memhub.MemBuddy*, - mod: llvmlite.LLVMModule*, - class_name: str, dunder: str) -> int: + def _cls_has_dunder(self, pool: memhub.MemBuddy*, mod: llvmlite.LLVMModule*, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" - if class_name is None or dunder is None or mod is None: - return 0 + if class_name is None or dunder is None or mod is None: return 0 lookup_name: str = pool.alloc(128) - if lookup_name is None: - return 0 + if lookup_name is None: return 0 viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None: - return 1 + if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None: return 1 # 继承链祖先查找 mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 @@ -445,8 +389,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return 1 mi += 1 # 跨模块:类有 SHA1(stub 中声明该方法)视为存在 - if self.Gen.StructGen.get_struct_sha1(class_name) is not None: - return 1 + if self.Gen.StructGen.get_struct_sha1(class_name) is not None: return 1 return 0 # ============================================================ # _extract_annot_class_name - 从返回注解文本提取结构体类名 @@ -456,17 +399,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: memhub.MemBuddy*, - annot: str) -> str: + def _extract_annot_class_name(self, pool: memhub.MemBuddy*, annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" - if pool is None or annot is None: - return None + if pool is None or annot is None: return None alen: sizet = string.strlen(annot) - if alen == 0: - return None + if alen == 0: return None seg: str = pool.alloc(256) - if seg is None: - return None + if seg is None: return None start: sizet = 0 i: sizet for i in range(alen): diff --git a/App/lib/core/Gen/Expr/ExprGenConst.vp b/App/lib/core/Gen/Expr/ExprGenConst.vp index b4ed314..879daaa 100644 --- a/App/lib/core/Gen/Expr/ExprGenConst.vp +++ b/App/lib/core/Gen/Expr/ExprGenConst.vp @@ -15,13 +15,8 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase # ============================================================ # ExprGenConst - ExprGenMixin 拆分(阶段 D):常量/全局字符串/list 字面量翻译 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenConst(ExprGenBase.ExprGenBase): +novirtual class ExprGenConst(ExprGenBase.ExprGenBase): """常量/全局字符串/list 字面量翻译""" # ============================================================ @@ -34,8 +29,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): trans: HT.Translator*) -> llvmlite.Value*: """创建全局字符串常量并返回 i8* bitcast""" escaped: str = self.escape_llvm_string(pool, str_val) - if escaped is None: - return None + if escaped is None: return None slen: sizet = string.strlen(str_val) count: int = slen + 1 @@ -276,13 +270,11 @@ class ExprGenConst(ExprGenBase.ExprGenBase): first_elem_val = self.Gen.ExprGen.translate_value(builder, pool, mod, first_elem_node, None, 0, trans) if first_elem_val is None or first_elem_val.Ty is None: # fail-fast:首元素翻译失败/Value 类型缺失,立即终止编译(暴露上游根因) - self.Gen.TypeGenErr.fatal_error( - first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError") + self.Gen.TypeGenErr.fatal_error(first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError") inferred_type_name = self._infer_elem_type_from_value(pool, first_elem_val) if inferred_type_name is None: # fail-fast:首元素 Value 类型无法映射为 list 元素类型,立即终止编译 - self.Gen.TypeGenErr.fatal_error( - first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError") + self.Gen.TypeGenErr.fatal_error(first_elem_node, "list 字面量元素类型推断失败(Value 类型缺失)", "TypeError") else: # 空 list 无元素可推断,保持默认 str(list[str]) inferred_type_name = "str" @@ -338,25 +330,21 @@ class ExprGenConst(ExprGenBase.ExprGenBase): return None string.memset(new_args, 0, 8 * 32) new_args[0] = sizet(pool_val) - new_ptr: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans) + new_ptr: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans) if new_ptr is not None: storage_ptr = new_ptr # 调用 __before_init__(storage_ptr) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) # 调用 __init__(storage_ptr, pool_val, elem_size=0) init_args: sizet* = pool.alloc(8 * 32) - if init_args is None: - return None + if init_args is None: return None string.memset(init_args, 0, 8 * 32) init_args[0] = sizet(pool_val) elem_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 0) init_args[1] = sizet(elem_size_val) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans) # 对每个元素调用 append(storage_ptr, elem_val) if elts_count > 0: @@ -366,12 +354,10 @@ class ExprGenConst(ExprGenBase.ExprGenBase): if append_args is not None: string.memset(append_args, 0, 8 * 32) append_args[0] = sizet(first_elem_val) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans) # 翻译剩余元素 - i: sizet = 1 - while i < elts_count: + for i in range(1, elts_count): elem_node_i: ast.AST* = elts.get(i) elem_val_i: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans) if elem_val_i is not None: @@ -379,8 +365,6 @@ class ExprGenConst(ExprGenBase.ExprGenBase): if ap_args is not None: string.memset(ap_args, 0, 8 * 32) ap_args[0] = sizet(elem_val_i) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans) - i += 1 + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans) return storage_ptr \ No newline at end of file diff --git a/App/lib/core/Gen/Expr/ExprGenFstr.vp b/App/lib/core/Gen/Expr/ExprGenFstr.vp index c3dce3b..17332a7 100644 --- a/App/lib/core/Gen/Expr/ExprGenFstr.vp +++ b/App/lib/core/Gen/Expr/ExprGenFstr.vp @@ -13,19 +13,14 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase # CDefine 查找 bug:ExprGenFstr(F) 在 ExprGenMixin(M) 之前按文件序 # 编译时,跨模块 CDefine 全局表未注册 → NameError 未定义) # ============================================================ -FSTR_BUF_SIZE: t.CDefine = 1024 -FSTR_SPEC_MAX: t.CDefine = 64 -FSTR_FMT_MAX: t.CDefine = 64 +define FSTR_BUF_SIZE = 1024 +define FSTR_SPEC_MAX = 64 +define FSTR_FMT_MAX = 64 # ============================================================ # ExprGenFstr - ExprGenMixin 拆分(阶段 D):f-string/格式化值翻译 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenFstr(ExprGenBase.ExprGenBase): +novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): """f-string/格式化值翻译""" # ============================================================ @@ -41,16 +36,13 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): node: ast.AST*, trans: HT.Translator* = None) -> llvmlite.Value*: """f-string → snprintf 生成 i8* 栈缓冲""" - if node is None or builder is None or trans is None: - return None + if node is None or builder is None or trans is None: return None js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](node) - if js is None or js.values is None: - return None + if js is None or js.values is None: return None # 编译期格式串缓冲(pool 分配) fmt_buf: str = pool.alloc(FSTR_BUF_SIZE) - if fmt_buf is None: - return None + if fmt_buf is None: return None fmt_buf[0] = '\0' # 运行时参数链表(Value.Next 链接,与 printf 调用一致) @@ -62,24 +54,19 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): pn: sizet = len(parts) for pi in range(pn): part: ast.AST* = parts.get(pi) - if part is None: - continue + if part is None: continue if part.kind() == ast.ASTKind.Constant: pcn: ast.Constant* = ast.Constant*(part) if pcn.const_kind == ast.CONST_STR and pcn.str_val is not None: self._fstr_append_literal(fmt_buf, pcn.str_val) - continue - if part.kind() != ast.ASTKind.FormattedValue: - continue + continue + if part.kind() != ast.ASTKind.FormattedValue: continue fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part) - if fv.value is None: - continue - val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, fv.value, None, 0, trans) + if fv.value is None: continue + val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fv.value, None, 0, trans) if val is None: # fail-fast:f-string 格式化值翻译失败必须终止编译,绝不在 - self.Gen.TypeGenErr.fatal_error( - fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError") + self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError") continue # 确定 C 格式说明符(format_spec 优先,否则按值类型推断) c_fmt: str = None @@ -94,8 +81,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1: string.strcat(fmt_buf, c_fmt) # 转换参数类型(i8/i16→i32、bool→i32、f32→f64) - cast_val: llvmlite.Value* = self._fstr_cast_value( - builder, pool, val, c_fmt, fv.value, trans) + cast_val: llvmlite.Value* = self._fstr_cast_value(builder, pool, val, c_fmt, fv.value, trans) if cast_val is None: cast_val = val cast_val.Next = None @@ -125,12 +111,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): arg_head: llvmlite.Value* = None arg_tail: llvmlite.Value* = None arg_count: int = 0 - val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, fv.value, None, 0, trans) + val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fv.value, None, 0, trans) if val is None: # fail-fast:裸 FormattedValue 翻译失败必须终止编译,绝不在 - self.Gen.TypeGenErr.fatal_error( - fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError") + self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式化值翻译失败(表达式返回 None)", "TypeError") else: c_fmt: str = None if fv.format_spec is not None: @@ -142,8 +126,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式无法推断(值类型缺失)", "TypeError") if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1: string.strcat(fmt_buf, c_fmt) - cast_val: llvmlite.Value* = self._fstr_cast_value( - builder, pool, val, c_fmt, fv.value, trans) + cast_val: llvmlite.Value* = self._fstr_cast_value(builder, pool, val, c_fmt, fv.value, trans) if cast_val is None: cast_val = val cast_val.Next = None @@ -166,20 +149,15 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): # 空 f-string(f"")→ 空字符串常量 return self.Gen.ExprGenConst.create_global_string(builder, pool, mod, "", trans) # 格式串 → 全局字符串常量(i8*) - fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, fmt_buf, trans) - if fmt_ptr is None: - return None + fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(builder, pool, mod, fmt_buf, trans) + if fmt_ptr is None: return None # 固定栈缓冲 [FSTR_BUF_SIZE x i8],GEP(0,0) 取 i8* buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, FSTR_BUF_SIZE) buf_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, buf_ty) - if buf_alloca is None: - return None + if buf_alloca is None: return None zero_i32: llvmlite.Value* = llvmlite.const_int32(pool, 0) - buf_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, buf_ty, i8_ty, buf_alloca, zero_i32) - if buf_ptr is None: - return None + buf_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, buf_ty, i8_ty, buf_alloca, zero_i32) + if buf_ptr is None: return None # snprintf(buf, FSTR_BUF_SIZE, fmt, args...) size_val: llvmlite.Value* = llvmlite.const_int64(pool, FSTR_BUF_SIZE) buf_ptr.Next = size_val @@ -192,12 +170,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): def _fstr_append_literal(self, fmt_buf: str, lit: str) -> None: """追加字面量到格式串(% 转义为 %%)""" - if fmt_buf is None or lit is None: - return + if fmt_buf is None or lit is None: return cur_len: sizet = string.strlen(fmt_buf) rem: sizet = FSTR_BUF_SIZE - 1 - cur_len - if rem == 0: - return + if rem == 0: return src_len: sizet = string.strlen(lit) si: sizet = 0 while si < src_len and rem > 0: @@ -238,18 +214,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): sk: int = spec_node.kind() if sk == ast.ASTKind.JoinedStr: jss: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](spec_node) - if jss.values is None: - return None + if jss.values is None: return None vn: sizet = len(jss.values) for vi in range(vn): vpart: ast.AST* = jss.values.get(vi) - if vpart is None: - continue - if vpart.kind() != ast.ASTKind.Constant: - return None + if vpart is None: continue + if vpart.kind() != ast.ASTKind.Constant: return None vcn: ast.Constant* = ast.Constant*(vpart) - if vcn.const_kind != ast.CONST_STR or vcn.str_val is None: - return None + if vcn.const_kind != ast.CONST_STR or vcn.str_val is None: return None if string.strlen(spec) + string.strlen(vcn.str_val) < FSTR_SPEC_MAX - 1: string.strcat(spec, vcn.str_val) elif sk == ast.ASTKind.Constant: @@ -257,11 +229,9 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): if cn.const_kind != ast.CONST_STR or cn.str_val is None: return None string.strncpy(spec, cn.str_val, FSTR_SPEC_MAX - 1) - else: - return None + else: return None slen: sizet = string.strlen(spec) - if slen == 0: - return None + if slen == 0: return None # 2. 逐段解析: [fill]align / sign / # / 0 / width / , / .precision / type pos: sizet = 0 @@ -279,8 +249,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): c_flags: str = pool.alloc(FSTR_FMT_MAX) c_width: str = pool.alloc(32) c_prec: str = pool.alloc(32) - if c_flags is None or c_width is None or c_prec is None: - return None + if c_flags is None or c_width is None or c_prec is None: return None c_flags[0] = '\0' c_width[0] = '\0' c_prec[0] = '\0' @@ -329,30 +298,24 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): if pos < slen: fmt_type = spec[pos] pos += 1 - if pos != slen: - return None # 多余字符无法解析 + if pos != slen: return None # 多余字符无法解析 # 3. 长度修饰(按值类型位宽) len_mod: str = pool.alloc(4) - if len_mod is None: - return None + if len_mod is None: return None len_mod[0] = '\0' ibits: int = self.Gen.ExprGenBase.get_llvm_type_bits(val.Ty) # 32 位**不写**长度修饰符(N14):`{x:08X}` 的实参是 i32,此前推导出 # `l` → 格式串 `%08lX`(long)与实参宽度不符(LP64 下 printf 按 64 位 # 读参 → 变参错位)。与同文件无 spec 路径 `_fstr_infer_c_fmt`(32 位用 # `%u/%d`)以及 TPC 侧 HandlesExprFormat.py 保持一致。 - if ibits == 64: - string.strcpy(len_mod, "ll") - elif ibits == 16: - string.strcpy(len_mod, "h") - elif ibits == 8: - string.strcpy(len_mod, "hh") + if ibits == 64: string.strcpy(len_mod, "ll") + elif ibits == 16: string.strcpy(len_mod, "h") + elif ibits == 8: string.strcpy(len_mod, "hh") # 4. 组装 C 格式串 out: str = pool.alloc(FSTR_FMT_MAX) - if out is None: - return None + if out is None: return None out[0] = '\0' string.strcat(out, "%") string.strcat(out, c_flags) @@ -411,18 +374,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): arg_node: ast.AST*, trans: HT.Translator*) -> str: """无 format_spec 时按值类型推断 C printf 格式(对齐 TPC 无 spec 分支,带 % 前缀)""" - if val is None or pool is None: - return None + if val is None or pool is None: return None out: str = pool.alloc(16) - if out is None: - return None + if out is None: return None out[0] = '\0' ibits: int = self.Gen.ExprGenBase.get_llvm_type_bits(val.Ty) fbits: int = self.Gen.ExprGenBase.get_llvm_float_bits(val.Ty) - if ibits == 1: - return "%d" # bool - if ibits == 8: - return "%c" # 字符 + if ibits == 1: return "%d" # bool + if ibits == 8: return "%c" # 字符 if ibits != 0: if self.Gen.ExprGenOps._node_type_unsigned(pool, arg_node, trans) != 0: if ibits == 64: diff --git a/App/lib/core/Gen/Expr/ExprGenMixin.vp b/App/lib/core/Gen/Expr/ExprGenMixin.vp index c02dcf1..6a75118 100644 --- a/App/lib/core/Gen/Expr/ExprGenMixin.vp +++ b/App/lib/core/Gen/Expr/ExprGenMixin.vp @@ -15,9 +15,9 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase # DOC_KEY_SZ: key "{module_sha1}.{symbol}" 缓冲宽度 # DOC_VAL_SZ: docstring 内容缓冲宽度 # ============================================================ -DOC_MAX: t.CDefine = 512 -DOC_KEY_SZ: t.CDefine = 192 -DOC_VAL_SZ: t.CDefine = 4096 +define DOC_MAX = 512 +define DOC_KEY_SZ = 192 +define DOC_VAL_SZ = 4096 # ============================================================ # f-string 翻译常量(对齐 TPC HandlesExprFormat) @@ -26,37 +26,22 @@ DOC_VAL_SZ: t.CDefine = 4096 # FSTR_SPEC_MAX: 编译期 format_spec 解析缓冲宽度 # FSTR_FMT_MAX: 编译期 C printf 格式串缓冲宽度 # ============================================================ -FSTR_BUF_SIZE: t.CDefine = 1024 -FSTR_SPEC_MAX: t.CDefine = 64 -FSTR_FMT_MAX: t.CDefine = 64 +define FSTR_BUF_SIZE = 1024 +define FSTR_SPEC_MAX = 64 +define FSTR_FMT_MAX = 64 # ============================================================ # ExprGenMixin - 表达式处理 Mixin(对象化 P3,wiki/14-oo-refactor.md) -# -# 从 HandlesExpr.vp(48 函数,无全局状态)与 HandlesExprOps.vp -# 迁移:模块级纯函数 → 类方法(self 替代,参数保留含 builder/pool)。 -# -# 迁移原则(与 P2 一致,行为零变化): -# 1. 方法保留原函数签名(含 builder/pool 首参),仅函数体内 -# 本模块函数调用改为 self.xxx(...) -# 2. 外部模块调用(HandlesExprCall.xxx / HandlesType.xxx 等)保留模块前缀 -# 3. HandlesExpr.vp / HandlesExprOps.vp 原函数保留为"委托":本地 -# 模块级单例 _g_gen(BuildPipeline/main 注入)cast 成 Generator 类型 -# 4. ExprHandle 类保留在 HandlesExpr.vp(translator handler 模式) -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ # ============================================================ # ExprGenMixin - 表达式/常量/下标/属性访问/运算符 # ============================================================ -@t.NoVTable -class ExprGenMixin(ExprGenBase.ExprGenBase): +novirtual class ExprGenMixin(ExprGenBase.ExprGenBase): """表达式处理 Mixin(纯方法化迁移,无状态字段)""" - # ============================================================ # 翻译值表达式(RHS 分派)— 模块级版本 # ============================================================ @@ -78,11 +63,9 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): """ if trans is not None: if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: - self.Gen.TypeGenErr.fatal_error( - node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") + self.Gen.TypeGenErr.fatal_error(node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") trans.TranslateDepth += 1 - rv: llvmlite.Value* = self._translate_value_impl( - builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx) + rv: llvmlite.Value* = self._translate_value_impl(builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx) if trans is not None: trans.TranslateDepth -= 1 return rv @@ -103,40 +86,19 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): if k == ast.ASTKind.Constant: rv: llvmlite.Value* = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty) return rv - elif k == ast.ASTKind.Name: - # target_ty(使用处类型:赋值目标 / 形参 / 返回)与 use_ctx(真实站点 - # 种类,仅供报文)下传给裸名翻译,供 CDefine 常量按使用处宽度物化; - # 非常量名不受影响(见 translate_name_value)。 - return self.Gen.ExprGenName.translate_name_value( - builder, pool, node, trans, target_ty, use_ctx) - elif k == ast.ASTKind.BinOp: - return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans) - elif k == ast.ASTKind.Call: - return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) - elif k == ast.ASTKind.Compare: - return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans) - elif k == ast.ASTKind.UnaryOp: - return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans) - elif k == ast.ASTKind.BoolOp: - return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans) - elif k == ast.ASTKind.Subscript: - return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans) - elif k == ast.ASTKind.Attribute: - return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans) - elif k == ast.ASTKind.List: - return self.Gen.ExprGenConst.translate_list_literal(builder, pool, mod, node, None, trans) - elif k == ast.ASTKind.IfExp: - return self.Gen.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans) - elif k == ast.ASTKind.Lambda: - # 模块级委托:translate_lambda 定义在 FuncGenMixin(跨 Mixin - # 方法不能 self. 直接调用,见 HandlesExpr.translate_lambda) - return self.Gen.FuncGen.translate_lambda(builder, pool, mod, node, trans) - elif k == ast.ASTKind.JoinedStr: - return self.Gen.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans) - elif k == ast.ASTKind.FormattedValue: - # 解析器对 f"{expr:spec}"(单 FormattedValue 无字面量)返回裸 FormattedValue - # 而非 JoinedStr(见 ast/parser.vp _parse_fstring),需单独翻译 - return self.Gen.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans) + elif k == ast.ASTKind.Name: return self.Gen.ExprGenName.translate_name_value(builder, pool, node, trans, target_ty, use_ctx) + elif k == ast.ASTKind.BinOp: return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans) + elif k == ast.ASTKind.Call: return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) + elif k == ast.ASTKind.Compare: return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans) + elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans) + elif k == ast.ASTKind.BoolOp: return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans) + elif k == ast.ASTKind.Subscript: return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans) + elif k == ast.ASTKind.Attribute: return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans) + elif k == ast.ASTKind.List: return self.Gen.ExprGenConst.translate_list_literal(builder, pool, mod, node, None, trans) + elif k == ast.ASTKind.IfExp: return self.Gen.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans) + elif k == ast.ASTKind.Lambda: return self.Gen.FuncGen.translate_lambda(builder, pool, mod, node, trans) + elif k == ast.ASTKind.JoinedStr: return self.Gen.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans) + elif k == ast.ASTKind.FormattedValue: return self.Gen.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans) elif k == ast.ASTKind.Await: # 协程 await(TPV-M1):await 目标是 async 函数调用时内联翻译 # (子帧创建 + resume 到 DONE + 取子帧 ret 存父帧 await 槽 + 父挂起), @@ -158,10 +120,8 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): # 全代码库无调用点使用;按 C 语义视为单目解引用(*ptr → load pointee, # 对齐 UnaryOp(Deref))。构造 Deref UnaryOp 复用既有翻译/错误路径。 st: rawptr[ast.Starred] = rawptr[ast.Starred](node) - if st is None or st.value is None: - return None + if st is None or st.value is None: return None deref_node: ast.AST* = ast.UnaryOp(pool, ast.OpKind.Deref, st.value) - if deref_node is None: - return None + if deref_node is None: return None return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, deref_node, trans) return None diff --git a/App/lib/core/Gen/Expr/ExprGenName.vp b/App/lib/core/Gen/Expr/ExprGenName.vp index 8c55767..8b25a58 100644 --- a/App/lib/core/Gen/Expr/ExprGenName.vp +++ b/App/lib/core/Gen/Expr/ExprGenName.vp @@ -10,19 +10,14 @@ import viperlib import lib.core.Gen.Translator as HT import lib.Stub.StubMerger.StubMergerStore as StubMergerStore - import lib.core.Gen.Expr.ExprGenBase as ExprGenBase import lib.core.Gen.GenApi as GenApi + # ============================================================ # ExprGenName - ExprGenMixin 拆分(阶段 D):Name/Subscript/下标访问 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenName(ExprGenBase.ExprGenBase): +novirtual class ExprGenName(ExprGenBase.ExprGenBase): """Name/Subscript/下标访问""" def _cut_from_import_mod(self, pool: memhub.MemBuddy*, @@ -36,16 +31,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): 对齐 ExprGenCdef._lookup_cross_module_cdefine 的截断逻辑)。 截断到空格/冒号/NUL;raw 无效返回 None。 """ - if raw is None: - return None + if raw is None: return None mbl_c: sizet = 0 while raw[mbl_c] != ' ' and raw[mbl_c] != '\0' and raw[mbl_c] != ':': mbl_c += 1 - if mbl_c == 0: - return None + if mbl_c == 0: return None buf_c: str = pool.alloc(mbl_c + 1) - if buf_c is None: - return None + if buf_c is None: return None string.strncpy(buf_c, raw, mbl_c) buf_c[mbl_c] = '\0' return buf_c @@ -71,11 +63,9 @@ class ExprGenName(ExprGenBase.ExprGenBase): # "use of undefined value '@.str.{sha1}.N'(SysLibTest _cleanup 根因)" mod: llvmlite.LLVMModule* = trans.Module nm: ast.Name* = ast.Name*(node) - if nm is None: - return None + if nm is None: return None nm_id: str = nm.id - if nm_id is None: - return None + if nm_id is None: return None # CDefine 编译期常量:返回常量值(浮点 CDefine → double 常量,整数 → i32;否则 double 函数里 return 会生成 ret i32 0 报错)。注意同名变量优先——当前作用域已存在变量时不得被 CDefine 表条目遮蔽(vpi stub 注入会把依赖模块的 CDefine 注册进导入方表,可能误解析局部变量为常量),守卫与下方跨模块 CDefine 查找的 lookup_var 检查一致 cdef_val_d: double = self.Gen.TypeGenCDef.lookup_cdefine_double(nm_id) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: @@ -95,8 +85,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 使用处宽度(经 translate_value 的 target_ty 下传;站点种类由 # use_ctx 携带,仅供报文使用): # 更宽 ⇒ 就地升宽物化;更窄 ⇒ fail-fast;取不到 ⇒ 既有默认 32/64。 - uw_val: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value( - pool, node, nm_id, cdef_val_c, target_ty, use_ctx) + uw_val: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(pool, node, nm_id, cdef_val_c, target_ty, use_ctx) if uw_val is not None: return uw_val return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val_c) @@ -114,8 +103,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 文件,且多 includes 目录下还可能触发 XMOD-CD 误报 # (ExprGenCdef._build_source_path_from_sha1 拼错路径)。 if self.Gen.VarGen.lookup_var(trans.SymTab, nm_id) is None: - cdef_val: int64 = self.Gen.ExprGenCdef._lookup_cross_module_cdefine( - pool, nm_id, trans._from_imports, trans._imported_modules, 0, node) + cdef_val: int64 = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, nm_id, trans._from_imports, trans._imported_modules, 0, node) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: if self.Gen.TypeGenCDef.is_cdefine_str() != 0: cdef_sv2: str = self.Gen.TypeGenCDef.lookup_cdefine_string(nm_id) @@ -128,8 +116,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): if self.Gen.TypeGenCDef.is_cdefine_double() != 0: return llvmlite.ConstFloat(pool, llvmlite.Double(pool), dchk_nm) # 使用处宽度同口径(跨模块 CDefine) - uw_x: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value( - pool, node, nm_id, cdef_val, target_ty, use_ctx) + uw_x: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value(pool, node, nm_id, cdef_val, target_ty, use_ctx) if uw_x is not None: return uw_x return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val) @@ -139,21 +126,17 @@ class ExprGenName(ExprGenBase.ExprGenBase): # i64 全局、非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)。from-import # 确认名称确实来自某模块后,按后缀匹配查找该全局并加载。 if trans is not None and trans._from_imports is not None: - fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, nm_id, 0) + fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, nm_id, 0) if fi_mod_raw is not None: # 带源模块 SHA1 前缀精确查找,避免多模块同名全局后缀匹配串扰。 # fi_mod_raw 非 NUL 结尾,先截断再查 SHA1(否则整串查不到退化裸名) fi_mod_cut: str = self._cut_from_import_mod(pool, fi_mod_raw) if fi_mod_cut is None: fi_mod_cut = fi_mod_raw - fi_gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1( - StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id) - fi_gv: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module( - trans.Module, fi_gv_q) + fi_gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id) + fi_gv: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(trans.Module, fi_gv_q) if fi_gv is not None and fi_gv.Ty is not None: - fi_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref( - pool, fi_gv.Name, fi_gv.Ty) + fi_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(pool, fi_gv.Name, fi_gv.Ty) if fi_ref is not None and fi_ref.Ty is not None: fi_pty: llvmlite.LLVMType* = fi_ref.Ty.Pointee if fi_pty is not None: @@ -168,16 +151,14 @@ class ExprGenName(ExprGenBase.ExprGenBase): # global 变量:从模块作用域查找(global 声明优先级最高) if trans is not None: if GenApi.is_global_name(trans, nm_id) != 0: - mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm_id) + mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm_id) if mod_alloca is not None: load_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: load_ty = mod_alloca.Ty.Pointee if load_ty is None: # fail-fast:global 变量存储类型缺失,立即终止编译(暴露上游根因) - self.Gen.TypeGenErr.fatal_error( - node, f"变量 '{nm_id}' 存储类型缺失", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"变量 '{nm_id}' 存储类型缺失", "TypeError") # 全局数组(如 pyzlib.pyzlib_error_msg: CArray[char, 512]): # 按 C 语义衰减为基址返回(对齐下方局部数组分支 L3383-3388)。 # 否则 load [512 x i8] 数组值当 i8* 传 → set_error 的 strncpy @@ -191,8 +172,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # t.CVolatile 全局:load 带 volatile 限定符(禁优化器消除重复读) vol_g: int = 0 if trans is not None: - ve_g: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_id) + ve_g: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_id) vol_g = self.Gen.VarGen.var_is_volatile(ve_g) return llvmlite.build_load(builder, load_ty, mod_alloca, vol_g) @@ -218,8 +198,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): load_ty = alloca.Ty.Pointee if load_ty is None: # fail-fast:局部变量存储类型缺失,立即终止编译(暴露上游根因) - self.Gen.TypeGenErr.fatal_error( - node, f"变量 '{nm_id}' 存储类型缺失", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"变量 '{nm_id}' 存储类型缺失", "TypeError") # 结构体值变量(alloca 类型为 Struct,如 `x: Cls | t.CPtr`): # 按"对象即指针"语义返回其地址(alloca 指针),而非加载结构体值。 # 结构体值无法参与 ptrtoint/方法调用等地址相关操作,加载值会导致 @@ -236,8 +215,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # t.CVolatile 局部变量:load 带 volatile 限定符 vol_l: int = 0 if trans is not None: - ve_l: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_id) + ve_l: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_id) vol_l = self.Gen.VarGen.var_is_volatile(ve_l) return llvmlite.build_load(builder, load_ty, alloca, vol_l) @@ -246,8 +224,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # ② 模块别名/模块函数引用之前(会话名不得被 printf 等本模块 declare 抢走)。 # 非 REPL(trans.ReplCtx is None)时 repl_try_read 立即返回 None ⇒ 原路径逐字不变。 if trans is not None and trans.ReplCtx is not None: - sess_val: llvmlite.Value* = self.Gen.VarGen.repl_try_read( - trans, nm_id, node) + sess_val: llvmlite.Value* = self.Gen.VarGen.repl_try_read(trans, nm_id, node) if sess_val is not None: return sess_val @@ -268,8 +245,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 最终打印出 `declare void @()` 空名函数。正确做法:按 Function 的 # RetTy/Params 构造真实函数类型,用 new_value 包装成普通 Value 再 bitcast。 if trans is not None and trans.Module is not None: - fn_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - trans.Module, nm_id) + fn_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, nm_id) if fn_ref is not None: fn_name: str = llvmlite.function_get_name(fn_ref) if fn_name is None: @@ -278,8 +254,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): fn_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(fn_ref) if fn_ret_ty is None: # fail-fast:函数返回类型缺失,无法构造函数指针(暴露上游根因) - self.Gen.TypeGenErr.fatal_error( - node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError") fn_pp: llvmlite.Param* = llvmlite.function_get_param_head(fn_ref) fn_first_node: llvmlite.Function* = None fn_prev_node: llvmlite.Function* = None @@ -295,8 +270,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): fn_prev_node = fn_pn fn_pcount += 1 fn_pp = llvmlite.param_get_next(fn_pp) - fn_ty: llvmlite.LLVMType* = llvmlite.Func( - pool, fn_ret_ty, fn_first_node, fn_pcount) + fn_ty: llvmlite.LLVMType* = llvmlite.Func(pool, fn_ret_ty, fn_first_node, fn_pcount) if fn_ty is None: return None # 构造函数指针 Value(new_value 包装,避免触碰 Function.Next) @@ -313,8 +287,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): else: viperlib.snprintf(fn_ref_name, 256, "@%s", fn_name) llvmlite.value_set_name(fn_ref_v, fn_ref_name) - fn_i8ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + fn_i8ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) return llvmlite.build_bitcast(builder, fn_ref_v, fn_i8ptr_ty) # ============================================================ @@ -329,8 +302,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): if trans is not None and trans._from_imports is not None: if trans.Module is not None: # 是 from-import 名称(禁用 star 回退,避免误归 star 模块) - fi_mod: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, nm_id, 0) + fi_mod: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, nm_id, 0) if fi_mod is not None: # 排除已注册类名/枚举名:这些是类型,不作为全局变量值读取 fi_is_class: int = 0 @@ -341,8 +313,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): fi_is_class = 1 if fi_is_class == 0: fi_gname: str = nm_id - fi_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, nm_id) + fi_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, nm_id) if fi_orig is not None: og_len_fi: sizet = 0 while fi_orig[og_len_fi] != ' ' and fi_orig[og_len_fi] != '\0': @@ -361,10 +332,8 @@ class ExprGenName(ExprGenBase.ExprGenBase): fi_mod_cut2: str = self._cut_from_import_mod(pool, fi_mod) if fi_mod_cut2 is None: fi_mod_cut2 = fi_mod - gv_fi_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1( - StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname) - gv_fi: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module( - trans.Module, gv_fi_q) + gv_fi_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname) + gv_fi: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(trans.Module, gv_fi_q) ref_fi: llvmlite.Value* = None if gv_fi is not None and gv_fi.Ty is not None: ref_fi = self.Gen.ExprGenAttr.make_global_ref(pool, gv_fi.Name, gv_fi.Ty) @@ -624,8 +593,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): s_val_ptr: llvmlite.Value* = self.coerce_to_type(builder, rhs_val, s_elem_ty, node) if s_val_ptr is None: return 0 - s_ep: llvmlite.Value* = llvmlite.build_bitcast( - builder, s_addr, llvmlite.Ptr(pool, s_elem_ty)) + s_ep: llvmlite.Value* = llvmlite.build_bitcast(builder, s_addr, llvmlite.Ptr(pool, s_elem_ty)) if s_ep is not None: llvmlite.build_store(builder, s_val_ptr, s_ep) return 0 @@ -695,24 +663,17 @@ class ExprGenName(ExprGenBase.ExprGenBase): return None match nl_ty: case llvmlite.LLVMType.Array(elem_ty_nl, _cnt_nl): - arr_ptr_nl: llvmlite.Value* = llvmlite.build_bitcast( - builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) + arr_ptr_nl: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) if arr_ptr_nl is None: return None - return llvmlite.build_gep_array( - builder, nl_ty, elem_ty_nl, arr_ptr_nl, - self._zext_index_to_i32(builder, idx_val)) + return llvmlite.build_gep_array(builder, nl_ty, elem_ty_nl, arr_ptr_nl, self._zext_index_to_i32(builder, idx_val)) case llvmlite.LLVMType.Ptr(inner_nl): - arr_ptr_nl2: llvmlite.Value* = llvmlite.build_bitcast( - builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) - if arr_ptr_nl2 is None: - return None + arr_ptr_nl2: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) + if arr_ptr_nl2 is None: return None return llvmlite.build_gep(builder, inner_nl, arr_ptr_nl2, idx_val) case _: - arr_ptr_nl3: llvmlite.Value* = llvmlite.build_bitcast( - builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) - if arr_ptr_nl3 is None: - return None + arr_ptr_nl3: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) + if arr_ptr_nl3 is None: return None return llvmlite.build_gep(builder, nl_ty, arr_ptr_nl3, idx_val) return None # ============================================================ @@ -741,16 +702,11 @@ class ExprGenName(ExprGenBase.ExprGenBase): # p.entry 垃圾 → 用户进程 iretq 到垃圾地址 → PF)。 if sub.slice is not None and sub.slice.kind() == ast.ASTKind.Slice: slc: rawptr[ast.Slice] = rawptr[ast.Slice](sub.slice) - base_v: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub.value, None, 0, trans) - if base_v is None: - return None - if slc.lower is None: - return base_v - start_v: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, slc.lower, None, 0, trans) - if start_v is None: - return None + base_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans) + if base_v is None: return None + if slc.lower is None: return base_v + start_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, slc.lower, None, 0, trans) + if start_v is None: return None i64_sc: llvmlite.LLVMType* = llvmlite.Int64(pool) start_w: llvmlite.Value* = start_v if start_v.Ty is not None: @@ -763,34 +719,26 @@ class ExprGenName(ExprGenBase.ExprGenBase): return llvmlite.build_gep(builder, i8_sc, base_v, start_w) # 翻译索引 - idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub.slice, None, 0, trans) - if idx_val is None: - return None + idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.slice, None, 0, trans) + if idx_val is None: return None # 嵌套下标读取: a[i][j] —— 递归取内层指针后 load # (与 get_subscript_ptr 嵌套分支对称;如 gfx.vp 的 # a.m[i][k] * b.m[k][j],内层 translate_value 会把行加载为 # Array 值(非指针)→ 通用路径失败 → "rhs 翻译失败") if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript: - inner_ptr_r: llvmlite.Value* = self.get_subscript_ptr( - builder, pool, mod, sub.value, trans) - if inner_ptr_r is None or inner_ptr_r.Ty is None: - return None + inner_ptr_r: llvmlite.Value* = self.get_subscript_ptr(builder, pool, mod, sub.value, trans) + if inner_ptr_r is None or inner_ptr_r.Ty is None: return None inner_elem_r: llvmlite.LLVMType* = inner_ptr_r.Ty.Pointee - if inner_elem_r is None: - return None + if inner_elem_r is None: return None match inner_elem_r: case llvmlite.LLVMType.Array(arr_ie_r, _): - elem_ptr_r: llvmlite.Value* = llvmlite.build_gep_array( - builder, inner_elem_r, arr_ie_r, inner_ptr_r, - self._zext_index_to_i32(builder, idx_val)) + elem_ptr_r: llvmlite.Value* = llvmlite.build_gep_array(builder, inner_elem_r, arr_ie_r, inner_ptr_r, self._zext_index_to_i32(builder, idx_val)) if elem_ptr_r is not None: return llvmlite.build_load(builder, arr_ie_r, elem_ptr_r) return None case _: - elem_ptr_r2: llvmlite.Value* = llvmlite.build_gep( - builder, inner_elem_r, inner_ptr_r, idx_val) + elem_ptr_r2: llvmlite.Value* = llvmlite.build_gep(builder, inner_elem_r, inner_ptr_r, idx_val) if elem_ptr_r2 is not None: return llvmlite.build_load(builder, inner_elem_r, elem_ptr_r2) return None @@ -802,14 +750,12 @@ class ExprGenName(ExprGenBase.ExprGenBase): # rawptr[t.CVolatile | T] 变量(volatile 指针指向物):本分支内 # 的**元素 load**(p[i] 解引用)带 volatile;仅读取指针值自身的 # load(alloca → 指针值)不带(那是指针变量而非所指物)。 - vol_sub_rd: int = self.Gen.VarGen.var_pointee_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) + vol_sub_rd: int = self.Gen.VarGen.var_pointee_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) # nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能 # lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃) # 读路径:元素指针 load 出元素值 if GenApi.is_nonlocal_name(trans, nm.id) != 0: - nl_ptr_r: llvmlite.Value* = self._nonlocal_subscript_ptr( - builder, pool, trans, nm.id, idx_val) + nl_ptr_r: llvmlite.Value* = self._nonlocal_subscript_ptr(builder, pool, trans, nm.id, idx_val) if nl_ptr_r is not None and nl_ptr_r.Ty is not None: nl_elem_ty: llvmlite.LLVMType* = nl_ptr_r.Ty.Pointee if nl_elem_ty is not None: @@ -825,9 +771,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): match pointee: case llvmlite.LLVMType.Array(elem_ty, count): # 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx - elem_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, pointee, elem_ty, alloca, - self._zext_index_to_i32(builder, idx_val)) + elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, pointee, elem_ty, alloca, self._zext_index_to_i32(builder, idx_val)) if elem_ptr is not None: return llvmlite.build_load(builder, elem_ty, elem_ptr) return None @@ -839,21 +783,15 @@ class ExprGenName(ExprGenBase.ExprGenBase): #(对齐 Ptr(Ptr(list)) 变量路径,修复 parts[0] 崩溃) if lsn_v is not None: if string.strstr(lsn_v, "list[") is not None: - elem_addr_v: llvmlite.Value* = \ - self.list_getitem_inline( - builder, pool, alloca, idx_val, node) + elem_addr_v: llvmlite.Value* = self.list_getitem_inline(builder, pool, alloca, idx_val, node) if elem_addr_v is not None: - elem_ty_v: llvmlite.LLVMType* = \ - self._list_elem_type_from_name(pool, lsn_v) + elem_ty_v: llvmlite.LLVMType* = self._list_elem_type_from_name(pool, lsn_v) if elem_ty_v is not None: - elem_ptr_ty_v: llvmlite.LLVMType* = \ - llvmlite.Ptr(pool, elem_ty_v) + elem_ptr_ty_v: llvmlite.LLVMType* = llvmlite.Ptr(pool, elem_ty_v) casted_v: llvmlite.Value* = \ - llvmlite.build_bitcast( - builder, elem_addr_v, elem_ptr_ty_v) + llvmlite.build_bitcast(builder, elem_addr_v, elem_ptr_ty_v) if casted_v is not None: - return llvmlite.build_load( - builder, elem_ty_v, casted_v) + return llvmlite.build_load(builder, elem_ty_v, casted_v) return None case llvmlite.LLVMType.Ptr(inner_ty): # 检查 inner_ty 是否是 list[T] 类型(泛型类不注册 struct) @@ -867,23 +805,17 @@ class ExprGenName(ExprGenBase.ExprGenBase): if list_struct_name is not None: if string.strstr(list_struct_name, "list[") is not None: # list[T] 类型: 内联生成 __getitem__ 逻辑 - ptr_val_list: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_list: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_list is not None: - elem_addr_list: llvmlite.Value* = self.list_getitem_inline( - builder, pool, ptr_val_list, idx_val, node) + elem_addr_list: llvmlite.Value* = self.list_getitem_inline(builder, pool, ptr_val_list, idx_val, node) if elem_addr_list is not None: # 根据类型名提取元素类型,bitcast 后 load - elem_ty_list: llvmlite.LLVMType* = self._list_elem_type_from_name( - pool, list_struct_name) + elem_ty_list: llvmlite.LLVMType* = self._list_elem_type_from_name(pool, list_struct_name) if elem_ty_list is not None: - elem_ptr_ty_list: llvmlite.LLVMType* = llvmlite.Ptr( - pool, elem_ty_list) - casted_addr_list: llvmlite.Value* = llvmlite.build_bitcast( - builder, elem_addr_list, elem_ptr_ty_list) + elem_ptr_ty_list: llvmlite.LLVMType* = llvmlite.Ptr(pool, elem_ty_list) + casted_addr_list: llvmlite.Value* = llvmlite.build_bitcast(builder, elem_addr_list, elem_ptr_ty_list) if casted_addr_list is not None: - return llvmlite.build_load( - builder, elem_ty_list, casted_addr_list) + return llvmlite.build_load(builder, elem_ty_list, casted_addr_list) return None # inner_ty 是 Ptr 说明 alloca.Ty 是三重指针 Ptr(Ptr(Ptr(...))), # 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。 @@ -892,11 +824,9 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 对比 HashTable|t.CPtr: alloca.Ty=HashTable**, inner_ty=Struct(HashTable) # (非 Ptr), 仍走下面的方法调用转发路径。 if self.is_ptr_type(inner_ty) != 0: - ptr_val_pp: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_pp: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_pp is not None: - elem_ptr_pp: llvmlite.Value* = llvmlite.build_gep( - builder, inner_ty, ptr_val_pp, idx_val) + elem_ptr_pp: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val_pp, idx_val) if elem_ptr_pp is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, inner_ty, elem_ptr_pp, vol_sub_rd) @@ -911,23 +841,18 @@ class ExprGenName(ExprGenBase.ExprGenBase): if gi_lookup_rd is not None: viperlib.snprintf(gi_lookup_rd, 128, "%s.__getitem__", cls_nm_rd_ptr) if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_rd) is not None: - obj_ptr_rd: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + obj_ptr_rd: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if not (obj_ptr_rd is None): arg_vals_rd_p: sizet* = pool.alloc(8) if not (arg_vals_rd_p is None): arg_vals_rd_p[0] = sizet(idx_val) - ret_rd_p: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_rd_ptr, "__getitem__", - obj_ptr_rd, arg_vals_rd_p, 1, trans, sub) + ret_rd_p: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_rd_ptr, "__getitem__", obj_ptr_rd, arg_vals_rd_p, 1, trans, sub) if not (ret_rd_p is None): return ret_rd_p # 无 __getitem__:结构体指针数组访问(GEP + load) - ptr_val_rd_g: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_rd_g: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_rd_g is not None: - elem_rd_g: llvmlite.Value* = llvmlite.build_gep( - builder, inner_ty, ptr_val_rd_g, idx_val) + elem_rd_g: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val_rd_g, idx_val) if elem_rd_g is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, inner_ty, elem_rd_g, vol_sub_rd) @@ -944,21 +869,17 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 必须先 load alloca 得指针值,再 GEP i8*(步长 8)—— # 否则 GEP base 用 alloca(&elem_ptr)读到栈变量而非数据区, # list.get 返回"元素地址"而非"元素值"(dump 虚调用读错 vtable)。 - ptr_val_pe_ts: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_pe_ts: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_pe_ts is not None: - elem_ptr_ts: llvmlite.Value* = llvmlite.build_gep( - builder, pointee, ptr_val_pe_ts, idx_val) + elem_ptr_ts: llvmlite.Value* = llvmlite.build_gep(builder, pointee, ptr_val_pe_ts, idx_val) if elem_ptr_ts is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, pointee, elem_ptr_ts, vol_sub_rd) return None # 普通指针遍历: 先 load 指针值,再 GEP - ptr_val: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val is not None: - elem_ptr2: llvmlite.Value* = llvmlite.build_gep( - builder, inner_ty, ptr_val, idx_val) + elem_ptr2: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val, idx_val) if elem_ptr2 is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, inner_ty, elem_ptr2, vol_sub_rd) @@ -975,13 +896,10 @@ class ExprGenName(ExprGenBase.ExprGenBase): match pointee: case llvmlite.LLVMType.Int(bits_rd): if bits_rd == 8: - i8_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - elem_ptr_rd: llvmlite.Value* = llvmlite.build_gep( - builder, i8_ptr_rd, alloca, idx_val) + i8_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + elem_ptr_rd: llvmlite.Value* = llvmlite.build_gep(builder, i8_ptr_rd, alloca, idx_val) if elem_ptr_rd is not None: - return llvmlite.build_load( - builder, i8_ptr_rd, elem_ptr_rd) + return llvmlite.build_load(builder, i8_ptr_rd, elem_ptr_rd) case _: pass # 自定义类(结构体类型): 仅当类定义了 __getitem__ @@ -993,23 +911,18 @@ class ExprGenName(ExprGenBase.ExprGenBase): if gi_lookup_sub is not None: viperlib.snprintf(gi_lookup_sub, 128, "%s.__getitem__", cls_nm_sub) if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_sub) is not None: - obj_val_sub: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + obj_val_sub: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if not (obj_val_sub is None): arg_vals_sub: sizet* = pool.alloc(8) if not (arg_vals_sub is None): arg_vals_sub[0] = sizet(idx_val) - ret_sub: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_sub, "__getitem__", - obj_val_sub, arg_vals_sub, 1, trans, sub) + ret_sub: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_sub, "__getitem__", obj_val_sub, arg_vals_sub, 1, trans, sub) if not (ret_sub is None): return ret_sub # 无 __getitem__:结构体指针数组访问(GEP + load) - ptr_val_sub_g: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_sub_g: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_sub_g is not None: - elem_sub_g: llvmlite.Value* = llvmlite.build_gep( - builder, pointee, ptr_val_sub_g, idx_val) + elem_sub_g: llvmlite.Value* = llvmlite.build_gep(builder, pointee, ptr_val_sub_g, idx_val) if elem_sub_g is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, pointee, elem_sub_g, vol_sub_rd) @@ -1017,8 +930,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): pass # 通用路径:翻译 value 获取指针 - ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub.value, None, 0, trans) + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans) if ptr_val is None or ptr_val.Ty is None: return None @@ -1027,16 +939,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 通用路径基址(如 self.ptr / 复杂表达式):仅当基址可解析到 # VarEntry/FieldEntry 且其为 rawptr[t.CVolatile|T] 时,元素 load 带 volatile; # 其余基址解析返回 0(明确不支持,见限制清单)。守卫为 0 时文本不变。 - vol_sub_gen: int = self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, sub.value) + vol_sub_gen: int = self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, sub.value) elem_ty2: llvmlite.LLVMType* = ptr_val.Ty.Pointee if elem_ty2 is not None: # 数组类型: 双索引 GEP + load 元素 match elem_ty2: case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2): - elem_ptr3: llvmlite.Value* = llvmlite.build_gep_array( - builder, elem_ty2, arr_elem_ty2, ptr_val, - self._zext_index_to_i32(builder, idx_val)) + elem_ptr3: llvmlite.Value* = llvmlite.build_gep_array(builder, elem_ty2, arr_elem_ty2, ptr_val, self._zext_index_to_i32(builder, idx_val)) if elem_ptr3 is not None: return llvmlite.build_load(builder, arr_elem_ty2, elem_ptr3, vol_sub_gen) return None @@ -1050,29 +959,20 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 存指针",合法 C 联合读回应按指针读回。统一按 i8* load(同宽 8 字节, # 位模式不变):指针目标直接 bitcast;整数目标隐式 ptrtoint 同样 # 保持位模式(对齐 MatchGenMixin 的 REnum 槽位按声明类型读机制)。 - if trans is not None and sub.value is not None \ - and sub.value.kind() == ast.ASTKind.Attribute: - fa_u64: str = self.Gen.ExprGenAttr._resolve_attr_field_class( - pool, trans, sub.value) + if trans is not None and sub.value is not None and sub.value.kind() == ast.ASTKind.Attribute: + fa_u64: str = self.Gen.ExprGenAttr._resolve_attr_field_class(pool, trans, sub.value) if fa_u64 is not None and self._annot_is_64bit_scalar(fa_u64) != 0: match elem_ty2: case llvmlite.LLVMType.Int(eb_u64): if eb_u64 == 64: - cell_p_u64: llvmlite.Value* = \ - llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val) + cell_p_u64: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val) if cell_p_u64 is not None: - i8_ty_u64: llvmlite.LLVMType* = \ - llvmlite.Int8(pool) - i8p_ty_u64: llvmlite.LLVMType* = \ - llvmlite.Ptr(pool, i8_ty_u64) - i8pp_ty_u64: llvmlite.LLVMType* = \ - llvmlite.Ptr(pool, i8p_ty_u64) - cast_cell_u64: llvmlite.Value* = \ - llvmlite.build_bitcast( - builder, cell_p_u64, i8pp_ty_u64) + i8_ty_u64: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8p_ty_u64: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_u64) + i8pp_ty_u64: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8p_ty_u64) + cast_cell_u64: llvmlite.Value* = llvmlite.build_bitcast(builder, cell_p_u64, i8pp_ty_u64) if cast_cell_u64 is not None: - return llvmlite.build_load( - builder, i8p_ty_u64, cast_cell_u64, vol_sub_gen) + return llvmlite.build_load(builder, i8p_ty_u64, cast_cell_u64, vol_sub_gen) case _: pass # 自定义结构体 (如 self._ht[key]): 仅当类定义了 __getitem__ 才转发方法调用; @@ -1086,20 +986,16 @@ class ExprGenName(ExprGenBase.ExprGenBase): arg_vals_rd_g: sizet* = pool.alloc(8) if not (arg_vals_rd_g is None): arg_vals_rd_g[0] = sizet(idx_val) - ret_rd_g: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, cls_nm_rd_gen, "__getitem__", - ptr_val, arg_vals_rd_g, 1, trans, sub) + ret_rd_g: llvmlite.Value* = self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_rd_gen, "__getitem__", ptr_val, arg_vals_rd_g, 1, trans, sub) if not (ret_rd_g is None): return ret_rd_g # 无 __getitem__:结构体指针数组访问(GEP + load) - elem_ptr_gen: llvmlite.Value* = llvmlite.build_gep( - builder, elem_ty2, ptr_val, idx_val) + elem_ptr_gen: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val) if elem_ptr_gen is not None: return llvmlite.build_load(builder, elem_ty2, elem_ptr_gen, vol_sub_gen) return None # 指针类型: 单索引 GEP + load - elem_ptr4: llvmlite.Value* = llvmlite.build_gep( - builder, elem_ty2, ptr_val, idx_val) + elem_ptr4: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val) if elem_ptr4 is not None: return llvmlite.build_load(builder, elem_ty2, elem_ptr4, vol_sub_gen) return None @@ -1110,14 +1006,10 @@ class ExprGenName(ExprGenBase.ExprGenBase): """注解是否为 64 位标量 | t.CPtr 联合(AnnotClassName 为提取出的 非 CPtr 侧类型名,如 int64|t.CPtr → "CInt64T")。此类联合的 8 字节单元格存 i64 标量,下标元素类型应为 Int64 而非指针。""" - if annot is None: - return 0 - if string.strstr(annot, "CInt64T") is not None: - return 1 - if string.strstr(annot, "CUInt64T") is not None: - return 1 - if string.strstr(annot, "CSizeT") is not None: - return 1 + if annot is None: return 0 + if string.strstr(annot, "CInt64T") is not None: return 1 + if string.strstr(annot, "CUInt64T") is not None: return 1 + if string.strstr(annot, "CSizeT") is not None: return 1 return 0 # ============================================================ @@ -1140,49 +1032,36 @@ class ExprGenName(ExprGenBase.ExprGenBase): trans: HT.Translator*, node: ast.AST*) -> int: """下标基座存储形态:1=数组 / 0=指针 / -1=无法判定""" - if node is None or trans is None: - return -1 + if node is None or trans is None: return -1 sub_bk: ast.Subscript* = ast.Subscript*(node) - if sub_bk is None or sub_bk.value is None: - return -1 + if sub_bk is None or sub_bk.value is None: return -1 base_ty_bk: llvmlite.LLVMType* = None if sub_bk.value.kind() == ast.ASTKind.Name: nm_bk: ast.Name* = ast.Name*(sub_bk.value) - if nm_bk.id is None: - return -1 - alloca_bk: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, nm_bk.id) + if nm_bk.id is None: return -1 + alloca_bk: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm_bk.id) if alloca_bk is None: alloca_bk = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm_bk.id) - if alloca_bk is None or alloca_bk.Ty is None: - return -1 - if self.is_ptr_type(alloca_bk.Ty) == 0: - return -1 + if alloca_bk is None or alloca_bk.Ty is None: return -1 + if self.is_ptr_type(alloca_bk.Ty) == 0: return -1 base_ty_bk = alloca_bk.Ty.Pointee elif sub_bk.value.kind() == ast.ASTKind.Attribute: # 单层 obj.field(如 self.arr):非 fatal 只读解析字段类型 - fe_bk: GenTypes.FieldEntry* = \ - self.Gen.ExprGenAttr._resolve_attr_field_entry(pool, trans, sub_bk.value) - if fe_bk is None or fe_bk.Ty is None: - return -1 + fe_bk: GenTypes.FieldEntry* = self.Gen.ExprGenAttr._resolve_attr_field_entry(pool, trans, sub_bk.value) + if fe_bk is None or fe_bk.Ty is None: return -1 base_ty_bk = fe_bk.Ty else: return -1 - if base_ty_bk is None: - return -1 + if base_ty_bk is None: return -1 # 基座自身是数组值 → 数组存储 - if self.is_array_type(base_ty_bk) != 0: - return 1 + if self.is_array_type(base_ty_bk) != 0: return 1 if self.is_ptr_type(base_ty_bk) != 0: inner_bk: llvmlite.LLVMType* = base_ty_bk.Pointee - if inner_bk is None: - return -1 + if inner_bk is None: return -1 # Ptr(Array) → t.CArray[T,N] 局部/字段(数组存储) - if self.is_array_type(inner_bk) != 0: - return 1 + if self.is_array_type(inner_bk) != 0: return 1 # Ptr(Struct) → rawptr[T](指针存储) - if inner_bk.kind() == llvmlite.LLVMType.Struct: - return 0 + if inner_bk.kind() == llvmlite.LLVMType.Struct: return 0 return -1 def get_subscript_ptr(self, builder: llvmlite.IRBuilder*, @@ -1191,17 +1070,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): node: ast.AST*, trans: HT.Translator* = None) -> llvmlite.Value*: """获取下标表达式的元素指针(用于赋值 lhs)""" - if node is None or builder is None: - return None + if node is None or builder is None: return None sub: ast.Subscript* = ast.Subscript*(node) - if sub is None: - return None + if sub is None: return None # 翻译索引 - idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub.slice, None, 0, trans) - if idx_val is None: - return None + idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.slice, None, 0, trans) + if idx_val is None: return None # 嵌套下标: a[i][j] = v —— 递归解析内层下标指针后 GEP # (如 gfx.vp Mat4.m: t.CArray[t.CArray[float, 4], 4] 的 m.m[0][0] = 1; @@ -1209,18 +1084,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 会把内层元素加载为值(Array 类型)→ is_ptr_type 失败 → 返回 None → # "subscript ptr is None" fail-fast。递归取内层指针再 GEP 根治。) if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript: - inner_ptr: llvmlite.Value* = self.get_subscript_ptr( - builder, pool, mod, sub.value, trans) - if inner_ptr is None or inner_ptr.Ty is None: - return None + inner_ptr: llvmlite.Value* = self.get_subscript_ptr(builder, pool, mod, sub.value, trans) + if inner_ptr is None or inner_ptr.Ty is None: return None inner_elem: llvmlite.LLVMType* = inner_ptr.Ty.Pointee - if inner_elem is None: - return None + if inner_elem is None: return None match inner_elem: case llvmlite.LLVMType.Array(arr_ie, _): - return llvmlite.build_gep_array( - builder, inner_elem, arr_ie, inner_ptr, - self._zext_index_to_i32(builder, idx_val)) + return llvmlite.build_gep_array(builder, inner_elem, arr_ie, inner_ptr, self._zext_index_to_i32(builder, idx_val)) case _: return llvmlite.build_gep(builder, inner_elem, inner_ptr, idx_val) @@ -1231,8 +1101,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能 # lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃) if GenApi.is_nonlocal_name(trans, nm.id) != 0: - return self._nonlocal_subscript_ptr( - builder, pool, trans, nm.id, idx_val) + return self._nonlocal_subscript_ptr(builder, pool, trans, nm.id, idx_val) alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) if alloca is not None and alloca.Ty is not None: if self.is_ptr_type(alloca.Ty) != 0: @@ -1242,19 +1111,15 @@ class ExprGenName(ExprGenBase.ExprGenBase): match pointee: case llvmlite.LLVMType.Array(elem_ty, count): # 数组遍历 - return llvmlite.build_gep_array( - builder, pointee, elem_ty, alloca, - self._zext_index_to_i32(builder, idx_val)) + return llvmlite.build_gep_array(builder, pointee, elem_ty, alloca, self._zext_index_to_i32(builder, idx_val)) case llvmlite.LLVMType.Ptr(inner_ty): # inner_ty 是 Ptr 说明 alloca.Ty 是三重指针, # 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。 # 此时 [i]=val 应该是指针解引用赋值, 而非调用 __setitem__。 if self.is_ptr_type(inner_ty) != 0: - ptr_val_gsp: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_gsp: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_gsp is not None: - return llvmlite.build_gep( - builder, inner_ty, ptr_val_gsp, idx_val) + return llvmlite.build_gep(builder, inner_ty, ptr_val_gsp, idx_val) return None # 自定义结构体 (如 HashTable|t.CPtr, JsonValue|t.CPtr): # 仅当类定义了 __setitem__(当前模块定义或跨模块 stub declare 注入) @@ -1279,8 +1144,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # alloca 得指针值,再 GEP——否则 GEP base 用 alloca(&elem_ptr) # 读到栈变量而非数据区,赋值写不进 list 数据 # (data 全 0xbaadf00d,dump 虚调用读错 vtable 崩溃)。 - ptr_val_pe: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_pe: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_pe is not None: # [FIX 2026-08-30] 64 位标量联合(int64|t.CPtr / # uint64|t.CPtr / sizet|t.CPtr):8 字节单元格存 @@ -1289,29 +1153,22 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 否则元素类型为指针 → i64 存储触发整数隐式转指针 # fail-fast(把解引用写入误判为 int→ptr)。 pe_annot: str = self.Gen.VarGen.var_annot_class_name(ve_pe) - if pe_annot is not None \ - and self._annot_is_64bit_scalar(pe_annot) != 0: - return llvmlite.build_gep( - builder, llvmlite.Int64(pool), ptr_val_pe, idx_val) + if pe_annot is not None and self._annot_is_64bit_scalar(pe_annot) != 0: + return llvmlite.build_gep(builder, llvmlite.Int64(pool), ptr_val_pe, idx_val) match pointee: case llvmlite.LLVMType.Int(bits_pe): if bits_pe == 8: - i8_ptr_pe: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - return llvmlite.build_gep( - builder, i8_ptr_pe, ptr_val_pe, idx_val) + i8_ptr_pe: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + return llvmlite.build_gep(builder, i8_ptr_pe, ptr_val_pe, idx_val) case _: pass - return llvmlite.build_gep( - builder, pointee, ptr_val_pe, idx_val) + return llvmlite.build_gep(builder, pointee, ptr_val_pe, idx_val) return None # 普通指针遍历: 先 load 指针值,再 GEP - ptr_val: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val is None: return None - gep_r: llvmlite.Value* = llvmlite.build_gep( - builder, inner_ty, ptr_val, idx_val) + gep_r: llvmlite.Value* = llvmlite.build_gep(builder, inner_ty, ptr_val, idx_val) return gep_r case _: # pointee 是普通标量类型 (如 i64, i32, i8): @@ -1329,26 +1186,21 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 得指针值,再按 i8* 步长 GEP——否则 GEP base 用 alloca # (&elem_ptr)算到栈地址,赋值写不进 list 数据区 # (append 只增 count、data 全 0xbaadf00d)。 - ptr_val_cs: llvmlite.Value* = llvmlite.build_load( - builder, pointee, alloca) + ptr_val_cs: llvmlite.Value* = llvmlite.build_load(builder, pointee, alloca) if ptr_val_cs is not None: match pointee: case llvmlite.LLVMType.Int(bits_cs): if bits_cs == 8: - i8_ptr_cs: llvmlite.LLVMType* = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - return llvmlite.build_gep( - builder, i8_ptr_cs, ptr_val_cs, idx_val) + i8_ptr_cs: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + return llvmlite.build_gep(builder, i8_ptr_cs, ptr_val_cs, idx_val) case _: pass - return llvmlite.build_gep( - builder, pointee, ptr_val_cs, idx_val) + return llvmlite.build_gep(builder, pointee, ptr_val_cs, idx_val) return None return llvmlite.build_gep(builder, pointee, alloca, idx_val) # 通用路径 - ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub.value, None, 0, trans) + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub.value, None, 0, trans) if ptr_val is None or ptr_val.Ty is None: return None if self.is_ptr_type(ptr_val.Ty) != 0: @@ -1357,9 +1209,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 数组类型: 双索引 GEP (getelementptr [N x ty], ptr, i32 0, i32 idx) match elem_ty2: case llvmlite.LLVMType.Array(arr_elem_ty, arr_count): - return llvmlite.build_gep_array( - builder, elem_ty2, arr_elem_ty, ptr_val, - self._zext_index_to_i32(builder, idx_val)) + return llvmlite.build_gep_array(builder, elem_ty2, arr_elem_ty, ptr_val, self._zext_index_to_i32(builder, idx_val)) case _: pass # 自定义结构体 (如 self._ht[key]): 仅当类定义了 __setitem__ diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 9ec51e4..053ed0d 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -14,13 +14,8 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase # ============================================================ # ExprGenOps - ExprGenMixin 拆分(阶段 D):比较/一元/布尔/binop 运算 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class ExprGenOps(ExprGenBase.ExprGenBase): +novirtual class ExprGenOps(ExprGenBase.ExprGenBase): """比较/一元/布尔/binop 运算""" # ============================================================ @@ -37,21 +32,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase): node: ast.AST*, trans: HT.Translator* = None) -> llvmlite.Value*: """翻译三元表达式 (body if test else orelse),返回 phi 结果 Value""" - if node is None or builder is None or trans is None: - return None + if node is None or builder is None or trans is None: return None ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node) - if ie is None: - return None + if ie is None: return None func: llvmlite.Function* = trans._cur_func - if func is None: - return None + if func is None: return None # 1. 求值条件 - cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, ie.test, None, 0, trans) - if cond_val is None: - return None + cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.test, None, 0, trans) + if cond_val is None: return None # 转换为 i1 cond_bits: int = self.get_llvm_type_bits(cond_val.Ty) if cond_bits == 1: @@ -78,16 +68,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase): viperlib.snprintf(name_buf, 32, "ifexp.merge.%d", cnt) merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) - if then_bb is None or else_bb is None or merge_bb is None: - return None + if then_bb is None or else_bb is None or merge_bb is None: return None # 3. 条件跳转 llvmlite.build_cond_br(builder, cond_i1, then_bb, else_bb) # 4. then 分支 llvmlite.position_at_end(builder, then_bb) - body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, ie.body, None, 0, trans) + body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.body, None, 0, trans) then_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock if body_val is None: # fail-fast:三元表达式 then 分支翻译失败,立即终止编译(暴露上游根因) @@ -106,8 +94,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if self.is_ptr_type(body_val.Ty) != 0: orelse_target_ty = body_val.Ty llvmlite.position_at_end(builder, else_bb) - orelse_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty) + orelse_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty) else_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock if orelse_val is None: # fail-fast:三元表达式 else 分支翻译失败,立即终止编译(暴露上游根因) @@ -157,10 +144,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # fail-fast:三元表达式分支类型缺失,立即终止编译(暴露上游根因) self.Gen.TypeGenErr.fatal_error(node, "三元表达式分支类型缺失", "TypeError") - inc1: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming( - pool, body_val, then_blk_for_phi) - inc2: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming( - pool, orelse_val, else_blk_for_phi) + inc1: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, body_val, then_blk_for_phi) + inc2: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, orelse_val, else_blk_for_phi) if inc1 is None or inc2 is None: return None # 链表顺序: inc1 (head) -> inc2 (tail) @@ -272,8 +257,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 1 # 2) 变量注解类型为无符号类型(trans 可用时查 SymTab) if trans is not None: - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if ve is not None: # [S4 切读] Spec 明确无符号(TS_UINT)优先于字符串判定 if self._entry_spec_unsigned(ve.Spec) != 0: @@ -302,8 +286,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if sub_su.value is not None and sub_su.value.kind() == ast.ASTKind.Name: snm_su: ast.Name* = ast.Name*(sub_su.value) if snm_su.id is not None and trans is not None: - ve_su: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, snm_su.id) + ve_su: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, snm_su.id) if ve_su is not None: # [S4 切读] Spec 明确无符号优先(数组元素为无符号的联合注解场景 # 时 Spec 仍是 Ptr/Array ⇒ 返回 0,自动回退字符串路径) @@ -322,8 +305,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if at_u.value.kind() == ast.ASTKind.Name: vn_u: ast.Name* = ast.Name*(at_u.value) if vn_u.id is not None: - ve_u: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, vn_u.id) + ve_u: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, vn_u.id) if ve_u is not None: cls_nm_u = self.Gen.VarGen.var_annot_class_name(ve_u) if cls_nm_u is not None: @@ -383,8 +365,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if self._spec_sign_from_annot(nm.id) == TSpec.TS_SIGN_SIGNED: return 1 if trans is not None: - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if ve is not None: ncn_s: str = self.Gen.VarGen.var_annot_class_name(ve) if ncn_s is not None: @@ -396,8 +377,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if sub_s.value is not None and sub_s.value.kind() == ast.ASTKind.Name: snm: ast.Name* = ast.Name*(sub_s.value) if snm.id is not None and trans is not None: - ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, snm.id) + ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, snm.id) if ve_s is not None: scn_s: str = self.Gen.VarGen.var_annot_class_name(ve_s) if scn_s is not None: @@ -483,8 +463,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if comparators is None or len(comparators) == 0: return None rhs_node: ast.AST* = comparators.get(0) - rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, rhs_node, None, 0, trans) + rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rhs_node, None, 0, trans) if rhs is None: return None @@ -523,27 +502,22 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if cmp_with_none == 0 and lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None: nm: ast.Name* = ast.Name*(lhs_node) if nm is not None and nm.id is not None: - lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, nm.id) + lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) if lhs_alloca is not None: if cmp_zero == 0 or self.get_ptr_level(lhs_alloca.Ty) == 0: ovl_self1: llvmlite.Value* = lhs_alloca # Ptr(Ptr(Struct)) 对象存储槽:load 出对象指针作 self # (与 translate_binop 路径 1 一致,避免槽地址当对象地址) - if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \ - and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: - load_self1: llvmlite.Value* = llvmlite.build_load( - builder, lhs_alloca.Ty.Pointee, lhs_alloca) + if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: + load_self1: llvmlite.Value* = llvmlite.build_load(builder, lhs_alloca.Ty.Pointee, lhs_alloca) if load_self1 is not None: ovl_self1 = load_self1 - ovl_result: llvmlite.Value* = self.try_operator_overload( - pool, builder, mod, ovl_self1, rhs, op, trans, 1) + ovl_result: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, ovl_self1, rhs, op, trans, 1) if ovl_result is not None: return ovl_result # 正常翻译 lhs - lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, cmp.left, None, 0, trans) + lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cmp.left, None, 0, trans) if lhs is None: return None @@ -559,8 +533,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): cn_lookup: str = pool.alloc(128) if cn_lookup is not None: viperlib.snprintf(cn_lookup, 128, "%s.__contains__", cn_cls) - cn_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - mod, cn_lookup) + cn_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, cn_lookup) if cn_fn is not None: cn_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(cn_fn) cn_fn_name: str = llvmlite.function_get_name(cn_fn) @@ -576,26 +549,22 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 参数链表: self → key(独立 null 结尾) cn_self.Next = lhs lhs.Next = None - cn_res: llvmlite.Value* = llvmlite.build_call( - builder, cn_fn_name, cn_self, 2, cn_ret, 0) + cn_res: llvmlite.Value* = llvmlite.build_call(builder, cn_fn_name, cn_self, 2, cn_ret, 0) if cn_res is not None: # 归一化到 i1(__contains__ 返回 int/i32 等) cn_i1: llvmlite.Value* = cn_res match cn_ret: case llvmlite.LLVMType.Int(cn_bits): if cn_bits > 1: - cn_zero: llvmlite.Value* = llvmlite.ConstInt( - pool, cn_ret, 0, "0") + cn_zero: llvmlite.Value* = llvmlite.ConstInt(pool, cn_ret, 0, "0") if cn_zero is not None: - cn_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cn_res, cn_zero) + cn_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cn_res, cn_zero) case _: pass if op == ast.OpKind.NotIn: i1_ty_ni: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_ni is not None and cn_i1 is not None: - one_i1_ni: llvmlite.Value* = llvmlite.ConstInt( - pool, i1_ty_ni, 1, "1") + one_i1_ni: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_ni, 1, "1") if one_i1_ni is not None: cn_i1 = llvmlite.build_xor(builder, cn_i1, one_i1_ni) if cn_i1 is not None: @@ -610,8 +579,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # Is/IsNot 不在 _cmpop_to_dunder 映射中,会自动返回 None 回退原生比较 # None 比较跳过重载(走身份比较);指针判空(cmp_zero + 指针)同样跳过 if cmp_with_none == 0 and (cmp_zero == 0 or self.get_ptr_level(lhs.Ty) == 0): - ovl_result2: llvmlite.Value* = self.try_operator_overload( - pool, builder, mod, lhs, rhs, op, trans, 1) + ovl_result2: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, lhs, rhs, op, trans, 1) if ovl_result2 is not None: return ovl_result2 @@ -677,10 +645,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): rhs = llvmlite.build_ptrtoint(builder, rhs, lhs.Ty) else: # 不同级指针(1 vs 2 等)→ 禁止(fast-fail) - self.Gen.TypeGenErr.fatal_error( - cmp, - f"比较类型不匹配: 不同级指针比较 (lhs 层级={lhs_ptr_level}, rhs 层级={rhs_ptr_level})", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cmp, f"比较类型不匹配: 不同级指针比较 (lhs 层级={lhs_ptr_level}, rhs 层级={rhs_ptr_level})", "TypeError") else: # None 比较: None 被翻译为 i8* null(一级指针) # 如果 lhs 是指针,将 rhs (i8* null) bitcast 为 lhs 的指针类型 @@ -786,21 +751,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase): trans: HT.Translator* = None) -> llvmlite.Value*: """翻译一元运算(-x, +x, not x, ~x)""" uo: ast.UnaryOp* = ast.UnaryOp*(node) - if uo is None: - return None + if uo is None: return None - operand: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, uo.operand, None, 0, trans) - if operand is None: - return None + operand: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo.operand, None, 0, trans) + if operand is None: return None # === 一元运算符重载: -obj/+obj/~obj 调用 __neg__/__pos__/__invert__ === # 仅 USub/UAdd/Invert 有重载语义(not 无 dunder 方法) if uo.op == ast.OpKind.USub or uo.op == ast.OpKind.UAdd or uo.op == ast.OpKind.Invert: - ovl_u: llvmlite.Value* = self.try_unary_operator_overload( - pool, builder, mod, operand, uo.op, trans) - if ovl_u is not None: - return ovl_u + ovl_u: llvmlite.Value* = self.try_unary_operator_overload(pool, builder, mod, operand, uo.op, trans) + if ovl_u is not None: return ovl_u if uo.op == ast.OpKind.USub: # -x @@ -854,8 +814,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if d_pointee is not None: return llvmlite.build_load(builder, d_pointee, operand) # 非指针即类型推断退化:fail-fast,绝不按 i8 兜底读取 - self.Gen.TypeGenErr.fatal_error( - node, "单目 '*' 解引用的操作数必须是指针类型(类型推断退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, "单目 '*' 解引用的操作数必须是指针类型(类型推断退化)", "TypeError") return None elif uo.op == ast.OpKind.AddrOf: # &x → 左值地址(不 load):Name 变量 alloca / 模块全局 / 模块函数 / @@ -868,8 +827,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # self/cls 对象引用:返回对象指针本身(Ptr(Struct))而非 # 指针变量的地址(Ptr(Ptr(Struct))) if string.strcmp(nm_ao.id, "self") == 0 or string.strcmp(nm_ao.id, "cls") == 0: - se_ao: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_ao.id) + se_ao: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ao.id) if se_ao is not None and se_ao.Alloca is not None and se_ao.Alloca.Ty is not None: match se_ao.Alloca.Ty: case llvmlite.LLVMType.Ptr(sa1): @@ -930,18 +888,15 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return llvmlite.SSAValue(pool, llvmlite.Ptr(pool, fn_ty_ao), fbuf_ao) elif uo.operand.kind() == ast.ASTKind.Attribute: # 字段地址(GEP,不 load) - fptr_ao: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, uo.operand, trans) + fptr_ao: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, uo.operand, trans) if fptr_ao is not None: return fptr_ao elif uo.operand.kind() == ast.ASTKind.Subscript: # 元素地址(GEP,不 load) - sptr_ao: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( - builder, pool, mod, uo.operand, trans) + sptr_ao: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, uo.operand, trans) if sptr_ao is not None: return sptr_ao - self.Gen.TypeGenErr.fatal_error( - node, "单目 '&' 取地址的操作数必须是左值(Name/Attribute/Subscript)", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, "单目 '&' 取地址的操作数必须是左值(Name/Attribute/Subscript)", "TypeError") return None return operand # ============================================================ @@ -991,16 +946,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase): merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) # phi 入边链表头/尾 - phi_head: rawptr[llvmlite.PhiIncoming] = None - phi_tail: rawptr[llvmlite.PhiIncoming] = None + phi_head: llvmlite.PhiIncoming* = None + phi_tail: llvmlite.PhiIncoming* = None phi_count: int = count - 1 # 循环次数 # 对每个值(除最后一个)求值并短路 for i in range(count - 1): val_node: ast.AST* = values.get(i) - val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, val_node, - funcs_ptr, func_count, trans) + val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, val_node, funcs_ptr, func_count, trans) if val is None: return None @@ -1030,7 +983,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 添加 phi 入边:(val_i1, cond_br 所在 BB) cur_bb: rawptr[llvmlite.BasicBlock] = builder.CurBlock - inc: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(pool, val_i1, cur_bb) + inc: llvmlite.PhiIncoming* = llvmlite.new_phi_incoming(pool, val_i1, cur_bb) if phi_head is None: phi_head = inc phi_tail = inc @@ -1043,9 +996,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 最后一个值:求值后直接跳 merge last_node: ast.AST* = values.get(count - 1) - last_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, last_node, - funcs_ptr, func_count, trans) + last_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, last_node, funcs_ptr, func_count, trans) if last_val is None: return None last_bits: int = self.get_llvm_type_bits(last_val.Ty) @@ -1194,35 +1145,28 @@ class ExprGenOps(ExprGenBase.ExprGenBase): mj += 1 # 既无函数定义也无 SHA1 → 该类没有此 dunder 方法,返回 None 回退原生运算 - if found_func is None and cls_sha1 is None: - return None + if found_func is None and cls_sha1 is None: return None # 方法在"定义它的模块"中确实不存在(同模块类但模块内无此 dunder): # 返回 None 回退原生运算,绝不发出幽灵 call——否则 IR 残留 # `call void @...__div__`(副作用)且调用方回退原生 sdiv 双重发射, # llc 报 invalid operand type for instruction(CPythonTest PyFloatObj 根因) if found_func is None and trans is not None and trans.ModuleSha1 is not None: - if cls_sha1 is not None and string.strcmp(cls_sha1, trans.ModuleSha1) == 0: - return None + if cls_sha1 is not None and string.strcmp(cls_sha1, trans.ModuleSha1) == 0: return None # 跨模块类:stub 可能未注入,方法存在性以依赖模块 vpi stub 为准。 # vpi 未命中(依赖模块确实无此 dunder)→ 回退原生比较(icmp), # 绝不发幽灵 call——`call @{cls_sha1}.{Class}.{dunder}` 链接 undefined # (MemBuddy 无 __eq__ 时 os._mbuddy == sys._mbuddy,SysLibTest 根因)。 - vpi_dup: llvmlite.LLVMType* = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi( - pool, cls_sha1, search_class, dunder) - if vpi_dup is None: - return None + vpi_dup: llvmlite.LLVMType* = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi(pool, cls_sha1, search_class, dunder) + if vpi_dup is None: return None # 构建 extra_args 数组(仅含 rhs 一个参数) extra_args: sizet* = pool.alloc(8) - if extra_args is None: - return None + if extra_args is None: return None extra_args[0] = sizet(rhs) # 调用方法: lhs.__dunder__(rhs) - return self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, search_class, dunder, - lhs, extra_args, 1, trans) + return self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, search_class, dunder, lhs, extra_args, 1, trans) # ============================================================ # try_unary_operator_overload - 尝试一元运算符重载 # @@ -1305,9 +1249,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return None # 一元方法无额外参数(extra_args 为空) - return self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, search_class, dunder, - operand, None, 0, trans) + return self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, search_class, dunder, operand, None, 0, trans) # ============================================================ # fail_if_double_ptr_binop - 双指针算术 fail-fast(**唯一实现**) # @@ -1404,8 +1346,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): op: int = binop.op # 先翻译 rhs(只翻译一次,避免副作用重复) - rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, rhs_node, None, 0, trans) + rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rhs_node, None, 0, trans) if rhs is None: return None @@ -1415,8 +1356,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None: nm: ast.Name* = ast.Name*(lhs_node) if nm is not None and nm.id is not None: - lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, nm.id) + lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) if lhs_alloca is not None: ovl_self1: llvmlite.Value* = lhs_alloca # alloca 是 Ptr(Ptr(Struct))(X|t.CPtr 对象存储槽)时, @@ -1424,32 +1364,27 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # load 槽内容(对象指针值)当字段读 → 垃圾(MultiInheritTest # Vec2Both __add__ 输出 (1.0,2.0) 根因;get_struct_type_from_value # 递归解指针后路径 1 能识别 alloca,需同步修正 self 语义) - if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \ - and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: - load_self1: llvmlite.Value* = llvmlite.build_load( - builder, lhs_alloca.Ty.Pointee, lhs_alloca) + if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: + load_self1: llvmlite.Value* = llvmlite.build_load(builder, lhs_alloca.Ty.Pointee, lhs_alloca) if load_self1 is not None: ovl_self1 = load_self1 - ovl_result: llvmlite.Value* = self.try_operator_overload( - pool, builder, mod, ovl_self1, rhs, op, trans, 0) + ovl_result: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, ovl_self1, rhs, op, trans, 0) if ovl_result is not None: return ovl_result # 正常翻译 lhs - lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, lhs_node, None, 0, trans) + lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, lhs_node, None, 0, trans) if lhs is None: return None # === 运算符重载路径 2: lhs 是 Ptr(Struct)(如 Counter|t.CPtr 变量 load 后)=== - ovl_result2: llvmlite.Value* = self.try_operator_overload( - pool, builder, mod, lhs, rhs, op, trans, 0) + ovl_result2: llvmlite.Value* = self.try_operator_overload(pool, builder, mod, lhs, rhs, op, trans, 0) if ovl_result2 is not None: return ovl_result2 # 获取操作数类型信息 - lhs_bits: int = self.get_llvm_type_bits(lhs.Ty) - rhs_bits: int = self.get_llvm_type_bits(rhs.Ty) + lhs_bits: int = self.get_llvm_type_bits(lhs.Ty) + rhs_bits: int = self.get_llvm_type_bits(rhs.Ty) lhs_fbits: int = self.get_llvm_float_bits(lhs.Ty) rhs_fbits: int = self.get_llvm_float_bits(rhs.Ty) @@ -1523,17 +1458,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lhs_bits == 0 and rhs_bits == 0: if op == ast.OpKind.BitOr or op == ast.OpKind.BitAnd or op == ast.OpKind.BitXor or op == ast.OpKind.LShift or op == ast.OpKind.RShift: # fail-fast:位运算操作数类型非法,立即终止编译(暴露上游根因) - self.Gen.TypeGenErr.fatal_error( - node, - "位运算操作数类型非法: lhs/rhs 均为非整数类型(指针或结构体),无法执行位运算", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, "位运算操作数类型非法: lhs/rhs 均为非整数类型(指针或结构体),无法执行位运算", "TypeError") - if op == ast.OpKind.Add: - return llvmlite.build_add(builder, lhs, rhs) - elif op == ast.OpKind.Sub: - return llvmlite.build_sub(builder, lhs, rhs) - elif op == ast.OpKind.Mult: - return llvmlite.build_mul(builder, lhs, rhs) + if op == ast.OpKind.Add: return llvmlite.build_add(builder, lhs, rhs) + elif op == ast.OpKind.Sub: return llvmlite.build_sub(builder, lhs, rhs) + elif op == ast.OpKind.Mult: return llvmlite.build_mul(builder, lhs, rhs) elif op == ast.OpKind.Div: # 无符号操作数 → udiv(binop_unsigned 经 _node_type_unsigned 判定, # 覆盖 sizet/uint64 及变量/数组元素的注解无符号性)。 @@ -1550,14 +1479,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if binop_unsigned != 0: return llvmlite.build_urem(builder, lhs, rhs) return llvmlite.build_srem(builder, lhs, rhs) - elif op == ast.OpKind.BitAnd: - return llvmlite.build_and(builder, lhs, rhs) - elif op == ast.OpKind.BitOr: - return llvmlite.build_or(builder, lhs, rhs) - elif op == ast.OpKind.BitXor: - return llvmlite.build_xor(builder, lhs, rhs) - elif op == ast.OpKind.LShift: - return llvmlite.build_shl(builder, lhs, rhs) + elif op == ast.OpKind.BitAnd: return llvmlite.build_and(builder, lhs, rhs) + elif op == ast.OpKind.BitOr: return llvmlite.build_or(builder, lhs, rhs) + elif op == ast.OpKind.BitXor: return llvmlite.build_xor(builder, lhs, rhs) + elif op == ast.OpKind.LShift: return llvmlite.build_shl(builder, lhs, rhs) elif op == ast.OpKind.RShift: # 无符号 >> → lshr(逻辑右移),有符号 >> → ashr(算术右移) # 对齐 TPC ExprGen.emit_binary_op:i8/i16 默认无符号;其余查操作数无符号性 diff --git a/App/lib/core/Gen/Func/FuncGenBase.vp b/App/lib/core/Gen/Func/FuncGenBase.vp index 1a325a6..24dde9a 100644 --- a/App/lib/core/Gen/Func/FuncGenBase.vp +++ b/App/lib/core/Gen/Func/FuncGenBase.vp @@ -14,16 +14,11 @@ import lib.core.Gen.Call.CallGenBase as CallGenBase # ============================================================ # FuncGenBase - FuncGenMixin 拆分(阶段 D):函数属性 / 命名 / mangle / create_function 基础工具 -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class FuncGenBase(CallGenBase.CallGenBase): +novirtual class FuncGenBase(CallGenBase.CallGenBase): """函数属性 / 命名 / mangle / create_function 基础工具""" - # ============================================================ + # ============================================================ # extract_func_attrs - 从 decorator_list 提取 c.Attribute 属性 # # 支持 @c.Attribute(t.attr.xxx()) 和 @c.Attribute(t.attr.xxx) 形式 @@ -35,77 +30,58 @@ class FuncGenBase(CallGenBase.CallGenBase): decorator_list: list[ast.AST*]*, imported_modules: str) -> str: """从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串""" - if decorator_list is None: - return None + if decorator_list is None: return None dn: sizet = len(decorator_list) - if dn == 0: - return None + if dn == 0: return None attrs_buf: str = pool.alloc(256) - if attrs_buf is None: - return None + if attrs_buf is None: return None attrs_buf[0] = '\0' found_any: int = 0 for di in range(dn): deco: ast.AST* = decorator_list.get(di) - if deco is None: - continue + if deco is None: continue dk: int = deco.kind() - if dk != ast.ASTKind.Call: - continue + if dk != ast.ASTKind.Call: continue call_node: ast.Call* = ast.Call*(deco) - if call_node.func is None: - continue + if call_node.func is None: continue cfk: int = call_node.func.kind() - if cfk != ast.ASTKind.Attribute: - continue + if cfk != ast.ASTKind.Attribute: continue # 检测 c.Attribute func_attr: ast.Attribute* = ast.Attribute*(call_node.func) - if func_attr.attr is None: - continue - if string.strcmp(func_attr.attr, "Attribute") != 0: - continue - if func_attr.value is None: - continue + if func_attr.attr is None: continue + if string.strcmp(func_attr.attr, "Attribute") != 0: continue + if func_attr.value is None: continue fvk: int = func_attr.value.kind() - if fvk != ast.ASTKind.Name: - continue + if fvk != ast.ASTKind.Name: continue c_name: ast.Name* = ast.Name*(func_attr.value) - if c_name.id is None: - continue - if string.strcmp(c_name.id, "c") != 0: - continue + if c_name.id is None: continue + if string.strcmp(c_name.id, "c") != 0: continue imp_c: int = self.Gen.ImportsGen.is_module_imported(imported_modules, "c") - if imp_c == 0: - continue + if imp_c == 0: continue # 遍历参数提取属性 - if call_node.args is None: - continue + if call_node.args is None: continue args_list: list[ast.AST*]* = call_node.args an: sizet = len(args_list) for ai in range(an): arg_node: ast.AST* = args_list.get(ai) - if arg_node is None: - continue + if arg_node is None: continue # 提取属性名(t.attr.xxx / t.attr.xxx() / t.attr.llvm.xxx) attr_name: str = self._get_attr_name_from_node(arg_node) - if attr_name is None: - continue + if attr_name is None: continue # B5:section 字符串属性(t.attr.section(".text.startup"))不能内联 # 在函数签名行(llc: expected string constant),必须走属性组 # #N(function_set_attr_group)→ 由 FuncGenDef 单独提取处理。 - if string.strcmp(attr_name, "section") == 0: - continue + if string.strcmp(attr_name, "section") == 0: continue # 映射到 LLVM 属性名并追加 ar: int = self._append_llvm_attr(attrs_buf, attr_name) if ar != 0: found_any = 1 - if found_any == 0: - return None + if found_any == 0: return None return attrs_buf def extract_func_section(self, pool: memhub.MemBuddy*, decorator_list: list[ast.AST*]*, @@ -116,38 +92,28 @@ class FuncGenBase(CallGenBase.CallGenBase): attributes #N = { ... }),不能内联(llc: expected string constant)。 main.vp boot 函数 t.attr.section(".text.startup") 供链接器按段放置。 """ - if pool is None or decorator_list is None: - return None + if pool is None or decorator_list is None: return None dn: sizet = len(decorator_list) - if dn == 0: - return None + if dn == 0: return None for di in range(dn): deco: ast.AST* = decorator_list.get(di) - if deco is None or deco.kind() != ast.ASTKind.Call: - continue + if deco is None or deco.kind() != ast.ASTKind.Call: continue call_node: ast.Call* = ast.Call*(deco) - if call_node.func is None or call_node.func.kind() != ast.ASTKind.Attribute: - continue + if call_node.func is None or call_node.func.kind() != ast.ASTKind.Attribute: continue func_attr: ast.Attribute* = ast.Attribute*(call_node.func) - if func_attr.attr is None or string.strcmp(func_attr.attr, "Attribute") != 0: - continue - if call_node.args is None: - continue + if func_attr.attr is None or string.strcmp(func_attr.attr, "Attribute") != 0: continue + if call_node.args is None: continue args_list: list[ast.AST*]* = call_node.args an: sizet = len(args_list) for ai in range(an): arg_node: ast.AST* = args_list.get(ai) - if arg_node is None: - continue + if arg_node is None: continue attr_name: str = self._get_attr_name_from_node(arg_node) - if attr_name is None or string.strcmp(attr_name, "section") != 0: - continue + if attr_name is None or string.strcmp(attr_name, "section") != 0: continue sec_val: str = self._get_attr_call_arg_str(arg_node) - if sec_val is None: - continue + if sec_val is None: continue sec_buf: str = pool.alloc(128) - if sec_buf is None: - return None + if sec_buf is None: return None viperlib.snprintf(sec_buf, 128, "\"section\"=\"%s\"", sec_val) return sec_buf return None @@ -159,15 +125,13 @@ class FuncGenBase(CallGenBase.CallGenBase): - Attribute: t.attr.packed -> "packed" - Attribute(t.attr.llvm.xxx): t.attr.llvm.nounwind -> "nounwind" """ - if node is None: - return None + if node is None: return None k: int = node.kind() # Call 节点: t.attr.always_inline() if k == ast.ASTKind.Call: call: ast.Call* = ast.Call*(node) - if call.func is None or call.func.kind() != ast.ASTKind.Attribute: - return None + if call.func is None or call.func.kind() != ast.ASTKind.Attribute: return None at: ast.Attribute* = ast.Attribute*(call.func) return at.attr @@ -179,55 +143,33 @@ class FuncGenBase(CallGenBase.CallGenBase): return None def _get_attr_call_arg_str(self, node: ast.AST*) -> str: """取 t.attr.xxx("val") 调用的首参字符串常量(如 section(".text.startup"))""" - if node is None or node.kind() != ast.ASTKind.Call: - return None + if node is None or node.kind() != ast.ASTKind.Call: return None cl: ast.Call* = ast.Call*(node) - if cl.args is None or len(cl.args) == 0: - return None + if cl.args is None or len(cl.args) == 0: return None a0: ast.AST* = cl.args.get(0) - if a0 is None or a0.kind() != ast.ASTKind.Constant: - return None + if a0 is None or a0.kind() != ast.ASTKind.Constant: return None cn: ast.Constant* = ast.Constant*(a0) - if cn.const_kind != ast.CONST_STR: - return None + if cn.const_kind != ast.CONST_STR: return None return cn.str_val def _append_llvm_attr(self, attrs_buf: str, attr_name: str) -> int: """将属性名映射到 LLVM 属性名并追加到缓冲区 返回 1 表示已追加,0 表示不支持该属性 """ - if attrs_buf is None or attr_name is None: - return 0 + if attrs_buf is None or attr_name is None: return 0 # 先确定映射的 LLVM 属性名 llvm_name: str = None - if string.strcmp(attr_name, "always_inline") == 0: - llvm_name = "alwaysinline" - elif string.strcmp(attr_name, "noinline") == 0: - llvm_name = "noinline" - elif string.strcmp(attr_name, "noreturn") == 0: - llvm_name = "noreturn" - elif string.strcmp(attr_name, "pure") == 0: - llvm_name = "readonly" - elif string.strcmp(attr_name, "const") == 0: - llvm_name = "readnone" - elif string.strcmp(attr_name, "nounwind") == 0: - llvm_name = "nounwind" - elif string.strcmp(attr_name, "noredzone") == 0: - llvm_name = "noredzone" - elif string.strcmp(attr_name, "stackrealign") == 0: - # 动态重对齐栈(LLVM 序言 and rsp,-16)。入口函数(_start)由 bootloader - # jmp 进入(rsp≡0 mod 16),而 llc 按 call 约定假设入口 rsp≡8 → 帧整体 - # 偏 8 → 所有调用 rsp≡8 → 变参函数保存 xmm 的 movaps #GP。stackrealign - # 使序言动态对齐,与入口约定无关(sched started 后 movaps #GP 根因)。 - # 注意:stackrealign 是 LLVM 字符串属性,必须带引号("stackrealign"), - # 与 noinline/nounwind 等枚举属性(无引号)区分,否则 llc 报 - # "expected '{' in function body"。 - llvm_name = '"stackrealign"' - elif string.strcmp(attr_name, "willreturn") == 0: - llvm_name = "willreturn" - elif string.strcmp(attr_name, "mustprogress") == 0: - llvm_name = "mustprogress" + if string.strcmp(attr_name, "always_inline") == 0: llvm_name = "alwaysinline" + elif string.strcmp(attr_name, "noinline") == 0: llvm_name = "noinline" + elif string.strcmp(attr_name, "noreturn") == 0: llvm_name = "noreturn" + elif string.strcmp(attr_name, "pure") == 0: llvm_name = "readonly" + elif string.strcmp(attr_name, "const") == 0: llvm_name = "readnone" + elif string.strcmp(attr_name, "nounwind") == 0: llvm_name = "nounwind" + elif string.strcmp(attr_name, "noredzone") == 0: llvm_name = "noredzone" + elif string.strcmp(attr_name, "stackrealign") == 0: llvm_name = '"stackrealign"' + elif string.strcmp(attr_name, "willreturn") == 0: llvm_name = "willreturn" + elif string.strcmp(attr_name, "mustprogress") == 0: llvm_name = "mustprogress" else: # packed/aligned/section/visibility/weak 等不支持作为函数内联属性 return 0 @@ -240,16 +182,14 @@ class FuncGenBase(CallGenBase.CallGenBase): def _append_str(self, buf: str, s: str, max_len: sizet = 256) -> None: """将字符串追加到 buf 末尾(有界,防 strcpy 越界写穿定长缓冲)""" - if buf is None or s is None: - return + if buf is None or s is None: return # 防御:TPV 方法默认参数注册存在缺陷(缺参调用 max_len 落到 0), # 显式兜底为 256,避免有界写入检查误判丢弃全部属性文本。 if max_len == 0: max_len = 256 cur_len: sizet = string.strlen(buf) s_len: sizet = string.strlen(s) - if cur_len + s_len + 1 > max_len: - return # 无剩余容量:丢弃本次追加,避免越界写 + if cur_len + s_len + 1 > max_len: return # 无剩余容量:丢弃本次追加,避免越界写 存疑 string.strcpy(buf + cur_len, s) # ============================================================ # _mangle_name - 为名称添加 SHA1 前缀 @@ -259,21 +199,17 @@ class FuncGenBase(CallGenBase.CallGenBase): # ============================================================ def _mangle_name(self, trans: HT.Translator*, name: str) -> str: """为任意名称添加 SHA1 前缀(不做 main/export 检查)""" - if trans is None or name is None: - return name - if trans.ModuleSha1 is None: - return name + if trans is None or name is None: return name + if trans.ModuleSha1 is None: return name name_len: sizet = string.strlen(name) # 已带 SHA1 前缀("{16hex}.")则跳过 # [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`。旧判据是 `name_len > 17`, # 与真源的 `>= 17` 只差"前缀之后为空串"这一退化形态(无实际意义),一并对齐。 - if GenApi.sha1_prefix_len(name) != 0: - return name + if GenApi.sha1_prefix_len(name) != 0: return name sha1: str = trans.ModuleSha1 sha1_len: sizet = string.strlen(sha1) mangled: str = stdlib.malloc(sha1_len + name_len + 2) - if mangled is None: - return name + if mangled is None: return name string.strcpy(mangled, sha1) mangled[sha1_len] = '.' string.strcpy(mangled + sha1_len + 1, name) @@ -286,17 +222,14 @@ class FuncGenBase(CallGenBase.CallGenBase): # ============================================================ def _mangle_name_with_sha1(self, sha1: str, name: str) -> str: """用指定 SHA1 为名称添加前缀(不做 main/export 检查)""" - if sha1 is None or name is None: - return name + if sha1 is None or name is None: return name name_len: sizet = string.strlen(name) # 已带 SHA1 前缀("{16hex}.")则跳过 # [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`(口径对齐同 _mangle_name)。 - if GenApi.sha1_prefix_len(name) != 0: - return name + if GenApi.sha1_prefix_len(name) != 0: return name sha1_len: sizet = string.strlen(sha1) mangled: str = stdlib.malloc(sha1_len + name_len + 2) - if mangled is None: - return name + if mangled is None: return name string.strcpy(mangled, sha1) mangled[sha1_len] = '.' string.strcpy(mangled + sha1_len + 1, name) @@ -313,12 +246,9 @@ class FuncGenBase(CallGenBase.CallGenBase): def _mangle_func_name(self, trans: HT.Translator*, name: str, has_export: int) -> str: """为函数名添加 SHA1 前缀(检查 main/export)""" - if trans is None or name is None: - return name - if has_export != 0: - return name - if string.strcmp(name, "main") == 0: - return name + if trans is None or name is None: return name + if has_export != 0: return name + if string.strcmp(name, "main") == 0: return name return self._mangle_name(trans, name) # ============================================================ # _body_has_raise - 函数体是否含 raise(非 StopIteration) @@ -335,13 +265,10 @@ class FuncGenBase(CallGenBase.CallGenBase): bn_f: sizet = len(body_f) for bi_f in range(bn_f): stmt_f: ast.AST* = body_f.get(bi_f) - if stmt_f is None: - continue - if stmt_f.kind() != ast.ASTKind.Raise: - continue + if stmt_f is None: continue + if stmt_f.kind() != ast.ASTKind.Raise: continue rn_f: rawptr[ast.Raise] = rawptr[ast.Raise](stmt_f) - if rn_f is None or rn_f.exc is None: - continue + if rn_f is None or rn_f.exc is None: continue ek_f: int = rn_f.exc.kind() is_stop_f: int = 0 if ek_f == ast.ASTKind.Name: @@ -372,31 +299,24 @@ class FuncGenBase(CallGenBase.CallGenBase): 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 + 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 + 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 + 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 + 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 + 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_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: @@ -417,12 +337,10 @@ class FuncGenBase(CallGenBase.CallGenBase): args_node: ast.AST*, ret_ty: llvmlite.LLVMType*) -> llvmlite.Function*: """创建 LLVM 函数并添加参数""" - if name is None or mod is None: - return None + if name is None or mod is None: return None func: llvmlite.Function* = llvmlite.create_function(pool, mod, name, ret_ty) - if func is None: - return None + if func is None: return None if args_node is not None: ags: ast.Arguments* = ast.Arguments*(args_node) @@ -437,18 +355,15 @@ class FuncGenBase(CallGenBase.CallGenBase): if arg.annotation is not None: if arg.annotation.kind() == ast.ASTKind.Attribute: at_cf: ast.Attribute* = ast.Attribute*(arg.annotation) - if at_cf.attr is not None and string.strcmp(at_cf.attr, "CVoid") == 0: - continue + if at_cf.attr is not None and string.strcmp(at_cf.attr, "CVoid") == 0: continue param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg.annotation, None, None, None, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, None, None, None, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32。 # 本函数不传 trans/imports 上下文,解析失败即调用方未补齐 # 上下文(暴露上游,不由本函数兜底)。 - self.Gen.TypeGenErr.fatal_error( - arg, f"函数 '{name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError") + self.Gen.TypeGenErr.fatal_error(arg, f"函数 '{name}' 形参 '{arg.arg}' 类型注解解析失败", "NameError") return None param_ty = resolved pname: str = pool.alloc(32) diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index 856998d..6a442cc 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -17,12 +17,8 @@ import lib.core.Gen.GenApi as GenApi # ============================================================ # FuncGenDef - 函数声明 / translate_function_def / decorator wrapper -# -# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesExprCall 委托。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class FuncGenDef(CallGenBase.CallGenBase): +novirtual class FuncGenDef(CallGenBase.CallGenBase): """函数声明 / translate_function_def / decorator wrapper""" # forward_declare_functions - 预扫描所有顶层 FunctionDef,创建前向声明 @@ -34,12 +30,10 @@ class FuncGenDef(CallGenBase.CallGenBase): def forward_declare_functions(self, trans: HT.Translator*, tree: ast.AST*) -> int: """预扫描所有顶层 FunctionDef,创建前向声明""" - if trans is None or tree is None: - return 0 + if trans is None or tree is None: return 0 pool: memhub.MemBuddy* = trans.Pool mod: llvmlite.LLVMModule* = trans.Module - if pool is None or mod is None: - return 0 + if pool is None or mod is None: return 0 imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports @@ -50,8 +44,7 @@ class FuncGenDef(CallGenBase.CallGenBase): i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) ch: list[ast.AST*]* = tree.children - if ch is None: - return 0 + if ch is None: return 0 # 解析函数签名期间临时切换到"仅声明"模式: # 签名里的泛型类注解(如 _empty_like(a: ndarray[t.CDouble]))会触发泛型特化, @@ -78,28 +71,20 @@ class FuncGenDef(CallGenBase.CallGenBase): pre_i: sizet for pre_i in range(cn_count): pre_child: ast.AST* = ch.get(pre_i) - if pre_child is None: - continue - if pre_child.kind() != ast.ASTKind.ClassDef: - continue + if pre_child is None: continue + if pre_child.kind() != ast.ASTKind.ClassDef: continue pre_cd: ast.ClassDef* = ast.ClassDef*(pre_child) - if pre_cd is None or pre_cd.name is None: - continue - pre_ex: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - pre_cd.name, trans.ModuleSha1) - if pre_ex is not None and pre_ex.FieldCount > 0: - continue + if pre_cd is None or pre_cd.name is None: continue + pre_ex: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(pre_cd.name, trans.ModuleSha1) + if pre_ex is not None and pre_ex.FieldCount > 0: continue self.Gen.ClassGenDef.translate_class_def(trans, pre_child) for ci in range(cn_count): child: ast.AST* = ch.get(ci) - if child is None: - continue - if child.kind() != ast.ASTKind.FunctionDef: - continue + if child is None: continue + if child.kind() != ast.ASTKind.FunctionDef: continue fd: ast.FunctionDef* = ast.FunctionDef*(child) - if fd is None or fd.name is None: - continue + if fd is None or fd.name is None: continue # PEP 695 泛型函数(def f[T](...) -> T)按普通函数编译(TPV 无泛型 # 函数特化机制,与 translate_function_def L678-691 一致):此处先设置 @@ -121,8 +106,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 推断返回类型 ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: - ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, fd.returns, imported_modules, from_imports, trans, 0) + ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0) # 单独 t.CExport 返回注解(def free(...) -> t.CExport:)= # 导出修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type # 回退为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。 @@ -141,15 +125,13 @@ class FuncGenDef(CallGenBase.CallGenBase): # 否则 declare i32 + define {i64,i64,i64} → llc "value doesn't # match function result type"——GetMemoryStats 根因) if ret_ty is None: - ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty( - pool, fd, imported_modules, from_imports, trans) + ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans) if ret_ty is None and fd.returns is not None: # 有返回注解但解析失败:编译期报错,不静默回退 i32。 # (i32 回退曾导致掉尾检查强制 return i32 / 跨模块调用返回类型错位, # mm.vp free / GetMemoryStats 根因。)无返回注解函数(def foo():) # 保留 i32 默认,不在此报错。 - self.Gen.TypeGenErr.fatal_error( - fd, "函数返回类型解析失败:注解不可解析", "TypeError") + self.Gen.TypeGenErr.fatal_error(fd, "函数返回类型解析失败:注解不可解析", "TypeError") return 0 if ret_ty is None: ret_ty = i32_ty @@ -193,8 +175,7 @@ class FuncGenDef(CallGenBase.CallGenBase): continue # 创建 declare - func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, mangled_name, ret_ty) + func: llvmlite.Function* = llvmlite.create_declare(pool, mod, mangled_name, ret_ty) if func is None: if tp_names_fd is not None: self.Gen.TypeGenBase.clear_generic_context() @@ -238,21 +219,17 @@ class FuncGenDef(CallGenBase.CallGenBase): an: sizet = len(alist) for ai in range(an): arg: ast.Arg* = ast.Arg*(alist.get(ai)) - if arg is None or arg.arg is None: - continue + if arg is None or arg.arg is None: continue # CVoid 表示空参:跳过 if arg.annotation is not None: - if self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0: - continue + if self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0: continue param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg.annotation, imported_modules, from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 # (declare 与 define 签名不一致 → ABI 错位,运行期读栈垃圾) - self.Gen.TypeGenErr.fatal_error( - arg, f"前向声明形参 '{arg.arg}' 类型注解解析失败", "NameError") + self.Gen.TypeGenErr.fatal_error(arg, f"前向声明形参 '{arg.arg}' 类型注解解析失败", "NameError") return 0 # 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致) # CArray 形参 → 元素指针 ty*(C 数组衰减,与 add_param 一致) @@ -331,8 +308,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 推断返回类型:优先使用返回类型注解 ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: - ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, fd.returns, imported_modules, from_imports, trans, 0) + ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans, 0) # 单独 t.CExport 返回注解(def free(...) -> t.CExport:)= 导出 # 修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type 回退 # 为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。 @@ -357,8 +333,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # declare 成 i32 → 定义阶段 ret {i64,i64,i64} 与 i32 不匹配。 # 公共方法 _resolve_creturn_ret_ty 保证声明/定义两阶段一致) if ret_ty is None: - ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty( - pool, fd, imported_modules, from_imports, trans) + ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(pool, fd, imported_modules, from_imports, trans) # 如果仍然为 None,扫描 return 语句推断(至少返回 i32) if ret_ty is None: @@ -371,18 +346,13 @@ class FuncGenDef(CallGenBase.CallGenBase): if self.Gen.TypeGenErr.body_has_value_return(pool, fd.children) != 0: rtn_err: str = pool.alloc(256) if rtn_err is not None: - viperlib.snprintf( - rtn_err, 256, - "函数 '%s' 无返回类型注解却返回了非 None 值," - "请添加显式返回类型注解(如 -> int)", fd.name) + viperlib.snprintf(rtn_err, 256, "函数 '%s' 无返回类型注解却返回了非 None 值,请添加显式返回类型注解(如 -> int)", fd.name) self.Gen.TypeGenErr.fatal_error(fd, rtn_err, "TypeError") return 0 - self.Gen.TypeGenErr.fatal_error( - fd, "函数无返回类型注解却返回了非 None 值", "TypeError") + self.Gen.TypeGenErr.fatal_error(fd, "函数无返回类型注解却返回了非 None 值", "TypeError") return 0 param_types_str: str = self.Gen.TypeGenErr.build_param_types_str(pool, fd.args) - ret_ty = self.Gen.TypeGenErr.infer_return_type( - pool, fd.children, param_types_str) + ret_ty = self.Gen.TypeGenErr.infer_return_type(pool, fd.children, param_types_str) # 检测是否为外部声明函数(t.CExtern 或 t.State) # 语义:t.CExtern 忽略 body 体,仅生成 declare(由链接器解析符号) # t.State = t.CExtern + t.CExport(既是声明又是导出) @@ -493,14 +463,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # 外部声明函数:生成 declare(仅声明,不定义) # 先检查是否已由 forward_declare_functions 创建,避免重复 declare existing_extern: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) - if existing_extern is not None: - # 已存在前向声明,复用之,不再重复创建 - return 0 + if existing_extern is not None: return 0 - func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, mangled_name, ret_ty) - if func is None: - return 0 + func: llvmlite.Function* = llvmlite.create_declare(pool, mod, mangled_name, ret_ty) + if func is None: return 0 # 注册到函数表 max_funcs_extern: int = 256 @@ -523,14 +489,11 @@ class FuncGenDef(CallGenBase.CallGenBase): continue param_ty_e: llvmlite.LLVMType* = i32_ty if arg_e.annotation is not None: - resolved_e: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg_e.annotation, imported_modules, from_imports, trans, 0) + resolved_e: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_e.annotation, imported_modules, from_imports, trans, 0) if resolved_e is None: # fail-fast:外部声明函数参数有注解但类型解析失败, # 不再静默保持 i32(声明签名错误会在 ABI 层暴露) - self.Gen.TypeGenErr.fatal_error( - arg_e, f"参数 '{arg_e.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_e.annotation)}", - "NameError") + self.Gen.TypeGenErr.fatal_error(arg_e, f"参数 '{arg_e.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_e.annotation)}", "NameError") resolved_e = i32_ty # 不可达(fatal_error 已退出) if resolved_e is not None: # 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致) @@ -560,8 +523,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if func_attrs_e is not None: llvmlite.function_set_attrs(func, func_attrs_e) # B5:section 字符串属性走属性组 #N - func_section_e: str = self.Gen.FuncGenBase.extract_func_section( - pool, fd.decorator_list, imported_modules) + func_section_e: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules) if func_section_e is not None: llvmlite.function_set_attr_group(func, func_section_e) @@ -583,8 +545,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if func_attrs_reuse is not None: llvmlite.function_set_attrs(func, func_attrs_reuse) # B5:section 字符串属性走属性组 #N - func_section_reuse: str = self.Gen.FuncGenBase.extract_func_section( - pool, fd.decorator_list, imported_modules) + func_section_reuse: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules) if func_section_reuse is not None: llvmlite.function_set_attr_group(func, func_section_reuse) else: @@ -599,8 +560,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if func_attrs is not None: llvmlite.function_set_attrs(func, func_attrs) # B5:section 字符串属性走属性组 #N(LLVM 不接受内联 section="...") - func_section: str = self.Gen.FuncGenBase.extract_func_section( - pool, fd.decorator_list, imported_modules) + func_section: str = self.Gen.FuncGenBase.extract_func_section(pool, fd.decorator_list, imported_modules) if func_section is not None: llvmlite.function_set_attr_group(func, func_section) @@ -640,13 +600,11 @@ class FuncGenDef(CallGenBase.CallGenBase): continue param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg.annotation, imported_modules, from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 # (形参类型错 → ABI 错位/字段访问错) - self.Gen.TypeGenErr.fatal_error( - arg, f"形参 '{arg.arg}' 类型注解解析失败", "NameError") + self.Gen.TypeGenErr.fatal_error(arg, f"形参 '{arg.arg}' 类型注解解析失败", "NameError") return 0 # 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致) # CArray 形参 → 元素指针 ty*(C 数组衰减:final(out: t.CArray[..., N]) @@ -707,8 +665,7 @@ class FuncGenDef(CallGenBase.CallGenBase): tls_flag_name: str = pool.alloc(128) if tls_flag_name is not None: viperlib.snprintf(tls_flag_name, 128, "__tls_init_done_%s", fd.name) - tls_flag_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int( - pool, mod, tls_flag_name, 1, 0) + tls_flag_gv: llvmlite.GlobalVariable* = llvmlite.create_global_int(pool, mod, tls_flag_name, 1, 0) if tls_flag_gv is not None: i1_ty_t: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_t is not None: @@ -719,49 +676,40 @@ class FuncGenDef(CallGenBase.CallGenBase): tls_ref_name: str = pool.alloc(64) if tls_ref_name is not None: viperlib.snprintf(tls_ref_name, 64, "@%s", tls_flag_name) - tls_flag_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, tls_gv_ptr_ty, tls_ref_name) + tls_flag_ref: llvmlite.Value* = llvmlite.SSAValue(pool, tls_gv_ptr_ty, tls_ref_name) if tls_flag_ref is not None: - tls_flag_ld: llvmlite.Value* = llvmlite.build_load( - func_builder, i1_ty_t, tls_flag_ref) + tls_flag_ld: llvmlite.Value* = llvmlite.build_load(func_builder, i1_ty_t, tls_flag_ref) # 块名唯一化(create_block 不自动编号,同函数同名 label 冲突) lc_t: int = trans._label_counter trans._label_counter = lc_t + 1 tls_bb_buf: str = pool.alloc(64) if tls_bb_buf is not None: viperlib.snprintf(tls_bb_buf, 64, "tls.skip.%d", lc_t) - tls_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, tls_bb_buf) + tls_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_bb_buf) viperlib.snprintf(tls_bb_buf, 64, "tls.cont.%d", lc_t) - tls_cont_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, tls_bb_buf) + tls_cont_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, tls_bb_buf) if tls_skip_bb is not None and tls_cont_bb is not None: - llvmlite.build_cond_br( - func_builder, tls_flag_ld, tls_skip_bb, tls_cont_bb) + llvmlite.build_cond_br(func_builder, tls_flag_ld, tls_skip_bb, tls_cont_bb) # skip 块:按返回类型生成默认值直接返回 llvmlite.position_at_end(func_builder, tls_skip_bb) match ret_ty: case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(func_builder) case llvmlite.LLVMType.Int(_): - tlz0: llvmlite.Value* = llvmlite.ConstInt( - pool, ret_ty, 0, "0") + tlz0: llvmlite.Value* = llvmlite.ConstInt(pool, ret_ty, 0, "0") if tlz0 is not None: llvmlite.build_ret(func_builder, tlz0) case llvmlite.LLVMType.Float(_): - tlf0: llvmlite.Value* = llvmlite.ConstFloat( - pool, ret_ty, 0.0) + tlf0: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0) if tlf0 is not None: llvmlite.build_ret(func_builder, tlf0) case _: - tln0: llvmlite.Value* = llvmlite.ConstNull( - pool, ret_ty, "null") + tln0: llvmlite.Value* = llvmlite.ConstNull(pool, ret_ty, "null") if tln0 is not None: llvmlite.build_ret(func_builder, tln0) # cont 块:置标志=1,继续函数体 llvmlite.position_at_end(func_builder, tls_cont_bb) - tlone: llvmlite.Value* = llvmlite.ConstInt( - pool, i1_ty_t, 1, "1") + tlone: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_t, 1, "1") if tlone is not None: llvmlite.build_store(func_builder, tlone, tls_flag_ref) @@ -798,13 +746,10 @@ class FuncGenDef(CallGenBase.CallGenBase): continue param_ty2: llvmlite.LLVMType* = i32_ty if arg2.annotation is not None: - resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg2.annotation, imported_modules, from_imports, trans, 0) + resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg2.annotation, imported_modules, from_imports, trans, 0) if resolved2 is None: # fail-fast:参数有注解但类型解析失败,不再静默保持 i32 - self.Gen.TypeGenErr.fatal_error( - arg2, f"参数 '{arg2.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg2.annotation)}", - "NameError") + self.Gen.TypeGenErr.fatal_error(arg2, f"参数 '{arg2.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg2.annotation)}", "NameError") resolved2 = i32_ty # 不可达(fatal_error 已退出) if resolved2 is not None: # 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针); @@ -824,11 +769,9 @@ class FuncGenDef(CallGenBase.CallGenBase): # 传 pool:泛型 Subscript 返回 mangled name(对齐 HandlesAnnAssign 修复) cls_nm: str = None if arg2.annotation is not None: - cls_nm = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - arg2.annotation, imported_modules, pool, trans._from_imports) + cls_nm = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg2.annotation, imported_modules, pool, trans._from_imports) if cls_nm is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, arg2.arg, cls_nm) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg2.arg, cls_nm) # t.CVolatile 形参:声明期标记,函数体内该参数名的 # load/store 带 volatile(volatile 参数对象的读改写不得 # 被优化器提升/合并,如自旋等待入参)。 @@ -837,28 +780,19 @@ class FuncGenDef(CallGenBase.CallGenBase): # 是否含 t.CConst,不看指针层数)——TPC 形参登记点 # HandlesFunctions 的 IsParam=True 用同一条件,两侧逐条 # 对齐(见 Debugger/type-descriptors.md 已知差异)。 - if self.Gen.TypeGenErr.has_decorator_marker( - arg2.annotation, "CConst", 0) != 0: - self.Gen.VarGen.set_var_const( - trans.SymTab, arg2.arg) - if self.Gen.TypeGenErr.has_decorator_marker( - arg2.annotation, "CVolatile", 0) != 0: - self.Gen.VarGen.set_var_volatile( - trans.SymTab, arg2.arg) + if self.Gen.TypeGenErr.has_decorator_marker(arg2.annotation, "CConst", 0) != 0: + self.Gen.VarGen.set_var_const(trans.SymTab, arg2.arg) + if self.Gen.TypeGenErr.has_decorator_marker(arg2.annotation, "CVolatile", 0) != 0: + self.Gen.VarGen.set_var_volatile(trans.SymTab, arg2.arg) # rawptr[t.CVolatile | T] 形参(volatile 指针指向物): # 函数体内该参数解引用(p[i]/p.field/c.Deref(p))带 volatile。 - if self.Gen.TypeGenErr.has_pointee_volatile_marker( - arg2.annotation) != 0: - self.Gen.VarGen.set_var_pointee_volatile( - trans.SymTab, arg2.arg) + if self.Gen.TypeGenErr.has_pointee_volatile_marker(arg2.annotation) != 0: + self.Gen.VarGen.set_var_pointee_volatile(trans.SymTab, arg2.arg) pname2: str = pool.alloc(32) if pname2 is not None: viperlib.snprintf(pname2, 32, "%%%s", arg2.arg) - param_val: llvmlite.Value* = llvmlite.SSAValue( - pool, param_ty2, pname2) - vol_p2: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry( - trans.SymTab, arg2.arg)) + param_val: llvmlite.Value* = llvmlite.SSAValue(pool, param_ty2, pname2) + vol_p2: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg2.arg)) llvmlite.build_store(func_builder, param_val, alloca, vol_p2) # *args 变长参数:创建 va_list 缓冲区 + 调用 va_start + 注册到符号表 @@ -879,12 +813,10 @@ class FuncGenDef(CallGenBase.CallGenBase): i8_ty_va: llvmlite.LLVMType* = llvmlite.Int8(pool) i8_ptr_ty_va: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_va) va_buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty_va, 24) - va_list_alloca: llvmlite.Value* = llvmlite.build_alloca_aligned( - func_builder, va_buf_ty, 16) + va_list_alloca: llvmlite.Value* = llvmlite.build_alloca_aligned(func_builder, va_buf_ty, 16) if va_list_alloca is not None: # i8* 地址(指向 24 字节 va_list 缓冲区)——vararg 名的值语义 - va_list_addr: llvmlite.Value* = llvmlite.build_bitcast( - func_builder, va_list_alloca, i8_ptr_ty_va) + va_list_addr: llvmlite.Value* = llvmlite.build_bitcast(func_builder, va_list_alloca, i8_ptr_ty_va) if va_list_addr is not None: # 注册到符号表(translate_name_value 对 vararg 名特殊处理返回地址) self.Gen.VarGen.define_var(trans.SymTab, vararg_name_str, va_list_alloca) @@ -916,10 +848,8 @@ class FuncGenDef(CallGenBase.CallGenBase): i32_ty_eh2: llvmlite.LLVMType* = llvmlite.Int32(pool) i32_ptr_ty_eh2: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty_eh2) if i8_ptr_ptr_ty_eh2 is not None and i32_ptr_ty_eh2 is not None: - msg_out_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__") - code_out_ref: llvmlite.Value* = llvmlite.SSAValue( - pool, i32_ptr_ty_eh2, "%__eh_code_out__") + msg_out_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__") + code_out_ref: llvmlite.Value* = llvmlite.SSAValue(pool, i32_ptr_ty_eh2, "%__eh_code_out__") trans._eh_msg_out_param = msg_out_ref trans._eh_code_out_param = code_out_ref trans._cur_func_has_eh = 1 @@ -970,9 +900,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 嵌套函数定义前:预扫描其链内 nonlocal 并建堆 # (不同层捕获不同变量的场景,见 _prepare_chain_nonlocals) if stmt2.kind() == ast.ASTKind.FunctionDef: - self.Gen.FuncGen._prepare_chain_nonlocals( - trans, stmt2, pool, func_builder, mod, - llvmlite.Int8(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool))) + self.Gen.FuncGen._prepare_chain_nonlocals(trans, stmt2, pool, func_builder, mod, llvmlite.Int8(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool))) self.Gen.StmtGen.translate_stmt(trans, stmt2) # 如果函数体最后一条语句不是 Return,添加隐式 ret @@ -1026,12 +954,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # ② 裸名 CVoid(from t import CVoid)③ -> None(CONST_NONE); # ①②统一经既有判据 TypeGenResolve._is_cvoid_marker 判定(不新增名字白名单)。 if _is_void == 0 and fd.returns is not None: - if self.Gen.TypeGenResolve._is_cvoid_marker( - fd.returns, imported_modules) != 0: + if self.Gen.TypeGenResolve._is_cvoid_marker(fd.returns, imported_modules) != 0: _is_void = 1 elif fd.returns.kind() == ast.ASTKind.Constant: - ret_none_cn: ast.Constant* = ( - ast.Constant*)(fd.returns) + ret_none_cn: ast.Constant* = (ast.Constant*)(fd.returns) if ret_none_cn.const_kind == ast.CONST_NONE: _is_void = 1 if _is_void != 0: @@ -1068,10 +994,7 @@ class FuncGenDef(CallGenBase.CallGenBase): rt_name = "?" err_fn: str = pool.alloc(256) if err_fn is not None: - viperlib.snprintf( - err_fn, 256, - "函数 '%s' 流程掉出函数末尾但未显式 return(返回类型 %s)," - "请补显式 return(如 return 0 / return null)", fd.name, rt_name) + viperlib.snprintf(err_fn, 256, "函数 '%s' 流程掉出函数末尾但未显式 return(返回类型 %s),请补显式 return(如 return 0 / return null)", fd.name, rt_name) self.Gen.TypeGenErr.fatal_error(node, err_fn, "TypeError") self.Gen.TypeGenErr.fatal_error(node, "函数流程掉出末尾但未显式 return", "TypeError") else: @@ -1105,9 +1028,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if wb_name is not None: viperlib.snprintf(wb_name, 128, "__decor_wrap_%s", fd.name) self.Gen.ClassGenBase.register_decorator(pool, fd.name, wb_name, decor_arg0) - self._gen_decor_wrapper( - trans, pool, mod, func, fd.name, wb_name, - decor_handler, decor_arg0) + self._gen_decor_wrapper(trans, pool, mod, func, fd.name, wb_name, decor_handler, decor_arg0) return 0 # ============================================================ @@ -1165,10 +1086,8 @@ class FuncGenDef(CallGenBase.CallGenBase): pp = llvmlite.param_get_next(pp) # ---- 创建 wrapper 函数并添加参数(名字 %a0..%aN)---- - wrapper: llvmlite.Function* = llvmlite.create_function( - pool, mod, wrapper_name, ret_ty) - if wrapper is None: - return None + wrapper: llvmlite.Function* = llvmlite.create_function(pool, mod, wrapper_name, ret_ty) + if wrapper is None: return None pi: int = 0 for pi in range(n_params): pname_w: str = pool.alloc(16) @@ -1217,8 +1136,7 @@ class FuncGenDef(CallGenBase.CallGenBase): return None rec_val: llvmlite.Value* = llvmlite.build_load(wb, i8_ty, rec_flag_ref) rec_zero: llvmlite.Value* = llvmlite.ConstInt(pool, i8_ty, 0, "0") - rec_is: llvmlite.Value* = llvmlite.build_icmp( - wb, llvmlite.ICMP_NE, rec_val, rec_zero) + rec_is: llvmlite.Value* = llvmlite.build_icmp(wb, llvmlite.ICMP_NE, rec_val, rec_zero) llvmlite.build_cond_br(wb, rec_is, rec_bb, dec_bb) # recursive_call:直接调用原函数返回(跳过所有装饰逻辑) llvmlite.position_at_end(wb, rec_bb) @@ -1229,8 +1147,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if an_r is None: continue viperlib.snprintf(an_r, 16, "%%a%d", ri) - av_r: llvmlite.Value* = llvmlite.SSAValue( - pool, (llvmlite.LLVMType*)(param_tys[ri]), an_r) + av_r: llvmlite.Value* = llvmlite.SSAValue(pool, (llvmlite.LLVMType*)(param_tys[ri]), an_r) if av_r is not None: llvmlite.value_set_next(av_r, None) if rec_args is None: @@ -1245,8 +1162,7 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.build_call(wb, orig_call_name, rec_args, n_params, ret_ty, 0) llvmlite.build_ret_void(wb) else: - rc_res: llvmlite.Value* = llvmlite.build_call( - wb, orig_call_name, rec_args, n_params, ret_ty, 0) + rc_res: llvmlite.Value* = llvmlite.build_call(wb, orig_call_name, rec_args, n_params, ret_ty, 0) if rc_res is not None: llvmlite.build_ret(wb, rc_res) else: @@ -1271,26 +1187,22 @@ class FuncGenDef(CallGenBase.CallGenBase): fields_head: llvmlite.Function* = None fk: int = 0 for fk in range(n_params - 1, -1, -1): - pn_n: llvmlite.Function* = llvmlite.new_param_node( - pool, (llvmlite.LLVMType*)(param_tys[fk])) + pn_n: llvmlite.Function* = llvmlite.new_param_node(pool, (llvmlite.LLVMType*)(param_tys[fk])) if pn_n is not None: pn_n.Next = fields_head fields_head = pn_n - args_ty: llvmlite.LLVMType* = llvmlite.Struct( - pool, fields_head, n_params, None) + args_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, fields_head, n_params, None) if args_ty is not None: args_alloca = llvmlite.build_alloca(wb, args_ty) fi2: int = 0 for fi2 in range(n_params): fld_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[fi2]) - fld_ptr: llvmlite.Value* = llvmlite.build_gep_struct( - wb, args_ty, fld_ty, args_alloca, fi2) + fld_ptr: llvmlite.Value* = llvmlite.build_gep_struct(wb, args_ty, fld_ty, args_alloca, fi2) if fld_ptr is not None: fld_nm: str = pool.alloc(16) if fld_nm is not None: viperlib.snprintf(fld_nm, 16, "%%a%d", fi2) - fld_v: llvmlite.Value* = llvmlite.SSAValue( - pool, fld_ty, fld_nm) + fld_v: llvmlite.Value* = llvmlite.SSAValue(pool, fld_ty, fld_nm) if fld_v is not None: llvmlite.build_store(wb, fld_v, fld_ptr) args_ptr = llvmlite.build_bitcast(wb, args_alloca, i8_ptr_ty) @@ -1313,15 +1225,13 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.build_store(wb, ret_zero, ret_alloca) # 4. 函数名字符串常量 - fn_str: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string( - wb, pool, mod, func_name, trans) + fn_str: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(wb, pool, mod, func_name, trans) if fn_str is None: fn_str = llvmlite.ConstNull(pool, i8_ptr_ty, "null") # 5. handler 声明(未翻译时 declare,固定签名 i32 (i8*,i8*,i32,i8*,i8*,i8*)) if self.Gen.CallGenBase.find_func_in_module(mod, handler_name) is None: - handler_d: llvmlite.Function* = llvmlite.create_declare( - pool, mod, handler_name, i32_ty) + handler_d: llvmlite.Function* = llvmlite.create_declare(pool, mod, handler_name, i32_ty) if handler_d is not None: llvmlite.add_param(pool, handler_d, i8_ptr_ty, "ctx") llvmlite.add_param(pool, handler_d, i8_ptr_ty, "func_name") @@ -1336,18 +1246,12 @@ class FuncGenDef(CallGenBase.CallGenBase): null_dec: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty, "null") # 参数链表(6 个独立值):ctx_ptr → fn_str → 0 → args_ptr → null → null # 注意:不能 self 链接(null.Next = null 会让 build_call 遍历死循环) - if ctx_ptr is not None: - llvmlite.value_set_next(ctx_ptr, fn_str) - if fn_str is not None: - llvmlite.value_set_next(fn_str, ph0) - if ph0 is not None: - llvmlite.value_set_next(ph0, args_ptr) - if args_ptr is not None: - llvmlite.value_set_next(args_ptr, null_ret) - if null_ret is not None: - llvmlite.value_set_next(null_ret, null_dec) - n_calls: llvmlite.Value* = llvmlite.build_call( - wb, handler_name, ctx_ptr, 6, i32_ty, 0) + if ctx_ptr is not None: llvmlite.value_set_next(ctx_ptr, fn_str) + if fn_str is not None: llvmlite.value_set_next(fn_str, ph0) + if ph0 is not None: llvmlite.value_set_next(ph0, args_ptr) + if args_ptr is not None: llvmlite.value_set_next(args_ptr, null_ret) + if null_ret is not None: llvmlite.value_set_next(null_ret, null_dec) + n_calls: llvmlite.Value* = llvmlite.build_call(wb, handler_name, ctx_ptr, 6, i32_ty, 0) # 7. 计数器 alloca(TPV 用 alloca 计数器替代 phi) cnt_alloca: llvmlite.Value* = llvmlite.build_alloca(wb, i32_ty) @@ -1359,8 +1263,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 8. loop.header:cur = load cnt; cur < n_calls → body / post llvmlite.position_at_end(wb, loop_h_bb) cur_i: llvmlite.Value* = llvmlite.build_load(wb, i32_ty, cnt_alloca) - loop_cond: llvmlite.Value* = llvmlite.build_icmp( - wb, llvmlite.ICMP_SLT, cur_i, n_calls) + loop_cond: llvmlite.Value* = llvmlite.build_icmp(wb, llvmlite.ICMP_SLT, cur_i, n_calls) llvmlite.build_cond_br(wb, loop_cond, loop_b_bb, post_bb) # 9. loop.body:读回参数(装饰器可能已修改)→ 调用原函数 → store ret @@ -1370,10 +1273,8 @@ class FuncGenDef(CallGenBase.CallGenBase): k: int = 0 for k in range(n_params): fld_ty_k: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[k]) - fld_pk: llvmlite.Value* = llvmlite.build_gep_struct( - wb, args_ty, fld_ty_k, args_alloca, k) - if fld_pk is None: - continue + fld_pk: llvmlite.Value* = llvmlite.build_gep_struct(wb, args_ty, fld_ty_k, args_alloca, k) + if fld_pk is None: continue fld_vk: llvmlite.Value* = llvmlite.build_load(wb, fld_ty_k, fld_pk) if fld_vk is not None: llvmlite.value_set_next(fld_vk, None) @@ -1384,12 +1285,10 @@ class FuncGenDef(CallGenBase.CallGenBase): while ct.Next is not None: ct = ct.Next llvmlite.value_set_next(ct, fld_vk) - res_v: llvmlite.Value* = llvmlite.build_call( - wb, orig_call_name, call_args, n_params, ret_ty, 0) + res_v: llvmlite.Value* = llvmlite.build_call(wb, orig_call_name, call_args, n_params, ret_ty, 0) if ret_alloca is not None and res_v is not None: llvmlite.build_store(wb, res_v, ret_alloca) - nxt_i: llvmlite.Value* = llvmlite.build_add( - wb, cur_i, llvmlite.ConstInt(pool, i32_ty, 1, "1")) + nxt_i: llvmlite.Value* = llvmlite.build_add(wb, cur_i, llvmlite.ConstInt(pool, i32_ty, 1, "1")) if nxt_i is not None and cnt_alloca is not None: llvmlite.build_store(wb, nxt_i, cnt_alloca) llvmlite.build_br(wb, loop_h_bb) @@ -1401,16 +1300,11 @@ class FuncGenDef(CallGenBase.CallGenBase): ret_ptr = llvmlite.build_bitcast(wb, ret_alloca, i8_ptr_ty) ph1: llvmlite.Value* = llvmlite.ConstInt(pool, i32_ty, 1, "1") # 后置参数链:ctx_ptr → fn_str → 1 → args_ptr → ret_ptr → null - if ctx_ptr is not None: - llvmlite.value_set_next(ctx_ptr, fn_str) - if fn_str is not None: - llvmlite.value_set_next(fn_str, ph1) - if ph1 is not None: - llvmlite.value_set_next(ph1, args_ptr) - if args_ptr is not None: - llvmlite.value_set_next(args_ptr, ret_ptr) - if ret_ptr is not None: - llvmlite.value_set_next(ret_ptr, null_dec) + if ctx_ptr is not None: llvmlite.value_set_next(ctx_ptr, fn_str) + if fn_str is not None: llvmlite.value_set_next(fn_str, ph1) + if ph1 is not None: llvmlite.value_set_next(ph1, args_ptr) + if args_ptr is not None: llvmlite.value_set_next(args_ptr, ret_ptr) + if ret_ptr is not None: llvmlite.value_set_next(ret_ptr, null_dec) llvmlite.build_call(wb, handler_name, ctx_ptr, 6, i32_ty, 0) if rec_flag_ref is not None: rec_zero2: llvmlite.Value* = llvmlite.ConstInt(pool, i8_ty, 0, "0") diff --git a/App/lib/core/Gen/Func/FuncGenMixin.vp b/App/lib/core/Gen/Func/FuncGenMixin.vp index 4661cef..4a91cec 100644 --- a/App/lib/core/Gen/Func/FuncGenMixin.vp +++ b/App/lib/core/Gen/Func/FuncGenMixin.vp @@ -15,55 +15,19 @@ import lib.core.Gen.GenApi as GenApi # ============================================================ -# FuncGenMixin - 函数/方法声明与翻译 Mixin(对象化 P5-1,wiki/14-oo-refactor.md) -# -# 从 HandlesFunctions.vp 迁移:模块级纯函数(trans 首参,无全局状态) -# → 类方法(self 替代,trans 参数保留)。 -# -# 迁移原则(与 P2/P3/P4 一致,行为零变化): -# 1. 方法保留原函数签名(含 trans 首参),仅函数体内的 -# 本模块函数调用改为 self.xxx(...) -# 2. 外部模块调用(HandlesExprCall.xxx/HandlesType.xxx 等)保留模块前缀 -# 3. HandlesFunctions.vp 原函数保留为"委托":本地模块级单例 _g_gen -# (BuildPipeline/main 注入)cast 成 Generator 类型 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 +# FuncGenMixin - 函数/方法声明与翻译 Mixin # ============================================================ - -# ============================================================ -# HandlesFunctions - 函数定义处理(trans 单参模式) -# -# 参考 Python 版 TransPyC FunctionHandle -# -# 函数有自己的局部作用域,通过 HandlesVar.enter_scope/exit_scope -# 管理嵌套作用域链,翻译函数体前进入函数作用域,翻译完退出。 -# ============================================================ - - -# 作用域类型常量(本地副本,与 HandlesFunctions.vp 保持一致) -SCOPE_FUNCTION: t.CDefine = 1 +# 作用域类型常量 存疑 +define SCOPE_FUNCTION = 1 # ============================================================ # FuncGenMixin - 函数属性/命名/声明/翻译 # ============================================================ -@t.NoVTable -class FuncGenMixin(CallGenBase.CallGenBase): +novirtual class FuncGenMixin(CallGenBase.CallGenBase): """函数/方法翻译 Mixin(纯方法化迁移,无状态字段)""" - - - - - - - - - - - - # ============================================================ # translate_nested_function_def - 嵌套函数提升 + 闭包创建 # @@ -74,12 +38,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节, malloc 分配) # Env 结构: {i8* ptr0, i8* ptr1, ...} (每个 nonlocal 变量 8 字节,指向父函数 alloca) # ============================================================ - def translate_nested_function_def(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_nested_function_def(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译嵌套函数定义:提升为顶层函数 + 创建闭包""" fd: ast.FunctionDef* = ast.FunctionDef*(node) - if fd is None or fd.name is None: - return 0 + if fd is None or fd.name is None: return 0 pool: memhub.MemBuddy* = trans.Pool mod: llvmlite.LLVMModule* = trans.Module @@ -96,10 +58,8 @@ class FuncGenMixin(CallGenBase.CallGenBase): mangled_promoted: str = self.Gen.FuncGenBase._mangle_name(trans, promoted_name) # 2. 创建提升后的函数: define i32 @__closure_{name}(i8* %env, args...) - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled_promoted, i32_ty) - if func is None: - return 0 + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_promoted, i32_ty) + if func is None: return 0 llvmlite.add_param(pool, func, i8_ptr_ty, "%env") # 2a. 嵌套函数参数:加入提升函数签名(i8* %env, 参数...), @@ -117,15 +77,12 @@ class FuncGenMixin(CallGenBase.CallGenBase): an_n: sizet = len(alist_n) for ai_n in range(an_n): arg_n: ast.Arg* = ast.Arg*(alist_n.get(ai_n)) - if arg_n is None or arg_n.arg is None: - continue + if arg_n is None or arg_n.arg is None: continue if arg_n.annotation is not None: - if self.Gen.TypeGenResolve._is_t_attr(arg_n.annotation, "CVoid", imported_modules) != 0: - continue + if self.Gen.TypeGenResolve._is_t_attr(arg_n.annotation, "CVoid", imported_modules) != 0: continue pty_n: llvmlite.LLVMType* = i32_ty if arg_n.annotation is not None: - resolved_n: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg_n.annotation, imported_modules, from_imports, trans, 0) + resolved_n: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_n.annotation, imported_modules, from_imports, trans, 0) if resolved_n is not None: match resolved_n: case llvmlite.LLVMType.Struct(_, _, _): @@ -135,8 +92,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): case _: pty_n = resolved_n if param_count < 64 and param_tys is not None: - pty_slot_n: str | t.CPtr = (t.CPtr)( - uint64(param_tys) + param_count * 8) + pty_slot_n: str | t.CPtr = (t.CPtr)(uint64(param_tys) + param_count * 8) pty_slot_n[0] = pty_n pname_n: str = pool.alloc(32) if pname_n is not None: @@ -146,11 +102,9 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 3. 创建 entry 块 + builder entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") - if entry_blk is None: - return 0 + if entry_blk is None: return 0 func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) - if func_builder is None: - return 0 + if func_builder is None: return 0 llvmlite.position_at_end(func_builder, entry_blk) # 4. 进入嵌套函数作用域(嵌套符号表) @@ -191,36 +145,27 @@ class FuncGenMixin(CallGenBase.CallGenBase): if p_alloca is not None: self.Gen.VarGen.define_var(trans.SymTab, arg_p.arg, p_alloca) if arg_p.annotation is not None: - cls_nm_p: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - arg_p.annotation, imported_modules, pool, trans._from_imports) + cls_nm_p: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(arg_p.annotation, imported_modules, pool, trans._from_imports) if cls_nm_p is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, arg_p.arg, cls_nm_p) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, arg_p.arg, cls_nm_p) # const 形参:沿用 TPC 形参的历史判据(只看注解是否含 # t.CConst,不看指针层数),两侧逐条对齐(见 # Debugger/type-descriptors.md 已知差异)。 - if self.Gen.TypeGenErr.has_decorator_marker( - arg_p.annotation, "CConst", 0) != 0: - self.Gen.VarGen.set_var_const( - trans.SymTab, arg_p.arg) + if self.Gen.TypeGenErr.has_decorator_marker(arg_p.annotation, "CConst", 0) != 0: + self.Gen.VarGen.set_var_const(trans.SymTab, arg_p.arg) # t.CVolatile 形参:声明期标记(与 FuncGenDef 主路径同款), # 函数体内该参数名的 load/store 带 volatile。 - if self.Gen.TypeGenErr.has_decorator_marker( - arg_p.annotation, "CVolatile", 0) != 0: - self.Gen.VarGen.set_var_volatile( - trans.SymTab, arg_p.arg) + if self.Gen.TypeGenErr.has_decorator_marker(arg_p.annotation, "CVolatile", 0) != 0: + self.Gen.VarGen.set_var_volatile(trans.SymTab, arg_p.arg) # rawptr[t.CVolatile | T] 形参(volatile 指针指向物): # 函数体内该参数解引用带 volatile(与 FuncGenDef 主路径同款)。 - if self.Gen.TypeGenErr.has_pointee_volatile_marker( - arg_p.annotation) != 0: - self.Gen.VarGen.set_var_pointee_volatile( - trans.SymTab, arg_p.arg) + if self.Gen.TypeGenErr.has_pointee_volatile_marker(arg_p.annotation) != 0: + self.Gen.VarGen.set_var_pointee_volatile(trans.SymTab, arg_p.arg) pname2_n: str = pool.alloc(32) if pname2_n is not None: viperlib.snprintf(pname2_n, 32, "%%%s", arg_p.arg) p_val: llvmlite.Value* = llvmlite.SSAValue(pool, pty2_n, pname2_n) - vol_pn: int = self.Gen.VarGen.var_is_volatile( - self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg_p.arg)) + vol_pn: int = self.Gen.VarGen.var_is_volatile(self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg_p.arg)) llvmlite.build_store(func_builder, p_val, p_alloca, vol_pn) idx_p += 1 @@ -326,8 +271,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): env_size_val: llvmlite.Value* = llvmlite.const_int64(pool, env_size) if env_size_val is not None: env_size_val.Next = None - env_ptr = llvmlite.build_call( - parent_builder, "malloc", env_size_val, 1, i8_ptr_ty, 0) + env_ptr = llvmlite.build_call(parent_builder, "malloc", env_size_val, 1, i8_ptr_ty, 0) # 为每个 nonlocal 变量建立堆存储并注册到 env: # 运行时 env 链式共享(无需编译期映射——映射存编译期 Value 对象 @@ -352,44 +296,33 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 1. 优先查全局堆地址映射(_prepare_chain_nonlocals 已为 # 链内 nonlocal 建堆并 store 到 @nlheap.*;不同层捕获 # 不同变量时(ClosureTest2 Test 7)level2 的 b 经此共享) - gname_ck: str = self._nl_heap_global_name( - pool, trans, nl_name) - if gname_ck is not None \ - and self._nl_heap_global_exists(mod, gname_ck) != 0: - gv_ref0: llvmlite.Value* = self._nl_heap_global_ref( - pool, trans, nl_name) + gname_ck: str = self._nl_heap_global_name(pool, trans, nl_name) + if gname_ck is not None and self._nl_heap_global_exists(mod, gname_ck) != 0: + gv_ref0: llvmlite.Value* = self._nl_heap_global_ref(pool, trans, nl_name) if gv_ref0 is not None: - heap_store = llvmlite.build_load( - parent_builder, i8_ptr_ty, gv_ref0) + heap_store = llvmlite.build_load(parent_builder, i8_ptr_ty, gv_ref0) if heap_store is None: - local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, nl_name) + local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nl_name) if local_alloca is not None and local_alloca.Ty is not None: # 父函数局部变量:新建堆存储 + 拷贝当前值 + 重定向 nl_load_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee if nl_load_ty is not None: - cur_val_nl: llvmlite.Value* = llvmlite.build_load( - parent_builder, nl_load_ty, local_alloca) + cur_val_nl: llvmlite.Value* = llvmlite.build_load(parent_builder, nl_load_ty, local_alloca) # 堆存储大小按类型字节数:数组(如 [4 x i32]=16 字节) # 不能固定 8 字节(越界写崩溃);指针/标量 ≥ 8 字节 st_size: int = self._type_byte_size(pool, nl_load_ty) - st_size_val: llvmlite.Value* = llvmlite.const_int64( - pool, st_size) + st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: llvmlite.Value* = llvmlite.build_call( - parent_builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) + var_storage: llvmlite.Value* = llvmlite.build_call(parent_builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) if var_storage is not None: # 拷贝当前值到堆存储 - st_slot_nl: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty)) + st_slot_nl: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty)) if st_slot_nl is not None and cur_val_nl is not None: llvmlite.build_store(parent_builder, cur_val_nl, st_slot_nl) # 父函数 VarEntry.Alloca 重定向到堆(父函数读写走共享堆) - ve_nl: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nl_name) - heap_typed: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty)) + ve_nl: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nl_name) + heap_typed: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty)) if ve_nl is not None and heap_typed is not None: ve_nl.Alloca = heap_typed # 记录到全局映射(后续层/父函数可见) @@ -405,8 +338,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): llvmlite.module_add_global(mod, gv_new) gv_ref_new = self._nl_heap_global_ref(pool, trans, nl_name) if gv_ref_new is not None: - llvmlite.build_store( - parent_builder, var_storage, gv_ref_new) + llvmlite.build_store(parent_builder, var_storage, gv_ref_new) heap_store = var_storage else: # 父函数中该变量是 nonlocal(多层嵌套):从父函数 env @@ -416,11 +348,9 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue # env[ni] = 堆存储地址(共享) offset_val: llvmlite.Value* = llvmlite.const_int32(pool, ni * 8) - slot: llvmlite.Value* = llvmlite.build_gep( - parent_builder, i8_ty, env_ptr, offset_val) + slot: llvmlite.Value* = llvmlite.build_gep(parent_builder, i8_ty, env_ptr, offset_val) if slot is not None: - slot_typed: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, slot, i8_ptr_ptr_ty) + slot_typed: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, slot, i8_ptr_ptr_ty) if slot_typed is not None: llvmlite.build_store(parent_builder, heap_store, slot_typed) @@ -428,8 +358,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16) if closure_size_val is not None: closure_size_val.Next = None - closure_ptr: llvmlite.Value* = llvmlite.build_call( - parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) + closure_ptr: llvmlite.Value* = llvmlite.build_call(parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) if closure_ptr is None: # malloc 失败,恢复状态 trans._cur_func_name = old_func_name @@ -457,20 +386,16 @@ class FuncGenMixin(CallGenBase.CallGenBase): fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name) # bitcast 函数指针到 i8*(闭包存储 i8* 类型) - fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, fn_ptr_val, i8_ptr_ty) - fn_slot: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) + fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, fn_ptr_val, i8_ptr_ty) + fn_slot: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) if fn_slot is not None and fn_as_i8ptr is not None: llvmlite.build_store(parent_builder, fn_as_i8ptr, fn_slot) # 13d. 存储 env_ptr 到 offset 8 eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8) - env_slot_addr: llvmlite.Value* = llvmlite.build_gep( - parent_builder, i8_ty, closure_ptr, eight_val) + env_slot_addr: llvmlite.Value* = llvmlite.build_gep(parent_builder, i8_ty, closure_ptr, eight_val) if env_slot_addr is not None: - env_slot: llvmlite.Value* = llvmlite.build_bitcast( - parent_builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty)) + env_slot: llvmlite.Value* = llvmlite.build_bitcast(parent_builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty)) if env_slot is not None: if env_ptr is not None: llvmlite.build_store(parent_builder, env_ptr, env_slot) @@ -512,27 +437,19 @@ class FuncGenMixin(CallGenBase.CallGenBase): k: int = node.kind() if k == ast.ASTKind.Name: nm: ast.Name* = ast.Name*(node) - if nm.id is None: - return 1 + if nm.id is None: return 1 # 当前作用域已定义(参数 / AnnAssign 局部,含分支内)→ 非捕获 - if self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) is not None: - return 1 + if self.Gen.VarGen.lookup_current(trans.SymTab, nm.id) is not None: return 1 # 已注册 nonlocal(显式 nonlocal 语句 / 已捕获)→ 跳过 - if GenApi.is_nonlocal_name(trans, nm.id) != 0: - return 1 - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) - if ve is None or ve.Alloca is None or ve.Alloca.Ty is None: - return 1 + if GenApi.is_nonlocal_name(trans, nm.id) != 0: return 1 + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) + if ve is None or ve.Alloca is None or ve.Alloca.Ty is None: return 1 nl_ty: llvmlite.LLVMType* = ve.Alloca.Ty.Pointee - if nl_ty is None: - return 1 + if nl_ty is None: return 1 # 模块级全局直接解析,无需 env 捕获 - mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm.id) + mod_gv: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) if mod_gv is not None: - if uint64(mod_gv) == uint64(ve.Alloca): - return 1 + if uint64(mod_gv) == uint64(ve.Alloca): return 1 # 外层函数局部变量 → 隐式捕获(注册为 nonlocal) GenApi.add_nonlocal_name(trans, nm.id, nl_ty) return 1 @@ -569,7 +486,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, ifn.orelse.get(bi_el)) return 1 if k == ast.ASTKind.For: - for_n: rawptr[ast.For] = rawptr[ast.For](node) + for_n: ast.For* = ast.For*(node) # 循环目标是新局部变量,不参与捕获 if for_n.iter is not None: self._closure_scan_captures(trans, for_n.iter) @@ -880,22 +797,18 @@ class FuncGenMixin(CallGenBase.CallGenBase): """计算 LLVM 类型占用的字节大小(递归)""" if ty is None: # [S4 fail-fast] 类型缺失 → 不再保守 8 字节(分配不足会越界写邻块) - self.Gen.TypeGenErr.fatal_error( - None, "nonlocal 共享存储:类型缺失,无法计算尺寸", "TypeError") + self.Gen.TypeGenErr.fatal_error(None, "nonlocal 共享存储:类型缺失,无法计算尺寸", "TypeError") return 0 match ty: case llvmlite.LLVMType.Int(bits): sz_i: int = (bits + 7) // 8 - if sz_i < 8: - sz_i = 8 + if sz_i < 8: sz_i = 8 return sz_i case llvmlite.LLVMType.Ptr(_pe): return 8 case llvmlite.LLVMType.Float(fb): - if fb == 64: - return 8 - if fb >= 128: - return 16 + if fb == 64: return 8 + if fb >= 128: return 16 return 4 case llvmlite.LLVMType.Array(et, cnt): esz: int = self._type_byte_size(pool, et) @@ -995,13 +908,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue dup: int = 0 for di in range(count): - if string.strcmp((str)( - uint64(names) + di * 8), nm_x.id) == 0: + if string.strcmp((str)(uint64(names) + di * 8), nm_x.id) == 0: dup = 1 break if dup == 0 and count < 64: - nm_slot: str | t.CPtr = (t.CPtr)( - uint64(names) + count * 8) + nm_slot: str* = (t.CPtr)(uint64(names) + count * 8) nm_slot[0] = nm_x.id count += 1 return count @@ -1024,38 +935,28 @@ class FuncGenMixin(CallGenBase.CallGenBase): i8_ty: llvmlite.LLVMType*, i8_ptr_ty: llvmlite.LLVMType*) -> int: """预收集嵌套函数链内 nonlocal 并建堆,1 成功""" - if node is None or trans is None or builder is None or mod is None: - return 0 + if node is None or trans is None or builder is None or mod is None: return 0 # 每函数只预建一次:多个嵌套函数定义共享同一堆(防重复 malloc + # 二次重定向 VarEntry.Alloca 导致兄弟闭包各持一堆,计数不同步) - if trans._nl_chain_done != 0: - return 1 + if trans._nl_chain_done != 0: return 1 if trans._nl_chain_names is None: trans._nl_chain_names = pool.alloc(8 * 64) if trans._nl_chain_names is not None: string.memset(trans._nl_chain_names, 0, 8 * 64) - if trans._nl_chain_names is None: - return 0 - trans._nl_chain_count = self._collect_chain_nonlocals( - trans, node, trans._nl_chain_names, 0) + if trans._nl_chain_names is None: return 0 + trans._nl_chain_count = self._collect_chain_nonlocals(trans, node, trans._nl_chain_names, 0) trans._nl_chain_done = 1 for ci in range(trans._nl_chain_count): - nm_slot: str | t.CPtr = (t.CPtr)( - uint64(trans._nl_chain_names) + ci * 8) + nm_slot: str* = (t.CPtr)(uint64(trans._nl_chain_names) + ci * 8) nl_name: str = nm_slot[0] - if nl_name is None: - continue + if nl_name is None: continue # 只在"定义它的函数"(当前顶层作用域有 alloca)中建堆 - local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, nl_name) - if local_alloca is None or local_alloca.Ty is None: - continue + local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nl_name) + if local_alloca is None or local_alloca.Ty is None: continue nl_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee - if nl_ty is None: - continue + if nl_ty is None: continue gname: str = self._nl_heap_global_name(pool, trans, nl_name) - if gname is None: - continue + if gname is None: continue # 建堆(按类型字节大小)并拷贝当前值——每次本函数执行都新建共享堆,并 store 到 # 模块级映射(跨函数可见)。不能因映射变量已存在就跳过:跳过会让本函数运行时 # @nlheap.* 保持上一函数的堆地址,env 读到错堆。映射变量仅首次 add(模块去重), @@ -1064,22 +965,17 @@ class FuncGenMixin(CallGenBase.CallGenBase): st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: llvmlite.Value* = llvmlite.build_call( - builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) + var_storage: llvmlite.Value* = llvmlite.build_call(builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) if var_storage is None: continue - cur_val: llvmlite.Value* = llvmlite.build_load( - builder, nl_ty, local_alloca) - st_slot: llvmlite.Value* = llvmlite.build_bitcast( - builder, var_storage, llvmlite.Ptr(pool, nl_ty)) + cur_val: llvmlite.Value* = llvmlite.build_load(builder, nl_ty, local_alloca) + st_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, nl_ty)) if st_slot is not None and cur_val is not None: llvmlite.build_store(builder, cur_val, st_slot) # 重定向 VarEntry(父函数读写走共享堆) - ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nl_name) + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nl_name) if ve is not None: - heap_typed: llvmlite.Value* = llvmlite.build_bitcast( - builder, var_storage, llvmlite.Ptr(pool, nl_ty)) + heap_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, nl_ty)) if heap_typed is not None: ve.Alloca = heap_typed # 创建/复用全局映射变量并 store 堆地址(跨函数可见) @@ -1099,8 +995,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): gv_found.Initializer = "null" llvmlite.module_add_global(mod, gv_found) if gv_found is not None: - gv_ref: llvmlite.Value* = self._nl_heap_global_ref( - pool, trans, nl_name) + gv_ref: llvmlite.Value* = self._nl_heap_global_ref(pool, trans, nl_name) if gv_ref is not None: llvmlite.build_store(builder, var_storage, gv_ref) return 1 @@ -1169,13 +1064,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): string.strncpy(param_names + param_count * 32, arg_n.arg, 31) p_ty: llvmlite.LLVMType* = i32_ty if arg_n.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg_n.annotation, trans._imported_modules, trans._from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, arg_n.annotation, trans._imported_modules, trans._from_imports, trans, 0) if resolved is None: # fail-fast:lambda 参数有注解但类型解析失败,不再静默保持 i32 - self.Gen.TypeGenErr.fatal_error( - arg_n, f"参数 '{arg_n.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_n.annotation)}", - "NameError") + self.Gen.TypeGenErr.fatal_error(arg_n, f"参数 '{arg_n.arg}' 类型解析失败: {self.Gen.TypeGenResolve.annotation_to_str(arg_n.annotation)}", "NameError") resolved = i32_ty # 不可达(fatal_error 已退出) if resolved is not None: match resolved: @@ -1185,8 +1077,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): p_ty = llvmlite.Ptr(pool, aelem_ty_l) case _: p_ty = resolved - ty_slot_p: str | t.CPtr = (t.CPtr)( - uint64(param_tys) + param_count * 8) + ty_slot_p: str* = (t.CPtr)(uint64(param_tys) + param_count * 8) ty_slot_p[0] = p_ty param_count += 1 @@ -1203,19 +1094,15 @@ class FuncGenMixin(CallGenBase.CallGenBase): if cap_tys is None: return None string.memset(cap_tys, 0, 8 * 64) - cap_count: int = self._lambda_scan_body( - trans, lam.body, param_names, param_count, - cap_names, cap_allocas, cap_tys, 0) + cap_count: int = self._lambda_scan_body(trans, lam.body, param_names, param_count, cap_names, cap_allocas, cap_tys, 0) # 4. 创建提升函数 __lambda_{id}(i8* %env, [args...]) - func: llvmlite.Function* = llvmlite.create_function( - pool, mod, mangled_promoted, i32_ty) - if func is None: - return None + func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_promoted, i32_ty) + if func is None: return None llvmlite.add_param(pool, func, i8_ptr_ty, "%env") for pi2 in range(param_count): ty_addr2: uint64 = uint64(param_tys) + pi2 * 8 - ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2) + ty_slot2: str* = (t.CPtr)(ty_addr2) p_ty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot2[0]) if p_ty2 is None: p_ty2 = i32_ty @@ -1261,30 +1148,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 注意:不能用 (str)(cap_addr) 整数转换——TPV 将其编译为 itoa(整数转字符串), # 会把 cap_slot 变成数字串,define_var 键名错乱,lambda body lookup 无法命中。 cap_slot: str = cap_names + ci * 64 - if cap_slot[0] == '\0': - continue + if cap_slot[0] == '\0': continue ty_addr3: uint64 = uint64(cap_tys) + ci * 8 ty_slot3: str | t.CPtr = (t.CPtr)(ty_addr3) cap_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot3[0]) - if cap_ty is None: - continue + if cap_ty is None: continue off_val: llvmlite.Value* = llvmlite.const_int32(pool, ci * 8) - slot_addr: llvmlite.Value* = llvmlite.build_gep( - func_builder, i8_ty, env_param_val, off_val) - if slot_addr is None: - continue - storage_addr: llvmlite.Value* = llvmlite.build_load( - func_builder, i8_ptr_ty, slot_addr) - if storage_addr is None: - continue - st_typed: llvmlite.Value* = llvmlite.build_bitcast( - func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty)) - if st_typed is None: - continue - cap_val: llvmlite.Value* = llvmlite.build_load( - func_builder, cap_ty, st_typed) - if cap_val is None: - continue + slot_addr: llvmlite.Value* = llvmlite.build_gep(func_builder, i8_ty, env_param_val, off_val) + if slot_addr is None: continue + storage_addr: llvmlite.Value* = llvmlite.build_load(func_builder, i8_ptr_ty, slot_addr) + if storage_addr is None: continue + st_typed: llvmlite.Value* = llvmlite.build_bitcast(func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty)) + if st_typed is None: continue + cap_val: llvmlite.Value* = llvmlite.build_load(func_builder, cap_ty, st_typed) + if cap_val is None: continue var_alloca: llvmlite.Value* = llvmlite.build_alloca(func_builder, cap_ty) if var_alloca is not None: llvmlite.build_store(func_builder, cap_val, var_alloca) @@ -1297,8 +1174,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): p_ty3: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot4[0]) if p_ty3 is None: # fail-fast:lambda 参数类型槽缺失(内部状态不一致),不再静默保持 i32 - self.Gen.TypeGenErr.fatal_error( - lam, f"lambda 参数 '{param_names + pi3 * 32}' 类型信息缺失", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(lam, f"lambda 参数 '{param_names + pi3 * 32}' 类型信息缺失", "InternalCompilerError") p_ty3 = i32_ty # 不可达(fatal_error 已退出) pname_ref: str = pool.alloc(32) if pname_ref is not None: @@ -1310,15 +1186,12 @@ class FuncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.define_var(trans.SymTab, param_names + pi3 * 32, arg_alloca) # 11. 翻译 body 表达式,coerce 到 i32 后 ret - body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - func_builder, pool, mod, lam.body, None, 0, trans) + body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(func_builder, pool, mod, lam.body, None, 0, trans) if body_val is not None and body_val.Ty is not None: - if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 \ - and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0: + if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0: llvmlite.build_ret(func_builder, body_val) else: - ret_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - func_builder, body_val, i32_ty, lam.body) + ret_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(func_builder, body_val, i32_ty, lam.body) if ret_val is not None: llvmlite.build_ret(func_builder, ret_val) else: @@ -1344,8 +1217,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): env_size_val: llvmlite.Value* = llvmlite.const_int64(pool, env_size) if env_size_val is not None: env_size_val.Next = None - env_ptr = llvmlite.build_call( - builder, "malloc", env_size_val, 1, i8_ptr_ty, 0) + env_ptr = llvmlite.build_call(builder, "malloc", env_size_val, 1, i8_ptr_ty, 0) if env_ptr is not None: for ci3 in range(cap_count): # 与步骤 9 一致:str 指针偏移判空,避免整数转换 itoa 语义 @@ -1354,16 +1226,12 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue al_addr: uint64 = uint64(cap_allocas) + ci3 * 8 al_slot: str | t.CPtr = (t.CPtr)(al_addr) - var_alloca2: llvmlite.Value* = ( - llvmlite.Value*)(al_slot[0]) - if var_alloca2 is None: - continue + var_alloca2: llvmlite.Value* = (llvmlite.Value*)(al_slot[0]) + if var_alloca2 is None: continue ty_addr5: uint64 = uint64(cap_tys) + ci3 * 8 ty_slot5: str | t.CPtr = (t.CPtr)(ty_addr5) - cap_ty2: llvmlite.LLVMType* = ( - llvmlite.LLVMType*)(ty_slot5[0]) - if cap_ty2 is None: - continue + cap_ty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot5[0]) + if cap_ty2 is None: continue # 堆存储大小:位宽/8,至少 8 字节(容纳指针/标量) ty_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cap_ty2) st_size: int = 8 @@ -1372,22 +1240,17 @@ class FuncGenMixin(CallGenBase.CallGenBase): st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: llvmlite.Value* = llvmlite.build_call( - builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) + var_storage: llvmlite.Value* = llvmlite.build_call(builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) if var_storage is not None: - cur_val: llvmlite.Value* = llvmlite.build_load( - builder, cap_ty2, var_alloca2) + cur_val: llvmlite.Value* = llvmlite.build_load(builder, cap_ty2, var_alloca2) if cur_val is not None: - st_slot5: llvmlite.Value* = llvmlite.build_bitcast( - builder, var_storage, llvmlite.Ptr(pool, cap_ty2)) + st_slot5: llvmlite.Value* = llvmlite.build_bitcast(builder, var_storage, llvmlite.Ptr(pool, cap_ty2)) if st_slot5 is not None: llvmlite.build_store(builder, cur_val, st_slot5) off_val2: llvmlite.Value* = llvmlite.const_int32(pool, ci3 * 8) - slot2: llvmlite.Value* = llvmlite.build_gep( - builder, i8_ty, env_ptr, off_val2) + slot2: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, env_ptr, off_val2) if slot2 is not None: - slot_typed2: llvmlite.Value* = llvmlite.build_bitcast( - builder, slot2, i8_ptr_ptr_ty) + slot_typed2: llvmlite.Value* = llvmlite.build_bitcast(builder, slot2, i8_ptr_ptr_ty) if slot_typed2 is not None: llvmlite.build_store(builder, var_storage, slot_typed2) @@ -1395,8 +1258,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16) if closure_size_val is not None: closure_size_val.Next = None - closure_ptr: llvmlite.Value* = llvmlite.build_call( - builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) + closure_ptr: llvmlite.Value* = llvmlite.build_call(builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) if closure_ptr is None: return None @@ -1411,20 +1273,16 @@ class FuncGenMixin(CallGenBase.CallGenBase): else: viperlib.snprintf(fn_ptr_name, 64, "@%s", mangled_promoted) fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name) - fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, fn_ptr_val, i8_ptr_ty) - fn_slot: llvmlite.Value* = llvmlite.build_bitcast( - builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) + fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_ptr_val, i8_ptr_ty) + fn_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) if fn_slot is not None and fn_as_i8ptr is not None: llvmlite.build_store(builder, fn_as_i8ptr, fn_slot) # 16. [8] = env_ptr(无捕获存 null) eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8) - env_slot_addr: llvmlite.Value* = llvmlite.build_gep( - builder, i8_ty, closure_ptr, eight_val) + env_slot_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val) if env_slot_addr is not None: - env_slot: llvmlite.Value* = llvmlite.build_bitcast( - builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty)) + env_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty)) if env_slot is not None: if env_ptr is not None: llvmlite.build_store(builder, env_ptr, env_slot) @@ -1481,11 +1339,9 @@ class FuncGenMixin(CallGenBase.CallGenBase): if cap_count >= 64: return cap_count string.strncpy(cap_names + cap_count * 64, nm.id, 63) - al_slot: str | t.CPtr = (t.CPtr)( - uint64(cap_allocas) + cap_count * 8) + al_slot: str | t.CPtr = (t.CPtr)(uint64(cap_allocas) + cap_count * 8) al_slot[0] = alloca - ty_slot: str | t.CPtr = (t.CPtr)( - uint64(cap_tys) + cap_count * 8) + ty_slot: str | t.CPtr = (t.CPtr)(uint64(cap_tys) + cap_count * 8) ty_slot[0] = pointee return cap_count + 1 # 递归遍历常见表达式子节点 diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index a1821c7..077da36 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -834,17 +834,14 @@ novirtual class ImportsGenMixin: self._check_import_sha1(node, alias.name) pool_val: memhub.MemBuddy* = trans.Pool im_val: str = trans._imported_modules - trans._imported_modules = self.add_imported_module( - pool_val, im_val, alias.name) + trans._imported_modules = self.add_imported_module(pool_val, im_val, alias.name) # 别名也加入导入模块列表(用于模块限定构造器检查 Module.Class()) if alias.asname is not None: - trans._imported_modules = self.add_imported_module( - pool_val, trans._imported_modules, alias.asname) + trans._imported_modules = self.add_imported_module(pool_val, trans._imported_modules, alias.asname) # 别名也加入 from_imports(asname:fullname), # 使 HT.func() 跨模块调用能通过 from_imports 查找别名→完整模块名→SHA1 # 否则 _lookup_module_sha1("HT") 找不到(mod_arr 只存文件名 HandlesTranslator) - trans._from_imports = self.add_from_import( - pool_val, trans._from_imports, alias.asname, alias.name) + trans._from_imports = self.add_from_import(pool_val, trans._from_imports, alias.asname, alias.name) else: # 无别名时(import a.b.c),将顶层包名 "a" 也加入 _imported_modules, # 使 a.b.c 作为属性访问的 base 被翻译时能通过 is_module_imported("a") 检查 @@ -856,8 +853,7 @@ novirtual class ImportsGenMixin: if pkg_buf is not None: string.strncpy(pkg_buf, alias.name, pkg_len) pkg_buf[pkg_len] = '\0' - trans._imported_modules = self.add_imported_module( - pool_val, trans._imported_modules, pkg_buf) + trans._imported_modules = self.add_imported_module(pool_val, trans._imported_modules, pkg_buf) return 0 # ============================================================ @@ -875,8 +871,7 @@ novirtual class ImportsGenMixin: if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 - resolved: str = self._resolve_relative_module( - trans.Pool, trans.CurrentPackage, + resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, impf.level, impf.module) if resolved is not None: # 导入时立即校验模块 SHA1 是否注册(fast-fail,仅全量翻译时检查) @@ -887,8 +882,7 @@ novirtual class ImportsGenMixin: # 下方 L759-762 逐个校验(LookupSha1ByModName / 本地兄弟文件)。 if trans._declare_only == 0 and impf.module is not None: self._check_import_sha1(node, resolved) - trans._imported_modules = self.add_imported_module( - trans.Pool, trans._imported_modules, resolved) + trans._imported_modules = self.add_imported_module(trans.Pool, trans._imported_modules, resolved) # from . import Y(impf.module is None):resolved 是包名(vpsdk), # 各 name 是包的子模块 vpsdk.Y。须把完整子模块名也加入 _imported_modules, # 否则别名 "syscall" 精确匹配不到包名 "vpsdk" → is_module_imported 返回 0 @@ -916,8 +910,7 @@ novirtual class ImportsGenMixin: or self._is_local_module_file(alias_m.name) != 0): if trans._declare_only == 0: self._check_import_sha1(node, jb_m) - trans._imported_modules = self.add_imported_module( - trans.Pool, trans._imported_modules, jb_m) + trans._imported_modules = self.add_imported_module(trans.Pool, trans._imported_modules, jb_m) return 0 # ============================================================ @@ -934,8 +927,7 @@ novirtual class ImportsGenMixin: if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 - resolved: str = self._resolve_relative_module( - trans.Pool, trans.CurrentPackage, + resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, impf.level, impf.module) if resolved is not None: names: list[ast.AST*]* = impf.names @@ -963,8 +955,7 @@ novirtual class ImportsGenMixin: jb_t[fl_t] = '.' string.strcpy(jb_t + fl_t + 1, alias.name) fi_target = jb_t - trans._from_imports = self.add_from_import( - trans.Pool, trans._from_imports, + trans._from_imports = self.add_from_import(trans.Pool, trans._from_imports, local_name, fi_target, orig_name) # 命名空间隔离:from-import 的名称标记为可见结构体 self.Gen.StructGen.add_visible_struct(trans.Pool, local_name) diff --git a/App/lib/core/Gen/MatchGenMixin.vp b/App/lib/core/Gen/MatchGenMixin.vp index dba3340..d03b304 100644 --- a/App/lib/core/Gen/MatchGenMixin.vp +++ b/App/lib/core/Gen/MatchGenMixin.vp @@ -16,14 +16,14 @@ import lib.core.Gen.Generator as Generator # match case 数量上限(原 HandlesMatch.MAX_MATCH_CASES) -MAX_MATCH_CASES: t.CDefine = 32 +define MAX_MATCH_CASES = 32 # 作用域种类常量(与 HandlesVar 的 Scope.Kind 区分,原 HandlesMatch.SCOPE_MATCH) -SCOPE_MATCH: t.CDefine = 6 +define SCOPE_MATCH = 6 # match 翻译最大递归深度(match → case body → translate_value → 嵌套 match)。 # 入口计数出口递减,超限即 fail-fast:AST 自引用环可致无限递归 → 栈溢出。 -MATCH_TRANSLATE_MAX_DEPTH: t.CDefine = 64 +define MATCH_TRANSLATE_MAX_DEPTH = 64 novirtual class MatchGenMixin: @@ -66,8 +66,7 @@ novirtual class MatchGenMixin: """match 语句翻译主入口(深度守卫包装器,原逻辑见 _translate_match_impl)""" if trans is not None: if trans.MatchTranslateDepth >= MATCH_TRANSLATE_MAX_DEPTH: - self.Gen.TypeGenErr.fatal_error( - node, "match 翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") + self.Gen.TypeGenErr.fatal_error(node, "match 翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") trans.MatchTranslateDepth += 1 mret: int = self._translate_match_impl(trans, node) if trans is not None: @@ -101,8 +100,7 @@ novirtual class MatchGenMixin: sk_seq: int = subject_node.kind() if sk_seq == ast.ASTKind.Tuple or sk_seq == ast.ASTKind.List: return self._handle_sequence_match(trans, m_node, subject_node) - subject_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, subject_node, + subject_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, subject_node, trans._funcs, trans._func_count, trans) if subject_val is None: # fail-fast: match subject 翻译失败 @@ -117,14 +115,11 @@ novirtual class MatchGenMixin: if subject_node.kind() == ast.ASTKind.Name: nm: ast.Name* = ast.Name*(subject_node) if nm.id is not None: - entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry) if entry_annot is not None \ - and (self.Gen.ClassGenEnum._is_renum_class_name( - entry_annot) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry( - entry_annot) != 0): + and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0 + or self.Gen.ClassGenEnum._is_renum_by_entry(entry_annot) != 0): is_renum = 1 renum_name = entry_annot subject_ptr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) @@ -139,8 +134,7 @@ novirtual class MatchGenMixin: case_node: ast.AST* = cases_list.get(ci) if case_node is not None \ and case_node.kind() == ast.ASTKind.MatchCase: - mc: rawptr[ast.MatchCase] = ( - rawptr[ast.MatchCase])(case_node) + mc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(case_node) pat: ast.AST* = mc.pattern if pat is not None \ and pat.kind() == ast.ASTKind.MatchClass: @@ -182,8 +176,7 @@ novirtual class MatchGenMixin: inner_nm: ast.Name* = ast.Name*(at.value) return inner_nm.id if at.value.kind() == ast.ASTKind.Attribute: - inner_at: ast.Attribute* = ( - ast.Attribute*)(at.value) + inner_at: ast.Attribute* = (ast.Attribute*)(at.value) return inner_at.attr # Name 形式:遍历所有 REnum 类反查 if cls_node.kind() == ast.ASTKind.Name: @@ -240,12 +233,10 @@ novirtual class MatchGenMixin: call_node: ast.Call* = ast.Call*(val) fn: ast.AST* = call_node.func if fn is not None and fn.kind() == ast.ASTKind.Attribute: - at: ast.Attribute* = ( - ast.Attribute*)(fn) + at: ast.Attribute* = (ast.Attribute*)(fn) if at.value is not None \ and at.value.kind() == ast.ASTKind.Name: - base_nm: ast.Name* = ( - ast.Name*)(at.value) + base_nm: ast.Name* = (ast.Name*)(at.value) if base_nm.id is not None \ and string.strcmp(base_nm.id, "c") == 0 \ and at.attr is not None \ @@ -287,25 +278,20 @@ novirtual class MatchGenMixin: and subj_ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0: # 情况1: T** → load 一次得 T* - loaded_sub: llvmlite.Value* = llvmlite.build_load( - builder, subj_ty.Pointee, subject_ptr) + loaded_sub: llvmlite.Value* = llvmlite.build_load(builder, subj_ty.Pointee, subject_ptr) if loaded_sub is not None: subject_ptr = loaded_sub # 情况2: 值型 subject(非指针)→ inttoptr 转回指针 # 值型 subject 来自 REnum payload 槽位 load(槽位类型 i64,存的是指针), # 所以直接 inttoptr 到 renum_sty* 即可,无需 alloca+store if subject_ptr.Ty is None or self.Gen.ExprGenBase.is_ptr_type(subject_ptr.Ty) == 0: - renum_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct( - renum_name) + renum_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(renum_name) renum_sty: llvmlite.LLVMType* = None if renum_se is not None: renum_sty = renum_se.Ty if renum_sty is None: # fail-fast: REnum 结构体未注册,无法构造 - self.Gen.TypeGenErr.fatal_error( - node, - f"REnum 结构体 '{renum_name}' 未注册", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REnum 结构体 '{renum_name}' 未注册", "NameError") i64_ty0: llvmlite.LLVMType* = llvmlite.Int64(pool) int_val: llvmlite.Value* = subject_ptr # 非 i64 整数值先扩展/截断到 i64(inttoptr 要求同宽) @@ -317,21 +303,18 @@ novirtual class MatchGenMixin: else: int_val = llvmlite.build_zext(builder, subject_ptr, i64_ty0) renum_ptr_ty0: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_sty) - subj_ptr0: llvmlite.Value* = llvmlite.build_inttoptr( - builder, int_val, renum_ptr_ty0) + subj_ptr0: llvmlite.Value* = llvmlite.build_inttoptr(builder, int_val, renum_ptr_ty0) if subj_ptr0 is not None: subject_ptr = subj_ptr0 # 1. bitcast subject 到 i32* 读 __tag i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) i32_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty) - tag_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, subject_ptr, i32_ptr_ty) + tag_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, subject_ptr, i32_ptr_ty) if tag_ptr is None: # fail-fast: REnum tag 指针转换失败 self.Gen.TypeGenErr.fatal_error(node, "REnum tag 指针转换失败", "TypeError") - tag_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty, tag_ptr) + tag_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, tag_ptr) if tag_val is None: # fail-fast: REnum tag 读取失败 self.Gen.TypeGenErr.fatal_error(node, "REnum tag 读取失败", "TypeError") @@ -344,11 +327,9 @@ novirtual class MatchGenMixin: # fail-fast: 标签缓冲区分配失败 self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError") viperlib.snprintf(name_buf, 32, "match.default.%d", cnt) - default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) viperlib.snprintf(name_buf, 32, "match.end.%d", cnt) - end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) # 3. 准备收集数组(用 CSizeT 数组存指针) cases_list: list[ast.AST*]* = node.cases @@ -427,11 +408,9 @@ novirtual class MatchGenMixin: # 先用裸类名查表(变体表按裸类名注册,与模式侧 2b 路径同口径); # 失败再用注解书写形态重试(泛型特化 mangled 名确需带点)。 # 两者都失败 → tag=-1 → step 5 前的硬校验 fail-fast。 - tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - tag_cls_bare, vnm) + tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(tag_cls_bare, vnm) if tag < 0 and string.strcmp(tag_cls_bare, renum_name) != 0: - tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - renum_name, vnm) + tag = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(renum_name, vnm) if tag >= 0: tag_buf: str = pool.alloc(32) if tag_buf is not None: @@ -445,9 +424,7 @@ novirtual class MatchGenMixin: has_default = 1 elif pk == ast.ASTKind.MatchValue: mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat) - cv = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, mv.value, - trans._funcs, trans._func_count, trans) + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans) elif pk == ast.ASTKind.MatchOr: # MatchOr: 多个值共享一个 BB(取第一个值做 case) mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat) @@ -456,19 +433,15 @@ novirtual class MatchGenMixin: first_pat: ast.AST* = pats.get(0) if first_pat is not None \ and first_pat.kind() == ast.ASTKind.MatchValue: - mv2: rawptr[ast.MatchValue] = ( - rawptr[ast.MatchValue])(first_pat) - cv = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, mv2.value, - trans._funcs, trans._func_count, trans) + mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(first_pat) + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv2.value, trans._funcs, trans._func_count, trans) # 创建 case BB if is_def == 0: if collected >= MAX_MATCH_CASES: break viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i) - bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) else: bb = default_bb @@ -495,8 +468,7 @@ novirtual class MatchGenMixin: # 构建 SwitchCase 链表(非 default case 且有值) if is_def == 0 and cv is not None: - sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case( - pool, cv, bb) + sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(pool, cv, bb) if sc is not None: if sw_head is None: sw_head = sc @@ -525,8 +497,7 @@ novirtual class MatchGenMixin: # 结构性不可达。故不等即 fail-fast,打印类名/查表名/应提交数/实际数/ # 各未取到值臂的 序号(变体名,tag),便于定位变体表失配。 if need_case != sw_count: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REnum match 分派丢失 case:class='{renum_name}'(查表名='{tag_cls_bare}')应提交 {need_case} 个 case,实际提交 {sw_count} 个;未取到值的臂:{miss_buf}", "InternalCompilerError") llvmlite.build_switch(builder, tag_val, default_bb, sw_head, sw_count) @@ -551,8 +522,7 @@ novirtual class MatchGenMixin: # 取 BB bb_addr: sizet = bb_arr[i] - case_bb: rawptr[llvmlite.BasicBlock] = ( - rawptr[llvmlite.BasicBlock])(bb_addr) + case_bb: rawptr[llvmlite.BasicBlock] = (rawptr[llvmlite.BasicBlock])(bb_addr) is_def: int = def_arr[i] nb: int = nb_arr[i] @@ -570,9 +540,7 @@ novirtual class MatchGenMixin: # 变体字段绑定(MatchClass) if pat is not None and pat.kind() == ast.ASTKind.MatchClass \ and renum_entry is not None and renum_ty is not None: - self._bind_variant_fields( - pat, renum_name, renum_entry, renum_ty, - subject_ptr, trans, pool, builder) + self._bind_variant_fields(pat, renum_name, renum_entry, renum_ty, subject_ptr, trans, pool, builder) # 翻译 case body body_list: list[ast.AST*]* = mc.children @@ -619,8 +587,7 @@ novirtual class MatchGenMixin: if def_arr[di] == 1: dcase: ast.AST* = cases_list.get(di) if dcase is not None: - dmc: rawptr[ast.MatchCase] = ( - rawptr[ast.MatchCase])(dcase) + dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dcase) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH) # dbody 预声明+重赋值会使 .get 误分派成 list[int].get # (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃, @@ -674,13 +641,11 @@ novirtual class MatchGenMixin: return # bitcast subject_ptr 到 renum_ptr_ty(确保 GEP 类型匹配) renum_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_ty) - casted_ptr: llvmlite.Value* = llvmlite.build_bitcast( - builder, subject_ptr, renum_ptr_ty) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, subject_ptr, renum_ptr_ty) if casted_ptr is None: casted_ptr = subject_ptr pn: sizet = len(pats) - j: int = 0 - while j < pn: + for j in range(pn): sub_pat: ast.AST* = pats.get(j) if sub_pat is not None and sub_pat.kind() == ast.ASTKind.MatchAs: ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](sub_pat) @@ -694,8 +659,7 @@ novirtual class MatchGenMixin: # class_name 用 CSizeT 指针值比较:必须传 renum_entry.Name # (注册时 _update_renum_alias_class_ptr 统一后的 perm_pool 指针); # renum_name(AnnotClassName 等)是不同指针,恒不匹配 → 误报 fail-fast。 - alt_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias( - renum_entry.Name, bind_name) + alt_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(renum_entry.Name, bind_name) if alt_idx >= 1: payload_idx = alt_idx else: @@ -703,34 +667,20 @@ novirtual class MatchGenMixin: # (node 在本函数不存在——参数是 pat/sub_pat,用 sub_pat # 定位到具体 MatchAs 模式;TPC Python 语义下未定义名只在 # 运行时求值才报错,TPV 惰性编译方法体时即 NameError) - self.Gen.TypeGenErr.fatal_error( - sub_pat, - f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败", "TypeError") # 获取字段类型 - fe: GenTypes.FieldEntry* = ( - self.Gen.StructGen._get_field_entry( - renum_entry, payload_idx)) + fe: GenTypes.FieldEntry* = (self.Gen.StructGen._get_field_entry(renum_entry, payload_idx)) field_ty: llvmlite.LLVMType* = None if fe is not None: field_ty = fe.Ty if field_ty is None: # fail-fast: 变体字段类型缺失,禁止兜底 i8 - self.Gen.TypeGenErr.fatal_error( - sub_pat, - f"REnum 变体字段类型缺失: {bind_name}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段类型缺失: {bind_name}", "TypeError") # GEP 取字段地址 - elem_ptr: llvmlite.Value* = ( - llvmlite.build_gep_struct( - builder, renum_ty, field_ty, - casted_ptr, payload_idx)) + elem_ptr: llvmlite.Value* = llvmlite.build_gep_struct(builder, renum_ty, field_ty,casted_ptr, payload_idx) if elem_ptr is None: # fail-fast: 变体字段地址计算失败 - self.Gen.TypeGenErr.fatal_error( - sub_pat, - f"REnum 变体字段 '{bind_name}' 地址计算失败", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sub_pat, f"REnum 变体字段 '{bind_name}' 地址计算失败", "TypeError") # 变体成员实际类型(对齐 TPC class_members):注册时别名表存了成员 # 注解解析出的类型(perm_pool 深拷贝),用它把槽位地址 bitcast 成 # Ptr(成员类型),使绑定变量按成员类型读 payload(否则按槽位 i64 读 → @@ -742,19 +692,14 @@ novirtual class MatchGenMixin: vnt_m: str = self._extract_variant_name_from_cls(pat) if vnt_m is not None and renum_entry is not None \ and renum_entry.Name is not None: - mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty( - renum_entry.Name, vnt_m, payload_idx) + mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty(renum_entry.Name, vnt_m, payload_idx) if mem_ty_m is not None: - mem_ptr_m: llvmlite.LLVMType* = llvmlite.Ptr( - pool, mem_ty_m) + mem_ptr_m: llvmlite.LLVMType* = llvmlite.Ptr(pool, mem_ty_m) if mem_ptr_m is not None: - cast_m: llvmlite.Value* = llvmlite.build_bitcast( - builder, elem_ptr, mem_ptr_m) + cast_m: llvmlite.Value* = llvmlite.build_bitcast(builder, elem_ptr, mem_ptr_m) if cast_m is not None: elem_ptr = cast_m - self.Gen.VarGen.define_var( - trans.SymTab, bind_name, elem_ptr) - j = j + 1 + self.Gen.VarGen.define_var(trans.SymTab, bind_name, elem_ptr) # ============================================================ # _seq_cmp_eq - 序列匹配元素相等比较 @@ -842,12 +787,10 @@ novirtual class MatchGenMixin: # 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式) elts_inl: list[ast.AST*]* = elts elt: ast.AST* = elts_inl.get(ei) - sv: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, elt, + sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, elt, trans._funcs, trans._func_count, trans) if sv is None: - self.Gen.TypeGenErr.fatal_error( - elt, f"match 序列元素 {ei} 翻译失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(elt, f"match 序列元素 {ei} 翻译失败", "TypeError") subj_vals[ei] = sizet(sv) # 2. 创建 default/end BB @@ -857,11 +800,9 @@ novirtual class MatchGenMixin: if name_buf is None: return 0 viperlib.snprintf(name_buf, 32, "match.seq.default.%d", cnt) - default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) viperlib.snprintf(name_buf, 32, "match.seq.end.%d", cnt) - end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) # 3. 第一遍:收集 case 信息(check/body BB、default 标记、nobreak、guard) cases_list: list[ast.AST*]* = node.cases @@ -887,10 +828,7 @@ novirtual class MatchGenMixin: # 否则 case 数超 MAX_MATCH_CASES 会越界写穿 pool 相邻块。超限直接 # fail-fast,不静默丢弃 case。 if collected >= MAX_MATCH_CASES: - self.Gen.TypeGenErr.fatal_error( - node, - f"match case 数量超过上限 MAX_MATCH_CASES={MAX_MATCH_CASES}", - "OverflowError") + self.Gen.TypeGenErr.fatal_error(node, f"match case 数量超过上限 MAX_MATCH_CASES={MAX_MATCH_CASES}", "OverflowError") break case_node: ast.AST* = cases_list.get(i) if case_node is None or case_node.kind() != ast.ASTKind.MatchCase: @@ -907,8 +845,7 @@ novirtual class MatchGenMixin: is_def = 1 elif pk != ast.ASTKind.MatchSequence: # fail-fast:序列匹配只接受 MatchSequence / 顶层 _ 通配 - self.Gen.TypeGenErr.fatal_error( - pat, "序列匹配 case 只支持 (元素) 或 _ 模式", "TypeError") + self.Gen.TypeGenErr.fatal_error(pat, "序列匹配 case 只支持 (元素) 或 _ 模式", "TypeError") if is_def == 1: has_default = 1 check_arr[collected] = 0 @@ -917,11 +854,9 @@ novirtual class MatchGenMixin: if collected >= MAX_MATCH_CASES: break viperlib.snprintf(name_buf, 32, "match.seq.check.%d.%d", cnt, i) - cbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + cbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) viperlib.snprintf(name_buf, 32, "match.seq.body.%d.%d", cnt, i) - bbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + bbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) check_arr[collected] = sizet(cbb) body_arr[collected] = sizet(bbb) if first_check < 0: @@ -957,8 +892,7 @@ novirtual class MatchGenMixin: cond: llvmlite.Value* = None cnode: ast.AST* = cases_list.get(ci) mc2: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](cnode) - ms: rawptr[ast.MatchSequence] = ( - rawptr[ast.MatchSequence])(mc2.pattern) + ms: rawptr[ast.MatchSequence] = (rawptr[ast.MatchSequence])(mc2.pattern) pats: list[ast.AST*]* = None if ms is not None: pats = ms.patterns @@ -978,14 +912,10 @@ novirtual class MatchGenMixin: continue pk1: int = pat1.kind() if pk1 == ast.ASTKind.MatchValue: - mv: rawptr[ast.MatchValue] = ( - rawptr[ast.MatchValue])(pat1) - pv: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, mv.value, - trans._funcs, trans._func_count, trans) + mv: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(pat1) + pv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans) if pv is None: - self.Gen.TypeGenErr.fatal_error( - pat1, f"序列模式元素 {pi} 翻译失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(pat1, f"序列模式元素 {pi} 翻译失败", "TypeError") sv1: llvmlite.Value* = llvmlite.Value*(subj_vals[pi]) c1: llvmlite.Value* = self._seq_cmp_eq(trans, builder, sv1, pv) if c1 is None: @@ -1000,31 +930,25 @@ novirtual class MatchGenMixin: continue # _ 通配:恒真 if ma2.name is not None: # fail-fast:序列模式变量绑定暂不支持 - self.Gen.TypeGenErr.fatal_error( - pat1, "序列模式变量绑定暂不支持", "NotImplementedError") + self.Gen.TypeGenErr.fatal_error(pat1, "序列模式变量绑定暂不支持", "NotImplementedError") elif pk1 == ast.ASTKind.MatchStar: continue # 剩余元素通配:恒真 else: - self.Gen.TypeGenErr.fatal_error( - pat1, "序列模式不支持的 pattern 类型", "TypeError") + self.Gen.TypeGenErr.fatal_error(pat1, "序列模式不支持的 pattern 类型", "TypeError") # guard(若有):匹配成立且 guard 非零 g_addr: sizet = guard_arr[ci] if g_addr != 0: gnode: ast.AST* = (ast.AST*)(g_addr) - gv: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, gnode, + gv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode, trans._funcs, trans._func_count, trans) if gv is None: - self.Gen.TypeGenErr.fatal_error( - gnode, "match guard 翻译失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(gnode, "match guard 翻译失败", "TypeError") gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty) if gbits == 1: g1: llvmlite.Value* = gv else: - gzero: llvmlite.Value* = llvmlite.const_int( - pool, gbits if gbits > 0 else 32, 0) - g1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, gv, gzero) + gzero: llvmlite.Value* = llvmlite.const_int(pool, gbits if gbits > 0 else 32, 0) + g1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, gv, gzero) if cond is None: cond = g1 else: @@ -1055,8 +979,7 @@ novirtual class MatchGenMixin: bbb3: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[ci]) llvmlite.position_at_end(builder, bbb3) cnode2: ast.AST* = cases_list.get(ci) - mc3: rawptr[ast.MatchCase] = ( - rawptr[ast.MatchCase])(cnode2) + mc3: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(cnode2) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH) body_list2: list[ast.AST*]* = mc3.children if body_list2 is not None: @@ -1098,8 +1021,7 @@ novirtual class MatchGenMixin: if def_arr[di] == 1: dnode: ast.AST* = cases_list.get(di) if dnode is not None: - dmc: rawptr[ast.MatchCase] = ( - rawptr[ast.MatchCase])(dnode) + dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dnode) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH) # dbody 预声明+重赋值会使 .get 误分派成 list[int].get # (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃, @@ -1170,11 +1092,9 @@ novirtual class MatchGenMixin: # fail-fast: 标签缓冲区分配失败 self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError") viperlib.snprintf(name_buf, 32, "match.default.%d", cnt) - default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) viperlib.snprintf(name_buf, 32, "match.end.%d", cnt) - end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) # 3. 收集 case 信息 cases_list: list[ast.AST*]* = node.cases @@ -1217,12 +1137,10 @@ novirtual class MatchGenMixin: pk: int = pat.kind() if pk == ast.ASTKind.MatchValue: mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat) - cv = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, mv.value, + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans) elif pk == ast.ASTKind.MatchSingleton: - ms: rawptr[ast.MatchSingleton] = ( - rawptr[ast.MatchSingleton])(pat) + ms: rawptr[ast.MatchSingleton] = (rawptr[ast.MatchSingleton])(pat) # None -> 0 cv = llvmlite.const_int32(pool, 0) elif pk == ast.ASTKind.MatchAs: @@ -1237,22 +1155,16 @@ novirtual class MatchGenMixin: first_pat: ast.AST* = pats.get(0) if first_pat is not None \ and first_pat.kind() == ast.ASTKind.MatchValue: - mv2: rawptr[ast.MatchValue] = ( - rawptr[ast.MatchValue])(first_pat) - cv = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, mv2.value, - trans._funcs, trans._func_count, trans) + mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(first_pat) + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv2.value, trans._funcs, trans._func_count, trans) elif pk == ast.ASTKind.MatchClass: # 本路径(非 REnum 分派)不为 class-pattern 臂产出 case 值 → 该臂被 # 静默丢弃、臂体不可达。若该 class-pattern 确实指向已注册 REnum # (_is_renum_class_name / _is_renum_by_entry 命中),说明是 REnum # 分派失配,必须 fail-fast 暴露,不得静默丢 case(禁止兜底掩盖)。 rnm_nr: str = self._extract_renum_name_from_cls(pat) - if rnm_nr is not None and ( - self.Gen.ClassGenEnum._is_renum_class_name(rnm_nr) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry(rnm_nr) != 0): - self.Gen.TypeGenErr.fatal_error( - pat, + if rnm_nr is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm_nr) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(rnm_nr) != 0): + self.Gen.TypeGenErr.fatal_error(pat, f"非 REnum 路径收到 REnum 变体模式 'case {rnm_nr}.*':case 值无法产出,该臂会被静默丢弃(REnum 分派失配)", "InternalCompilerError") @@ -1260,8 +1172,7 @@ novirtual class MatchGenMixin: if collected >= MAX_MATCH_CASES: break viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i) - bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, func, name_buf) + bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf) else: bb = default_bb @@ -1276,8 +1187,7 @@ novirtual class MatchGenMixin: collected = collected + 1 if is_def == 0 and cv is not None: - sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case( - pool, cv, bb) + sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(pool, cv, bb) if sc is not None: if sw_head is None: sw_head = sc @@ -1351,8 +1261,7 @@ novirtual class MatchGenMixin: if def_arr[di] == 1: dcase: ast.AST* = cases_list.get(di) if dcase is not None: - dmc: rawptr[ast.MatchCase] = ( - rawptr[ast.MatchCase])(dcase) + dmc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(dcase) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH) # dbody 预声明+重赋值会使 .get 误分派成 list[int].get # (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃, diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index 48447d5..871ad27 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -14,24 +14,17 @@ import lib.core.Gen.Translator as HT import lib.core.Gen.Type.TypeSpec as TSpec import lib.core.CompilerFactory as CompilerFactory import lib.Projectrans.Config as Config + + # ============================================================ -# StmtGenCifMixin - StmtGen 拆分 1/3:CIf 编译期求值 + NewXxxHandle 工厂 -# -# 按功能域从 StmtGenMixin.vp 拆出(500~1500 行/文件架构重构,试点): -# 簇 B(CIf 宏求值)+ NewIfHandle/NewWhileHandle/NewForHandle/ -# NewReturnHandle/NewMatchHandle 工厂。 -# 全部字段保留在本最底层父类(顺序 CifEvalOk->EnumTable->EnumCount-> -# DiagStmtCount 与 Generator 组合布局一致,见下方字段注释)。 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 +# StmtGenCifMixin - CIf 编译期求值 + NewXxxHandle 工厂 # ============================================================ # ============================================================ # StmtGenCifMixin - CIf 求值 + 工厂(最底层父类) # ============================================================ -@t.NoVTable -class StmtGenCifMixin: +novirtual class StmtGenCifMixin: """CIf 编译期求值 + NewXxxHandle 工厂(StmtGen 拆分 1/3,最底层)""" # --- 编译期 CIf 求值状态(原 HandlesIf._g_cif_eval_ok) --- @@ -135,8 +128,7 @@ class StmtGenCifMixin: if self.Gen.TypeGenCDef.is_cdefine_found() != 0: self.CifEvalOk = 1 return v - v2: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine( - pool, name, trans._from_imports, trans._imported_modules) + v2: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, name, trans._from_imports, trans._imported_modules) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: self.CifEvalOk = 1 return v2 @@ -167,8 +159,7 @@ class StmtGenCifMixin: # 跨模块: 确定真实模块名(解析 from_imports 别名) real_mod: str = vn.id if trans._from_imports is not None: - resolved: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, vn.id, 0) + resolved: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, vn.id, 0) if resolved is not None: rm_len: sizet = 0 while resolved[rm_len] != ' ' and resolved[rm_len] != '\0' and resolved[rm_len] != ':': @@ -485,8 +476,7 @@ class StmtGenCifMixin: rt_tail: llvmlite.Function* = None rvi: sizet for rvi in range(rt_n): - ev_i: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, rtp_elts.get(rvi), + ev_i: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rtp_elts.get(rvi), trans._funcs, trans._func_count, trans) if ev_i is None: rt_val_ok = 0 @@ -519,8 +509,7 @@ class StmtGenCifMixin: rvi3: sizet for rvi3 in range(rt_n): rv3: llvmlite.Value* = llvmlite.Value*(rt_vals[rvi3]) - rfp: llvmlite.Value* = llvmlite.build_gep_struct( - builder, rt_struct_ty, rv3.Ty, rt_tmp, rvi3) + rfp: llvmlite.Value* = llvmlite.build_gep_struct(builder, rt_struct_ty, rv3.Ty, rt_tmp, rvi3) if rfp is None: rt_val_ok = 0 break @@ -535,8 +524,7 @@ class StmtGenCifMixin: ret_nm: ast.Name* = ast.Name*(rt.value) if ret_nm is not None and ret_nm.id is not None \ and string.strcmp(ret_nm.id, "self") == 0: - self_ptr: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, "self") + self_ptr: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "self") if self_ptr is not None: # 检查 self_ptr 是否是 Ptr(Ptr(...))(alloca 存储指针) self_pointee_ty: llvmlite.LLVMType* = None @@ -560,8 +548,7 @@ class StmtGenCifMixin: # 构造(`-> Stack[int]` 里 `return Stack()`)用 CurFuncRetAnnot # 里的类型实参特化;仅该直接值生效(identity 判定在 CallGenCtor)。 trans.CurRetNode = rt.value - val = self.Gen.ExprGen.translate_value( - builder, pool, mod, rt.value, + val = self.Gen.ExprGen.translate_value(builder, pool, mod, rt.value, trans._funcs, trans._func_count, trans, ret_val_ty, "返回注解") trans.CurRetNode = None @@ -741,8 +728,7 @@ class StmtGenCifMixin: return 0 # 1. 求值条件表达式 - cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, if_node.test, + cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, if_node.test, trans._funcs, trans._func_count, trans) # 2. 转换为 i1 条件 @@ -756,12 +742,10 @@ class StmtGenCifMixin: elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0: # 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type") null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null") - cond_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cond_val, null_cond) + cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond) else: zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) - cond_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cond_val, zero) + cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero) # 3. 创建基本块(使用 trans._label_counter 生成唯一标签名,不与 SSA 名共享) cnt: int = trans._label_counter @@ -898,8 +882,7 @@ class StmtGenCifMixin: # 3. cond 块: 求值条件,条件分支 llvmlite.position_at_end(builder, cond_bb) - cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, while_node.test, + cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, while_node.test, trans._funcs, trans._func_count, trans) if cond_val is None: # fail-fast: while 条件表达式翻译失败 @@ -912,12 +895,10 @@ class StmtGenCifMixin: elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0: # 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type") null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null") - cond_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cond_val, null_cond) + cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond) else: zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) - cond_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cond_val, zero) + cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero) llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb) # 4. body 块: 翻译循环体,跳回 cond @@ -1048,7 +1029,7 @@ class StmtGenCifMixin: if builder is None or func is None: return 0 - for_node: rawptr[ast.For] = rawptr[ast.For](node) + for_node: ast.For* = ast.For*(node) # 1. 获取循环变量(Name 单变量 / Tuple 多变量) target: ast.AST* = for_node.target @@ -1125,16 +1106,14 @@ class StmtGenCifMixin: if iter_node.kind() == ast.ASTKind.Name and trans is not None: nm_lst: ast.Name* = ast.Name*(iter_node) if nm_lst.id is not None: - ve_lst: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_lst.id) + ve_lst: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_lst.id) lst_annot: str = self.Gen.VarGen.var_annot_class_name(ve_lst) if lst_annot is not None: # dict 容器变量:按 __count__/__keys__ 布局迭代(__iter__ 协议内联) # [S4] 容器基名精确比较(SpecTypeNameBaseIs):原 strstr("dict") 子串匹配 # 会误命中任何含 "dict" 的类名(如 MyDictHelper)。 if TSpec.SpecTypeNameBaseIs(lst_annot, "dict") != 0: - lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, iter_node, + lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if lst_val is not None and lst_val.Ty is not None \ and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0: @@ -1142,53 +1121,42 @@ class StmtGenCifMixin: # [S4] 同上:原 strstr("list") 会误命中 playlist / GSList 等; # 非 list 基名的用户类改由下方 OOP __iter__/__next__ 路径处理(更正确)。 if TSpec.SpecTypeNameBaseIs(lst_annot, "list") != 0: - lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, iter_node, - trans._funcs, trans._func_count, trans) + lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if lst_val is not None and lst_val.Ty is not None \ and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0: return self._handle_list_iter(trans, for_node, var_name, lst_val) # OOP iter 协议:迭代源是类对象且类有 __iter__/__next__ 方法 → # 走 __iter__/__next__ 调用迭代(对齐 TPC HandlesFor.py L142-166 # _HandleForIterLlvm)。dict/list 是内置泛型容器已在上方内联处理。 - ov_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, iter_node, + ov_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if ov_val is not None and ov_val.Ty is not None \ and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0: - ov_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value( - ov_val) + ov_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(ov_val) if ov_st is not None: ov_cn: str = self.Gen.StructGen.get_class_name_by_type(pool, ov_st) if ov_cn is not None: oi_lookup: str = pool.alloc(128) if oi_lookup is not None: viperlib.snprintf(oi_lookup, 128, "%s.__iter__", ov_cn) - oi_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - trans.Module, oi_lookup) + oi_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, oi_lookup) if oi_fn is not None: on_lookup: str = pool.alloc(128) if on_lookup is not None: viperlib.snprintf(on_lookup, 128, "%s.__next__", ov_cn) - on_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - trans.Module, on_lookup) + on_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(trans.Module, on_lookup) if on_fn is not None: - return self._handle_oop_iter( - trans, for_node, var_name, ov_cn, ov_val) + return self._handle_oop_iter(trans, for_node, var_name, ov_cn, ov_val) # 其它不支持的字面量:fast-fail 显式报错, # 避免 translate_value 触发 list[T] 特化崩溃或语义歧义。 ik: int = iter_node.kind() if ik == ast.ASTKind.Constant: cn_ik: ast.Constant* = ast.Constant*(iter_node) if cn_ik.const_kind != ast.CONST_STR: - self.Gen.TypeGenErr.fatal_error( - iter_node, - "for 迭代不支持该常量(仅支持字符串、数组、列表字面量、range())") + self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持该常量(仅支持字符串、数组、列表字面量、range())") elif ik == ast.ASTKind.Dict or ik == ast.ASTKind.Set or ik == ast.ASTKind.Tuple \ or ik == ast.ASTKind.SetComp or ik == ast.ASTKind.DictComp: - self.Gen.TypeGenErr.fatal_error( - iter_node, - "for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量") + self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量") return self._handle_ptr_iter(trans, for_node, var_name) call: ast.Call* = ast.Call*(iter_node) @@ -1208,29 +1176,21 @@ class StmtGenCifMixin: # fail-fast: range 无参数,立即终止 self.Gen.TypeGenErr.fatal_error(call, "range 需要至少一个参数", "SyntaxError") elif arg_count == 1: - stop_val = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, args.get(0), - trans._funcs, trans._func_count, trans) + stop_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(0), trans._funcs, trans._func_count, trans) if stop_val is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(args.get(0), "range 参数翻译失败", "TypeError") elif arg_count >= 2: - start_val = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, args.get(0), - trans._funcs, trans._func_count, trans) + start_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(0), trans._funcs, trans._func_count, trans) if start_val is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(args.get(0), "range 参数翻译失败", "TypeError") - stop_val = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, args.get(1), - trans._funcs, trans._func_count, trans) + stop_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(1), trans._funcs, trans._func_count, trans) if stop_val is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(args.get(1), "range 参数翻译失败", "TypeError") if arg_count >= 3: - step_val = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, args.get(2), - trans._funcs, trans._func_count, trans) + step_val = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, args.get(2), trans._funcs, trans._func_count, trans) if step_val is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(args.get(2), "range 参数翻译失败", "TypeError") @@ -1330,8 +1290,7 @@ class StmtGenCifMixin: # 命中父函数同名变量(如父函数自己的循环计数器 i)→ 循环计数写到 # 父函数存储 → 跨函数 SSA 错乱(llc "instruction expected to be # numbered",Terminal _cmd_cd 的 for i in range(1,64) 根因)。 - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: # 用 _alloca_at_entry:alloca 放函数入口块,保证支配性 @@ -1343,8 +1302,7 @@ class StmtGenCifMixin: # 位宽随 range 参数类型(loop_store_ty),不再固定 i32: # uint64 上界 → i64 alloca,避免 trunc i64→i32 丢失高位。 var_alloca = self.Gen.VarGen._alloca_at_entry(builder, loop_store_ty) - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 获取循环变量的实际元素类型(alloca 是指针类型,需解引用 Pointee) @@ -1416,8 +1374,7 @@ class StmtGenCifMixin: range_cmp_op = llvmlite.ICMP_UGT else: range_cmp_op = llvmlite.ICMP_ULT - cond_i1: llvmlite.Value* = llvmlite.build_icmp( - builder, range_cmp_op, cmp_lhs, cmp_rhs) + cond_i1: llvmlite.Value* = llvmlite.build_icmp(builder, range_cmp_op, cmp_lhs, cmp_rhs) llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb) # 9. body 块: 翻译循环体,跳到 incr @@ -1517,8 +1474,7 @@ class StmtGenCifMixin: if k == ast.ASTKind.Name: nm_s: ast.Name* = ast.Name*(src) if nm_s.id is not None and trans is not None: - ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_s.id) + ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_s.id) sq_annot: str = self.Gen.VarGen.var_annot_class_name(ve_s) if sq_annot is not None: # [S4] 容器基名精确比较(原 strstr("list") 子串匹配会误命中 playlist 等) @@ -1528,7 +1484,7 @@ class StmtGenCifMixin: return 0 def _build_seq_loop(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, t1: str, t2: str, src1: ast.AST*, src2: ast.AST*, @@ -1570,50 +1526,37 @@ class StmtGenCifMixin: if cargs1 is not None: n1: sizet = len(cargs1) if n1 >= 1: - sv: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs1.get(0), + sv: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(0), trans._funcs, trans._func_count, trans) if sv is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs1.get(0), "range 参数翻译失败", "TypeError") r1_stop = self.Gen.ExprGenBase.coerce_to_type(builder, sv, i64_ty, cargs1.get(0)) if n1 >= 2: - sv2: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs1.get(1), - trans._funcs, trans._func_count, trans) + sv2: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(1), trans._funcs, trans._func_count, trans) if sv2 is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs1.get(1), "range 参数翻译失败", "TypeError") r1_start = self.Gen.ExprGenBase.coerce_to_type(builder, sv2, i64_ty, cargs1.get(1)) if n1 >= 3: - sv3: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs1.get(2), - trans._funcs, trans._func_count, trans) + sv3: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(2), trans._funcs, trans._func_count, trans) if sv3 is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs1.get(2), "range 参数翻译失败", "TypeError") r1_step = self.Gen.ExprGenBase.coerce_to_type(builder, sv3, i64_ty, cargs1.get(2)) elif kind1 == GenTypes.SEQ_KIND_STR: elem1_ty = i8_ty - s1_ptr = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, src1, - trans._funcs, trans._func_count, trans) + s1_ptr = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src1, trans._funcs, trans._func_count, trans) if s1_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源翻译失败") elif kind1 == GenTypes.SEQ_KIND_LIST: elem1_ty = i8_ptr_ty - l1_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, src1, - trans._funcs, trans._func_count, trans) - if l1_obj is None or l1_obj.Ty is None \ - or self.Gen.ExprGenBase.is_ptr_type(l1_obj.Ty) == 0: + l1_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src1, trans._funcs, trans._func_count, trans) + if l1_obj is None or l1_obj.Ty is None or self.Gen.ExprGenBase.is_ptr_type(l1_obj.Ty) == 0: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: list 源不是指针类型") - l1_count = llvmlite.build_load(builder, i64_ty, - llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 1))) - l1_data = llvmlite.build_load(builder, i8_ptr_ty, - llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 0))) - l1_esize = llvmlite.build_load(builder, i64_ty, - llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 4))) + l1_count = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 1))) + l1_data = llvmlite.build_load(builder, i8_ptr_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 0))) + l1_esize = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l1_obj, llvmlite.const_int64(pool, 4))) # ---- 源 2 准备(zip)---- kind2: int = 0 @@ -1640,50 +1583,36 @@ class StmtGenCifMixin: if cargs2 is not None: n2: sizet = len(cargs2) if n2 >= 1: - svz: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs2.get(0), - trans._funcs, trans._func_count, trans) + svz: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(0), trans._funcs, trans._func_count, trans) if svz is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs2.get(0), "range 参数翻译失败", "TypeError") r2_stop = self.Gen.ExprGenBase.coerce_to_type(builder, svz, i64_ty, cargs2.get(0)) if n2 >= 2: - svz2: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs2.get(1), - trans._funcs, trans._func_count, trans) + svz2: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(1), trans._funcs, trans._func_count, trans) if svz2 is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs2.get(1), "range 参数翻译失败", "TypeError") r2_start = self.Gen.ExprGenBase.coerce_to_type(builder, svz2, i64_ty, cargs2.get(1)) if n2 >= 3: - svz3: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, cargs2.get(2), - trans._funcs, trans._func_count, trans) + svz3: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs2.get(2), trans._funcs, trans._func_count, trans) if svz3 is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs2.get(2), "range 参数翻译失败", "TypeError") r2_step = self.Gen.ExprGenBase.coerce_to_type(builder, svz3, i64_ty, cargs2.get(2)) elif kind2 == GenTypes.SEQ_KIND_STR: elem2_ty = i8_ty - s2_ptr = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, src2, - trans._funcs, trans._func_count, trans) + s2_ptr = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src2, trans._funcs, trans._func_count, trans) if s2_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源 2 翻译失败") elif kind2 == GenTypes.SEQ_KIND_LIST: elem2_ty = i8_ptr_ty - l2_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, src2, - trans._funcs, trans._func_count, trans) - if l2_obj is None or l2_obj.Ty is None \ - or self.Gen.ExprGenBase.is_ptr_type(l2_obj.Ty) == 0: + l2_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, src2, trans._funcs, trans._func_count, trans) + if l2_obj is None or l2_obj.Ty is None or self.Gen.ExprGenBase.is_ptr_type(l2_obj.Ty) == 0: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: list 源 2 不是指针类型") - l2_count = llvmlite.build_load(builder, i64_ty, - llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 1))) - l2_data = llvmlite.build_load(builder, i8_ptr_ty, - llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 0))) - l2_esize = llvmlite.build_load(builder, i64_ty, - llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 4))) + l2_count = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 1))) + l2_data = llvmlite.build_load(builder, i8_ptr_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 0))) + l2_esize = llvmlite.build_load(builder, i64_ty, llvmlite.build_gep(builder, i64_ty, l2_obj, llvmlite.const_int64(pool, 4))) # ---- 循环变量 alloca ---- # t1: enumerate → 序号 (i32);zip → 源 1 元素 @@ -1860,7 +1789,7 @@ class StmtGenCifMixin: # end: # ============================================================ def _handle_ptr_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str) -> int: """指针迭代: for x in ptr: 直到解引用为空""" pool: memhub.MemBuddy* = trans.Pool @@ -1868,9 +1797,7 @@ class StmtGenCifMixin: func: llvmlite.Function* = trans._cur_func # 翻译迭代器表达式,获取指针值 - ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, for_node.iter, - trans._funcs, trans._func_count, trans) + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, for_node.iter, trans._funcs, trans._func_count, trans) if ptr_val is None: self.Gen.TypeGenErr.fatal_error(for_node, "指针迭代: 无法翻译迭代器表达式") @@ -1904,13 +1831,11 @@ class StmtGenCifMixin: i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 创建循环变量 alloca(存储元素值) - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty) - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 创建隐式 index 变量,初始为 0 @@ -1940,8 +1865,7 @@ class StmtGenCifMixin: # cond 块: load index, GEP, load elem, 空值判定(整数==0 / 指针==null / 浮点==0.0) llvmlite.position_at_end(builder, cond_bb) cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca) - elem_ptr: llvmlite.Value* = llvmlite.build_gep( - builder, elem_ty, ptr_val, cur_idx) + elem_ptr: llvmlite.Value* = llvmlite.build_gep(builder, elem_ty, ptr_val, cur_idx) cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr) is_null: llvmlite.Value* = None if elem_is_ptr2 != 0: @@ -2024,7 +1948,7 @@ class StmtGenCifMixin: # end: # ============================================================ def _handle_array_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str, array_val: llvmlite.Value*) -> int: """数组迭代: for x in arr: 按数组长度迭代""" @@ -2054,13 +1978,11 @@ class StmtGenCifMixin: i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 循环变量 alloca(存储元素值) - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty) - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 隐式 index 变量,初始为 0 @@ -2093,16 +2015,14 @@ class StmtGenCifMixin: llvmlite.position_at_end(builder, cond_bb) cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca) count_val: llvmlite.Value* = llvmlite.const_int32(pool, elem_count) - in_bounds: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_SLT, cur_idx, count_val) + in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, elem_check_bb, end_bb) # elem_check 块: GEP(0, idx) → load elem → 空值判定(NULL 终止) # 用户语义:整数/指针/浮点元素按"解引用为空"提前终止(如 split 尾哨兵 # 的 str 数组),同时保留长度上限防越界读;聚合元素只按长度迭代。 llvmlite.position_at_end(builder, elem_check_bb) - elem_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, arr_ty, elem_ty, arr_tmp, cur_idx) + elem_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, arr_tmp, cur_idx) cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr) elem_bits_a: int = self.Gen.ExprGenBase.get_llvm_type_bits(elem_ty) elem_ptr_a: int = self.Gen.ExprGenBase.is_ptr_type(elem_ty) @@ -2170,7 +2090,7 @@ class StmtGenCifMixin: # 元素类型取第一个元素的值类型,其余元素 coerce 到该类型。 # ============================================================ def _handle_list_literal_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str, list_node: ast.AST*) -> int: """列表字面量迭代: for x in [a, b, c]: 按元素顺序迭代""" @@ -2193,8 +2113,7 @@ class StmtGenCifMixin: # 列表元素计数 > 实际填充 ⇒ 该槽为裸 0 ⇒ 上层某处产生了空 AST 元素。 # 不给下游 translate_value 的守卫吞掉(那会静默跳过 store、产出错值),此处响亮失败。 if first_el is None: - self.Gen.TypeGenErr.fatal_error( - for_node, + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到空 AST 元素:第 0 个元素为裸空指针(0)," f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", "ValueError") @@ -2202,14 +2121,12 @@ class StmtGenCifMixin: # @t.CVTable 类对象首字即 vptr,为 0 时下游任意虚调用(kind()/dump())都会 # `load [0+slot]` ⇒ ASan READ at 0x0。读首字的唯一可用写法是 c.Deref((uint64*)(p))。 if c.Deref((uint64*)(first_el)) == 0: - self.Gen.TypeGenErr.fatal_error( - for_node, + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 0 个元素指针非 0" f"(地址 {uint64(first_el)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", "ValueError") - first_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, first_el, + first_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, first_el, trans._funcs, trans._func_count, trans) if first_val is None or first_val.Ty is None: self.Gen.TypeGenErr.fatal_error(first_el, "列表字面量迭代: 无法确定元素类型") @@ -2221,8 +2138,7 @@ class StmtGenCifMixin: tmp_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, arr_ty) if tmp_alloca is None: self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 临时数组分配失败") - first_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, 0)) + first_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, 0)) if first_ptr is not None: llvmlite.build_store(builder, first_val, first_ptr) # 写其余元素(coerce 到 elem_ty) @@ -2231,27 +2147,21 @@ class StmtGenCifMixin: el_node: ast.AST* = elts.get(i) # 显式判空(同上,用 `is None`):不得让空元素被 translate_value 的 None 守卫静默吞掉。 if el_node is None: - self.Gen.TypeGenErr.fatal_error( - for_node, + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到空 AST 元素:第 {i} 个元素为裸空指针(0)," f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", "ValueError") # 对象有效性校验(vptr 非 0),同第 0 元素处:同族"取元素后即用"路径。 if c.Deref((uint64*)(el_node)) == 0: - self.Gen.TypeGenErr.fatal_error( - for_node, + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 {i} 个元素指针非 0" f"(地址 {uint64(el_node)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", "ValueError") - el_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, el_node, - trans._funcs, trans._func_count, trans) + el_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, el_node, trans._funcs, trans._func_count, trans) if el_val is not None: el_val = self.Gen.ExprGenBase.coerce_to_type(builder, el_val, elem_ty, el_node) - el_ptr: llvmlite.Value* = llvmlite.build_gep_array( - builder, arr_ty, elem_ty, tmp_alloca, - llvmlite.const_int32(pool, i)) + el_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, i)) if el_ptr is not None: llvmlite.build_store(builder, el_val, el_ptr) i += 1 @@ -2291,7 +2201,7 @@ class StmtGenCifMixin: # end: # ============================================================ def _handle_list_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str, list_val: llvmlite.Value*) -> int: """list[T] 容器迭代: for v in lst: 按 __count__ 动态长度迭代""" @@ -2304,20 +2214,17 @@ class StmtGenCifMixin: i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 读取 __count__ (偏移 8, GEP index 1) - cnt_ptr: llvmlite.Value* = llvmlite.build_gep( - builder, i64_ty, list_val, llvmlite.const_int64(pool, 1)) + cnt_ptr: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 1)) if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "list 迭代: 无法定位 __count__") count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr) # 循环变量 alloca(元素类型 i8*,与 list.get 内联一致) - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty) - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 隐式 index 变量 (i64,与 __count__ 类型对齐) @@ -2346,21 +2253,17 @@ class StmtGenCifMixin: # cond 块: load index, icmp slt idx, count llvmlite.position_at_end(builder, cond_bb) cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca) - in_bounds: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_SLT, cur_idx, count_val) + in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb) # body 块: __data__ + idx*__elem_size__ → load 元素 → store to var llvmlite.position_at_end(builder, body_bb) - dpp: llvmlite.Value* = llvmlite.build_gep( - builder, i64_ty, list_val, llvmlite.const_int64(pool, 0)) + dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 0)) data_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, dpp) - epp: llvmlite.Value* = llvmlite.build_gep( - builder, i64_ty, list_val, llvmlite.const_int64(pool, 4)) + epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, list_val, llvmlite.const_int64(pool, 4)) esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, epp) offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, esize) - elem_addr: llvmlite.Value* = llvmlite.build_gep( - builder, i8_ty, data_ptr, offset) + elem_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, data_ptr, offset) cur_elem: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, elem_addr) llvmlite.build_store(builder, cur_elem, var_alloca) @@ -2398,7 +2301,7 @@ class StmtGenCifMixin: return new_vars def _handle_dict_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str, dict_val: llvmlite.Value*) -> int: """dict 容器迭代: for key in d: 按 __count__/__keys__ 布局迭代 @@ -2417,20 +2320,17 @@ class StmtGenCifMixin: i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 读取 __count__(槽 2,字节偏移 16) - cnt_ptr: llvmlite.Value* = llvmlite.build_gep( - builder, i64_ty, dict_val, llvmlite.const_int64(pool, 2)) + cnt_ptr: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, dict_val, llvmlite.const_int64(pool, 2)) if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "dict 迭代: 无法定位 __count__") count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr) # 循环变量 alloca(元素类型 i8*,与 dict.__next__ 返回 str 一致) - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty) - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 隐式 index 变量 (i64,与 __count__ 类型对齐) @@ -2459,19 +2359,16 @@ class StmtGenCifMixin: # cond 块: load index, icmp slt idx, count llvmlite.position_at_end(builder, cond_bb) cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca) - in_bounds: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_SLT, cur_idx, count_val) + in_bounds: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb) # body 块: __keys__ + idx*8 → load key (i8*) → store to var llvmlite.position_at_end(builder, body_bb) - kpp: llvmlite.Value* = llvmlite.build_gep( - builder, i64_ty, dict_val, llvmlite.const_int64(pool, 0)) + kpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, dict_val, llvmlite.const_int64(pool, 0)) keys_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, kpp) eight_val: llvmlite.Value* = llvmlite.const_int64(pool, 8) key_offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, eight_val) - key_addr: llvmlite.Value* = llvmlite.build_gep( - builder, i8_ty, keys_ptr, key_offset) + key_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, keys_ptr, key_offset) cur_key: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, key_addr) llvmlite.build_store(builder, cur_key, var_alloca) @@ -2535,7 +2432,7 @@ class StmtGenCifMixin: # VpiReader stub 声明同步该参数(_inject_method_declare)。 # ============================================================ def _handle_oop_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, var_name: str, class_name: str, obj_val: llvmlite.Value*) -> int: @@ -2557,11 +2454,9 @@ class StmtGenCifMixin: if iter_lookup is None: return 0 viperlib.snprintf(iter_lookup, 128, "%s.__iter__", class_name) - iter_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - mod, iter_lookup) + iter_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, iter_lookup) if iter_fn is None: - self.Gen.TypeGenErr.fatal_error( - for_node, f"OOP 迭代: 类 '{class_name}' 没有 __iter__ 方法") + self.Gen.TypeGenErr.fatal_error(for_node, f"OOP 迭代: 类 '{class_name}' 没有 __iter__ 方法") iter_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(iter_fn) iter_fn_name: str = llvmlite.function_get_name(iter_fn) if iter_ret_ty is None or iter_fn_name is None: @@ -2576,8 +2471,7 @@ class StmtGenCifMixin: if iter_self is None: return 0 iter_self.Next = None - iter_result: llvmlite.Value* = llvmlite.build_call( - builder, iter_fn_name, iter_self, 1, iter_ret_ty, 0) + iter_result: llvmlite.Value* = llvmlite.build_call(builder, iter_fn_name, iter_self, 1, iter_ret_ty, 0) if iter_result is None: return 0 @@ -2586,25 +2480,21 @@ class StmtGenCifMixin: if next_lookup is None: return 0 viperlib.snprintf(next_lookup, 128, "%s.__next__", class_name) - next_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - mod, next_lookup) + next_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, next_lookup) if next_fn is None: - self.Gen.TypeGenErr.fatal_error( - for_node, f"OOP 迭代: 类 '{class_name}' 没有 __next__ 方法") + self.Gen.TypeGenErr.fatal_error(for_node, f"OOP 迭代: 类 '{class_name}' 没有 __next__ 方法") next_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(next_fn) next_fn_name: str = llvmlite.function_get_name(next_fn) if next_ret_ty is None or next_fn_name is None: return 0 # 3. 循环变量 alloca(元素类型 = __next__ 返回类型) - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, var_name) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: var_alloca = self.Gen.VarGen._alloca_at_entry(builder, next_ret_ty) if var_alloca is not None: - if self.Gen.VarGen.define_var( - trans.SymTab, var_name, var_alloca) == 0: + if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1 # 4. stop flag alloca(i1,初始 0) @@ -2649,8 +2539,7 @@ class StmtGenCifMixin: # 参数链表: arg1(iter).Next = arg2(flag);flag 独立 null 结尾防自链接 next_self.Next = flag_alloca flag_alloca.Next = None - next_val: llvmlite.Value* = llvmlite.build_call( - builder, next_fn_name, next_self, 2, next_ret_ty, 0) + next_val: llvmlite.Value* = llvmlite.build_call(builder, next_fn_name, next_self, 2, next_ret_ty, 0) if next_val is None: return 0 stop_val: llvmlite.Value* = llvmlite.build_load(builder, i1_ty, flag_alloca) @@ -2659,8 +2548,7 @@ class StmtGenCifMixin: flag_zero2: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty, 0, "0") continue_i1: llvmlite.Value* = None if flag_zero2 is not None: - continue_i1 = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, stop_val, flag_zero2) + continue_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, stop_val, flag_zero2) if continue_i1 is None: return 0 llvmlite.build_cond_br(builder, continue_i1, body_bb, end_bb) @@ -2694,7 +2582,7 @@ class StmtGenCifMixin: return new_vars def _handle_enumerate_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, t1: str, t2: str, call: ast.Call*) -> int: """enumerate 迭代: for i, v in enumerate(x)""" @@ -2706,7 +2594,7 @@ class StmtGenCifMixin: return self._build_seq_loop(trans, for_node, t1, t2, cargs.get(0), None, 1) def _handle_zip_iter(self, trans: HT.Translator*, - for_node: rawptr[ast.For], + for_node: ast.For*, t1: str, t2: str, call: ast.Call*) -> int: """zip 迭代: for a, b in zip(x, y)""" diff --git a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp index 9b3517b..fcc7026 100644 --- a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp @@ -18,26 +18,19 @@ import lib.core.Gen.GenApi as GenApi # ============================================================ # StmtGenDeclMixin - StmtGen 拆分 2/3:声明/枚举/nonlocal 访问 -# -# 按功能域从 StmtGenMixin.vp 拆出(500~1500 行/文件架构重构,试点): -# translate_global/nonlocal/expr_stmt/pre_scan、break/continue、 -# nonlocal 闭包 env 访问、枚举注册表。继承 StmtGenCifMixin。 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ # ============================================================ -# 常量(与 HandlesEnum 保持一致,本地副本避免跨模块 CDefine 查找 bug) +# 常量 # ============================================================ -ENUM_MAX: t.CDefine = 64 -ENUM_MEMBER_MAX: t.CDefine = 128 +define ENUM_MAX = 64 +define ENUM_MEMBER_MAX = 128 # ============================================================ # StmtGenDeclMixin - 声明/枚举/nonlocal(中层级) # ============================================================ -@t.NoVTable -class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): +novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """声明/枚举/nonlocal 访问(StmtGen 拆分 2/3,继承 Cif)""" def translate_global(self, trans: HT.Translator*, @@ -78,8 +71,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if nm.id is not None: # 查找父作用域中的变量 alloca,获取类型信息 var_ty: llvmlite.LLVMType* = None - var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, nm.id) + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) if var_alloca is not None and var_alloca.Ty is not None: var_ty = var_alloca.Ty.Pointee # Void 类型视为无效(Pointee 访问异常时可能返回 Void), @@ -127,11 +119,9 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # printf / print 走特殊路径(print 是类型感知格式化,不映射到 printf) if string.strcmp(func_name, "printf") == 0: - self.Gen.CallGenLeafKit.translate_printf_call( - trans.Pool, trans._cur_builder, trans.Module, cl, trans) + self.Gen.CallGenLeafKit.translate_printf_call(trans.Pool, trans._cur_builder, trans.Module, cl, trans) elif string.strcmp(func_name, "print") == 0: - self.Gen.CallGenLeafKit.translate_print_call( - trans.Pool, trans._cur_builder, trans.Module, cl, trans) + self.Gen.CallGenLeafKit.translate_print_call(trans.Pool, trans._cur_builder, trans.Module, cl, trans) else: # 通用函数调用(返回值丢弃) # M3:裸名调用**会话函数**(跨片段)时额外把返回值写进 ctx 结果区回显 @@ -147,20 +137,15 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): sfn_ent: rawptr[GenTypes.ReplFuncEntry] = \ self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) if sfn_ent is not None and sfn_ent.RetTag != GenTypes.REPL_TY_VOID: - sfn_v: llvmlite.Value* = self.Gen.CallGen.translate_call( - trans.Pool, trans._cur_builder, trans.Module, call_node, + sfn_v: llvmlite.Value* = self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans) if sfn_v is not None: - ctx_v: llvmlite.Value* = self.Gen.VarGen.repl_ctx_ptr( - trans, trans.ReplCtx, call_node) + ctx_v: llvmlite.Value* = self.Gen.VarGen.repl_ctx_ptr(trans, trans.ReplCtx, call_node) if ctx_v is not None: - self.Gen.VarGen.repl_emit_result( - trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits, + self.Gen.VarGen.repl_emit_result(trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits, call_node) return 0 - self.Gen.CallGen.translate_call( - trans.Pool, trans._cur_builder, trans.Module, call_node, - trans._funcs, trans._func_count, trans) + self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans) return 0 def pre_scan_allocas(self, trans: HT.Translator*, @@ -192,7 +177,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.pre_scan_allocas(trans, ifn.orelse.get(bi_pre_e)) return 0 if k == ast.ASTKind.For: - for_n: rawptr[ast.For] = rawptr[ast.For](node) + for_n: ast.For* = ast.For*(node) if for_n.children is not None: bn_pre_f: sizet = len(for_n.children) for bi_pre_f in range(bn_pre_f): @@ -340,8 +325,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): def get_env_ptr_var(self, trans: HT.Translator*) -> llvmlite.Value*: """获取或创建 _env_ptr 变量(存储闭包 env 指针)""" - env_var: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, "_env_ptr") + env_var: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "_env_ptr") if env_var is not None: return env_var # 创建 alloca 存储 env @@ -519,8 +503,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 注意:StdlibAlloc 是 StructGenMixin 字段,本 Mixin 方法体不能直接 self.StdlibAlloc # (NoVTable 按本 Mixin 字段布局编译),走模块级委托。 if self.Gen.StructGen.get_stdlib_alloc() != 0: - base_ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, base_ty) + base_ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, base_ty) if base_ty_copy is not None: entry.BaseTy = base_ty_copy else: @@ -544,8 +527,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 去重:同名成员已存在则跳过(跨模块同名枚举合并注册 / 同模块 # 重复处理幂等——如 w32.fileio 与 fat32_types 都有 FRESULT) for ei_d in range(enum_entry.MemberCount): - ex_d: rawptr[GenTypes.EnumMember] = self._get_enum_member( - enum_entry, ei_d) + ex_d: rawptr[GenTypes.EnumMember] = self._get_enum_member(enum_entry, ei_d) if ex_d is not None and ex_d.Name is not None: if string.strcmp(ex_d.Name, member_name) == 0: return ei_d diff --git a/App/lib/core/Gen/Stmt/StmtGenMixin.vp b/App/lib/core/Gen/Stmt/StmtGenMixin.vp index 346c615..4486fc3 100644 --- a/App/lib/core/Gen/Stmt/StmtGenMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenMixin.vp @@ -19,22 +19,13 @@ import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin # ============================================================ # StmtGenMixin - 语句/流程翻译 Mixin(P6 对象化重构 A 组,拆分后顶层) -# -# 按功能域拆分(500~1500 行/文件架构重构,试点): -# 顶层保留语句分派中枢簇 A(translate_stmt/try/raise/with/delete/ -# _eh_ret_default/_with_ctx_call);global/nonlocal/枚举/CIf 已拆至 -# StmtGenDeclMixin / StmtGenCifMixin(本类继承链 1/3、2/3)。 -# 外部引用(Generator.vp import + HandlesBody 委托)零改动。 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ # ============================================================ # StmtGenMixin - 语句分派中枢(顶层) # ============================================================ -@t.NoVTable -class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): +novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """语句/流程翻译 Mixin(拆分后顶层,继承 Decl)""" def translate_stmt(self, trans: HT.Translator*, @@ -42,8 +33,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """翻译单条语句,返回新增的变量数(深度守卫包装器,原逻辑见 _translate_stmt_impl)""" if trans is not None: if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: - self.Gen.TypeGenErr.fatal_error( - node, "语句翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") + self.Gen.TypeGenErr.fatal_error(node, "语句翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") trans.TranslateDepth += 1 mret: int = self._translate_stmt_impl(trans, node) if trans is not None: @@ -129,28 +119,23 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if tgt.kind() == ast.ASTKind.Attribute: del_at: ast.Attribute* = ast.Attribute*(tgt) if del_at is not None: - self.Gen.CallGenProp._try_property_deleter( - pool, builder, mod, del_at, trans) + self.Gen.CallGenProp._try_property_deleter(pool, builder, mod, del_at, trans) # del obj[key] → __delitem__(obj, key)(对齐 TPC HandlesDelete.py)。 # 不能静默忽略 Subscript 目标——否则 del 不生效(len 不变)。 elif tgt.kind() == ast.ASTKind.Subscript: dl_sub: ast.Subscript* = ast.Subscript*(tgt) if dl_sub is not None and dl_sub.value is not None and dl_sub.slice is not None: - dl_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, dl_sub.value, None, 0, trans) - dl_idx: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, dl_sub.slice, None, 0, trans) + dl_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, dl_sub.value, None, 0, trans) + dl_idx: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, dl_sub.slice, None, 0, trans) if dl_obj is not None and dl_idx is not None: - dl_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value( - dl_obj) + dl_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(dl_obj) if dl_st is not None: dl_cls: str = self.Gen.StructGen.get_class_name_by_type(pool, dl_st) if dl_cls is not None: dl_lookup: str = pool.alloc(128) if dl_lookup is not None: viperlib.snprintf(dl_lookup, 128, "%s.__delitem__", dl_cls) - dl_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( - mod, dl_lookup) + dl_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, dl_lookup) if dl_fn is not None: dl_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(dl_fn) dl_fn_name: str = llvmlite.function_get_name(dl_fn) @@ -166,8 +151,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 参数链表: self → key(独立 null 结尾) dl_self.Next = dl_idx dl_idx.Next = None - llvmlite.build_call( - builder, dl_fn_name, dl_self, 2, dl_ret, 0) + llvmlite.build_call(builder, dl_fn_name, dl_self, 2, dl_ret, 0) return 0 # ============================================================ @@ -290,17 +274,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 无 except(非法 try,防御):直接吞掉 llvmlite.build_br(builder, unhandled_bb) else: - eh_code_val: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty_t, exception_code) + eh_code_val: llvmlite.Value* = llvmlite.build_load(builder, i32_ty_t, exception_code) next_check_t: rawptr[llvmlite.BasicBlock] = None for i_t in range(n_handlers_t): - hdr_t: ast.ExceptHandler* = ast.ExceptHandler*( - tr.handlers.get(i_t)) + hdr_t: ast.ExceptHandler* = ast.ExceptHandler*(tr.handlers.get(i_t)) match_bb_t: rawptr[llvmlite.BasicBlock] = match_bbs.get(i_t) if i_t > 0 and next_check_t is not None: llvmlite.position_at_end(builder, next_check_t) - eh_code_val = llvmlite.build_load( - builder, i32_ty_t, exception_code) + eh_code_val = llvmlite.build_load(builder, i32_ty_t, exception_code) if hdr_t is None or hdr_t.type is None: # 裸 except:无条件匹配 llvmlite.build_br(builder, match_bb_t) @@ -320,8 +301,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): return 0 n_codes_t: int = 0 if hname_t is not None and self.Gen.ClassGenBase.is_exception_name(hname_t) != 0: - n_codes_t = self.Gen.ClassGenBase.collect_descendant_codes( - hname_t, codes_buf_t, 64) + n_codes_t = self.Gen.ClassGenBase.collect_descendant_codes(hname_t, codes_buf_t, 64) else: c0_t: int = 1 if hname_t is not None: @@ -332,22 +312,18 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): n_codes_t = 1 match_cond_t: llvmlite.Value* = None for ci_t in range(n_codes_t): - code_val_t: llvmlite.Value* = llvmlite.const_int32( - pool, codes_buf_t[ci_t]) - is_match_t: llvmlite.Value* = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, eh_code_val, code_val_t) + code_val_t: llvmlite.Value* = llvmlite.const_int32(pool, codes_buf_t[ci_t]) + is_match_t: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, eh_code_val, code_val_t) if match_cond_t is None: match_cond_t = is_match_t elif is_match_t is not None: - match_cond_t = llvmlite.build_or( - builder, match_cond_t, is_match_t) + match_cond_t = llvmlite.build_or(builder, match_cond_t, is_match_t) if i_t < n_handlers_t - 1: viperlib.snprintf(bb_buf_t, 64, "try.check.%d.%d", lc_t, i_t) next_check_t = llvmlite.create_block(pool, func, bb_buf_t) else: next_check_t = unhandled_bb - llvmlite.build_cond_br( - builder, match_cond_t, match_bb_t, next_check_t) + llvmlite.build_cond_br(builder, match_cond_t, match_bb_t, next_check_t) # MatchBB:绑定 handler 变量(e = 消息指针),跳 ExceptBB llvmlite.position_at_end(builder, match_bb_t) if hdr_t is not None and hdr_t.name is not None and hdr_t.name[0] != '\0': @@ -355,8 +331,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 重复 define_var 不 shadow——多 try 共用 `as e` 时各 MatchBB # 各自 store 消息,各 ExceptBB 读同一入口 alloca,避免 # 非支配 alloca 触发 "does not dominate all uses")。 - h_ent_t: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, hdr_t.name) + h_ent_t: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, hdr_t.name) if h_ent_t is not None and h_ent_t.Alloca is not None: h_alloca_t: llvmlite.Value* = h_ent_t.Alloca else: @@ -364,8 +339,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if h_alloca_t is not None: self.Gen.VarGen.define_var(trans.SymTab, hdr_t.name, h_alloca_t) if h_alloca_t is not None: - h_msg_t: llvmlite.Value* = llvmlite.build_load( - builder, i8_ptr_ty_t, eh_message) + h_msg_t: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty_t, eh_message) if h_msg_t is not None: llvmlite.build_store(builder, h_msg_t, h_alloca_t) except_bb_t: rawptr[llvmlite.BasicBlock] = except_bbs.get(i_t) @@ -375,10 +349,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): llvmlite.position_at_end(builder, unhandled_bb) if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \ and trans._eh_code_out_param is not None: - un_msg_t: llvmlite.Value* = llvmlite.build_load( - builder, i8_ptr_ty_t, eh_message) - un_code_t: llvmlite.Value* = llvmlite.build_load( - builder, i32_ty_t, exception_code) + un_msg_t: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty_t, eh_message) + un_code_t: llvmlite.Value* = llvmlite.build_load(builder, i32_ty_t, exception_code) if un_msg_t is not None: llvmlite.build_store(builder, un_msg_t, trans._eh_msg_out_param) if un_code_t is not None: @@ -391,8 +363,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # ---- 7. Except 体 ---- for i_t in range(n_handlers_t): - hdr2_t: ast.ExceptHandler* = ast.ExceptHandler*( - tr.handlers.get(i_t)) + hdr2_t: ast.ExceptHandler* = ast.ExceptHandler*(tr.handlers.get(i_t)) except_bb2_t: rawptr[llvmlite.BasicBlock] = except_bbs.get(i_t) llvmlite.position_at_end(builder, except_bb2_t) if hdr2_t is not None and hdr2_t.children is not None: @@ -467,11 +438,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if trans._stop_iter_flag_ptr is not None: i1_ty_r: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_r is not None: - one_i1_r: llvmlite.Value* = llvmlite.ConstInt( - pool, i1_ty_r, 1, "1") + one_i1_r: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty_r, 1, "1") if one_i1_r is not None: - llvmlite.build_store( - builder, one_i1_r, trans._stop_iter_flag_ptr) + llvmlite.build_store(builder, one_i1_r, trans._stop_iter_flag_ptr) self._eh_ret_default(trans, pool, builder) return 0 @@ -497,8 +466,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if exc_code == 0: exc_code = 1 if ecl2.args is not None and len(ecl2.args) > 0: - exc_msg = self.Gen.ExprGen.translate_value( - builder, pool, mod, ecl2.args.get(0), None, 0, trans) + exc_msg = self.Gen.ExprGen.translate_value(builder, pool, mod, ecl2.args.get(0), None, 0, trans) # ---- 异常分发 ---- # 1. try 内:写入 try 的 eh_code/eh_message alloca,分支 DispatchBB @@ -507,8 +475,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if code_val_r is not None: llvmlite.build_store(builder, code_val_r, trans._eh_code_ptr) if exc_msg is None: - exc_msg = llvmlite.ConstNull( - pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null") + exc_msg = llvmlite.ConstNull(pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null") if exc_msg is not None and trans._eh_msg_ptr is not None: llvmlite.build_store(builder, exc_msg, trans._eh_msg_ptr) llvmlite.build_br(builder, trans._eh_dispatch_bb) @@ -520,8 +487,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if code_val_r2 is not None: llvmlite.build_store(builder, code_val_r2, trans._eh_code_out_param) if exc_msg is None: - exc_msg = llvmlite.ConstNull( - pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null") + exc_msg = llvmlite.ConstNull(pool, llvmlite.Ptr(pool, llvmlite.Int8(pool)), "null") if exc_msg is not None: llvmlite.build_store(builder, exc_msg, trans._eh_msg_out_param) self._eh_ret_default(trans, pool, builder) @@ -603,8 +569,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): n: sizet = len(items) # 保存外层 __with_ctx(嵌套 with 时退出后恢复) - old_ctx_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( - trans.SymTab, "__with_ctx") + old_ctx_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "__with_ctx") # 记录每个 item 的类名(__exit__ 调用时设置 __with_ctx 类型用) ctx_class_buf: sizet* = pool.alloc(8 * n) @@ -623,9 +588,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if item is None or item.context_expr is None: continue # 翻译 context_expr(对象构造,如 MemPool(arena, 4096)) - ctx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, item.context_expr, - trans._funcs, trans._func_count, trans) + ctx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, item.context_expr, trans._funcs, trans._func_count, trans) if ctx_val is None: continue # 提取类名(注解类名,Attribute 时带模块前缀,如 "memhub.MemPool"—— @@ -651,19 +614,16 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): elif cfn.kind() == ast.ASTKind.Name: cls_name = (ast.Name*(cfn)).id # context 对象存入 __with_ctx(方法调用解析 self 用) - ctx_alloca: llvmlite.Value* = llvmlite.build_alloca( - builder, ctx_val.Ty) + ctx_alloca: llvmlite.Value* = llvmlite.build_alloca(builder, ctx_val.Ty) if ctx_alloca is None: continue llvmlite.build_store(builder, ctx_val, ctx_alloca) self.Gen.VarGen.define_var(trans.SymTab, "__with_ctx", ctx_alloca) if cls_name is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, "__with_ctx", cls_name) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, "__with_ctx", cls_name) ctx_class_buf[i] = sizet(cls_name) # 调用 __enter__() - enter_val: llvmlite.Value* = self._with_ctx_call( - trans, pool, builder, mod, "__enter__") + enter_val: llvmlite.Value* = self._with_ctx_call(trans, pool, builder, mod, "__enter__") # asname 绑定(__enter__ 返回值,缺失时退回 context 对象) if item.optional_vars is not None: ov: ast.AST* = item.optional_vars @@ -674,14 +634,12 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if bind_val is None: bind_val = ctx_val if bind_val is not None: - asn_alloca: llvmlite.Value* = llvmlite.build_alloca( - builder, bind_val.Ty) + asn_alloca: llvmlite.Value* = llvmlite.build_alloca(builder, bind_val.Ty) if asn_alloca is not None: llvmlite.build_store(builder, bind_val, asn_alloca) self.Gen.VarGen.define_var(trans.SymTab, asname, asn_alloca) if cls_name is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, asname, cls_name) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, asname, cls_name) # FakeDuck: __provides__ 元数据 → 生成 _push_provider 调用 # (对齐 TPC HandlesWith.py L138-159;经 gen 单例委托 CallGenMixin。 # 类名去模块前缀后查 __provides__ 表,如 memhub.MemBuddy → MemBuddy) @@ -691,8 +649,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if fd_dot is not None: fd_cls_bare = fd_dot + 1 if fd_cls_bare is not None: - self.Gen.CallGenFd._emit_provider_push( - trans, pool, builder, mod, fd_cls_bare, ctx_val) + self.Gen.CallGenFd._emit_provider_push(trans, pool, builder, mod, fd_cls_bare, ctx_val) # 2. 翻译 body body: list[ast.AST*]* = wt.children @@ -714,16 +671,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if fd_dot_p is not None: fd_cls_bare_p = fd_dot_p + 1 if fd_cls_bare_p is not None: - self.Gen.CallGenFd._emit_provider_pop( - trans, pool, builder, mod, fd_cls_bare_p) + self.Gen.CallGenFd._emit_provider_pop(trans, pool, builder, mod, fd_cls_bare_p) # 3. 逆序调用 __exit__()(Python with 语义:后进先出) for i in range(n): ci: int = n - 1 - i if ctx_class_buf[ci] != 0: cls_ci: str = (str | t.CPtr)(ctx_class_buf[ci]) - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, "__with_ctx", cls_ci) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, "__with_ctx", cls_ci) self._with_ctx_call(trans, pool, builder, mod, "__exit__") # 4. 恢复外层 __with_ctx @@ -737,18 +692,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): mod: llvmlite.LLVMModule*, method_name: str) -> llvmlite.Value*: """构造并翻译 __with_ctx.() 调用(__enter__/__exit__)""" - if pool is None or method_name is None: - return None + if pool is None or method_name is None: return None name_node: ast.AST* = ast.Name(pool, "__with_ctx", ast.ASTCtx.Load) - if name_node is None: - return None - attr_node: ast.AST* = ast.Attribute( - pool, name_node, method_name, ast.ASTCtx.Load) - if attr_node is None: - return None + if name_node is None: return None + attr_node: ast.AST* = ast.Attribute(pool, name_node, method_name, ast.ASTCtx.Load) + if attr_node is None: return None call_node: ast.AST* = ast.Call(pool, attr_node, None, None) - if call_node is None: - return None - return self.Gen.ExprGen.translate_value( - builder, pool, mod, call_node, - trans._funcs, trans._func_count, trans) + if call_node is None: return None + return self.Gen.ExprGen.translate_value(builder, pool, mod, call_node, trans._funcs, trans._func_count, trans) diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index 48d26d3..aa1ab23 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -578,8 +578,7 @@ novirtual class StructGenMixin: if default_val.kind() == ast.ASTKind.List: return self._deep_copy_list_ast(pool, default_val) if default_val.kind() != ast.ASTKind.Constant: return None src_c: ast.Constant* = ast.Constant*(default_val) - dst_c: ast.Constant* = ast.Constant*( - pool.alloc_tagged(ast.Constant.__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_641)) + dst_c: ast.Constant* = ast.Constant*(pool.alloc_tagged(ast.Constant.__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_641)) if dst_c is None: return None string.memset(dst_c, 0, ast.Constant.__sizeof__()) @@ -639,8 +638,7 @@ novirtual class StructGenMixin: src_elts_l: list[ast.AST*]* = src_l.elts if src_elts_l is not None: cnt_l: sizet = len(src_elts_l) - lst_copy_l: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)( - pool.alloc_tagged(list[ast.AST*].__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_693)) + lst_copy_l: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)(pool.alloc_tagged(list[ast.AST*].__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_693)) if lst_copy_l is not None: string.memset(lst_copy_l, 0, list[ast.AST*].__sizeof__()) # 计数**绝不先按源计数写死**:必须在填充循环里按"实际写入槽数"落定 @@ -672,8 +670,7 @@ novirtual class StructGenMixin: # 源列表自身存在空元素,说明产生源已损坏(计数 > 实际填充) # ——响亮失败,绝不静默补 0。 if elem_src_l is None: - self.Gen.TypeGenErr.fatal_error( - default_val, + self.Gen.TypeGenErr.fatal_error(default_val, f"字段默认值深拷贝:列表字面量第 {li_l} 个元素为空 AST 元素(指针为 0)。" f"上层某处产生了空 AST 元素(元素计数与实际填充不一致)," f"拒绝静默补 0 生成残缺的默认值;已终止编译。", @@ -681,8 +678,7 @@ novirtual class StructGenMixin: return None elem_dst_l: ast.AST* = self._deep_copy_default_ast(pool, elem_src_l) if elem_dst_l is None: - self.Gen.TypeGenErr.fatal_error( - elem_src_l, + self.Gen.TypeGenErr.fatal_error(elem_src_l, f"字段默认值深拷贝:列表字面量第 {li_l} 个元素(kind={elem_src_l.kind()})" f"既非 Constant 也非 List,无法深拷贝到永久池。若在此静默跳过该槽," f"会形成【计数 > 实际填充数】的空槽(后续 elts.get 读到裸 0 崩溃);" @@ -1175,11 +1171,9 @@ novirtual class StructGenMixin: self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_q) rn_alias_q: int = -1 if rn_is_renum_q != 0: - rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias( - rn_cls_q, field_name) + rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(rn_cls_q, field_name) if rn_alias_q < 1 and bare_q is not rn_cls_q: - rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias( - bare_q, field_name) + rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(bare_q, field_name) if rn_alias_q >= 1: rn_fe_q: GenTypes.FieldEntry* = \ self._get_field_entry(mod_entry_q, rn_alias_q) @@ -1233,13 +1227,11 @@ novirtual class StructGenMixin: rn_is_renum_l = self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_l) rn_alias_l: int = -1 if rn_is_renum_l != 0: - rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias( - rn_cls_l, field_name) + rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(rn_cls_l, field_name) if rn_alias_l < 1 and class_name is not rn_cls_l: # 双保险:别名表可能仍持有旧 AST 指针(_update_renum_alias_class_ptr # 未执行/多模块重复注册场景),用调用方 class_name 再试一次 - rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias( - class_name, field_name) + rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(class_name, field_name) if rn_alias_l >= 1: rn_fe_l: GenTypes.FieldEntry* = \ self.Gen.StructGen._get_field_entry(entry, rn_alias_l) @@ -1835,9 +1827,7 @@ novirtual class StructGenMixin: # (G3 LinkedNode.prepend 挂起候选),超限立即报错终止 cnt_ef += 1 if cnt_ef > 100000: - VLogger.error( - "字段链表疑似成环(_ensure_field_types_in_module),强制终止", - "STRUCT") + VLogger.error("字段链表疑似成环(_ensure_field_types_in_module),强制终止", "STRUCT") stdlib.exit(1) if fld.Ty is not None: # 值类型子结构体(如 FILETIME)需要完整定义 diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index 7f5c8f1..0cc18eb 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -463,8 +463,7 @@ novirtual class Translator: i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 声明 printf - printf_func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, "printf", i32_ty) + printf_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "printf", i32_ty) if printf_func is None: VLogger.error("CreateDeclare printf returned NULL", "TR") return 1 @@ -474,18 +473,15 @@ novirtual class Translator: # declare void @llvm.va_start(i8*) # declare void @llvm.va_end(i8*) void_ty_decl: llvmlite.LLVMType* = llvmlite.Void(pool) - va_start_func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, "llvm.va_start", void_ty_decl) + va_start_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "llvm.va_start", void_ty_decl) if va_start_func is not None: llvmlite.add_param(pool, va_start_func, i8_ptr_ty, "ap") - va_end_func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, "llvm.va_end", void_ty_decl) + va_end_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "llvm.va_end", void_ty_decl) if va_end_func is not None: llvmlite.add_param(pool, va_end_func, i8_ptr_ty, "ap") # 声明 malloc(闭包分配用) - malloc_func: llvmlite.Function* = llvmlite.create_declare( - pool, mod, "malloc", i8_ptr_ty) + malloc_func: llvmlite.Function* = llvmlite.create_declare(pool, mod, "malloc", i8_ptr_ty) if malloc_func is not None: i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) llvmlite.add_param(pool, malloc_func, i64_ty, "size") @@ -571,9 +567,7 @@ novirtual class Translator: if self._imported_modules is not None: # 错误上下文帧:当前模块触发依赖 stub 加载的 import 位置 GenApi.push_trace(GenApi.get_current_file(), cur_imp_lineno) - StubMergerBuild.LoadDepVpiIntoModule( - pool, mod, self._imported_modules, self._from_imports, - GenApi.get_temp_dir(), self) + StubMergerBuild.LoadDepVpiIntoModule(pool, mod, self._imported_modules, self._from_imports, GenApi.get_temp_dir(), self) GenApi.pop_trace() # 预注册模块级变量(AnnAssign/Assign)到 SymTab # 解决时序问题:class Logger 的 __init__ 引用 _mbuddy 时, @@ -629,15 +623,13 @@ novirtual class Translator: # (Phase1 1b / Phase2 pre-inc / PhaseA)——否则 _list/_dict 显式 # import memhub 且 memhub 用容器泛型时成 2-环,Phase A 永不收敛。 if self._ContainerInjectionCreatesCycle("_dict") == 0: - self._imported_modules = GenApi.add_imported_module( - pool, self._imported_modules, "_dict") + self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_dict") if need_list_box[0] != 0: GenApi.add_visible_struct(pool, "list") if self._imported_modules is None or \ GenApi.is_module_imported(self._imported_modules, "_list") == 0: if self._ContainerInjectionCreatesCycle("_list") == 0: - self._imported_modules = GenApi.add_imported_module( - pool, self._imported_modules, "_list") + self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_list") stdlib.free(need_list_box) stdlib.free(need_dict_box) @@ -736,8 +728,7 @@ novirtual class Translator: if arg_s is not None: ag_s: ast.Arg* = ast.Arg*(arg_s) if ag_s.annotation is not None: - self._check_container_type_node( - ag_s.annotation, need_list_box, need_dict_box) + self._check_container_type_node(ag_s.annotation, need_list_box, need_dict_box) # `[...]`/`{}` 字面量不触发 _list/_dict 导入:字面量广泛用于编译期常量列表 # (c.Asm 的 op/inp/out CLOBBER 参数、数组数据初始化),并非 list 容器使用。 # list/dict 容器的真实使用由类型位置检测覆盖:`x: list` / `list[...]` 注解、 diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 4195099..9b94358 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -209,10 +209,7 @@ novirtual class TranslatorGenMixin: # 元素数超过声明长度 → fail-fast(不按声明长度截断、静默丢弃多余元素)。 if sizet(arr_count) < elts_count: - self.Gen.TypeGenErr.fatal_error( - list_node, - f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许静默截断", - "OverflowError") + self.Gen.TypeGenErr.fatal_error(list_node, f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许静默截断", "OverflowError") return None # 非整数元素类型(struct/指针等聚合):不存在 "%s %lld" 文本展开,仅当列表 @@ -252,23 +249,20 @@ novirtual class TranslatorGenMixin: if en_n is not None: ek_n: int = en_n.kind() if ek_n == ast.ASTKind.List: - sub_n = self._build_array_initializer_text( - pool, elem_ty, ast.List*(en_n)) + sub_n = self._build_array_initializer_text(pool, elem_ty, ast.List*(en_n)) elif ek_n == ast.ASTKind.Set: # 花括号行字面量(如点阵字库 {0x00, ...}):Set.elts # 与 List 同构,包装为临时 List 递归生成子数组文本 se_n: rawptr[ast.Set] = rawptr[ast.Set](en_n) if se_n is not None and se_n.elts is not None: - sub_n = self._build_array_initializer_text( - pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load)) + sub_n = self._build_array_initializer_text(pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load)) if sub_n is None: # 元素缺失/无法展开:子数组整体零初始化 sub_n = "zeroinitializer" if i_n > 0: written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, ", ") pos_n += sizet(written_n) - written_n = viperlib.snprintf( - buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n) + written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n) pos_n += sizet(written_n) i_n += 1 viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]") @@ -408,8 +402,7 @@ novirtual class TranslatorGenMixin: viperlib.snprintf(str_name_buf, 64, ".str.%s", var_name) # 调用 llvmlite.create_global_string 创建字符串常量全局 - str_gv: llvmlite.GlobalVariable* = llvmlite.create_global_string( - pool, mod, str_name_buf, str_val) + str_gv: llvmlite.GlobalVariable* = llvmlite.create_global_string(pool, mod, str_name_buf, str_val) if str_gv is None: return None @@ -604,9 +597,7 @@ novirtual class TranslatorGenMixin: return None sec_val: str = self.Gen.FuncGenBase._get_attr_call_arg_str(hit) if sec_val is None or sec_val[0] == 0: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级变量 '{var_name}' 的 t.attr.section(...) 段名缺失或为空", - "ValueError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 的 t.attr.section(...) 段名缺失或为空", "ValueError") return None return sec_val def _extract_global_attr_aligned(self, node: ast.AST*, @@ -621,9 +612,7 @@ novirtual class TranslatorGenMixin: return 0 al_val: int = self.Gen.ClassGenBase._tattr_aligned_int(hit) if al_val <= 0: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级变量 '{var_name}' 的 t.attr.aligned(N) 需要正整数字面量 N", - "ValueError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 的 t.attr.aligned(N) 需要正整数字面量 N", "ValueError") return 0 return al_val def _extract_global_attr_weak(self, node: ast.AST*) -> int: @@ -656,16 +645,14 @@ novirtual class TranslatorGenMixin: if nm_cd.id is not None: if self.Gen.AssignGen.is_cdefine_annotation(aa_cd.annotation) != 0: # 浮点/整数自动识别注册(浮点 CDefine 如 vipermath U_M_PI) - self.Gen.AssignGen._register_cdefine_from_value( - pool, nm_cd.id, aa_cd.value, aa_cd.annotation) + self.Gen.AssignGen._register_cdefine_from_value(pool, nm_cd.id, aa_cd.value, aa_cd.annotation) return 0 # CTypedef 注解(如 posix.vp mode_t: t.CTypedef = uint32): # 不创建全局变量(否则生成 @mode_t 符号 → 链接 duplicate symbol)。 # 预注册阶段按需注册到 CTypedef 表:翻译期表已被 clear_ctypedefs 清空 # (每文件隔离),不注册则函数参数注解查表失败 → NameError。 if self.Gen.TypeGenCType._is_ctypedef_annotation(aa_cd.annotation) != 0: - ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation( - pool, aa_cd.value) + ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, aa_cd.value) if ctd_str is not None: self.Gen.TypeGenCType.register_ctypedef(pool, nm_cd.id, ctd_str) return 0 @@ -712,20 +699,15 @@ novirtual class TranslatorGenMixin: # (CallGenLeafKit.vp:698-699、:783-788),跨文件查找可见。 # t.CDefine/t.CTypedef 等分支已在 :675-689 提前返回,行为不变。 if annot_node is not None: - ml_callable_ret: llvmlite.LLVMType* = ( - self.Gen.TypeGenErr.try_extract_callable_ret( - pool, annot_node, trans._imported_modules, - trans._from_imports, trans)) + ml_callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot_node, trans._imported_modules,trans._from_imports, trans) if ml_callable_ret is not None: # 返回值:0=成功/同类型幂等命中;非 0 已在 register_func_ptr_sig # 内部 fatal_error 终止编译,此处分支仅防御(见 AssignGenMixin 同处)。 - if self.Gen.CallGenLeafKit.register_func_ptr_sig( - pool, var_name, ml_callable_ret, aa) != 0: + if self.Gen.CallGenLeafKit.register_func_ptr_sig(pool, var_name, ml_callable_ret, aa) != 0: return 0 # 解析类型 if aa.annotation is not None: - resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: # 对象类模块级变量(@t.Object/@t.CVTable:对象即指针)→ Ptr(struct): # 裸类名注解 resolve 返回 struct 值,模块级变量此处需包装 Ptr;若建成 @@ -757,8 +739,7 @@ novirtual class TranslatorGenMixin: # [S4 fail-fast] 模块级变量有注解但解析失败 → 不再静默用 i32 # (类型错会使全局存储尺寸/字段访问/ABI 全错);前向引用未注册类 # 应收敛为多遍注册而非回退 i32。 - self.Gen.TypeGenErr.fatal_error( - aa.annotation, f"模块级变量 '{var_name}' 类型注解解析失败", "NameError") + self.Gen.TypeGenErr.fatal_error(aa.annotation, f"模块级变量 '{var_name}' 类型注解解析失败", "NameError") return 0 # 解析初始值(支持整数、负数字面量、列表字面量、字符串字面量) if aa.value is not None: @@ -853,20 +834,15 @@ novirtual class TranslatorGenMixin: case _: pass if is_fty_g == 0: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型", + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型", "TypeError") return 0 - if self.Gen.AssignGen._recover_float_literal( - var_name, t.CPtr(c.Addr(init_fval)), 0) != 1: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级浮点变量 '{var_name}' 初始化值源文件恢复失败", - "InternalCompilerError") + if self.Gen.AssignGen._recover_float_literal(var_name, t.CPtr(c.Addr(init_fval)), 0) != 1: + self.Gen.TypeGenErr.fatal_error(node, f"模块级浮点变量 '{var_name}' 初始化值源文件恢复失败", "InternalCompilerError") return 0 # 检查是否已注册 - existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( - trans.SymTab, var_name) + existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, var_name) if existing is not None: return 0 @@ -884,8 +860,7 @@ novirtual class TranslatorGenMixin: # 无法在 LLVM MC 中解析)。 is_global_cexport: int = 0 if annot_node is not None: - is_global_cexport = self.Gen.TypeGenErr.has_decorator_marker( - annot_node, "CExport", 0) + is_global_cexport = self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CExport", 0) # 全局变量侧 t.attr.* 属性(`T | t.attr.xxx` 注解联合形态): # section→gv.Section、aligned→gv.Align、weak→gv.Linkage(见下方应用点)。 # 仅在 AnnAssign(annot_node 非 None)时存在,与 t.CExport 同一条路。 @@ -956,13 +931,11 @@ novirtual class TranslatorGenMixin: case _: pass if is_arr_g != 0: - arr_str_init: str = self._build_string_array_initializer_text( - pool, var_ty, init_str_val) + arr_str_init: str = self._build_string_array_initializer_text(pool, var_ty, init_str_val) if arr_str_init is not None: gv.Initializer = arr_str_init else: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级数组变量 '{var_name}' 字符串初始化器构建失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级数组变量 '{var_name}' 字符串初始化器构建失败", "TypeError") else: # 指针类型(如 b64_tab: t.CArray[char, None] = "ABC..."): # 创建字符串常量全局 + GEP 引用 @@ -970,8 +943,7 @@ novirtual class TranslatorGenMixin: if str_init is not None: gv.Initializer = str_init else: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级变量 '{var_name}' 初始化器构建失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 初始化器构建失败", "TypeError") elif init_kind == 4: # 浮点初始值:LLVM IR 的浮点常量必须写成位模式文本(0x%016llx / 0x%08x)—— # 十进制文本经 llc 解析对部分值有 ±1 ulp 误差(见 llvmlite.ConstFloat 注释)。 @@ -980,8 +952,7 @@ novirtual class TranslatorGenMixin: if fc_g is not None and fc_g.Name is not None: gv.Initializer = fc_g.Name else: - self.Gen.TypeGenErr.fatal_error( - node, f"模块级变量 '{var_name}' 浮点初始化器构建失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 浮点初始化器构建失败", "TypeError") else: # 使用 zeroinitializer 而非 "0":指针类型必须用 null/zeroinitializer, # 整数/聚合类型也兼容 zeroinitializer,避免 "integer constant must have integer type" @@ -1019,8 +990,7 @@ novirtual class TranslatorGenMixin: vt_sha1 = resolved_stg_entry.ModuleSha1 if vt_sha1 is None: vt_sha1 = trans.ModuleSha1 - vt_mangled: str = self.Gen.FuncGenBase._mangle_name_with_sha1( - vt_sha1, vt_name_buf) + vt_mangled: str = self.Gen.FuncGenBase._mangle_name_with_sha1(vt_sha1, vt_name_buf) if vt_mangled is not None: # 完整 struct 初始化器(LLVM 拒绝部分初始化): # 字段 0 = __vtable__(i8* @vtable),其余用户字段按类型零值。 @@ -1038,16 +1008,14 @@ novirtual class TranslatorGenMixin: # 如 `_mbuddy: MemBuddy` 的字段默认不再丢失); # 全部默认值恰为零时回退逐字段零值,避免无谓文本。 # 两者均列全字段(LLVM 要求初始化器元素数匹配)。 - rest_v: str = self._build_stg_struct_body_text( - pool, resolved_stg_entry, 1) + rest_v: str = self._build_stg_struct_body_text(pool, resolved_stg_entry, 1) if rest_v is not None: written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", rest_v) pos_v += sizet(written_v) else: fc_v: int = resolved_stg_entry.FieldCount for fi_v in range(1, fc_v): - fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( - resolved_stg_entry, fi_v) + fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(resolved_stg_entry, fi_v) if fe_v is None or fe_v.Ty is None: continue ty_buf_v: str = pool.alloc(128) @@ -1065,16 +1033,14 @@ novirtual class TranslatorGenMixin: # 无 vtable 的对象全局(@t.Object / 普通类):按字段默认值生成常量初始化器; # 一律 zeroinitializer 会丢掉全部字段默认值(模块级 X: T = T() 的构造调用 # 不发射)。无任何非零默认值时返回 None → 保持 zeroinitializer(零开销)。 - stg_default_text: str = self._build_stg_struct_init_text( - pool, resolved_stg_entry, 0) + stg_default_text: str = self._build_stg_struct_init_text(pool, resolved_stg_entry, 0) if stg_default_text is not None: stg_init_text = stg_default_text stg_name_len: sizet = sizet(string.strlen(mangled_name)) + 8 stg_name_buf: str = pool.alloc(stg_name_len) if stg_name_buf is not None: viperlib.snprintf(stg_name_buf, stg_name_len, "%s.stg", mangled_name) - stg_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable( - pool, stg_name_buf, resolved_stg_ty) + stg_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, stg_name_buf, resolved_stg_ty) if stg_gv is not None: llvmlite.module_add_global(mod, stg_gv) stg_gv.Linkage = None @@ -1093,8 +1059,7 @@ novirtual class TranslatorGenMixin: gv.Initializer = stg_init_buf # 注册 storage 引用(key: var_name.__stg),供 AssignGenMixin # 全局赋值分支检测对象类全局并复制对象到 storage。 - stg_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref( - pool, stg_name_buf, resolved_stg_ty) + stg_ref: llvmlite.Value* = self.Gen.ExprGenAttr.make_global_ref(pool, stg_name_buf, resolved_stg_ty) if stg_ref is not None: stg_key_len: sizet = sizet(string.strlen(var_name)) + 8 stg_key: str = pool.alloc(stg_key_len) @@ -1122,8 +1087,7 @@ novirtual class TranslatorGenMixin: # const 对象全局:注解含 t.CConst 且类型非指针 ⇒ 登记 IsConst, # 之后对该全局名的赋值/增量赋值/元素赋值 fail-fast(判据同 TPC # 的 Gen.global_const_flags,见 Debugger/type-descriptors.md)。 - if self.Gen.TypeGenErr.is_const_object_marker( - annot_node, var_ty) != 0: + if self.Gen.TypeGenErr.is_const_object_marker(annot_node, var_ty) != 0: self.Gen.VarGen.set_var_const(trans.SymTab, var_name) if self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile(trans.SymTab, var_name) @@ -1137,11 +1101,9 @@ novirtual class TranslatorGenMixin: if k == ast.ASTKind.AnnAssign: aa_ml: ast.AnnAssign* = ast.AnnAssign*(node) if aa_ml is not None and aa_ml.annotation is not None: - cls_nm_ml: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( - aa_ml.annotation, trans._imported_modules, pool, trans._from_imports) + cls_nm_ml: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(aa_ml.annotation, trans._imported_modules, pool, trans._from_imports) if cls_nm_ml is not None: - self.Gen.VarGen.set_var_annot_class_name( - trans.SymTab, var_name, cls_nm_ml) + self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, var_name, cls_nm_ml) # 模块级 str|t.CPtr / bytes|t.CPtr 全局:标记 IsPtrElement # (i8** 语义,var[i] 按 8 字节指针步长),对齐 TPC 的 # global_var_ptr_element(_argv 等字符串指针数组)。否则 @@ -1149,12 +1111,9 @@ novirtual class TranslatorGenMixin: if aa_ml.annotation.kind() == ast.ASTKind.BinOp: bop_ml: ast.BinOp* = ast.BinOp*(aa_ml.annotation) if bop_ml.op == ast.OpKind.BitOr: - if self.Gen.AssignGen._annotation_contains_name( - aa_ml.annotation, "str") != 0 \ - or self.Gen.AssignGen._annotation_contains_name( - aa_ml.annotation, "bytes") != 0: - self.Gen.VarGen.set_var_ptr_element( - trans.SymTab, var_name) + if self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "str") != 0 \ + or self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "bytes") != 0: + self.Gen.VarGen.set_var_ptr_element(trans.SymTab, var_name) return 1 return 0 @@ -1181,14 +1140,12 @@ novirtual class TranslatorGenMixin: pool: memhub.MemBuddy* = trans.Pool mod: llvmlite.LLVMModule* = trans.Module - main_func: llvmlite.Function* = llvmlite.create_function( - pool, mod, "main", i32_ty) + main_func: llvmlite.Function* = llvmlite.create_function(pool, mod, "main", i32_ty) if main_func is None: VLogger.error("CreateFunction main returned NULL", "TR") return 0 - entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, main_func, "entry") + entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, main_func, "entry") if entry_blk is None: VLogger.error("CreateBlock returned NULL", "TR") return 0 diff --git a/App/lib/core/Gen/Type/TypeGenBase.vp b/App/lib/core/Gen/Type/TypeGenBase.vp index 27bf86a..4f6ca31 100644 --- a/App/lib/core/Gen/Type/TypeGenBase.vp +++ b/App/lib/core/Gen/Type/TypeGenBase.vp @@ -23,12 +23,8 @@ import lib.core.Gen.Type.TypeSpec as TSpec # ============================================================ # TypeGenBase - 类型表基础设施:字段 + InitTypeGen + trace/临时目录/generic 上下文 -# -# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesType 委托。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class TypeGenBase: +novirtual class TypeGenBase: """字段 + InitTypeGen + trace/临时目录/generic 上下文""" # --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) --- @@ -128,8 +124,7 @@ class TypeGenBase: Specs: TSpec.TypeSpecArena* def InitTypeGen(self) -> int: """初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)""" - if self is None: - return 1 + if self is None: return 1 self.TraceFrames = None self.TraceCount = 0 self.GenericTpNames = None @@ -181,15 +176,12 @@ class TypeGenBase: # ============================================================ def ensure_spec_arena(self) -> TSpec.TypeSpecArena*: """确保 TypeSpec 驻留表已创建,返回 arena;失败返回 None""" - if self.Specs is not None: - return self.Specs + if self.Specs is not None: return self.Specs size: sizet = TSpec.TypeSpecArena.__sizeof__() arena: TSpec.TypeSpecArena* = TSpec.TypeSpecArena*(CompilerFactory.factory.PermPool.alloc(size)) - if arena is None: - return None + if arena is None: return None string.memset(arena, 0, size) - if TSpec.SpecArenaInit(arena, 0) != 0: - return None + if TSpec.SpecArenaInit(arena, 0) != 0: return None self.Specs = arena return arena # ============================================================ @@ -199,30 +191,24 @@ class TypeGenBase: def _ensure_trace_init(self) -> int: """确保调用栈已初始化(懒加载,用 malloc 不依赖 pool)""" - if self.TraceFrames is not None: - return 1 + if self.TraceFrames is not None: return 1 entry_size: sizet = GenTypes.TraceFrame.__sizeof__() self.TraceFrames = CompilerFactory.factory.PermPool.alloc(entry_size * TypeGenMixin.TRACE_MAX) - if self.TraceFrames is None: - return 0 + if self.TraceFrames is None: return 0 string.memset(self.TraceFrames, 0, entry_size * TypeGenMixin.TRACE_MAX) return 1 def _get_trace_frame(self, i: int) -> rawptr[GenTypes.TraceFrame]: """获取第 i 个 TraceFrame 槽位""" - if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX: - return None + if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX: return None entry_size: sizet = GenTypes.TraceFrame.__sizeof__() addr: uint64 = uint64(self.TraceFrames) + i * entry_size return rawptr[GenTypes.TraceFrame](addr) def push_trace(self, file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None: """压入一个翻译上下文帧(进入新的翻译作用域时调用)""" - if self._ensure_trace_init() == 0: - return - if self.TraceCount >= TypeGenMixin.TRACE_MAX: - return + if self._ensure_trace_init() == 0: return + if self.TraceCount >= TypeGenMixin.TRACE_MAX: return frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount) - if frame is None: - return + if frame is None: return frame.file_name = file_name frame.lineno = lineno frame.col_start = col_start @@ -230,8 +216,7 @@ class TypeGenBase: self.TraceCount += 1 def pop_trace(self) -> None: """弹出栈顶帧(退出翻译作用域时调用)""" - if self.TraceCount <= 0: - return + if self.TraceCount <= 0: return self.TraceCount -= 1 frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount) if frame is not None: @@ -241,7 +226,6 @@ class TypeGenBase: frame.col_end = 0 def clear_trace(self) -> None: """清空调用栈(每个文件翻译开始前调用)""" - i: int for i in range(self.TraceCount): frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(i) if frame is not None: diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index 388c1d3..d38bbb9 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -22,22 +22,17 @@ import lib.core.Gen.Type.TypeGenBase as TypeGenBase # 槽存槽下标 + 1(0=空槽)。CDefineNames 只追加不重排 ⇒ 槽下标稳定; # Built == len(CDefineNames) 才可信。 # ============================================================ -CDEFINE_IDX_CAP: t.CDefine = 4096 -# 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致) -CDEF_IDX_FNV_OFFSET: t.CDefine = 2166136261 -CDEF_IDX_FNV_PRIME: t.CDefine = 16777619 -CDEF_IDX_FNV_MASK: t.CDefine = 4294967295 +define CDEFINE_IDX_CAP = 4096 +# 索引哈希常量(32 位 FNV-1a) +define CDEF_IDX_FNV_OFFSET = 2166136261 +define CDEF_IDX_FNV_PRIME = 16777619 +define CDEF_IDX_FNV_MASK = 4294967295 # ============================================================ # TypeGenCDef - TypeGenMixin 拆分(阶段 D):CDefine 编译期常量表(register/lookup/is/set/clear) -# -# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class TypeGenCDef(TypeGenBase.TypeGenBase): +novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): """CDefine 编译期常量表(register/lookup/is/set/clear)""" # ============================================================ @@ -169,8 +164,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): # 建表失败(池不可用/耗尽)⇒ 明确报错并返回,绝不让下面的 append # 落到 None 或未初始化地址(原实现无检查 ⇒ append 写进 NULL/0xCD 区崩) if tn is None or tv is None or td is None or tsf is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 表分配失败(表本体池不可用或耗尽)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 表分配失败(表本体池不可用或耗尽)", "MemoryError") return self.CDefineNames = tn self.CDefineValues = tv @@ -181,8 +175,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): # 不写垃圾(append 之前必有非空断言) if self.CDefineNames is None or self.CDefineValues is None \ or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") return name_copy: str = pool.alloc(string.strlen(name) + 1) if name_copy is None: @@ -223,8 +216,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): td: list[int] | t.CPtr = list[int](tp, 64) tsf: list[int] | t.CPtr = list[int](tp, 64) if tn is None or tv is None or td is None or tsf is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 浮点表分配失败(表本体池不可用或耗尽)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点表分配失败(表本体池不可用或耗尽)", "MemoryError") return self.CDefineNames = tn self.CDefineValues = tv @@ -234,8 +226,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): # 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言 if self.CDefineNames is None or self.CDefineValues is None \ or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 浮点表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") return name_copy_d: str = pool.alloc(string.strlen(name) + 1) if name_copy_d is None: @@ -281,8 +272,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): td: list[int] | t.CPtr = list[int](tp, 64) tsf: list[int] | t.CPtr = list[int](tp, 64) if tn is None or tv is None or td is None or tsf is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 字符串表分配失败(表本体池不可用或耗尽)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 字符串表分配失败(表本体池不可用或耗尽)", "MemoryError") return self.CDefineNames = tn self.CDefineValues = tv @@ -292,8 +282,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): # 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言 if self.CDefineNames is None or self.CDefineValues is None \ or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None: - self.Gen.TypeGenErr.fatal_error( - None, "CDefine 字符串表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") + self.Gen.TypeGenErr.fatal_error(None, "CDefine 字符串表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError") return ncopy_s: str = pool.alloc(string.strlen(name) + 1) if ncopy_s is None: diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index a48fc94..d015fd3 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -23,18 +23,17 @@ import lib.core.Gen.Type.TypeSpec as TSpec # 槽存槽下标 + 1(0=空槽)。CTypedefNames 只追加不重排(同名注册原地更新类型串) # ⇒ 槽下标稳定;Built == len(CTypedefNames) 才可信。 # ============================================================ -CTYPEDEF_IDX_CAP: t.CDefine = 4096 +define CTYPEDEF_IDX_CAP = 4096 # 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致) -CTYPEDEF_IDX_FNV_OFFSET: t.CDefine = 2166136261 -CTYPEDEF_IDX_FNV_PRIME: t.CDefine = 16777619 -CTYPEDEF_IDX_FNV_MASK: t.CDefine = 4294967295 +define CTYPEDEF_IDX_FNV_OFFSET = 2166136261 +define CTYPEDEF_IDX_FNV_PRIME = 16777619 +define CTYPEDEF_IDX_FNV_MASK = 4294967295 def _ctypedef_idx_hash(name: str) -> uint64: """CTypedef 名 → 64 位哈希(32 位 FNV-1a,逐字节到 NUL 结束)""" h: uint64 = uint64(CTYPEDEF_IDX_FNV_OFFSET) - if name is None: - return h + if name is None: return h i: sizet = 0 while name[i] != '\0': h = (h ^ uint64(int(name[i]))) * uint64(CTYPEDEF_IDX_FNV_PRIME) @@ -222,15 +221,13 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if self.LastBuiltinsTypedefNameBuf is None: self.LastBuiltinsTypedefNameBuf = stdlib.malloc(need) else: - self.LastBuiltinsTypedefNameBuf = stdlib.realloc( - self.LastBuiltinsTypedefNameBuf, need) + self.LastBuiltinsTypedefNameBuf = stdlib.realloc(self.LastBuiltinsTypedefNameBuf, need) buf: str = self.LastBuiltinsTypedefNameBuf else: if self.LastBuiltinsTypedefResultBuf is None: self.LastBuiltinsTypedefResultBuf = stdlib.malloc(need) else: - self.LastBuiltinsTypedefResultBuf = stdlib.realloc( - self.LastBuiltinsTypedefResultBuf, need) + self.LastBuiltinsTypedefResultBuf = stdlib.realloc(self.LastBuiltinsTypedefResultBuf, need) buf = self.LastBuiltinsTypedefResultBuf if buf is None: return None @@ -707,8 +704,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # ExprGenMixin 方法,TypeGenMixin 直接调用会生成未定义引用) if (from_imports is not None or imported_modules is not None) \ and pool is not None: - x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine( - pool, nm.id, from_imports, imported_modules) + x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, nm.id, from_imports, imported_modules) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: self.ConstEvalOk = 1 return x_val @@ -739,8 +735,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): for mi in range(mod_len): fi_buf[2 + mi] = at_mod.id[mi] fi_buf[2 + mod_len] = '\0' - av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine( - pool, at.attr, fi_buf, imported_modules) + av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, at.attr, fi_buf, imported_modules) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: self.ConstEvalOk = 1 return av diff --git a/App/lib/core/Gen/Type/TypeGenErr.vp b/App/lib/core/Gen/Type/TypeGenErr.vp index 9fee6a6..0295472 100644 --- a/App/lib/core/Gen/Type/TypeGenErr.vp +++ b/App/lib/core/Gen/Type/TypeGenErr.vp @@ -22,21 +22,15 @@ import lib.core.Gen.Type.TypeSpec as TSpec # ============================================================ # TypeGenErr - 错误上报/源行读取/类型推断(fatal_error/infer_* 等) -# -# 继承链仅 1 级(TPV self 调用仅支持 1 级父类);跨 Mixin 调用统一走 HandlesType 委托。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class TypeGenErr(TypeGenBase.TypeGenBase): +novirtual class TypeGenErr(TypeGenBase.TypeGenBase): """错误上报/源行读取/类型推断(fatal_error/infer_* 等)""" def _read_source_line(self, file_path: str, lineno: int) -> str: """从源文件读取第 lineno 行内容""" - if file_path is None or lineno <= 0: - return None + if file_path is None or lineno <= 0: return None f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R) - if f.closed: - return None + if f.closed: return None # 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 → # 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第 # 8390 行)。64MB 上限防御异常超大文件整体读取。 @@ -355,10 +349,8 @@ class TypeGenErr(TypeGenBase.TypeGenBase): elif k == ast.ASTKind.BinOp: binop: ast.BinOp* = ast.BinOp*(node) - lhs_ty: llvmlite.LLVMType* = self.infer_expr_type( - pool, binop.left, param_types) - rhs_ty: llvmlite.LLVMType* = self.infer_expr_type( - pool, binop.right, param_types) + lhs_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, binop.left, param_types) + rhs_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, binop.right, param_types) lhs_bits: int = self.get_llvm_type_bits(lhs_ty) rhs_bits: int = self.get_llvm_type_bits(rhs_ty) if lhs_bits >= rhs_bits: @@ -380,8 +372,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if stmt is not None and stmt.kind() == ast.ASTKind.Return: rt: rawptr[ast.Return] = rawptr[ast.Return](stmt) if rt.value is not None: - expr_ty: llvmlite.LLVMType* = self.infer_expr_type( - pool, rt.value, param_types) + expr_ty: llvmlite.LLVMType* = self.infer_expr_type(pool, rt.value, param_types) if expr_ty is not None: cur_bits: int = self.get_llvm_type_bits(ret_ty) new_bits: int = self.get_llvm_type_bits(expr_ty) diff --git a/App/lib/core/Gen/Type/TypeGenMixin.vp b/App/lib/core/Gen/Type/TypeGenMixin.vp index 28be6fe..5996306 100644 --- a/App/lib/core/Gen/Type/TypeGenMixin.vp +++ b/App/lib/core/Gen/Type/TypeGenMixin.vp @@ -26,13 +26,12 @@ import lib.core.Gen.Type.TypeGenBase as TypeGenBase # ============================================================ # 常量(与 HandlesType 保持一致) # ============================================================ -TRACE_MAX: t.CDefine = 32 -MAX_CTYPEDEF_DEPTH: t.CDefine = 10 +define TRACE_MAX = 32 +define MAX_CTYPEDEF_DEPTH = 10 # ============================================================ # TypeGenMixin - 类型映射/注解解析/编译期常量表/错误上报 # ============================================================ -@t.NoVTable -class TypeGenMixin(TypeGenBase.TypeGenBase): +novirtual class TypeGenMixin(TypeGenBase.TypeGenBase): """类型映射与解析 Mixin(阶段 D 拆分后顶层,方法全部在子 Mixin)""" diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index c553c18..effb9b0 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -27,13 +27,8 @@ import w32.fileio as fileio # ============================================================ # TypeGenResolve - TypeGenMixin 拆分(阶段 D):类型映射/注解解析(map_t_type/resolve_annotation_type 等) -# -# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class TypeGenResolve(TypeGenBase.TypeGenBase): +novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): """类型映射/注解解析(map_t_type/resolve_annotation_type 等)""" def _get_type_name_from_annotation(self, pool: memhub.MemBuddy*, @@ -179,8 +174,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): es3: str = self._subscript_slice_to_str(pool, e3) if es3 is None: # 类型名缺失 ⇒ 立即报错(静默丢弃会拼出错误类型串) - self.Gen.TypeGenErr.fatal_error( - e3, "类型注解的元素无法解析为类型名(列表/元组注解)", "NameError") + self.Gen.TypeGenErr.fatal_error(e3, "类型注解的元素无法解析为类型名(列表/元组注解)", "NameError") return None cnt3 += 1 total3 += string.strlen(es3) @@ -468,8 +462,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): mod_buf[mod_len] = '\0' # 4a. mod 是 import 别名(import X as mod 注册 "mod:X")→ 完整模块名 → SHA1 if from_imports is not None: - orig_mod: str = self.Gen.ImportsGen.lookup_from_import( - from_imports, mod_buf, 0) + orig_mod: str = self.Gen.ImportsGen.lookup_from_import(from_imports, mod_buf, 0) if orig_mod is not None: sha1a: str = self.Gen.CallGenBase._lookup_sha1_from_modname_raw(pool, orig_mod) if sha1a is not None: @@ -486,8 +479,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return type_name # ---- 5. 裸名 "Class":查 from_imports 所属模块 SHA1 ---- if from_imports is not None: - sha1c: str = self.Gen.CallGenBase._lookup_mod_sha1( - pool, from_imports, type_name, 0) + sha1c: str = self.Gen.CallGenBase._lookup_mod_sha1(pool, from_imports, type_name, 0) if sha1c is not None: res_c: str = self._concat_sha1_class(pool, sha1c, type_name) if res_c is not None: @@ -572,8 +564,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): left_buf[left_len] = '\0' left_node: ast.AST* = self._parse_type_string(pool, left_buf, ctx) # 右段前导空格由递归入口跳过 - right_node: ast.AST* = self._parse_type_string( - pool, type_str + pipe_idx + 1, ctx) + right_node: ast.AST* = self._parse_type_string(pool, type_str + pipe_idx + 1, ctx) stdlib.free(left_buf) if left_node is not None and right_node is not None: return ast.BinOp(pool, left_node, ast.OpKind.BitOr, right_node) @@ -726,8 +717,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): inner_rt: ast.AST* = self._parse_type_string(pool, ts_rt, ast.ASTCtx.Load) if inner_rt is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - ity_rt: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, inner_rt, imported_modules, from_imports, trans, 1) + ity_rt: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_rt, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if ity_rt is not None: @@ -742,8 +732,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if btd_node_r is not None: if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - btd_ty_r: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, btd_node_r, imported_modules, from_imports, trans, 1) + btd_ty_r: llvmlite.LLVMType* = self.resolve_annotation_type(pool, btd_node_r, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 if btd_ty_r is not None: return btd_ty_r @@ -759,8 +748,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_node is not None: if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - lib_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, lib_node, imported_modules, from_imports, trans, 1) + lib_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, lib_node, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 if lib_ty is not None: return lib_ty @@ -1267,8 +1255,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strncpy(m_tb, m_buf + m_ls + m_vs, m_vlen) m_tb[m_vlen] = '\0' # 写入持久缓存(首次遇到的名字为准) - self._register_lib_typedef_cache( - m_real, m_buf + m_ls, m_nl, m_tb) + self._register_lib_typedef_cache(m_real, m_buf + m_ls, m_nl, m_tb) # 原实现语义:attr 的首次匹配值 if m_res is None and m_nl == attr_len: m_nm_ok: int = 1 @@ -1581,8 +1568,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if at.value is not None: prefix: str = self.annotation_to_str(at.value) if prefix is not None: - buf: str = stdlib.malloc( - string.strlen(prefix) + string.strlen(at.attr) + 2) + buf: str = stdlib.malloc(string.strlen(prefix) + string.strlen(at.attr) + 2) if buf is not None: viperlib.snprintf(buf, string.strlen(prefix) + string.strlen(at.attr) + 2, @@ -1608,8 +1594,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): left_s: str = self.annotation_to_str(bo.left) right_s: str = self.annotation_to_str(bo.right) if left_s is not None and right_s is not None: - buf3: str = stdlib.malloc( - string.strlen(left_s) + string.strlen(right_s) + 5) + buf3: str = stdlib.malloc(string.strlen(left_s) + string.strlen(right_s) + 5) if buf3 is not None: viperlib.snprintf(buf3, string.strlen(left_s) + string.strlen(right_s) + 5, @@ -1727,8 +1712,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if alias_mod2 is not None: real_mod2 = alias_mod2 # 返回模块限定名 "module.Class"(如 "memhub.MemBuddy") - mod_qual_buf: str = stdlib.malloc( - string.strlen(real_mod2) + string.strlen(at.attr) + 2) + mod_qual_buf: str = stdlib.malloc(string.strlen(real_mod2) + string.strlen(at.attr) + 2) if mod_qual_buf is not None: viperlib.snprintf(mod_qual_buf, string.strlen(real_mod2) + string.strlen(at.attr) + 2, @@ -1782,15 +1766,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): rp_nm: ast.Name* = ast.Name*(sub.value) if rp_nm.id is not None and string.strcmp(rp_nm.id, "rawptr") == 0: if sub.slice is not None: - return self.extract_class_name_from_annotation( - sub.slice, imported_modules, pool, from_imports) + return self.extract_class_name_from_annotation(sub.slice, imported_modules, pool, from_imports) return None # 递归取 base 时必须把 from_imports 一并下传:否则同一份注解在派发名/查表键/ # 注册键三处算出的 mangled 名不一致(如 list[ast.AST*] 的元素段), # 出现「alloca 裸 list* / pass1 按 list[ast.ASTptr] / pass2 按 list[ast.ClassDefptr]」 # 的分裂崩溃。其余调用点均已传。 - base_name: str = self.extract_class_name_from_annotation( - sub.value, imported_modules, pool, from_imports) + base_name: str = self.extract_class_name_from_annotation(sub.value, imported_modules, pool, from_imports) if base_name is None: return None # pool 不可用时,只返回裸类名(向后兼容) @@ -1888,8 +1870,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): tup_elt: ast.AST* = tp_elts.get(tui) if tup_elt is None: continue - tup_ety: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, tup_elt, imported_modules, from_imports, trans, depth + 1) + tup_ety: llvmlite.LLVMType* = self.resolve_annotation_type(pool, tup_elt, imported_modules, from_imports, trans, depth + 1) if tup_ety is None: return None tup_node: llvmlite.Function* = llvmlite.new_param_node(pool, tup_ety) @@ -1978,8 +1959,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if inj_owner is None: inj_owner = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name) if inj_owner is not None: - ty_inj: llvmlite.LLVMType* = self._repl_opaque_class_ty( - pool, inj_owner, gen_mangled) + ty_inj: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, inj_owner, gen_mangled) if ty_inj is not None: return ty_inj # 归属未知(模板/归属均未登记)⇒ 保持原口径返回 None,由上层按 @@ -2007,14 +1987,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if trans is not None: template_cd_chk: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) if template_cd_chk is not None: - type_args_chk: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice( - pool, sub.slice, from_imports) + type_args_chk: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub.slice, from_imports) if type_args_chk is not None and len(type_args_chk) > 0: # 错误定位:压入触发特化的调用方帧(注解所在文件+行号) gen_cur_f2: str = self.Gen.TypeGenResolve.get_current_file() self.Gen.TypeGenBase.push_trace(gen_cur_f2, sub.lineno) - spec_name_chk: str = self.Gen.ClassGenGeneric._specialize_generic_class( - trans, gen_cls_name, type_args_chk) + spec_name_chk: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, gen_cls_name, type_args_chk) self.Gen.TypeGenBase.pop_trace() if spec_name_chk is not None: gen_spec_ty = self.Gen.StructGen.get_struct_type(gen_mangled) @@ -2042,8 +2020,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 与实际模板名。仅当基名确为泛型模板时才触发(避免误伤 rawptr/CArray 等 builtin)。 if trans is not None and trans._declare_only == 0 \ and self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) is not None: - self.Gen.TypeGenErr.fatal_error( - sub, + self.Gen.TypeGenErr.fatal_error(sub, f"泛型下标 '{gen_mangled}' 未解析出特化结构体(泛型模板='{gen_cls_name}');" f"该注解将退化为裸基类/i8* → 后续 .get() 按错误元素类型分派并截断指针", "TypeError") @@ -2063,8 +2040,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if trans is not None and trans.ReplCtx is not None: gowner_sha1: str = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name) if gowner_sha1 is not None: - ty_repl_g: llvmlite.LLVMType* = self._repl_opaque_class_ty( - pool, gowner_sha1, gen_mangled) + ty_repl_g: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, gowner_sha1, gen_mangled) if ty_repl_g is not None: return ty_repl_g # 未特化:返回 None(不报错,让后续流程处理) @@ -2140,8 +2116,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(gp_ta, gp_tpn) == 0: # 泛型类型参数自映射(T→T):编译期报错,不静默退化 # (静默退化会让运行时数据损坏难定位)。 - self.Gen.TypeGenErr.fatal_error( - nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError") + self.Gen.TypeGenErr.fatal_error(nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError") polluted: int = 0 gp_j: sizet for gp_j in range(gp_n): @@ -2159,8 +2134,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 实参串包含类型参数名(如 "T | t.CPtr"/"list[T]"): # 解析后仍产出 Name(参数名) → 无条件自递归卡死。编译期 # 报错(此前 return None 静默退化)。 - self.Gen.TypeGenErr.fatal_error( - nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError") + self.Gen.TypeGenErr.fatal_error(nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError") # 用具体类型名递归解析(支持 BinOp/Attribute 类型实参) gp_sub_node: ast.AST* = self._parse_type_string(pool, gp_ta, nm.ctx) if gp_sub_node is not None: @@ -2180,8 +2154,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if sp_sha_buf2 is not None: string.strncpy(sp_sha_buf2, nm.id, sp_len2 - 1) sp_sha_buf2[sp_len2 - 1] = '\0' - sp_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( - nm.id + sp_len2, sp_sha_buf2) + sp_entry2: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(nm.id + sp_len2, sp_sha_buf2) if sp_entry2 is not None and sp_entry2.Ty is not None: if sp_entry2.HasNew != 0: return llvmlite.Ptr(pool, sp_entry2.Ty) @@ -2276,8 +2249,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): inner_node: ast.AST* = self._parse_type_string(pool, ctypedef_str, nm.ctx) if inner_node is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - inner_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, inner_node, imported_modules, from_imports, trans, depth + 1) + inner_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_node, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if inner_ty is not None: @@ -2311,8 +2283,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 用原始名重建节点递归解析(depth 守卫复用 resolve 上限) orig_node_a: ast.AST* = self._parse_type_string(pool, oa_buf, nm.ctx) if orig_node_a is not None: - alias_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, orig_node_a, imported_modules, from_imports, trans, depth + 1) + alias_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, orig_node_a, imported_modules, from_imports, trans, depth + 1) if alias_ty is not None: return alias_ty # [builtins 最后匹配] 常规路径全部 miss 后的最终兜底:查 @@ -2322,8 +2293,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if btd_n is not None: btd_node_n: ast.AST* = self._parse_type_string(pool, btd_n, nm.ctx) if btd_node_n is not None: - btd_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, btd_node_n, imported_modules, from_imports, trans, depth + 1) + btd_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, btd_node_n, imported_modules, from_imports, trans, depth + 1) if btd_ty_n is not None: return btd_ty_n # 库 typedef 兜底:stdint / w32.win32base 等库模块的裸 typedef @@ -2336,8 +2306,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_ts_n is not None: lib_node_n: ast.AST* = self._parse_type_string(pool, lib_ts_n, nm.ctx) if lib_node_n is not None: - lib_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, lib_node_n, imported_modules, from_imports, trans, depth + 1) + lib_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, lib_node_n, imported_modules, from_imports, trans, depth + 1) if lib_ty_n is not None: return lib_ty_n # [REPL 会话] 归属模块已知(from_imports 解析出 sha1;或本模块自身 = @@ -2359,8 +2328,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): and string.strcmp(trans.ModuleSha1, GenTypes.REPL_SESSION_SHA1) != 0: own_sha_rn = trans.ModuleSha1 if own_sha_rn is not None: - ty_repl_n: llvmlite.LLVMType* = self._repl_opaque_class_ty( - pool, own_sha_rn, nm.id) + ty_repl_n: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, own_sha_rn, nm.id) if ty_repl_n is not None: return ty_repl_n return None @@ -2418,8 +2386,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): inner_attr: ast.AST* = self._parse_type_string(pool, ctypedef_attr, ast.ASTCtx.Load) if inner_attr is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - inner_ty_attr: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, inner_attr, imported_modules, from_imports, trans, depth + 1) + inner_ty_attr: llvmlite.LLVMType* = self.resolve_annotation_type(pool, inner_attr, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if inner_ty_attr is not None: @@ -2453,8 +2420,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if is_builtin_attr == 0: # 模块名 → sha1(精确/后缀/import 别名还原,统一经 # StructGenMixin._resolve_module_sha1 逐级尝试) - mod_sha1_v: str = self.Gen.StructGen._resolve_module_sha1( - val_name.id, from_imports) + mod_sha1_v: str = self.Gen.StructGen._resolve_module_sha1(val_name.id, from_imports) mod_sha1_rv = mod_sha1_v if mod_sha1_v is not None: full_q_v: str = self._concat_sha1_class(pool, mod_sha1_v, at.attr) @@ -2486,12 +2452,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): mod_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) if mod_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: - mod_td_inner: ast.AST* = self._parse_type_string( - pool, mod_td_str, at.ctx) + mod_td_inner: ast.AST* = self._parse_type_string(pool, mod_td_str, at.ctx) if mod_td_inner is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - mod_td_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, mod_td_inner, imported_modules, from_imports, trans, depth + 1) + mod_td_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, mod_td_inner, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if mod_td_ty is not None: @@ -2503,8 +2467,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 不可解析被跳过)⇒ 用 opaque 具名类型占位(不写 StructTable ⇒ # 字段访问仍按"类未注册"明确报错)。批处理 trans.ReplCtx 恒 None。 if trans is not None and trans.ReplCtx is not None and mod_sha1_rv is not None: - ty_repl_a: llvmlite.LLVMType* = self._repl_opaque_class_ty( - pool, mod_sha1_rv, at.attr) + ty_repl_a: llvmlite.LLVMType* = self._repl_opaque_class_ty(pool, mod_sha1_rv, at.attr) if ty_repl_a is not None: return ty_repl_a return None @@ -2525,12 +2488,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): nested_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) if nested_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: - nested_inner: ast.AST* = self._parse_type_string( - pool, nested_td_str, at.ctx) + nested_inner: ast.AST* = self._parse_type_string(pool, nested_td_str, at.ctx) if nested_inner is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - nested_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, nested_inner, imported_modules, from_imports, trans, depth + 1) + nested_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, nested_inner, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if nested_ty is not None: @@ -2551,8 +2512,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_td_na is not None: td_node_na: ast.AST* = self._parse_type_string(pool, lib_td_na, at.ctx) if td_node_na is not None: - td_ty_na: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, td_node_na, imported_modules, from_imports, trans, depth + 1) + td_ty_na: llvmlite.LLVMType* = self.resolve_annotation_type(pool, td_node_na, imported_modules, from_imports, trans, depth + 1) if td_ty_na is not None: return td_ty_na return None @@ -2593,8 +2553,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): other_is_cvoid = 1 if other_is_cvoid != 0: return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - other_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, other_node, imported_modules, from_imports, trans, depth + 1) + other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, other_node, imported_modules, from_imports, trans, depth + 1) # 仅裸名(Name)场景验证解析结果必须是已注册 struct: # 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。 # Attribute 场景(Module.Class / t.XXX)resolve 结果直接可用 @@ -2664,8 +2623,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): case _: td_res_is_ptr = 0 if td_res_is_ptr == 0: - td_alias_ty: llvmlite.LLVMType* = self.resolve_typedef_or_map( - pool, other_nm_td.id, imported_modules, from_imports, trans) + td_alias_ty: llvmlite.LLVMType* = self.resolve_typedef_or_map(pool, other_nm_td.id, imported_modules, from_imports, trans) if td_alias_ty is not None: keep_other_ty = 1 if keep_other_ty == 0: @@ -2709,10 +2667,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): cptr_sub_side = bop.right cptr_other = bop.left if cptr_sub_side is not None and cptr_other is not None: - cptr_sub_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, cptr_sub_side, imported_modules, from_imports, trans, depth + 1) - cptr_other_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, cptr_other, imported_modules, from_imports, trans, depth + 1) + cptr_sub_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, cptr_sub_side, imported_modules, from_imports, trans, depth + 1) + cptr_other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, cptr_other, imported_modules, from_imports, trans, depth + 1) if cptr_sub_ty is not None and cptr_other_ty is not None: # 计算 CPtr 侧外层 Ptr 嵌套数(如 t.CPtr[t.CPtr]=i8** → 2 层) cptr_level: int = 0 @@ -2740,12 +2696,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return res_ty # 无 CPtr 标记:返回第一个非 None(装饰器标记如 CExport/CExtern 被忽略) - left_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, bop.left, imported_modules, from_imports, trans, depth + 1) + left_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, bop.left, imported_modules, from_imports, trans, depth + 1) if left_ty is not None: return left_ty - right_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, bop.right, imported_modules, from_imports, trans, depth + 1) + right_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, bop.right, imported_modules, from_imports, trans, depth + 1) if right_ty is not None: return right_ty return None @@ -2782,12 +2736,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): cnt_arr0: ast.Constant* = ast.Constant*(count_node_arr) if cnt_arr0.const_kind == ast.CONST_NONE: self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是正整型常量(>0),不允许 None(长度自动推导请改用 t.CArray[E])。正确示例:state: array[uint32, 4]") - elem_ty_arr: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, elem_node_arr, imported_modules, from_imports, trans, depth + 1) + elem_ty_arr: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node_arr, imported_modules, from_imports, trans, depth + 1) if elem_ty_arr is None: return None - count_arr: int = self.Gen.TypeGenCType._eval_const_int_expr( - count_node_arr, pool, from_imports, imported_modules) + count_arr: int = self.Gen.TypeGenCType._eval_const_int_expr(count_node_arr, pool, from_imports, imported_modules) if self.Gen.TypeGenCType.ConstEvalOk == 0: self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是整型常量表达式(字面量 / CDefine 常量名 / 常量算术表达式)。正确示例:state: array[uint8, MAX_LEN]") if count_arr <= 0: @@ -2799,8 +2751,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(gen_nm.id, "CArray") == 0 or string.strcmp(gen_nm.id, "rawarray") == 0: # 单参数: CArray[elem_ty] → Ptr(elem_ty)(静态推导长度数组) if sub.slice.kind() != ast.ASTKind.Tuple: - elem_n: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, sub.slice, imported_modules, from_imports, trans, depth + 1) + elem_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if elem_n is None: return None return llvmlite.Ptr(pool, elem_n) @@ -2812,8 +2763,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): count_node_n: ast.AST* = tup_n.elts.get(1) if elem_node_n is None or count_node_n is None: return None - elem_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, elem_node_n, imported_modules, from_imports, trans, depth + 1) + elem_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node_n, imported_modules, from_imports, trans, depth + 1) if elem_ty_n is None: return None # count=None → Ptr(elem)(等价单参) @@ -2821,8 +2771,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): cnt_n: ast.Constant* = ast.Constant*(count_node_n) if cnt_n.const_kind == ast.CONST_NONE: return llvmlite.Ptr(pool, elem_ty_n) - count_n: int = self.Gen.TypeGenCType._eval_const_int_expr( - count_node_n, pool, from_imports, imported_modules) + count_n: int = self.Gen.TypeGenCType._eval_const_int_expr(count_node_n, pool, from_imports, imported_modules) if self.Gen.TypeGenCType.ConstEvalOk == 0 or count_n <= 0: return None return llvmlite.Array(pool, elem_ty_n, count_n) @@ -2831,14 +2780,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # "函数返回类型解析失败:注解不可解析"。 if string.strcmp(gen_nm.id, "rawptr") == 0: if sub.slice.kind() != ast.ASTKind.Tuple: - rp_elem: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, sub.slice, imported_modules, from_imports, trans, depth + 1) + rp_elem: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if rp_elem is None: return None return llvmlite.Ptr(pool, rp_elem) return None - gen_ty_nm: llvmlite.LLVMType* = self._resolve_generic_subscript_ty( - pool, sub, gen_nm.id, trans, + gen_ty_nm: llvmlite.LLVMType* = self._resolve_generic_subscript_ty(pool, sub, gen_nm.id, trans, imported_modules, from_imports, depth + 1) if gen_ty_nm is not None: return gen_ty_nm @@ -2863,8 +2810,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(fb_str, "]") fb_node: ast.AST* = self._parse_type_string(pool, fb_str, ast.ASTCtx.Load) if fb_node is not None: - fb_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, fb_node, imported_modules, from_imports, trans, depth + 1) + fb_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, fb_node, imported_modules, from_imports, trans, depth + 1) if fb_ty is not None: return fb_ty return None @@ -2899,8 +2845,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \ and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0: self.Gen.TypeGenErr.fatal_type_error(node, "t.CPtr 模块未导入") - inner_cptr_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, sub.slice, imported_modules, from_imports, trans, depth + 1) + inner_cptr_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if inner_cptr_ty is None: # 元素类型依赖未就绪(如 t.CPtr[类] 中类尚未注册):返回 None 交上层多遍 # 收敛,不在此 fatal 中断 Phase 1a 预注册(UINT 等只经 CTypedef 动态表解析, @@ -2916,8 +2861,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 单参数形式: t.CArray[elem_ty] → Ptr(elem_ty) # 相当于 t.CArray[elem_ty, None],表示静态推导长度数组 if sub.slice.kind() != ast.ASTKind.Tuple: - elem_ty_single: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, sub.slice, imported_modules, from_imports, trans, depth + 1) + elem_ty_single: llvmlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if elem_ty_single is None: # 元素类型依赖未就绪(同 L1807 注释):返回 None 交多遍收敛 return None @@ -2935,8 +2879,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if elem_node is None or count_node is None: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素为 None") # 递归解析元素类型 - elem_ty: llvmlite.LLVMType* = self.resolve_annotation_type( - pool, elem_node, imported_modules, from_imports, trans, depth + 1) + elem_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, elem_node, imported_modules, from_imports, trans, depth + 1) if elem_ty is None: # 元素类型依赖未就绪(如 t.CArray[类, N] 中类尚未注册):返回 None 交上层多遍 # 收敛,不在此 fatal 中断 Phase 1a 预注册(UINT 等只经 CTypedef 动态表解析, diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index e9a01f5..f12892f 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -25,46 +25,28 @@ import lib.core.Gen.GenApi as GenApi # ============================================================ # Kind - 基础类型种类 # ============================================================ -TS_UNKNOWN: t.CDefine = 0 -TS_INT: t.CDefine = 1 -TS_UINT: t.CDefine = 2 -TS_FLOAT: t.CDefine = 3 -TS_BOOL: t.CDefine = 4 -TS_PTR: t.CDefine = 5 -TS_ARRAY: t.CDefine = 6 -TS_STRUCT: t.CDefine = 7 -TS_VOID: t.CDefine = 8 -TS_FUNC: t.CDefine = 9 -TS_UNION: t.CDefine = 10 -TS_ENUM: t.CDefine = 11 +define TS_UNKNOWN = 0 +define TS_INT = 1 +define TS_UINT = 2 +define TS_FLOAT = 3 +define TS_BOOL = 4 +define TS_PTR = 5 +define TS_ARRAY = 6 +define TS_STRUCT = 7 +define TS_VOID = 8 +define TS_FUNC = 9 +define TS_UNION = 10 +define TS_ENUM = 11 # ============================================================ # IsSigned - 符号性(单一真源,替代 _annot_str_unsigned 的子串扫描) # ============================================================ -TS_SIGN_UNKNOWN: t.CDefine = -1 -TS_SIGN_UNSIGNED: t.CDefine = 0 -TS_SIGN_SIGNED: t.CDefine = 1 +define TS_SIGN_UNKNOWN = -1 +define TS_SIGN_UNSIGNED = 0 +define TS_SIGN_SIGNED = 1 -# 驻留表默认容量与单条类型文本上限(超限 fail-fast,绝不静默丢弃/截断) -# 容量 × 文本上限即驻留表键缓冲的 PermPool 占用(8192 × 256 = 2MB) -# 注:键文本超 SPEC_TEXT_MAX 的长签名/深嵌套类型 ⇒ 不驻留(保留完整实例, -# 仅放弃去重),见 InternSpec —— 截断键会让 strcmp 撞类型、返回错误实例。 -SPEC_INTERN_MAX: t.CDefine = 8192 -SPEC_TEXT_MAX: t.CDefine = 256 - - -# ============================================================ -# 符号性精确名表 - 按「名字切片」判定(**不做子串扫描**) -# -# 必须精确匹配:strstr 子串扫描会误判 `BYTEPTR`(含 `BYTE`)以及任何含 `uint32` -# 子串的名字(含 sha1 前缀名)。 -# 覆盖范围:本模块只认 t/c 核心原语名与少数内建名;stdint 别名(DWORD/WORD/size_t/ -# uint32_t/…)由调用方沿 CTypedef 链逐层展开后再落到本函数(链展开需 CTypedef 表, -# 不在本模块做,避免反向依赖)。 -# 口径:SSizeT 为**有符号**;BOOL 按 stdint.vp 定义是 int(**有符号**); -# 指针名(BYTEPTR/UINTPTR/INTPTR/CHARPTR/…)返回 UNKNOWN——指针的"无符号"语义 -# 由 PtrLevel 表达,与整数符号性无关。 -# ============================================================ +define SPEC_INTERN_MAX = 8192 +define SPEC_TEXT_MAX = 256 # ============================================================ @@ -72,18 +54,13 @@ SPEC_TEXT_MAX: t.CDefine = 256 # ============================================================ def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int: """切片名比较:长度相同且逐字符相等返回 1,否则 0""" - if text is None or lit is None: - return 0 - if end <= start: - return 0 + if text is None or lit is None: return 0 + if end <= start: return 0 ln: sizet = string.strlen(lit) - if end - start != ln: - return 0 - k: sizet = 0 - while k < ln: + if end - start != ln: return 0 + for k in range(ln): if text[start + k] != lit[k]: return 0 - k += 1 return 1 @@ -102,11 +79,9 @@ def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int: # ============================================================ def SpecTypeNameBaseIs(name: str, base: str) -> int: """类型名的容器基名是否精确等于 base(1=是 / 0=否)""" - if name is None or base is None: - return 0 + if name is None or base is None: return 0 n: sizet = string.strlen(name) - if n == 0: - return 0 + if n == 0: return 0 # 基名上界:第一个 '['(泛型实参起点;无 '[' 则到串尾) end: sizet = n lb: str = string.strchr(name, '[') @@ -215,7 +190,7 @@ class TypeSpec: Bits: int # 位宽;非整型/浮点为 0 IsSigned: int # TS_SIGN_* (-1 未知 / 0 无符号 / 1 有符号) PtrLevel: int # 指针层级(0=非指针) - Elem: TypeSpec | t.CPtr # Ptr/Array 的指向或元素(None=无) + Elem: TypeSpec* # Ptr/Array 的指向或元素(None=无) ArrayCount: int # Array 的元素个数(0=未知/动态) BaseName: str # 结构体/枚举/类名(带模块 sha1;PermPool 深拷贝) # SourceName: 注解侧「来源名」(替代 AnnotClassName)。 @@ -229,7 +204,7 @@ class TypeSpec: # 入键会让 InternSpec 条目暴增且线性查找变慢;驻留本意只是跨 reset 存活, # 而 PermPool 分配天然满足 ⇒ SpecWithSource 返回独立副本、不进表。 SourceName: str - Ret: TypeSpec | t.CPtr # Func:返回类型 + Ret: TypeSpec* # Func:返回类型 Params: sizet* # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个) ParamCount: int # Func:参数个数 IsVarArg: int # Func:1=变参(...) @@ -382,11 +357,11 @@ def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: # ============================================================ # _spec_alloc - 从 PermPool 分配一个清零的 TypeSpec(不驻留,内部用) # ============================================================ -def _spec_alloc() -> TypeSpec | t.CPtr: +def _spec_alloc() -> TypeSpec*: """分配并清零一个 TypeSpec(PermPool)""" pp: memhub.MemBuddy* = CompilerFactory.factory.PermPool size: sizet = TypeSpec.__sizeof__() - sp: TypeSpec | t.CPtr = (TypeSpec | t.CPtr)(pp.alloc(size)) + sp: TypeSpec* = (TypeSpec*)(pp.alloc(size)) if sp is None: return None string.memset(sp, 0, size) @@ -402,9 +377,9 @@ def _spec_alloc() -> TypeSpec | t.CPtr: # ============================================================ # _spec_make - 构造一个基础 TypeSpec(不驻留) # ============================================================ -def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr: +def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec*: """构造基础 TypeSpec(PermPool,不驻留)""" - sp: TypeSpec | t.CPtr = _spec_alloc() + sp: TypeSpec* = _spec_alloc() if sp is None: return None sp.Kind = kind @@ -416,7 +391,7 @@ def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr: # ============================================================ # _spec_set_struct_name - 深拷贝类名到 PermPool(跨文件存活) # ============================================================ -def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int: +def _spec_set_struct_name(sp: TypeSpec*, name: str) -> int: """把类名深拷贝到 PermPool 并写入 BaseName,返回 0=成功 / 1=失败""" if sp is None or name is None: return 1 @@ -435,9 +410,9 @@ def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int: # NewTypeSpec - 构造基础类型(驻留) # ============================================================ def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int, - bits: int, is_signed: int) -> TypeSpec | t.CPtr: + bits: int, is_signed: int) -> TypeSpec*: """构造基础 TypeSpec 并驻留,失败返回 None""" - sp: TypeSpec | t.CPtr = _spec_make(kind, bits, is_signed) + sp: TypeSpec* = _spec_make(kind, bits, is_signed) if sp is None: return None return InternSpec(arena, sp) @@ -447,9 +422,9 @@ def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int, # NewTypeStruct - 构造结构体/枚举/类类型(驻留) # ============================================================ def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int, - base_name: str) -> TypeSpec | t.CPtr: + base_name: str) -> TypeSpec*: """构造 struct/union/enum 类型(BaseName 深拷贝 + 驻留),失败返回 None""" - sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) + sp: TypeSpec* = _spec_make(kind, 0, TS_SIGN_UNKNOWN) if sp is None: return None if _spec_set_struct_name(sp, base_name) != 0: @@ -461,11 +436,11 @@ def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int, # NewTypePtr - 构造指针类型(PtrLevel = 元素 PtrLevel + 1,驻留) # ============================================================ def NewTypePtr(arena: TypeSpecArena | t.CPtr, - elem: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + elem: TypeSpec*) -> TypeSpec*: """构造指针类型:指向 elem(PtrLevel 逐层递增),失败返回 None""" if elem is None: return None - sp: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) + sp: TypeSpec* = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) if sp is None: return None sp.Elem = elem @@ -480,12 +455,12 @@ def NewTypePtr(arena: TypeSpecArena | t.CPtr, # ============================================================ # NewTypeArray - 构造数组类型(ArrayCount 个 elem,驻留) # ============================================================ -def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr, - count: int) -> TypeSpec | t.CPtr: +def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec*, + count: int) -> TypeSpec*: """构造数组类型:elem[count](count<=0 表示长度未知/动态),失败返回 None""" if elem is None or count < 0: return None - sp: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) + sp: TypeSpec* = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) if sp is None: return None sp.Elem = elem @@ -501,15 +476,15 @@ def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr, # NewTypeFunc - 构造函数签名类型(ret + 参数数组 + 变参,驻留) # params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个 # ============================================================ -def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr, +def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec*, params: sizet*, count: int, - is_vararg: int) -> TypeSpec | t.CPtr: + is_vararg: int) -> TypeSpec*: """构造函数签名类型,失败返回 None""" if ret is None or count < 0: return None if count > 0 and params is None: return None - sp: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) + sp: TypeSpec* = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) if sp is None: return None sp.Ret = ret @@ -523,7 +498,7 @@ def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr, # SpecBaseText - 基础类型(非 Ptr/Array/Func)的规范文本 # 返回 0=已写入 / 1=不适用/失败 # ============================================================ -def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: +def SpecBaseText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int: """把基础类型写成规范文本;Ptr/Array/Func 不适用时返回 1""" if sp is None or buf is None or buf_size == 0: return 1 @@ -572,12 +547,12 @@ def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: # fn(INNER,INNER,...)->RET 函数签名(变参追加 "...") # 递归深度上限 32(防环);超限或缓冲不足返回 1(fail-fast 由调用方决定) # ============================================================ -def SpecToText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: +def SpecToText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int: """把 TypeSpec 编码为规范文本,返回 0=成功 / 1=失败""" return _spec_to_text(sp, buf, buf_size, 0) -def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, +def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int: """SpecToText 的递归实现(depth 上限 32)""" if sp is None or buf is None or buf_size == 0 or depth > 32: @@ -627,7 +602,7 @@ def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, pos = _spec_text_append(buf, buf_size, pos, ",") if pos >= buf_size: return 1 - param: TypeSpec | t.CPtr = _spec_param_at(sp, i) + param: TypeSpec* = _spec_param_at(sp, i) if param is None: return 1 param_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) @@ -686,7 +661,7 @@ def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet # ============================================================ # _spec_param_at - 取函数签名第 i 个参数 TypeSpec 指针 # ============================================================ -def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr: +def _spec_param_at(sp: TypeSpec*, index: int) -> TypeSpec*: """返回 Func 类型第 index 个参数的 TypeSpec 指针,越界返回 None""" if sp is None or sp.Params is None or index < 0 or index >= sp.ParamCount: return None @@ -694,30 +669,30 @@ def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr: slot: sizet* = (sizet*)(addr) if slot is None: return None - return (TypeSpec | t.CPtr)(uint64(slot[0])) + return (TypeSpec*)(uint64(slot[0])) # ============================================================ # TextToSpec - 规范文本解码(SpecToText 的逆;不驻留,由调用方决定是否驻留) # 解析失败返回 None(fail-fast 由调用方决定) # ============================================================ -def TextToSpec(text: str) -> TypeSpec | t.CPtr: +def TextToSpec(text: str) -> TypeSpec*: """把规范文本解码为 TypeSpec(PermPool,不驻留),失败返回 None""" if text is None: return None return _text_to_spec(text, 0) -def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr: +def _text_to_spec(text: str, depth: int) -> TypeSpec*: """TextToSpec 的递归实现(depth 上限 32)""" if text is None or depth > 32: return None # 指针:p:INNER if string.strncmp(text, "p:", 2) == 0: - inner: TypeSpec | t.CPtr = _text_to_spec(text + 2, depth + 1) + inner: TypeSpec* = _text_to_spec(text + 2, depth + 1) if inner is None: return None - sp_p: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) + sp_p: TypeSpec* = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) if sp_p is None: return None sp_p.Elem = inner @@ -737,10 +712,10 @@ def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr: colon: str = string.strchr(rb, ':') if colon is None: return None - inner_a: TypeSpec | t.CPtr = _text_to_spec(colon + 1, depth + 1) + inner_a: TypeSpec* = _text_to_spec(colon + 1, depth + 1) if inner_a is None: return None - sp_a: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) + sp_a: TypeSpec* = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) if sp_a is None: return None sp_a.Elem = inner_a @@ -779,11 +754,11 @@ def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr: # ============================================================ # _spec_make_struct - 构造 struct(深拷贝名字) # ============================================================ -def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr: +def _spec_make_struct(kind: int, name: str) -> TypeSpec*: """构造 struct/union/enum 类型(不驻留),失败返回 None""" if name is None or name[0] == '\0': return None - sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) + sp: TypeSpec* = _spec_make(kind, 0, TS_SIGN_UNKNOWN) if sp is None: return None if _spec_set_struct_name(sp, name) != 0: @@ -794,7 +769,7 @@ def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr: # ============================================================ # _text_to_func - 解析 "fn(p1,p2,...)->RET" # ============================================================ -def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: +def _text_to_func(text: str, depth: int) -> TypeSpec*: """解析函数签名文本,失败返回 None""" lp: str = string.strchr(text, '(') if lp is None: @@ -839,7 +814,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: continue if pcount >= 64: return None - psp: TypeSpec | t.CPtr = _text_to_spec(seg, depth + 1) + psp: TypeSpec* = _text_to_spec(seg, depth + 1) if psp is None: return None slot_p: sizet* = (sizet*)(uint64(param_specs) + uint64(pcount * 8)) @@ -847,10 +822,10 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: return None slot_p[0] = sizet(psp) pcount += 1 - ret: TypeSpec | t.CPtr = _text_to_spec(arrow + 3, depth + 1) + ret: TypeSpec* = _text_to_spec(arrow + 3, depth + 1) if ret is None: return None - sp_f: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) + sp_f: TypeSpec* = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) if sp_f is None: return None sp_f.Ret = ret @@ -867,7 +842,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: # (绝不写入截断键)。 # ============================================================ def InternSpec(arena: TypeSpecArena | t.CPtr, - sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + sp: TypeSpec*) -> TypeSpec*: """按规范文本键驻留 TypeSpec;失败返回 None""" if arena is None or sp is None: return sp @@ -891,7 +866,7 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, slot_e: sizet* = (sizet*)(uint64(arena.Specs) + uint64(found * 8)) if slot_e is None: return None - return (TypeSpec | t.CPtr)(uint64(slot_e[0])) + return (TypeSpec*)(uint64(slot_e[0])) if arena.Index is None: # 索引不可用:回退原线性查找(规模与类型种数同阶) i: int = 0 @@ -901,26 +876,21 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8)) if slot_e2 is None: return None - return (TypeSpec | t.CPtr)(uint64(slot_e2[0])) + return (TypeSpec*)(uint64(slot_e2[0])) i += 1 # 未命中:追加。**表满 = fail-fast**:不能返回 None——调用链会把 None 一路传到 # entry.Spec,条目静默失去类型信息(如符号性判定恒返回 0 ⇒ zext/sext 方向取错), # 属静默数据损坏,与「不兜底 / fail-fast」原则直接冲突。 if arena.Count >= arena.Cap: - GenApi.fatal_error( - None, - f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", - "InternalCompilerError") + GenApi.fatal_error(None, f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", "InternalCompilerError") # 仅在 fatal_error 无 gen 通道(no-op)时可达:退化为「不驻留但返回完整实例」, # 守住"不返回 None"这一底线 —— 宁失去同型共享,也不让条目静默丢类型。 return sp dst_key: str = _spec_key_at(arena.Keys, arena.Count) - if dst_key is None: - return None + if dst_key is None: return None string.strcpy(dst_key, key_buf) slot_n: sizet* = (sizet*)(uint64(arena.Specs) + uint64(arena.Count * 8)) - if slot_n is None: - return None + if slot_n is None: return None slot_n[0] = sizet(sp) # 同步写入哈希索引(下标 = 追加前的 Count)。插入失败仅意味着后续查找对该键 # 回退线性扫描,不影响正确性。 @@ -932,19 +902,16 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, # ============================================================ # 只读访问器(供 S3 起替换旧的字符串判定) # ============================================================ -def SpecIsPtr(sp: TypeSpec | t.CPtr) -> int: +def SpecIsPtr(sp: TypeSpec*) -> int: """是否指针类型(PtrLevel>0)""" - if sp is None: - return 0 - if sp.PtrLevel > 0: - return 1 + if sp is None: return 0 + if sp.PtrLevel > 0: return 1 return 0 -def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: +def SpecPointedTo(sp: TypeSpec*) -> TypeSpec*: """指针的指向类型(非指针返回 None)""" - if sp is None or sp.Kind != TS_PTR: - return None + if sp is None or sp.Kind != TS_PTR: return None return sp.Elem @@ -955,13 +922,11 @@ def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: # 供 SpecWithSign / SpecWithSource / SpecWithElemBits 复用,避免多处重复 # 逐字段拷贝(漏字段是最容易引入的隐蔽 bug:例如忘了 IsElemPtr)。 # ============================================================ -def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: +def _spec_clone(sp: TypeSpec*) -> TypeSpec*: """浅拷贝 sp(含全部字段),分配失败返回 None""" - if sp is None: - return None - cp: TypeSpec | t.CPtr = _spec_alloc() - if cp is None: - return None + if sp is None: return None + cp: TypeSpec* = _spec_alloc() + if cp is None: return None cp.Kind = sp.Kind cp.Bits = sp.Bits cp.IsSigned = sp.IsSigned @@ -994,8 +959,8 @@ def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: # 仅当符号性实际变化才复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。 # ============================================================ def SpecWithSign(arena: TypeSpecArena | t.CPtr, - sp: TypeSpec | t.CPtr, - is_signed: int) -> TypeSpec | t.CPtr: + sp: TypeSpec*, + is_signed: int) -> TypeSpec*: """复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None""" if sp is None: return None @@ -1009,7 +974,7 @@ def SpecWithSign(arena: TypeSpecArena | t.CPtr, new_signed = TS_SIGN_SIGNED if new_kind == sp.Kind: return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) + cp: TypeSpec* = _spec_clone(sp) if cp is None: return None cp.Kind = new_kind @@ -1025,7 +990,7 @@ def SpecWithSign(arena: TypeSpecArena | t.CPtr, # ============================================================ # _spec_set_source_name - 深拷贝注解来源名到 PermPool 并写入 SourceName # ============================================================ -def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int: +def _spec_set_source_name(sp: TypeSpec*, name: str) -> int: """把注解来源名深拷贝到 PermPool 并写入 SourceName,返回 0=成功 / 1=失败""" if sp is None or name is None: return 1 @@ -1053,13 +1018,13 @@ def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int: # # 幂等:sp.SourceName 已等于 name 时返回原实例(避免重复副本)。 # ============================================================ -def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr: +def SpecWithSource(sp: TypeSpec*, name: str) -> TypeSpec*: """复制 sp 并设置 SourceName(独立副本,不驻留);name 为空返回原实例""" if sp is None or name is None or name[0] == '\0': return sp if sp.SourceName is not None and string.strcmp(sp.SourceName, name) == 0: return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) + cp: TypeSpec* = _spec_clone(sp) if cp is None: return sp if _spec_set_source_name(cp, name) != 0: @@ -1078,27 +1043,27 @@ def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr: # ElemBits 是派生字段(**不在 SpecToText 键内**)⇒ 必须返回独立副本: # 若走 InternSpec 会命中键相同但 ElemBits 未覆盖的实例,覆盖丢失。 # ============================================================ -def SpecWithElemBits(sp: TypeSpec | t.CPtr, elem_bits: int) -> TypeSpec | t.CPtr: +def SpecWithElemBits(sp: TypeSpec*, elem_bits: int) -> TypeSpec*: """复制 sp 并设置 ElemBits(独立副本,不驻留);无变化返回原实例""" if sp is None: return sp if sp.ElemBits == elem_bits: return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) + cp: TypeSpec* = _spec_clone(sp) if cp is None: return sp cp.ElemBits = elem_bits return cp -def SpecSourceName(sp: TypeSpec | t.CPtr) -> str: +def SpecSourceName(sp: TypeSpec*) -> str: """Spec 的注解来源名(未设置返回 None)""" if sp is None: return None return sp.SourceName -def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int: +def SpecIsUnsigned(sp: TypeSpec*) -> int: """是否无符号整数(单一真源;未知返回 0)""" if sp is None: return 0 @@ -1107,7 +1072,7 @@ def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int: return 0 -def SpecBitWidth(sp: TypeSpec | t.CPtr) -> int: +def SpecBitWidth(sp: TypeSpec*) -> int: """位宽(非整形/浮点返回 0)""" if sp is None: return 0 @@ -1184,7 +1149,7 @@ def SpecTypeBits(ty: llvmlite.LLVMType*) -> int: SPEC_LLVM_TEXT_MAX_DEPTH: t.CDefine = 100 -def SpecToLLVMText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: +def SpecToLLVMText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int: """TypeSpec → LLVM IR 类型文本(对齐 TypePrint),返回 0=成功 / 1=失败""" if sp is None or buf is None or buf_size == 0: return 1 @@ -1204,7 +1169,7 @@ def _spec_llvm_append(buf: str, buf_size: sizet, src: str) -> int: return 0 -def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, +def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int: """把 sp 的 LLVM 文本**追加**到 buf 末尾(buf 已有前缀时保持原前缀)""" if sp is None or buf is None: @@ -1238,7 +1203,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, return 0 # --- 指针 --- if sp.Kind == TS_PTR: - inner: TypeSpec | t.CPtr = sp.Elem + inner: TypeSpec* = sp.Elem if inner is None or inner.Kind == TS_VOID: viperlib.snprintf(buf + pos, buf_size - pos, "i8*") return 0 @@ -1277,7 +1242,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, if i > 0: if _spec_llvm_append(buf, buf_size, ", ") != 0: return 1 - ps: TypeSpec | t.CPtr = _spec_param_at(sp, i) + ps: TypeSpec* = _spec_param_at(sp, i) if ps is None: return 1 if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: @@ -1315,7 +1280,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, # 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。 # ============================================================ def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, - ty: llvmlite.LLVMType*) -> TypeSpec | t.CPtr: + ty: llvmlite.LLVMType*) -> TypeSpec*: """把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None""" if arena is None or ty is None: return None @@ -1341,9 +1306,9 @@ def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, - pointee: llvmlite.LLVMType*) -> TypeSpec | t.CPtr: + pointee: llvmlite.LLVMType*) -> TypeSpec*: """Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)""" - inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pointee) + inner: TypeSpec* = SpecFromLLVMType(arena, pointee) if inner is None: return None return NewTypePtr(arena, inner) @@ -1351,9 +1316,9 @@ def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, def _spec_from_array(arena: TypeSpecArena | t.CPtr, elem_ty: llvmlite.LLVMType*, - count: int) -> TypeSpec | t.CPtr: + count: int) -> TypeSpec*: """[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)""" - inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, elem_ty) + inner: TypeSpec* = SpecFromLLVMType(arena, elem_ty) if inner is None: return None return NewTypeArray(arena, inner, count) @@ -1362,9 +1327,9 @@ def _spec_from_array(arena: TypeSpecArena | t.CPtr, def _spec_from_func(arena: TypeSpecArena | t.CPtr, ret: llvmlite.LLVMType*, params: llvmlite.Function*, - pcount: int) -> TypeSpec | t.CPtr: + pcount: int) -> TypeSpec*: """函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)""" - ret_s: TypeSpec | t.CPtr = SpecFromLLVMType(arena, ret) + ret_s: TypeSpec* = SpecFromLLVMType(arena, ret) if ret_s is None: return None if pcount <= 0: @@ -1377,7 +1342,7 @@ def _spec_from_func(arena: TypeSpecArena | t.CPtr, i: int = 0 while node is not None and i < pcount: pty: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(node) - ps: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pty) + ps: TypeSpec* = SpecFromLLVMType(arena, pty) if ps is None: return None slot: sizet* = (sizet*)(uint64(params_arr) + uint64(i * 8)) @@ -1390,7 +1355,7 @@ def _spec_from_func(arena: TypeSpecArena | t.CPtr, def _spec_from_struct(arena: TypeSpecArena | t.CPtr, - sname: str) -> TypeSpec | t.CPtr: + sname: str) -> TypeSpec*: """有名结构体 → TS_STRUCT + BaseName;匿名结构体 → 无名 TS_STRUCT""" if sname is not None: return NewTypeStruct(arena, TS_STRUCT, sname) @@ -1413,28 +1378,28 @@ def SpecSelfCheck() -> int: return 1 # 1) u64 - s_u64: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) + s_u64: TypeSpec* = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) if s_u64 is None: return 1 if _check_roundtrip(s_u64, "u64") != 0: return 1 # 2) i32 - s_i32: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED) + s_i32: TypeSpec* = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED) if s_i32 is None: return 2 if _check_roundtrip(s_i32, "i32") != 0: return 2 # 3) u64* - s_p: TypeSpec | t.CPtr = NewTypePtr(arena, s_u64) + s_p: TypeSpec* = NewTypePtr(arena, s_u64) if s_p is None: return 3 if _check_roundtrip(s_p, "p:u64") != 0: return 3 # 4) i8[4] - s_arr: TypeSpec | t.CPtr = NewTypeArray(arena, s_i32, 4) + s_arr: TypeSpec* = NewTypeArray(arena, s_i32, 4) if s_arr is None: return 4 if _check_roundtrip(s_arr, "arr[4]:i32") != 0: @@ -1452,14 +1417,14 @@ def SpecSelfCheck() -> int: if slot1 is None: return 5 slot1[0] = sizet(s_u64) - s_fn: TypeSpec | t.CPtr = NewTypeFunc(arena, s_i32, params, 2, 1) + s_fn: TypeSpec* = NewTypeFunc(arena, s_i32, params, 2, 1) if s_fn is None: return 5 if _check_roundtrip(s_fn, "fn(i32,u64,...)->i32") != 0: return 5 # 6) 驻留去重:同一文本第二次应返回同一实例 - s_u64_again: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) + s_u64_again: TypeSpec* = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) if s_u64_again is None: return 6 if uint64(s_u64_again) != uint64(s_u64): @@ -1470,7 +1435,7 @@ def SpecSelfCheck() -> int: # ============================================================ # _check_roundtrip - 自检辅助:编码应等于 expect,且解码再编码应一致 # ============================================================ -def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int: +def _check_roundtrip(sp: TypeSpec*, expect: str) -> int: """编码比对 + 解码往返一致;返回 0=通过 / 1=失败""" if sp is None or expect is None: return 1 @@ -1481,7 +1446,7 @@ def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int: return 1 if string.strcmp(buf1, expect) != 0: return 1 - back: TypeSpec | t.CPtr = TextToSpec(buf1) + back: TypeSpec* = TextToSpec(buf1) if back is None: return 1 buf2: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) diff --git a/App/lib/core/Gen/VarGenMixin.vp b/App/lib/core/Gen/VarGenMixin.vp index 2058228..4b5f9f0 100644 --- a/App/lib/core/Gen/VarGenMixin.vp +++ b/App/lib/core/Gen/VarGenMixin.vp @@ -169,9 +169,7 @@ novirtual class VarGenMixin: # PtrLevel>=1。不满足即上游异常(类型缺失/退化),fail-fast 暴露 —— # 若静默放过,读点 var_is_ptr_element 返回 0 → 下标按 1 字节误算(数据损坏)。 if entry.Spec is None or entry.Spec.PtrLevel < 1: - self.Gen.TypeGenErr.fatal_error( - None, f"变量 '{name}' 标记为 ptr-element,但其 Spec 不可承载指针语义", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(None, f"变量 '{name}' 标记为 ptr-element,但其 Spec 不可承载指针语义", "InternalCompilerError") return 1 entry.Spec = TSpec.SpecWithElemBits(entry.Spec, 64) return 0 @@ -456,8 +454,7 @@ novirtual class VarGenMixin: return None scope: rawptr[GenTypes.Scope] = symtab.Current while scope is not None: - result: llvmlite.Value* = self.find_var( - scope.Vars, scope.VarCount, name) + result: llvmlite.Value* = self.find_var(scope.Vars, scope.VarCount, name) if result is not None: return result scope = scope.Parent @@ -518,8 +515,7 @@ novirtual class VarGenMixin: return None scope: rawptr[GenTypes.Scope] = symtab.Current while scope is not None: - result: llvmlite.Value* = self.find_var( - scope.Vars, scope.VarCount, name) + result: llvmlite.Value* = self.find_var(scope.Vars, scope.VarCount, name) if result is not None: return result if scope.Kind == SCOPE_MATCH: @@ -609,10 +605,7 @@ novirtual class VarGenMixin: symtab: rawptr[GenTypes.SymbolTable] = trans.SymTab param_alloca: llvmlite.Value* = self.lookup_var(symtab, ctx.CtxParam) if param_alloca is None or param_alloca.Ty is None or param_alloca.Ty.Pointee == 0: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 片段函数缺少 ctx 形参 '{ctx.CtxParam}'(包裹模板与 M2 调用约定不一致)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 片段函数缺少 ctx 形参 '{ctx.CtxParam}'(包裹模板与 M2 调用约定不一致)", "InternalCompilerError") return None return llvmlite.build_load(trans._cur_builder, param_alloca.Ty.Pointee, param_alloca) @@ -731,17 +724,10 @@ novirtual class VarGenMixin: return None hit[0] = 1 if kw_count != 0: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)", "TypeError") return None if can != entry.ParamCount: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参," - f"调用处给了 {can} 个(M3 不支持默认参数/缺省补全)", - "TypeError") + self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参,调用处给了 {can} 个(M3 不支持默认参数/缺省补全)", "TypeError") return None ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, ctx, node) if ctx_val is None: @@ -749,16 +735,13 @@ novirtual class VarGenMixin: i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # ① 槽内取函数地址:槽地址是 i8**(Ptr(i8*)),load 得 i8* - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty) if slot is None: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError") return None fn_i8: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, slot) if fn_i8 is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError") return None # ② 签名构造前先取形参类型(token → LLVM 类型;不支持 ⇒ 明确报错) ptypes: t.CPtr = pool.alloc(8 * GenTypes.REPL_FUNC_PARAM_MAX) @@ -767,14 +750,9 @@ novirtual class VarGenMixin: string.memset(ptypes, 0, 8 * GenTypes.REPL_FUNC_PARAM_MAX) ai_chk: int for ai_chk in range(entry.ParamCount): - pty_chk: llvmlite.LLVMType* = self.repl_func_ty( - pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk])) + pty_chk: llvmlite.LLVMType* = self.repl_func_ty(pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk])) if pty_chk is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token " - f"不受支持(M3 支持 iN/float/double/i8*)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token 不受支持(M3 支持 iN/float/double/i8*)", "TypeError") return None pty_slot: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai_chk * 8) pty_slot[0] = pty_chk @@ -787,26 +765,17 @@ novirtual class VarGenMixin: for ai in range(entry.ParamCount): arg: ast.AST* = cargs.get(ai) if arg is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失", - "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失", "SyntaxError") return None pty_slot2: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai * 8) pty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(pty_slot2[0]) - arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, pty) + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans, pty) if arg_val is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败", "TypeError") return None - coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val, pty, arg, trans) + coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, pty, arg, trans) if coerced is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容", "TypeError") return None coerced.Next = None tail.Next = coerced @@ -818,11 +787,7 @@ novirtual class VarGenMixin: if entry.RetTag != GenTypes.REPL_TY_VOID: ret_ty = self.repl_func_ty(pool, entry.RetTag, entry.RetBits) if ret_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持" - f"(M3 支持 void/iN/float/double/i8*)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持(M3 支持 void/iN/float/double/i8*)", "TypeError") return None fp_first: llvmlite.Function* = None fp_prev: llvmlite.Function* = None @@ -845,8 +810,7 @@ novirtual class VarGenMixin: func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty) fn_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty) if fn_typed is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError") return None return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) @@ -874,8 +838,7 @@ novirtual class VarGenMixin: # 同型时不发 bitcast:llvmlite 类型非 canonical(同类型不同实例地址不同), # 而 LLVM 拒绝 `bitcast i8* %x to i8*`(同型 cast 非法)——val_ty 为 i8 # (char 会话变量)时目标恰是 i8*,必须直接返回 GEP 结果。 - if base.Ty is not None and self.Gen.AssignGen._stg_ty_equal( - pool, base.Ty, target_ptr_ty) != 0: + if base.Ty is not None and self.Gen.AssignGen._stg_ty_equal(pool, base.Ty, target_ptr_ty) != 0: return base return llvmlite.build_bitcast(builder, base, target_ptr_ty) @@ -1076,8 +1039,7 @@ novirtual class VarGenMixin: return 1 perm: memhub.MemBuddy* = self.repl_perm_pool(trans) if perm is None: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") return 1 tag: int = 0 bits: int = 0 @@ -1126,15 +1088,13 @@ novirtual class VarGenMixin: sz: int = self.repl_type_size(val_ty) al: int = self.repl_type_align(val_ty) if sz <= 0 or al <= 0: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 尺寸/对齐未知" f"(无法判定能否放入 {GenTypes.REPL_SLOT_SIZE} 字节槽)", "TypeError") return 1 if sz > GenTypes.REPL_SLOT_SIZE or al > GenTypes.REPL_SLOT_SIZE: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 体积 {sz} 字节、" f"对齐 {al} 字节,无法放入 {GenTypes.REPL_SLOT_SIZE} 字节槽" f"(M2 结构体值须内联进槽;大对象请改用对象指针/堆分配)", @@ -1145,8 +1105,7 @@ novirtual class VarGenMixin: kind = GenTypes.REPL_KIND_SCALAR tname = sname else: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的类型暂不支持" f"(M2 支持 int/bool/浮点/str/bytes/指针/结构体值)", "TypeError") @@ -1160,8 +1119,7 @@ novirtual class VarGenMixin: entry.TyName = self.repl_perm_strdup(perm, tname) return 0 if entry.Kind != kind or entry.TyTag != tag: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 已定型为 {self.repl_tag_label(entry.TyTag, entry.Bits)}," f"不能再赋成 {self.repl_tag_label(tag, bits)}(如需换型请重启会话)", "TypeError") @@ -1230,29 +1188,24 @@ novirtual class VarGenMixin: if hit is not None: return hit if ctx.Table is None or ctx.Cap <= 0: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话变量表未初始化(宿主未建 ctx)", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话变量表未初始化(宿主未建 ctx)", "InternalCompilerError") return None if ctx.Count >= ctx.Cap: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量已达上限 {ctx.Cap} 个(ctx 槽位用尽)," f"无法为 '{name}' 再分配槽位;请重启会话", "ResourceError") return None perm: memhub.MemBuddy* = self.repl_perm_pool(trans) if perm is None: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") return None name_copy: str = self.repl_perm_strdup(perm, name) if name_copy is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话变量 '{name}' 的名字深拷贝失败", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的名字深拷贝失败", "InternalCompilerError") return None entry_size: sizet = GenTypes.ReplVarEntry.__sizeof__() - entry: rawptr[GenTypes.ReplVarEntry] = rawptr[GenTypes.ReplVarEntry]( - uint64(ctx.Table) + uint64(ctx.Count) * uint64(entry_size)) + entry: rawptr[GenTypes.ReplVarEntry] = rawptr[GenTypes.ReplVarEntry](uint64(ctx.Table) + uint64(ctx.Count) * uint64(entry_size)) if entry is None: return None entry.Name = name_copy @@ -1296,8 +1249,7 @@ novirtual class VarGenMixin: i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) zero64: llvmlite.Value* = llvmlite.const_int64(pool, 0) if tag == GenTypes.REPL_TY_INT: - iv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, val, i64_ty, node, trans) + iv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, val, i64_ty, node, trans) if iv is None: return 1 if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, @@ -1307,8 +1259,7 @@ novirtual class VarGenMixin: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) if tag == GenTypes.REPL_TY_FLOAT: - dv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, val, llvmlite.Double(pool), node, trans) + dv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, val, llvmlite.Double(pool), node, trans) if dv is None: return 1 # double → i64 位模式(bitcast,不做数值转换):宿主按位重解释回 double @@ -1331,8 +1282,7 @@ novirtual class VarGenMixin: if pv is None: return 1 # 指针 → i64(ptrtoint):宿主按整数读回后再 inttoptr 成地址 - pbits: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, pv, i64_ty, node, trans) + pbits: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, pv, i64_ty, node, trans) if pbits is None: return 1 kind: int = GenTypes.REPL_RES_OBJ @@ -1365,8 +1315,7 @@ novirtual class VarGenMixin: return 1 pool: memhub.MemBuddy* = trans.Pool builder: llvmlite.IRBuilder* = trans._cur_builder - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, builder, ctx_val, off, llvmlite.Int64(pool)) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, off, llvmlite.Int64(pool)) if slot is None: return 1 llvmlite.build_store(builder, val, slot) @@ -1383,8 +1332,7 @@ novirtual class VarGenMixin: builder: llvmlite.IRBuilder* = trans._cur_builder if pool is None or builder is None: return 1 - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, builder, ctx_val, off, llvmlite.Int32(pool)) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, off, llvmlite.Int32(pool)) if slot is None: return 1 cv: llvmlite.Value* = llvmlite.const_int32(pool, val) @@ -1409,16 +1357,14 @@ novirtual class VarGenMixin: if self.repl_in_frag_scope(trans.SymTab) == 0: return None if entry.Kind == GenTypes.REPL_KIND_UNTYPED: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 尚未赋值(未定型,先执行一条 'x = ...' 或 'x: int = ...')", "NameError") return None pool: memhub.MemBuddy* = trans.Pool slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型 " f"{self.repl_tag_label(entry.TyTag, entry.Bits)} 在当前片段不可用" f"(跨片段类型可见性属 M4)", @@ -1427,8 +1373,7 @@ novirtual class VarGenMixin: ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) if slot is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽地址生成失败", "InternalCompilerError") return None @@ -1452,27 +1397,23 @@ novirtual class VarGenMixin: if self.repl_in_frag_scope(trans.SymTab) == 0: return None if entry.Kind == GenTypes.REPL_KIND_UNTYPED: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 尚未赋值(未定型),无法取址(c.Addr)", "NameError") return None pool: memhub.MemBuddy* = trans.Pool slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型在当前片段不可用(跨片段类型可见性属 M4)", "NameError") return None ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) if slot is None: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话槽地址生成失败", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽地址生成失败", "InternalCompilerError") return None # 值内联在槽里(无装箱间接层)⇒ 槽地址即值地址 return slot @@ -1494,17 +1435,14 @@ novirtual class VarGenMixin: builder: llvmlite.IRBuilder* = trans._cur_builder slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的槽类型不可用" f"(类型在当前片段不可解析,或结构体值体积超出槽容量)", "TypeError") return 1 - store_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( - builder, rhs_val, slot_ty, node, trans) + store_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, slot_ty, node, trans) if store_val is None: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 无法把右侧值转换为" f" {self.repl_tag_label(entry.TyTag, entry.Bits)}", "CastError") @@ -1519,8 +1457,7 @@ novirtual class VarGenMixin: if store_val is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽指针同型化失败", "CastError") return 1 - slot: llvmlite.Value* = self.repl_slot_ptr( - pool, builder, ctx_val, entry.Offset, slot_ty) + slot: llvmlite.Value* = self.repl_slot_ptr(pool, builder, ctx_val, entry.Offset, slot_ty) if slot is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽写入失败", "InternalCompilerError") return 1 @@ -1549,8 +1486,7 @@ novirtual class VarGenMixin: if self.repl_in_frag_entry_scope(trans) == 0: return 0 if rhs_val.Ty is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话变量 '{name}' 的赋值右侧类型未知", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的赋值右侧类型未知", "TypeError") return 1 if self.repl_seal(trans, entry, rhs_val.Ty, rhs_node) != 0: return 1 @@ -1583,17 +1519,14 @@ novirtual class VarGenMixin: pool: memhub.MemBuddy* = trans.Pool builder: llvmlite.IRBuilder* = trans._cur_builder if annot_node is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话变量 '{name}' 的注解缺失", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的注解缺失", "SyntaxError") return 1 # 与普通 AnnAssign 同口径:先注册泛型特化,避免 list[X] 退化为裸基类 # (裸 list* 会让后续 .get() 误分派并截断指针) self.Gen.AssignGen._prespecialize_generic_annotation(trans, pool, annot_node) - annot_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0) + annot_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0) if annot_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型注解解析失败" f"(片段无 import;仅内建名 int/str/bytes/bool/float/double/char 等可解析)", "NameError") @@ -1607,13 +1540,11 @@ novirtual class VarGenMixin: # 与普通 AnnAssign 四处同口径:翻译 RHS 前设置上下文(裸名泛型构造推断用) trans.CurAssignAnnot = annot_node trans.CurAssignNode = value_node - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, value_node, None, 0, trans, slot_ty) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, value_node, None, 0, trans, slot_ty) trans.CurAssignAnnot = None trans.CurAssignNode = None if rhs_val is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话变量 '{name}' 的初值翻译失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的初值翻译失败", "TypeError") return 1 ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: @@ -1642,24 +1573,20 @@ novirtual class VarGenMixin: pool: memhub.MemBuddy* = trans.Pool builder: llvmlite.IRBuilder* = trans._cur_builder if entry.TyTag == GenTypes.REPL_TY_STRUCT: - self.Gen.TypeGenErr.fatal_error( - node, + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 是结构体值,不支持增强赋值", "TypeError") return 1 cur_val: llvmlite.Value* = self.repl_try_read(trans, name, node) if cur_val is None: return 1 - rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, rhs_node, None, 0, trans) + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, rhs_node, None, 0, trans) if rhs_val is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 增强赋值右侧翻译失败", "TypeError") return 1 - result: llvmlite.Value* = self.Gen.AssignGen._apply_aug_op( - pool, builder, op, cur_val, rhs_val, node, trans, node) + result: llvmlite.Value* = self.Gen.AssignGen._apply_aug_op(pool, builder, op, cur_val, rhs_val, node, trans, node) if result is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话变量 '{name}' 的增强赋值运算失败 op={op}", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的增强赋值运算失败 op={op}", "TypeError") return 1 # 写回槽(复用赋值路径:定型已存在 ⇒ 只做转换与存储) return self.repl_try_assign(trans, name, result, node, node) @@ -1676,11 +1603,9 @@ novirtual class VarGenMixin: return 1 pool: memhub.MemBuddy* = trans.Pool builder: llvmlite.IRBuilder* = trans._cur_builder - val: llvmlite.Value* = self.Gen.ExprGen.translate_value( - builder, pool, trans.Module, value_node, None, 0, trans) + val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, value_node, None, 0, trans) if val is None or val.Ty is None: - self.Gen.TypeGenErr.fatal_error( - value_node, "REPL: 表达式片段求值失败", "TypeError") + self.Gen.TypeGenErr.fatal_error(value_node, "REPL: 表达式片段求值失败", "TypeError") return 1 ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, value_node) if ctx_val is None: @@ -1688,8 +1613,7 @@ novirtual class VarGenMixin: # 类型分类用宿主的影子条目(不占会话槽、不进表):每次先复位为未定型 sh: rawptr[GenTypes.ReplVarEntry] = trans.ReplCtx.Scratch if sh is None: - self.Gen.TypeGenErr.fatal_error( - value_node, "REPL: 会话缺少影子条目(宿主未初始化)", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(value_node, "REPL: 会话缺少影子条目(宿主未初始化)", "InternalCompilerError") return 1 sh.Kind = GenTypes.REPL_KIND_UNTYPED sh.TyTag = 0 diff --git a/App/lib/core/Repl.vp b/App/lib/core/Repl.vp index 381268c..ff7f6e0 100644 --- a/App/lib/core/Repl.vp +++ b/App/lib/core/Repl.vp @@ -1,4 +1,4 @@ -import t, c +import t from stdint import * import stdio import stdlib @@ -40,7 +40,7 @@ import lib.Stub.StubGen.VpiReader as VpiReader # ctx(会话内存,宿主 PermPool 一次性分配;布局见 GenTypes 顶部注释): # 偏移 0..63 固定头(magic/version/result_kind/result_a/result_b/var_count/last_frag) # 偏移 64 起为变量槽(每槽 16 字节)。宿主与片段在**同一进程**内共享该内存: -# 会话变量只存一份 ⇒ c.Addr(x) 得到的就是槽地址(地址同一性)。 +# 会话变量只存一份 ⇒ &x 得到的就是槽地址(地址同一性)。 # 值的类型按首次赋值推导(`x = 1` 与 `x: int = 1` 等价,均定型并分配槽)。 # # 错误可恢复依赖 VLogger 的 jit_flag + setjmp/longjmp: @@ -57,18 +57,18 @@ import lib.Stub.StubGen.VpiReader as VpiReader # ============================================================ # 输入行缓冲容量(含 NUL 终止符) -_REPL_LINE_CAP: t.CDefine = 4096 +define _REPL_LINE_CAP = 4096 # 块输入缓冲容量(会话级 PermPool,含 NUL 终止符):续行状态下逐行追加的用户原文, # 行间以一个 '\n' 连接、无行尾换行。 # 取 8 KiB 的理由:常见多行块(10 行 × 80 列 ≈ 0.8 KiB)绰绰有余;整段粘贴 # 100 行 × 80 列 ≈ 8 KiB 也刚好容纳;再大属异常输入,按"明确报错 + 丢弃该块" # 处理(绝不截断后执行)。上界同时约束包裹源码缓冲的下界(见 _REPL_FRAG_SRC_CAP)。 -_REPL_BLOCK_CAP: t.CDefine = 8192 +define _REPL_BLOCK_CAP = 8192 # jmp_buf 实测大小:mingw-w64 x86_64 setjmp.h 中 _JBLEN=16、_JBTYPE=SETJMP_FLOAT128(16B) # ⇒ 16 * 16 = 256 字节(已用 C 探针 sizeof(jmp_buf) 实测 = 256) -_REPL_JMPBUF_SIZE: t.CDefine = 256 +define _REPL_JMPBUF_SIZE = 256 # setjmp/longjmp:mingw-w64 x86_64 的 _setjmp 第二参数为 frame 指针, # setjmp 宏即展开为 _setjmp(buf, NULL)(非 SEH 场景传 None 即可) @@ -171,8 +171,7 @@ _REPL_PROJECT_PROBE_CAP: t.CDefine = 16 # 片段把 double 的 IEEE754 位模式写进 result_a;宿主按本视图读回即得 double # (位模式重解释,不做数值转换)。 # ============================================================ -@t.NoVTable -class ReplFloatView: +novirtual class ReplFloatView: """ctx 头(+16 处按 double 读)""" Magic: int Version: int @@ -188,8 +187,7 @@ class ReplFloatView: # 16 字节(低 8 字节 = 地址,高 8 字节保留)。片段侧按同一偏移(i8** 视图) # load 该地址后间接调用;宿主用本视图写入 ⇒ 两侧对"槽内是什么"只有一个约定。 # ============================================================ -@t.NoVTable -class ReplFuncSlotView: +novirtual class ReplFuncSlotView: """ctx 函数指针槽(Addr = 定义片段 DLL 里该函数的入口地址)""" Addr: VOIDPTR Reserved: VOIDPTR @@ -204,8 +202,7 @@ class ReplFuncSlotView: # ReplFuncEntry 的签名 token;调用片段再用 token 重建同型签名 ⇒ 两侧一致。 # 形参/返回的 token 数组写进会话 scratch(ReplSigTags/ReplSigBits)。 # ============================================================ -@t.NoVTable -class ReplSigOut: +novirtual class ReplSigOut: """签名解析结果(Bad/EHTag 非 0 时拒绝注册)""" RetTag: int # GenTypes.REPL_TY_VOID / INT / FLOAT / STR RetBits: int @@ -529,11 +526,11 @@ def _read_line(h: win32base.HANDLE, buf: bytes, cap: int) -> int: eof: int = 0 while total < cap - 1: bytes_read = 0 - ok = w32file.ReadFile(h, buf + total, 1, t.CPtr(c.Addr(bytes_read)), None) + ok = w32file.ReadFile(h, buf + total, 1, &bytes_read, None) if ok == 0 or bytes_read == 0: eof = 1 break - # 注意:不能用 c.Deref(buf + total)——其 IR 生成 i32 load(读 4 字节), + # 注意:不能用 &(buf + total)——其 IR 生成 i32 load(读 4 字节), # 比较 '\n'/'\r' 永不命中;字节索引 buf[total] 才是 i8 load ch: char = buf[total] if ch == 10: # '\n':行结束 @@ -933,8 +930,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, GenApi.SetTempDir(vpi_dir) GenApi.set_current_file_type(vpi_dir) tmp_mod: llvmlite.LLVMModule* = llvmlite.new_module(_perm_pool, _REPL_INC_MOD_NAME) - tr_inc: rawptr[HandlesTranslator.Translator] = _perm_pool.alloc( - HandlesTranslator.Translator.__sizeof__()) + tr_inc: rawptr[HandlesTranslator.Translator] = _perm_pool.alloc(HandlesTranslator.Translator.__sizeof__()) if tmp_mod is None or tr_inc is None: return 1 tr_inc.__before_init__() @@ -978,8 +974,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, "仍可按需注册)\n", GenApi.get_struct_count()) stdio.fflush(None) return 0 - ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry]( - uint64(sr.Entries) + uint64(i) * uint64(es)) + ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(sr.Entries) + uint64(i) * uint64(es)) if ent is None or ent.Sha1 is None: st[i] = sizet(1) ReplIncClsFail += 1 @@ -1171,8 +1166,7 @@ def ReplInitSession() -> int: ReplScratch.Bits = 0 # ⑤' 会话函数表(M3;PermPool,宿主写、Gen 只读)——条目数组清零 func_entry_size: sizet = GenTypes.ReplFuncEntry.__sizeof__() - ReplFuncTable: rawptr[GenTypes.ReplFuncEntry] = _perm_pool.alloc( - func_entry_size * GenTypes.REPL_FUNC_CAP) + ReplFuncTable: rawptr[GenTypes.ReplFuncEntry] = _perm_pool.alloc(func_entry_size * GenTypes.REPL_FUNC_CAP) if ReplFuncTable is None: return 1 string.memset(ReplFuncTable, 0, func_entry_size * GenTypes.REPL_FUNC_CAP) @@ -1296,8 +1290,7 @@ def _repl_gen_includes_vpi(mb: memhub.MemBuddy*, dl: sizet = string.strlen(vpi_dir) n: int for n in range(sr.Count): - ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry]( - uint64(sr.Entries) + uint64(n) * es) + ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(sr.Entries) + uint64(n) * es) if ent is None or ent.Sha1 is None or ent.Path is None: ReplIncVpiFail += 1 continue @@ -1871,8 +1864,7 @@ def _repl_func_entry_find(name: str) -> rawptr[GenTypes.ReplFuncEntry]: es: sizet = GenTypes.ReplFuncEntry.__sizeof__() i: int for i in range(ReplCtxObj.FuncCount): - e: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry]( - uint64(ReplCtxObj.FuncTable) + uint64(i) * uint64(es)) + e: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry](uint64(ReplCtxObj.FuncTable) + uint64(i) * uint64(es)) if e.Name is not None and string.strcmp(e.Name, name) == 0: return e return None @@ -2045,8 +2037,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int) -> int: return 1 j: int = ReplCtxObj.FuncCount es: sizet = GenTypes.ReplFuncEntry.__sizeof__() - ent = rawptr[GenTypes.ReplFuncEntry]( - uint64(ReplCtxObj.FuncTable) + uint64(j) * uint64(es)) + ent = rawptr[GenTypes.ReplFuncEntry](uint64(ReplCtxObj.FuncTable) + uint64(j) * uint64(es)) nm_c: str = _repl_perm_dup(nm) nm_s: str = _repl_perm_dup(nm) tags_b: bytes = _perm_pool.alloc(GenTypes.REPL_FUNC_PARAM_MAX) @@ -2072,8 +2063,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int) -> int: # 重定义(同签名):只换地址与段号,槽偏移不变 ent.FragNo = frag_no # 写 ctx 槽(低 8 字节=地址,高 8 字节保留 0) - sv: rawptr[ReplFuncSlotView] = rawptr[ReplFuncSlotView]( - uint64(ReplCtxBuf) + uint64(ent.SlotOff)) + sv: rawptr[ReplFuncSlotView] = rawptr[ReplFuncSlotView](uint64(ReplCtxBuf) + uint64(ent.SlotOff)) sv.Addr = addr sv.Reserved = None stdio.printf("会话函数 %s: 导出符号 %s → ctx 槽 +%d(定义片段 %d,签名 %s)\n", @@ -2817,7 +2807,7 @@ def run(mb: memhub.MemBuddy*) -> int: stdio.printf("TransPyV REPL (M2/M3/M4) - 会话变量 + 会话函数(跨片段)+ ctx 回传结果;\n") stdio.printf(" 支持表达式(1+2)、定义(x = 1 / x: int = 5)、引用(x + 1)、\n") - stdio.printf(" 增强赋值(x += 2)、取址(p = c.Addr(x))等;空行跳过,Ctrl+Z 或 EOF 退出\n") + stdio.printf(" 增强赋值(x += 2)、取址(p = &x)等;空行跳过,Ctrl+Z 或 EOF 退出\n") stdio.printf(" 多行块:行尾 ':' 进入续行(提示符 ...),空行结束并整块执行一次\n") stdio.printf(" 跨片段函数:块里顶格的 def 会被提升为片段模块的 export def(裸名导出),\n") stdio.printf(" 后续片段可直接调用(如 def f(x: int) -> int: 换行 +4 空格 return x + 1);\n")