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:
1 parent
2b2c242d14
commit
1fe7878074
2 files changed
+124
-1
No files matched your search
@@ -1165,6 +1165,30 @@ class AssignGenMixin:
|
|||||||
builder, pool, mod, aa.value,
|
builder, pool, mod, aa.value,
|
||||||
None, 0, trans)
|
None, 0, trans)
|
||||||
if rhs_val is not None:
|
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
|
target_ty: llvmlite.LLVMType | t.CPtr = None
|
||||||
if mod_alloca.Ty is not None:
|
if mod_alloca.Ty is not None:
|
||||||
target_ty = mod_alloca.Ty.Pointee
|
target_ty = mod_alloca.Ty.Pointee
|
||||||
@@ -1218,6 +1242,30 @@ class AssignGenMixin:
|
|||||||
builder, pool, mod, aa.value,
|
builder, pool, mod, aa.value,
|
||||||
None, 0, trans)
|
None, 0, trans)
|
||||||
if rhs_val_mg is not None:
|
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
|
target_ty_mg: llvmlite.LLVMType | t.CPtr = None
|
||||||
if mod_glob.Ty is not None:
|
if mod_glob.Ty is not None:
|
||||||
target_ty_mg = mod_glob.Ty.Pointee
|
target_ty_mg = mod_glob.Ty.Pointee
|
||||||
@@ -1826,6 +1874,35 @@ class AssignGenMixin:
|
|||||||
target,
|
target,
|
||||||
f"global 变量 '{nm.id}' 未注册,无法赋值",
|
f"global 变量 '{nm.id}' 未注册,无法赋值",
|
||||||
"NameError")
|
"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
|
target_ty: llvmlite.LLVMType | t.CPtr = None
|
||||||
if mod_alloca.Ty is not None:
|
if mod_alloca.Ty is not None:
|
||||||
target_ty = mod_alloca.Ty.Pointee
|
target_ty = mod_alloca.Ty.Pointee
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ class TranslatorGenMixin:
|
|||||||
|
|
||||||
var_name: str = None
|
var_name: str = None
|
||||||
var_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
var_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||||
|
resolved_stg_ty: llvmlite.LLVMType | t.CPtr = None # 对象类全局:静态 storage 类型(BSS 实例)
|
||||||
init_val: t.CInt64T = 0
|
init_val: t.CInt64T = 0
|
||||||
init_kind: int = 0 # 0=none, 1=int, 2=list, 3=str
|
init_kind: int = 0 # 0=none, 1=int, 2=list, 3=str
|
||||||
init_str_val: str = None
|
init_str_val: str = None
|
||||||
@@ -518,6 +519,11 @@ class TranslatorGenMixin:
|
|||||||
gv_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(resolved)
|
gv_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(resolved)
|
||||||
if gv_entry is not None \
|
if gv_entry is not None \
|
||||||
and (gv_entry.HasNew != 0 or gv_entry.HasVTable != 0 or gv_entry.IsOOP != 0):
|
and (gv_entry.HasNew != 0 or gv_entry.HasVTable != 0 or gv_entry.IsOOP != 0):
|
||||||
|
# 对象类全局(裸类名注解 → 对象即指针):记录原 Struct 值类型,
|
||||||
|
# 用于创建静态 storage 全局承载对象实例(BSS)。
|
||||||
|
# 否则 @g = global T* zeroinitializer → NULL → 对象字段落在
|
||||||
|
# 物理页 0(IVT+BDA 混叠),devfs/fat32/sched 全部对象失效根因。
|
||||||
|
resolved_stg_ty = resolved
|
||||||
resolved = llvmlite.Ptr(pool, resolved)
|
resolved = llvmlite.Ptr(pool, resolved)
|
||||||
var_ty = resolved
|
var_ty = resolved
|
||||||
# 解析初始值(支持整数、列表字面量、字符串字面量)
|
# 解析初始值(支持整数、列表字面量、字符串字面量)
|
||||||
@@ -650,7 +656,47 @@ class TranslatorGenMixin:
|
|||||||
else:
|
else:
|
||||||
# 使用 zeroinitializer 而非 "0":指针类型必须用 null/zeroinitializer,
|
# 使用 zeroinitializer 而非 "0":指针类型必须用 null/zeroinitializer,
|
||||||
# 整数/聚合类型也兼容 zeroinitializer,避免 "integer constant must have integer type"
|
# 整数/聚合类型也兼容 zeroinitializer,避免 "integer constant must have integer type"
|
||||||
gv.Initializer = "zeroinitializer"
|
# 对象类全局(有 storage)的 Initializer 由下方 storage 逻辑设为 &@storage,
|
||||||
|
# 此处不覆盖。
|
||||||
|
if resolved_stg_ty is None:
|
||||||
|
gv.Initializer = "zeroinitializer"
|
||||||
|
|
||||||
|
# 对象类全局:创建静态 storage 全局(BSS)承载对象实例,@g 编译期引用它。
|
||||||
|
# 函数内 `g = T()` 构造时把对象复制到 storage(见 AssignGenMixin 全局分支),
|
||||||
|
# 不再依赖栈 alloca(悬垂);c.Addr(g) load @g 得到 &storage,均非 NULL。
|
||||||
|
if resolved_stg_ty is not None:
|
||||||
|
# 值类型 storage 需要完整 struct 定义(跨模块类默认 opaque →
|
||||||
|
# @g.stg = global %T zeroinitializer 报 "use of undefined type")
|
||||||
|
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, resolved_stg_ty)
|
||||||
|
stg_name_len: t.CSizeT = t.CSizeT(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 | t.CPtr = 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
|
||||||
|
stg_gv.Initializer = "zeroinitializer"
|
||||||
|
# @g 初始值 = &@storage(对象引用指向 BSS 实例,非 NULL)
|
||||||
|
stg_init_len: t.CSizeT = t.CSizeT(string.strlen(mangled_name)) + 8
|
||||||
|
stg_init_buf: str = pool.alloc(stg_init_len)
|
||||||
|
if stg_init_buf is not None:
|
||||||
|
if self.Gen.ClassGenVTable._vtable_name_needs_quote(stg_name_buf) != 0:
|
||||||
|
viperlib.snprintf(stg_init_buf, stg_init_len, "@\"%s\"", stg_name_buf)
|
||||||
|
else:
|
||||||
|
viperlib.snprintf(stg_init_buf, stg_init_len, "@%s", stg_name_buf)
|
||||||
|
gv.Initializer = stg_init_buf
|
||||||
|
# 注册 storage 引用(key: var_name.__stg),供 AssignGenMixin
|
||||||
|
# 全局赋值分支检测对象类全局并复制对象到 storage。
|
||||||
|
stg_ref: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.make_global_ref(
|
||||||
|
pool, stg_name_buf, resolved_stg_ty)
|
||||||
|
if stg_ref is not None:
|
||||||
|
stg_key_len: t.CSizeT = t.CSizeT(string.strlen(var_name)) + 8
|
||||||
|
stg_key: str = pool.alloc(stg_key_len)
|
||||||
|
if stg_key is not None:
|
||||||
|
viperlib.snprintf(stg_key, stg_key_len, "%s.__stg", var_name)
|
||||||
|
self.Gen.VarGen.define_module_var(trans.SymTab, stg_key, stg_ref)
|
||||||
|
|
||||||
# 创建 Value 引用(@mangled_name, 类型为 var_ty*)
|
# 创建 Value 引用(@mangled_name, 类型为 var_ty*)
|
||||||
var_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, var_ty)
|
var_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, var_ty)
|
||||||
|
|||||||
Reference in new issue
Block a user