From f5ee17840728ec6e66283f51efbd2cfa18e678c3 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 11 Sep 2026 14:52:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(tpv):=20=E6=A8=A1=E5=9D=97=E7=BA=A7?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=85=A8=E5=B1=80=E6=8C=89=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC=E7=94=9F=E6=88=90=20storage=20?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 _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 --- App/lib/core/Gen/TranslatorGenMixin.vp | 107 +++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 72c275b..a48c780 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -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: