From 9f19673072b2d68ca48c1a11ea885f1d90d0a8ef Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 26 Aug 2026 19:30:31 +0800 Subject: [PATCH] =?UTF-8?q?fix(classgen):=20=E6=96=B9=E6=B3=95=E9=A2=84?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E8=A1=A5=20pre=5Fscan=5Fscope=5Fdecls?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=20global=20=E5=90=8D=E8=A2=AB?= =?UTF-8?q?=E5=BD=93=E5=B1=80=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 方法(method)预扫描只调 pre_scan_allocas,漏调 pre_scan_scope_decls(模块级 函数路径 FuncGenDef 是先 scope_decls 再 allocas)。导致 global BootInfo 未 注册时 prescan 把 BootInfo 当局部创建 alloca(define_var 注册局部),后续翻译 is_global_name 为真又写全局 → 局部 alloca 永不写入 → 读全 0(main.vp __init__ BootInfo memmap 全 0 根因)。 修复:方法预扫描先 pre_scan_scope_decls 注册 global/nonlocal,再 pre_scan_allocas, 与 FuncGenDef/FuncGenMixin 路径对齐。 --- App/lib/core/Gen/ClassGenVTable.vp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/App/lib/core/Gen/ClassGenVTable.vp b/App/lib/core/Gen/ClassGenVTable.vp index f8e14c2..e588682 100644 --- a/App/lib/core/Gen/ClassGenVTable.vp +++ b/App/lib/core/Gen/ClassGenVTable.vp @@ -719,9 +719,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): ret_ty: llvmlite.LLVMType | t.CPtr = None if fd.returns is not None: ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, fd.returns, imported_modules, from_imports, trans) + pool, fd.returns, imported_modules, from_imports, trans, 0) if ret_ty is None and fd.returns is not None: - if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State") != 0: + if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0: ret_ty = llvmlite.Void(pool) if ret_ty is None: # __init__ 和 __before_init__ 返回 void @@ -800,7 +800,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): param_ty: llvmlite.LLVMType | t.CPtr = i32_ty if arg.annotation is not None: resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg.annotation, imported_modules, from_imports, trans) + pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is not None: # 裸类形参 → Ptr(struct):按"对象即指针"引用传参。 # 若按 struct 值传参,self.Head = node 会取局部拷贝地址 @@ -944,7 +944,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): param_ty2: llvmlite.LLVMType | t.CPtr = i32_ty if arg2.annotation is not None: resolved2: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, arg2.annotation, imported_modules, from_imports, trans) + pool, arg2.annotation, imported_modules, from_imports, trans, 0) if resolved2 is None: # fail-fast:参数有注解但类型解析失败,不再静默保持 i32 self.Gen.TypeGenErr.fatal_error( @@ -1009,9 +1009,17 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): HT.clear_scope_names(trans) # 预扫描方法体:为局部变量提前创建 alloca + # 必须先预扫描 Global/Nonlocal 声明(对齐 FuncGenDef 模块级函数路径), + # 否则 `global BootInfo` 未注册时 prescan 把 BootInfo 当局部创建 alloca, + # 后续翻译 is_global_name 为真又写全局 → 局部 alloca 永不写入 → 读全 0 + # (main.vp __init__ BootInfo memmap 全 0 根因)。 body: list[ast.AST | t.CPtr] | t.CPtr = fd.children if body is not None: bn: t.CSizeT = len(body) + for bi in range(bn): + stmt: ast.AST | t.CPtr = body.get(bi) + if stmt is not None: + self.Gen.StmtGenDecl.pre_scan_scope_decls(trans, stmt) for bi in range(bn): stmt: ast.AST | t.CPtr = body.get(bi) if stmt is not None: @@ -1261,7 +1269,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 静态数组字段 + 列表字面量默认值 → 整体置零 + 逐元素 GEP+store # (与局部 AnnAssign 数组初始化一致;translate_value 会把列表字面量 # 误译成动态 list 对象指针,coerce 到 [N x elem] 会失败)。 - # 单参 CArray 字段(如 t.CArray[str] = ["py", ...])经类体字段收集 + # 单参 CArray 字段(如 t.CArray[str] = [...])经类体字段收集 # 推断为静态数组,此处保证 __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: