feat(tpv): 模块级对象全局按字段默认值生成 storage 初始化器
- 新增 _default_val_const_text:字段默认值 AST -> 常量文本(仅整型/字符/负号字面量可折叠,其余零值兜底) - 新增 _build_stg_struct_init_text:按 StructEntry 字段默认值生成完整 struct 常量初始化器(LLVM 要求列全字段);无非零默认值返回 None - storage 分支新增 elif:无 vtable 对象全局走默认值初始化器(vtable 路径不变) - 效果:fat32.default_fs 的 .stg 由 zeroinitializer 变为含 sector_size=512/root_cluster=2/free_clusters=0xFFFFFFFF/backup_sector=6/winsect=-1 的完整常量;drive_lock 等零值等价场景保持 zeroinitializer
This commit is contained in:
1 parent
e20a6f3d11
commit
f5ee178407
1 file changed
+107
@@ -504,6 +504,102 @@ class TranslatorGenMixin:
|
||||
viperlib.snprintf(buf, 160, "%s zeroinitializer", ty_str)
|
||||
return buf
|
||||
|
||||
# ============================================================
|
||||
# _default_val_const_text - 字段默认值 → LLVM 常量元素文本
|
||||
#
|
||||
# 仅处理可常量折叠的整型默认值(CONST_INT/CONST_CHAR 及负号字面量);
|
||||
# 其余(浮点/字符串/None/名字/表达式)返回 None,由调用方按零值兜底。
|
||||
# ============================================================
|
||||
def _default_val_const_text(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
fty: llvmlite.LLVMType | t.CPtr,
|
||||
ty_str: str,
|
||||
dval: ast.AST | t.CPtr) -> str:
|
||||
"""字段默认值 → "ty 值" 文本;不可折叠返回 None"""
|
||||
if dval is None or fty is None or ty_str is None:
|
||||
return None
|
||||
is_int: int = 0
|
||||
dv_int: t.CInt64T = 0
|
||||
if dval.kind() == ast.ASTKind.Constant:
|
||||
dc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(dval)
|
||||
if dc is not None:
|
||||
if dc.const_kind == ast.CONST_INT or dc.const_kind == ast.CONST_CHAR:
|
||||
dv_int = dc.int_val
|
||||
is_int = 1
|
||||
elif dval.kind() == ast.ASTKind.UnaryOp:
|
||||
# 负数/按位取反字面量(如 -1 / 0xFFFFFFFFFFFFFFFF)
|
||||
dv_int = self.Gen.AssignGen.extract_cdefine_int_value(dval)
|
||||
is_int = 1
|
||||
if is_int == 0:
|
||||
return None
|
||||
# 仅整型字段可写整数常量(浮点/指针/聚合交给零值兜底)
|
||||
match fty:
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
pass
|
||||
case _:
|
||||
return None
|
||||
buf: str = pool.alloc(48)
|
||||
if buf is None:
|
||||
return None
|
||||
viperlib.snprintf(buf, 48, "%s %lld", ty_str, dv_int)
|
||||
return buf
|
||||
|
||||
# ============================================================
|
||||
# _build_stg_struct_init_text - storage struct 完整常量初始化器(含字段默认值)
|
||||
#
|
||||
# 用于模块级对象全局 `X: T = T()`:此前 storage 一律 zeroinitializer,
|
||||
# `__before_init__`/字段默认(如 fat32.volinfo 的 sector_size=512、
|
||||
# root_cluster=2、free_clusters=0xFFFFFFFF、backup_sector=6)全部丢失。
|
||||
# 现按字段默认值生成完整 struct 常量(LLVM 要求列全每个字段)。
|
||||
# 无任何非零默认值时返回 None,由调用方保持 zeroinitializer(避免无谓文本)。
|
||||
# start_idx:vtable 对象跳过字段 0(首元素由调用方单独写 vtable 指针)。
|
||||
# ============================================================
|
||||
def _build_stg_struct_init_text(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
se: GenTypes.StructEntry | t.CPtr,
|
||||
start_idx: int) -> str:
|
||||
"""按字段默认值生成完整 struct 初始化器;无非零默认值返回 None"""
|
||||
if se is None or se.Fields is None:
|
||||
return None
|
||||
fc: int = se.FieldCount
|
||||
if fc <= start_idx:
|
||||
return None
|
||||
buf_size: t.CSizeT = 256 + t.CSizeT(fc) * 160
|
||||
buf: str = pool.alloc(buf_size)
|
||||
if buf is None:
|
||||
return None
|
||||
written: t.CInt = viperlib.snprintf(buf, buf_size, "{ ")
|
||||
pos: t.CSizeT = t.CSizeT(written)
|
||||
first: int = 1
|
||||
has_nonzero: int = 0
|
||||
i: int = start_idx
|
||||
while i < fc:
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(se, i)
|
||||
i += 1
|
||||
if fe is None or fe.Ty is None:
|
||||
continue
|
||||
ty_str: str = pool.alloc(128)
|
||||
if ty_str is None:
|
||||
continue
|
||||
llvmlite.TypePrint(ty_str, 128, fe.Ty, pool)
|
||||
elem: str = self._default_val_const_text(pool, fe.Ty, ty_str, fe.DefaultVal)
|
||||
is_zero: int = 0
|
||||
if elem is None:
|
||||
elem = self._stg_field_zero_text(pool, fe.Ty, ty_str)
|
||||
is_zero = 1
|
||||
if elem is None:
|
||||
continue
|
||||
if first == 0:
|
||||
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
|
||||
pos += t.CSizeT(written)
|
||||
written = viperlib.snprintf(buf + pos, buf_size - pos, "%s", elem)
|
||||
pos += t.CSizeT(written)
|
||||
first = 0
|
||||
if is_zero == 0:
|
||||
has_nonzero = 1
|
||||
if has_nonzero == 0:
|
||||
return None
|
||||
viperlib.snprintf(buf + pos, buf_size - pos, " }")
|
||||
return buf
|
||||
|
||||
# ============================================================
|
||||
# handle_module_level_var - 模块级变量声明 → 创建 LLVM 全局变量
|
||||
#
|
||||
@@ -901,6 +997,17 @@ class TranslatorGenMixin:
|
||||
pos_v += t.CSizeT(written_v)
|
||||
viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, " }")
|
||||
stg_init_text = init_full
|
||||
elif resolved_stg_entry is not None:
|
||||
# 无 vtable 的对象全局(@t.Object / 普通类):按字段默认值生成常量
|
||||
# 初始化器(如 fat32.volinfo:sector_size=512、root_cluster=2、
|
||||
# free_clusters=0xFFFFFFFF、backup_sector=6、winsect/fat_winsect=-1…)。
|
||||
# 此前一律 zeroinitializer → 字段默认全部丢失(模块级 X: T = T() 的
|
||||
# 构造调用不发射,见第十三节)。无任何非零默认值时返回 None →
|
||||
# 保持 zeroinitializer(drive_lock 等零值等价场景零开销)。
|
||||
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: 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:
|
||||
|
||||
Reference in new issue
Block a user