From 6b180c8f5965ab7425f59f5c23fa9876c3984c3d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 15:53:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(viperc/life):=20=E8=BF=9B=E7=A8=8B=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=E8=B1=81=E5=85=8D=E8=A1=A5=E4=B8=8A=20`=5Fstart`?= =?UTF-8?q?=EF=BC=88ViperOS=20=E5=BA=94=E7=94=A8=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E6=B6=88=E9=99=A4=E6=A0=88=E9=80=83=E9=80=B8?= =?UTF-8?q?=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:Apps/HelloWorld/main.vp 报 LifetimeError(`master` frame-local,传给构造器参数会 悬垂)。而 `master = &root` 中 root 是 _start 的帧内 Tk,_start 是进程入口 (@__attribute__(section(".text.startup")),结尾 mainloop/process.exit),本帧返回即进程 结束 —— 与 main 同口径,确无逃逸。 _CurFuncIsEntryMain 此前只认 "main",现把 `_start` 一并视为进程入口。 --- App/lib/core/Gen/AssignGenMixin.vp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index 375570f..fd03ace 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -1055,14 +1055,19 @@ novirtual class AssignGenMixin: self.Gen.VarGen.set_var_life(trans.SymTab, tnm.id, life) return 0 - # _CurFuncIsEntryMain - 当前正在翻译的函数是否为**入口 main**(1=是 / 0=否)。 + # _CurFuncIsEntryMain - 当前正在翻译的函数是否为**进程入口**(1=是 / 0=否)。 + # 进程入口有两类:`main`(普通可执行)与 `_start`(ViperOS 应用/库的导出入口, + # 见 `@__attribute__(section(".text.startup"), ...)`)。两者的帧生命期都等于进程生命期: + # 本帧返回即进程结束,栈对象其后不可能再被使用 —— 故同样不做栈地址逃逸检查。 # 嵌套函数不算:它们的帧不是进程生命期,不能享受豁免。 def _CurFuncIsEntryMain(self, trans: HT.Translator*) -> int: - """当前函数是否为入口 main(按 llirlite 函数名判,与 FuncGenDef 对 main 不改名同口径)""" + """当前函数是否为进程入口(main / _start;与 FuncGenDef 对入口不改名同口径)""" if trans is None or trans._cur_func is None: return 0 nm: str = mlirlite.function_get_name(trans._cur_func) if nm is None: return 0 - return 1 if string.strcmp(nm, "main") == 0 else 0 + if string.strcmp(nm, "main") == 0: return 1 + if string.strcmp(nm, "_start") == 0: return 1 + return 0 # fail_if_life_escapes - 汇点检查:被写出表达式的生命期为 LIFE_FRAME → LifetimeError。 # 这是 GenApi.fail_if_stack_addr_escape 的唯一实现(语法判据已并入 life_of_expr)。