fix(compiler): 对象类模块级全局改静态 BSS storage,修复页 0 混叠与栈悬垂

对象类全局(裸类名注解)此前编译为 NULL 指针,实例建在栈 alloca 后悬垂,对象字段落在物理页 0(IVT+BDA 混叠),导致 VKernel devfs/fat32/sched 全部对象失效。新增 @g.stg 静态 storage(BSS),@g 编译期指向它;赋值/构造点(translate_assign/translate_annassign 全局分支)检测 storage 后绑定引用并复制对象,消除 NULL 与悬垂。
This commit is contained in:
TermiNexus committed 2026-08-29 17:27:21 +08:00
1 parent 2b2c242d14
commit 1fe7878074
2 files changed
+124 -1

No files matched your search

+77
View File
@@ -1165,6 +1165,30 @@ class AssignGenMixin:
builder, pool, mod, aa.value,
None, 0, trans)
if rhs_val is not None:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_aa: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_aa: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
if stg_key_aa is not None:
viperlib.snprintf(stg_key_aa, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_aa = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_aa)
if stg_ref_aa is not None and rhs_val.Ty is not None \
and stg_ref_aa.Ty is not None and stg_ref_aa.Ty.Pointee is not None:
stg_ty_aa: llvmlite.LLVMType | t.CPtr = stg_ref_aa.Ty.Pointee
rhs_inner_aa: llvmlite.LLVMType | t.CPtr = None
match rhs_val.Ty:
case llvmlite.LLVMType.Ptr(pointee_aa):
rhs_inner_aa = pointee_aa
case _:
pass
if rhs_inner_aa is not None and rhs_inner_aa.kind() == llvmlite.LLVMType.Struct \
and stg_ty_aa == rhs_inner_aa:
llvmlite.build_store(builder, stg_ref_aa, mod_alloca)
stg_obj_val_aa: llvmlite.Value | t.CPtr = 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)
return 0
target_ty: llvmlite.LLVMType | t.CPtr = None
if mod_alloca.Ty is not None:
target_ty = mod_alloca.Ty.Pointee
@@ -1218,6 +1242,30 @@ class AssignGenMixin:
builder, pool, mod, aa.value,
None, 0, trans)
if rhs_val_mg is not None:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_mg: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_mg: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
if stg_key_mg is not None:
viperlib.snprintf(stg_key_mg, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_mg = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_mg)
if stg_ref_mg is not None and rhs_val_mg.Ty is not None \
and stg_ref_mg.Ty is not None and stg_ref_mg.Ty.Pointee is not None:
stg_ty_mg: llvmlite.LLVMType | t.CPtr = stg_ref_mg.Ty.Pointee
rhs_inner_mg: llvmlite.LLVMType | t.CPtr = None
match rhs_val_mg.Ty:
case llvmlite.LLVMType.Ptr(pointee_mg):
rhs_inner_mg = pointee_mg
case _:
pass
if rhs_inner_mg is not None and rhs_inner_mg.kind() == llvmlite.LLVMType.Struct \
and t.CUInt64T(stg_ty_mg) == t.CUInt64T(rhs_inner_mg):
llvmlite.build_store(builder, stg_ref_mg, mod_glob)
stg_obj_val_mg: llvmlite.Value | t.CPtr = 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)
return 0
target_ty_mg: llvmlite.LLVMType | t.CPtr = None
if mod_glob.Ty is not None:
target_ty_mg = mod_glob.Ty.Pointee
@@ -1826,6 +1874,35 @@ class AssignGenMixin:
target,
f"global 变量 '{nm.id}' 未注册,无法赋值",
"NameError")
# 对象类全局(裸类名注解 → 静态 storage):对象构造/赋值 → 引用
# 绑定到 storage + 复制对象到 storage。否则 store 栈 alloca 指针
# 悬垂(devfs serial0_file 根因),或模块级构造初始化器被丢弃后
# 全局保持 NULL(页 0 混叠根因,见 TranslatorGenMixin storage 逻辑)。
stg_ref_as: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_as: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
if stg_key_as is not None:
viperlib.snprintf(stg_key_as, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_as = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_as)
if stg_ref_as is not None and rhs_val is not None and rhs_val.Ty is not None \
and stg_ref_as.Ty is not None and stg_ref_as.Ty.Pointee is not None:
stg_ty_as: llvmlite.LLVMType | t.CPtr = stg_ref_as.Ty.Pointee
rhs_inner_as: llvmlite.LLVMType | t.CPtr = None
match rhs_val.Ty:
case llvmlite.LLVMType.Ptr(pointee_as):
rhs_inner_as = pointee_as
case _:
pass
if rhs_inner_as is not None and rhs_inner_as.kind() == llvmlite.LLVMType.Struct \
and t.CUInt64T(stg_ty_as) == t.CUInt64T(rhs_inner_as):
# 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂)
llvmlite.build_store(builder, stg_ref_as, mod_alloca)
# 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效)
stg_obj_val_as: llvmlite.Value | t.CPtr = 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
target_ty: llvmlite.LLVMType | t.CPtr = None
if mod_alloca.Ty is not None:
target_ty = mod_alloca.Ty.Pointee