feat(type): 支持字符串 CDefine(如 ZLIB_VERSION = "1.3.2")

- 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 委托同步初始化新字段
This commit is contained in:
TermiNexus committed 2026-08-13 02:58:15 +08:00
1 parent 9eee43c304
commit 64195f183e
5 files changed
+127

No files matched your search

+5
View File
@@ -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)
+12
View File
@@ -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)
+2
View File
@@ -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
+81
View File
@@ -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:
+27
View File
@@ -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)。