fix(classgen): 方法预扫描补 pre_scan_scope_decls,修复 global 名被当局部
方法(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 路径对齐。
This commit is contained in:
1 parent
53c72ff57a
commit
9f19673072
1 file changed
+13
-5
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user