From 357a8bba052e0b257cbb682d07a677e0924db0ae Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 9 Oct 2026 22:36:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(lifetime):=20=E6=9E=84=E9=80=A0=E5=99=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=90=8C=E5=91=BD=E8=A3=81=E5=89=AA=E7=9A=84?= =?UTF-8?q?=E9=80=8F=E4=BC=A0=E7=AE=A1=E9=81=93=EF=BC=88recv=5Flife?= =?UTF-8?q?=EF=BC=8C=E9=BB=98=E8=AE=A4=20-1=20=3D=20=E7=8E=B0=E7=8A=B6?= =?UTF-8?q?=E4=B8=8D=E5=8F=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _call_method_on_ptr 新增 recv_life: int = -1(被构造对象的生命期,由调用方 CallGenCtor 算出); 构造器分支在指令最终裁决之后,若 recv_life ∈ {FRAME, VALUE} 则复用 _FrameArgsEscapeClearsMethod (recv_node=None,接收者已由 recv_life 判定)清"写进形参对象字段"那类位。 下一轮只需在 3 个 __init__ 调用点(CallGenCtor:171/665、ExprGenConst:257)填 recv_life;未填 = 完全现状。 --- App/lib/core/Gen/Call/CallGenCall.vp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 68fb7ff..477ec7f 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -141,7 +141,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # first argument (goes through virtual dispatch if the method is in the vtable). # ============================================================ - def _call_method_on_ptr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, self_ptr: mlirlite.Value*, extra_args: sizet*, extra_count: int, trans: HT.Translator*, node: ast.AST* = None, is_volatile: int = 0, arg_nodes: list[ast.AST*]* = None) -> mlirlite.Value*: + def _call_method_on_ptr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, self_ptr: mlirlite.Value*, extra_args: sizet*, extra_count: int, trans: HT.Translator*, node: ast.AST* = None, is_volatile: int = 0, arg_nodes: list[ast.AST*]* = None, recv_life: int = -1) -> mlirlite.Value*: """Call a method on a struct pointer; adds a volatile barrier for constructors.""" if pool is None or builder is None or class_name is None or method_name is None: return None if self_ptr is None: return None @@ -165,7 +165,19 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 跨模块:本文件指令表为空,改查对方模块 .vpi 的 esce=/escn= f_ci = self.Gen.CallGenBase.lookup_escape_dir_via_vpi(sha_ci, class_name, method_name, 0) n_ci = self.Gen.CallGenBase.lookup_escape_dir_via_vpi(sha_ci, class_name, method_name, 1) - if f_ci != 0 or n_ci != 0: esc_mask_ci = (esc_mask_ci | f_ci) & (~n_ci) + if f_ci != 0 or n_ci != 0: esc_mask_ci = (esc_mask_ci | f_ci) & (~n_ci) + # 同命裁剪(构造器路径):被构造对象的生命期由**调用方**(CallGenCtor)算出并经 + # recv_life 传入 —— 这里只有 self_ptr(LLVM 值),拿不到 AST/生命期。 + # recv_life == -1 = 未知 → **不做裁剪**(与接这条之前的行为完全一致)。 + # 对象在本帧(裸 `T()` / `new stack` / `slife`)时,其余实参也都在本帧即可清位。 + if recv_life >= 0 and esc_mask_ci != 0: + if recv_life == GenTypes.LIFE_FRAME or recv_life == GenTypes.LIFE_VALUE: + hard_ci: int = GenApi.get_param_escapes_hard_method(pool, class_name, method_name) + fld_ci: int = esc_mask_ci & (~hard_ci) + if fld_ci != 0: + can_ci2: sizet = len(arg_nodes) + cl_ci: int = self.Gen.CallGen._FrameArgsEscapeClearsMethod(trans, None, arg_nodes, can_ci2, fld_ci) + if cl_ci != 0: esc_mask_ci = esc_mask_ci & (~cl_ci) if esc_mask_ci != 0: dummy_ptr_ci: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool)) can_ci: sizet = len(arg_nodes)