From 64195f183ee8f4b33cbd1d3e2e632d1f6734e9c0 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 13 Aug 2026 02:58:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(type):=20=E6=94=AF=E6=8C=81=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=20CDefine=EF=BC=88=E5=A6=82=20ZLIB=5FVERSION?= =?UTF-8?q?=20=3D=20"1.3.2"=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TypeGenMixin 新增 CDefineStrFlags/CDefineIsStr 字段与 register_cdefine_string/lookup_cdefine_string/is_cdefine_str 方法 - AssignGenMixin._register_cdefine_from_value 新增 CONST_STR 分支 - ExprGenMixin.translate_name_value CDefine 本地/跨模块均支持字符串 - Generator.InitGen / HandlesType 委托同步初始化新字段 --- App/lib/core/Gen/AssignGenMixin.vp | 5 ++ App/lib/core/Gen/ExprGenMixin.vp | 12 +++++ App/lib/core/Gen/Generator.vp | 2 + App/lib/core/Gen/TypeGenMixin.vp | 81 +++++++++++++++++++++++++++++ App/lib/core/Handles/HandlesType.vp | 27 ++++++++++ 5 files changed, 127 insertions(+) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index 5751999..d44ff08 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -157,6 +157,11 @@ class AssignGenMixin: return if val_node is not None and val_node.kind() == ast.ASTKind.Constant: cn_fp: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(val_node) + if cn_fp.const_kind == ast.CONST_STR: + # 字符串 CDefine(如 ZLIB_VERSION: t.CDefine = "1.3.2"): + # 注册为字符串常量,读取端返回 global string(对齐 TPC)。 + HandlesType.register_cdefine_string(pool, name, cn_fp.str_val) + return if cn_fp.const_kind == ast.CONST_FLOAT: # 源文件重读恢复(最可靠:AST 节点 float_val 可能被 pool 操作覆写, # 源文件文本不受影响;用输出参数绕开跨模块 double 返回值传递 bug) diff --git a/App/lib/core/Gen/ExprGenMixin.vp b/App/lib/core/Gen/ExprGenMixin.vp index b83b612..d3451f5 100644 --- a/App/lib/core/Gen/ExprGenMixin.vp +++ b/App/lib/core/Gen/ExprGenMixin.vp @@ -2826,6 +2826,13 @@ class ExprGenMixin: # 否则在 double 函数里 return 生成 ret i32 0(llc 报错)。 cdef_val_d: double = HandlesType.lookup_cdefine_double(nm_id) if HandlesType.is_cdefine_found() != 0: + if HandlesType.is_cdefine_str() != 0: + # 字符串 CDefine(如 ZLIB_VERSION: t.CDefine = "1.3.2"): + # 返回 global string(i8*),供 return ZLIB_VERSION 等使用。 + cdef_sv: str = HandlesType.lookup_cdefine_string(nm_id) + if cdef_sv is not None: + return self.create_global_string(builder, pool, mod, cdef_sv, trans) + HandlesType.fatal_error(node, f"CDefine 字符串值缺失: {nm_id}", "InternalCompilerError") if HandlesType.is_cdefine_double() != 0: return llvmlite.ConstFloat(pool, llvmlite.Double(pool), cdef_val_d) cdef_val_i: int = t.CInt(cdef_val_d) @@ -2839,6 +2846,11 @@ class ExprGenMixin: cdef_val = self._lookup_cross_module_cdefine( pool, nm_id, trans._from_imports, trans._imported_modules) if HandlesType.is_cdefine_found() != 0: + if HandlesType.is_cdefine_str() != 0: + cdef_sv2: str = HandlesType.lookup_cdefine_string(nm_id) + if cdef_sv2 is not None: + return self.create_global_string(builder, pool, mod, cdef_sv2, trans) + HandlesType.fatal_error(node, f"CDefine 字符串值缺失: {nm_id}", "InternalCompilerError") # 跨模块浮点 CDefine 已缓存为 double(is_cdefine_double), # 需返回浮点常量而非截断的整数 dchk_nm: double = HandlesType.lookup_cdefine_double(nm_id) diff --git a/App/lib/core/Gen/Generator.vp b/App/lib/core/Gen/Generator.vp index 04d15b5..59bdeb7 100644 --- a/App/lib/core/Gen/Generator.vp +++ b/App/lib/core/Gen/Generator.vp @@ -64,7 +64,9 @@ class Generator(BaseGenMixin.BaseGenMixin, TypeGenMixin.TypeGenMixin, self.CDefineNames = None self.CDefineValues = None self.CDefineDoubleFlags = None + self.CDefineStrFlags = None self.CDefineIsDouble = 0 + self.CDefineIsStr = 0 self.CDefineFound = 0 self.CurrentModuleSha1 = None self.CTypedefNames = None diff --git a/App/lib/core/Gen/TypeGenMixin.vp b/App/lib/core/Gen/TypeGenMixin.vp index 734aeae..a148e67 100644 --- a/App/lib/core/Gen/TypeGenMixin.vp +++ b/App/lib/core/Gen/TypeGenMixin.vp @@ -62,7 +62,9 @@ class TypeGenMixin: CDefineNames: list[str] | t.CPtr CDefineValues: list[str] | t.CPtr CDefineDoubleFlags: list[int] | t.CPtr + CDefineStrFlags: list[int] | t.CPtr # 1=字符串值(如 ZLIB_VERSION: t.CDefine = "1.3.2") CDefineIsDouble: int + CDefineIsStr: int CDefineFound: int # --- 当前模块 SHA1(原 _g_current_module_sha1) --- @@ -93,7 +95,9 @@ class TypeGenMixin: self.CDefineNames = None self.CDefineValues = None self.CDefineDoubleFlags = None + self.CDefineStrFlags = None self.CDefineIsDouble = 0 + self.CDefineIsStr = 0 self.CDefineFound = 0 self.CurrentModuleSha1 = None self.CTypedefNames = None @@ -196,6 +200,7 @@ class TypeGenMixin: self.CDefineNames = list[str](pool, 64) self.CDefineValues = list[str](pool, 64) self.CDefineDoubleFlags = list[int](pool, 64) + self.CDefineStrFlags = list[int](pool, 64) self.CDefineNames.append(name) val_buf: str = pool.alloc(32) if val_buf is not None: @@ -205,6 +210,8 @@ class TypeGenMixin: self.CDefineValues.append("0") if self.CDefineDoubleFlags is not None: self.CDefineDoubleFlags.append(0) + if self.CDefineStrFlags is not None: + self.CDefineStrFlags.append(0) def register_cdefine_double(self, pool: memhub.MemBuddy | t.CPtr, name: str, value: double) -> None: @@ -216,6 +223,7 @@ class TypeGenMixin: self.CDefineNames = list[str](pool, 64) self.CDefineValues = list[str](pool, 64) self.CDefineDoubleFlags = list[int](pool, 64) + self.CDefineStrFlags = list[int](pool, 64) self.CDefineNames.append(name) val_buf: str = pool.alloc(32) if val_buf is not None: @@ -228,12 +236,44 @@ class TypeGenMixin: self.CDefineValues.append("0") if self.CDefineDoubleFlags is not None: self.CDefineDoubleFlags.append(1) + if self.CDefineStrFlags is not None: + self.CDefineStrFlags.append(0) # fail-fast:CDefine 值缓冲区分配失败必须终止编译, # 绝不以 "(null)" 掩盖内存分配异常。 if val_buf is None: VLogger.error("CDefine 浮点值缓冲区分配失败", "CDEF-DBG") HandlesType.fatal_error(None, "CDefine 浮点值缓冲区分配失败", "MemoryError") + def register_cdefine_string(self, pool: memhub.MemBuddy | t.CPtr, + name: str, value: str) -> None: + """注册字符串 CDefine 编译期常量(如 ZLIB_VERSION: t.CDefine = "1.3.2") + + 字符串值深拷贝到 pool(AST 节点的 str_val 可能被 pool 操作覆写, + 与浮点 CDefine 的恢复同理)。 + """ + if pool is None or name is None: + return + if value is None: + HandlesType.fatal_error(None, f"CDefine 字符串值缺失: {name}", "InternalCompilerError") + return + if self.CDefineNames is None: + self.CDefineNames = list[str](pool, 64) + self.CDefineValues = list[str](pool, 64) + self.CDefineDoubleFlags = list[int](pool, 64) + self.CDefineStrFlags = list[int](pool, 64) + self.CDefineNames.append(name) + vlen: t.CSizeT = string.strlen(value) + vcopy: str = pool.alloc(vlen + 1) + if vcopy is None: + HandlesType.fatal_error(None, f"CDefine 字符串值分配失败: {name}", "MemoryError") + return + string.strcpy(vcopy, value) + self.CDefineValues.append(vcopy) + if self.CDefineDoubleFlags is not None: + self.CDefineDoubleFlags.append(0) + if self.CDefineStrFlags is not None: + self.CDefineStrFlags.append(1) + def lookup_cdefine_constant(self, name: str) -> int: """查找 CDefine 编译期常量 @@ -244,6 +284,7 @@ class TypeGenMixin: """ self.CDefineFound = 0 self.CDefineIsDouble = 0 + self.CDefineIsStr = 0 if self.CDefineNames is None: return 0 n: t.CSizeT = len(self.CDefineNames) @@ -254,6 +295,11 @@ class TypeGenMixin: val_str: str = self.CDefineValues.get(i) if val_str is not None: self.CDefineFound = 1 + if self.CDefineStrFlags is not None and self.CDefineStrFlags.get(i) == 1: + # 字符串 CDefine(如 ZLIB_VERSION="1.3.2"):整数查询路径 + # 标记 is_str,调用方改用 lookup_cdefine_string 取字符串。 + self.CDefineIsStr = 1 + return 0 if self.CDefineDoubleFlags is not None and self.CDefineDoubleFlags.get(i) == 1: self.CDefineIsDouble = 1 return string.atoi(val_str) @@ -268,6 +314,7 @@ class TypeGenMixin: """ self.CDefineFound = 0 self.CDefineIsDouble = 0 + self.CDefineIsStr = 0 if self.CDefineNames is None: return 0.0 n: t.CSizeT = len(self.CDefineNames) @@ -278,6 +325,9 @@ class TypeGenMixin: val_str: str = self.CDefineValues.get(i) if val_str is not None: self.CDefineFound = 1 + if self.CDefineStrFlags is not None and self.CDefineStrFlags.get(i) == 1: + self.CDefineIsStr = 1 + return 0.0 if self.CDefineDoubleFlags is not None and self.CDefineDoubleFlags.get(i) == 1: self.CDefineIsDouble = 1 ret_d: double = string.atof(val_str) @@ -286,6 +336,35 @@ class TypeGenMixin: return ret_i2 return 0.0 + def lookup_cdefine_string(self, name: str) -> str: + """查找 CDefine 编译期字符串值(found=1 且 is_str=1 时有效) + + 返回的字符串指针位于 pool 内(当前模块生命周期内有效), + 调用方应尽快用于 create_global_string 拷贝到 LLVM 常量。 + """ + self.CDefineFound = 0 + self.CDefineIsDouble = 0 + self.CDefineIsStr = 0 + if self.CDefineNames is None: + return None + n: t.CSizeT = len(self.CDefineNames) + i: t.CSizeT + for i in range(n): + nm: str = self.CDefineNames.get(i) + if nm is not None and string.strcmp(nm, name) == 0: + val_str: str = self.CDefineValues.get(i) + if val_str is not None: + self.CDefineFound = 1 + if self.CDefineStrFlags is not None and self.CDefineStrFlags.get(i) == 1: + self.CDefineIsStr = 1 + return val_str + return val_str + return None + + def is_cdefine_str(self) -> int: + """检查最近一次 CDefine 查找命中的是否是字符串常量""" + return self.CDefineIsStr + def is_cdefine_double(self) -> int: """检查最近一次 CDefine 查找命中的是否是浮点常量""" return self.CDefineIsDouble @@ -303,6 +382,8 @@ class TypeGenMixin: self.CDefineNames = None self.CDefineValues = None self.CDefineDoubleFlags = None + self.CDefineStrFlags = None + self.CDefineIsStr = 0 def register_ctypedef(self, pool: memhub.MemBuddy | t.CPtr, name: str, type_str: str) -> None: diff --git a/App/lib/core/Handles/HandlesType.vp b/App/lib/core/Handles/HandlesType.vp index 572ef74..bb0f17e 100644 --- a/App/lib/core/Handles/HandlesType.vp +++ b/App/lib/core/Handles/HandlesType.vp @@ -157,6 +157,15 @@ def register_cdefine_double(pool: memhub.MemBuddy | t.CPtr, g.register_cdefine_double(pool, name, value) +def register_cdefine_string(pool: memhub.MemBuddy | t.CPtr, + name: str, value: str) -> None: + """注册字符串 CDefine 编译期常量(委托到 gen.register_cdefine_string)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + g.register_cdefine_string(pool, name, value) + + def lookup_cdefine_constant(name: str) -> int: """查找 CDefine 编译期常量(委托到 gen.lookup_cdefine_constant)""" import lib.core.Gen.Generator as Generator @@ -175,6 +184,24 @@ def lookup_cdefine_double(name: str) -> double: return 0.0 +def lookup_cdefine_string(name: str) -> str: + """查找 CDefine 编译期字符串值(委托到 gen.lookup_cdefine_string)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.lookup_cdefine_string(name) + return None + + +def is_cdefine_str() -> int: + """检查最近一次 CDefine 查找命中的是否是字符串常量(委托到 gen.is_cdefine_str)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.is_cdefine_str() + return 0 + + def eval_ctraits_isptr(symtab: HandlesVar.SymbolTable | t.CPtr, name: str) -> int: """ctraits.isptr(name) 编译期求值(委托到 gen._eval_ctraits_isptr)。