feat(lifetime): 构造器路径同命裁剪的透传管道(recv_life,默认 -1 = 现状不变)

_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;未填 = 完全现状。
This commit is contained in:
TermiNexus committed 2026-10-09 22:36:09 +08:00
1 parent bf5ecd7668
commit 357a8bba05
1 file changed
+14 -2
+14 -2
View File
@@ -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)