fix(gen): 逃逸检查把模块级(根 scope)变量判为 LIFE_STATIC,修模块级数组 return 误判帧逃逸(pyzlib_error_msg)

This commit is contained in:
TermiNexus committed 2026-10-12 21:23:23 +08:00
1 parent c0ff5c9d96
commit 22475e0fda
1 file changed
+19
+19
View File
@@ -884,6 +884,19 @@ novirtual class AssignGenMixin:
if rk != 0: return rk
return -1
# _is_module_scope_var - 该名字是否定义在**模块根 scope**(= LLVM 全局存储,静态生命期)。
# 逃逸检查据此把模块级变量(含其数组名退让)判为 LIFE_STATIC,而不是「本帧局部」。
# 注意与 is_global_name 区分:后者只认**函数内** `global X` 声明,认不出模块级定义。
def _is_module_scope_var(self, trans: HT.Translator*, name: str) -> int:
"""1 = name is defined in the module root scope (static storage); else 0."""
if trans is None or name is None or trans.SymTab is None: return 0
sc_m: GenTypes.Scope* = trans.SymTab.Current
while sc_m is not None:
if self.Gen.VarGen.find_var(sc_m.Vars, sc_m.VarCount, name) is not None:
if sc_m.Parent is None: return 1
return 0
sc_m = sc_m.Parent
return 0
# life_of_expr - 求表达式当前值的生命期标签。
# target_ty 参与判定:裸本帧数组名在**指针**目标位置 = 数组退让(交出本帧栈地址),
# 在同型聚合目标位置 = 按值拷贝(LIFE_VALUE)。
@@ -901,6 +914,10 @@ novirtual class AssignGenMixin:
nm: ast.Name* = ast.Name*(node)
if nm.id is None: return GenTypes.LIFE_UNKNOWN
if GenApi.is_global_name(trans, nm.id) != 0: return GenTypes.LIFE_STATIC
# 模块级(根 scope)变量 = LLVM 全局存储(静态生命期):裸数组名的「退让」拿到的正是
# 静态地址,返回/交出它都不会悬垂。此前只认函数内 `global X` 声明,于是模块级数组
# (如 pyzlib_error_msg)被当成「本帧局部数组」误判成 LIFE_FRAME。
if self._is_module_scope_var(trans, nm.id) != 0: return GenTypes.LIFE_STATIC
if GenApi.is_nonlocal_name(trans, nm.id) != 0: return GenTypes.LIFE_UNKNOWN
v: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
if v is None: return GenTypes.LIFE_STATIC
@@ -918,6 +935,8 @@ novirtual class AssignGenMixin:
onm: ast.Name* = ast.Name*(uo.operand)
if onm.id is not None:
if GenApi.is_global_name(trans, onm.id) != 0: return GenTypes.LIFE_STATIC
# 模块级(根 scope)变量:静态存储,同 Name 分支判据(`&<模块级数组>` 不悬垂)
if self._is_module_scope_var(trans, onm.id) != 0: return GenTypes.LIFE_STATIC
if GenApi.is_nonlocal_name(trans, onm.id) != 0: return GenTypes.LIFE_UNKNOWN
if self.Gen.VarGen.lookup_var(trans.SymTab, onm.id) is not None: return GenTypes.LIFE_FRAME
return GenTypes.LIFE_STATIC