feat(tpv): vtable 对象全局 storage 也按字段默认值折叠
补 f5ee178 未覆盖的 vtable 分支:抽出 _build_stg_struct_body_text,_build_stg_struct_init_text 改为其包装;vtable 分支以 start_idx=1 复用默认值折叠,字段默认值全零时回退原零值循环(元素个数语义不变)。
This commit is contained in:
1 parent
f5ee178407
commit
751fbccb29
1 file changed
+58
-26
@@ -544,19 +544,19 @@ class TranslatorGenMixin:
|
||||
return buf
|
||||
|
||||
# ============================================================
|
||||
# _build_stg_struct_init_text - storage struct 完整常量初始化器(含字段默认值)
|
||||
# _build_stg_struct_body_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 指针)。
|
||||
# 生成 "elem0, elem1, ..." 形式(含字段默认值折叠,缺失处按类型零值兜底),
|
||||
# 供两处复用:
|
||||
# - _build_stg_struct_init_text:外包 "{ ... }" 作为完整初始化器;
|
||||
# - vtable 对象 storage:首元素为 vtable 指针,其后追加本函数结果
|
||||
# (此时 start_idx=1 跳过字段 0)。
|
||||
# 无任何非零默认值时返回 None,调用方据此保持原零值路径(避免无谓文本)。
|
||||
# ============================================================
|
||||
def _build_stg_struct_init_text(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
def _build_stg_struct_body_text(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
se: GenTypes.StructEntry | t.CPtr,
|
||||
start_idx: int) -> str:
|
||||
"""按字段默认值生成完整 struct 初始化器;无非零默认值返回 None"""
|
||||
"""按字段默认值生成 "e0, e1, ..." 元素文本;无非零默认值返回 None"""
|
||||
if se is None or se.Fields is None:
|
||||
return None
|
||||
fc: int = se.FieldCount
|
||||
@@ -566,8 +566,7 @@ class TranslatorGenMixin:
|
||||
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)
|
||||
pos: t.CSizeT = 0
|
||||
first: int = 1
|
||||
has_nonzero: int = 0
|
||||
i: int = start_idx
|
||||
@@ -587,6 +586,7 @@ class TranslatorGenMixin:
|
||||
is_zero = 1
|
||||
if elem is None:
|
||||
continue
|
||||
written: t.CInt = 0
|
||||
if first == 0:
|
||||
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
|
||||
pos += t.CSizeT(written)
|
||||
@@ -597,7 +597,29 @@ class TranslatorGenMixin:
|
||||
has_nonzero = 1
|
||||
if has_nonzero == 0:
|
||||
return None
|
||||
viperlib.snprintf(buf + pos, buf_size - pos, " }")
|
||||
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(避免无谓文本)。
|
||||
# ============================================================
|
||||
def _build_stg_struct_init_text(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
se: GenTypes.StructEntry | t.CPtr,
|
||||
start_idx: int) -> str:
|
||||
"""按字段默认值生成完整 struct 初始化器;无非零默认值返回 None"""
|
||||
body: str = self._build_stg_struct_body_text(pool, se, start_idx)
|
||||
if body is None:
|
||||
return None
|
||||
body_len: t.CSizeT = t.CSizeT(string.strlen(body))
|
||||
buf: str = pool.alloc(body_len + 8)
|
||||
if buf is None:
|
||||
return None
|
||||
viperlib.snprintf(buf, body_len + 8, "{ %s }", body)
|
||||
return buf
|
||||
|
||||
# ============================================================
|
||||
@@ -980,21 +1002,31 @@ class TranslatorGenMixin:
|
||||
else:
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, "i8* @%s", vt_mangled)
|
||||
pos_v += t.CSizeT(written_v)
|
||||
fc_v: int = resolved_stg_entry.FieldCount
|
||||
for fi_v in range(1, fc_v):
|
||||
fe_v: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
resolved_stg_entry, fi_v)
|
||||
if fe_v is None or fe_v.Ty is None:
|
||||
continue
|
||||
ty_buf_v: str = pool.alloc(128)
|
||||
if ty_buf_v is None:
|
||||
continue
|
||||
llvmlite.TypePrint(ty_buf_v, 128, fe_v.Ty, pool)
|
||||
zero_v: str = self._stg_field_zero_text(pool, fe_v.Ty, ty_buf_v)
|
||||
if zero_v is None:
|
||||
continue
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", zero_v)
|
||||
# 字段 1..N 优先按字段默认值折叠(vtable 对象全局
|
||||
# 如 `_mbuddy: MemBuddy` 的字段默认不再丢失);
|
||||
# 全部默认值恰为零时回退逐字段零值,避免无谓文本。
|
||||
# 两者均列全字段(LLVM 要求初始化器元素数匹配)。
|
||||
rest_v: str = self._build_stg_struct_body_text(
|
||||
pool, resolved_stg_entry, 1)
|
||||
if rest_v is not None:
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", rest_v)
|
||||
pos_v += t.CSizeT(written_v)
|
||||
else:
|
||||
fc_v: int = resolved_stg_entry.FieldCount
|
||||
for fi_v in range(1, fc_v):
|
||||
fe_v: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
resolved_stg_entry, fi_v)
|
||||
if fe_v is None or fe_v.Ty is None:
|
||||
continue
|
||||
ty_buf_v: str = pool.alloc(128)
|
||||
if ty_buf_v is None:
|
||||
continue
|
||||
llvmlite.TypePrint(ty_buf_v, 128, fe_v.Ty, pool)
|
||||
zero_v: str = self._stg_field_zero_text(pool, fe_v.Ty, ty_buf_v)
|
||||
if zero_v is None:
|
||||
continue
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", zero_v)
|
||||
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:
|
||||
|
||||
Reference in new issue
Block a user