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)