feat(lifetime): 方法/构造器调用点也接 @life(escape/noescape) 最终裁决
StructGenMixin: 新增 _DirForceOf / _DirForceMethod(查 "Class.method" 并沿 MRO 回退)与 get_param_escape_force_method / get_param_noescape_force_method;GenApi 加同名委托。 CallGenCall: 构造器分支(esc_mask_ci)与方法分支(esc_mask_mc)在跨模块回退、常量特化之后 最后套用一次 esc_mask = (esc_mask | escape_force) & ~noescape_force,与模块级函数那条口径一致。
This commit is contained in:
1 parent
fc7c5d5560
commit
2bd37e80e3
3 files changed
+53
-1
No files matched your search
@@ -157,6 +157,10 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
|
||||
sha_ci: str = self.Gen.StructGen.get_struct_sha1(class_name)
|
||||
pk_ci: int = self.Gen.CallGenBase.lookup_escape_via_vpi(pool, sha_ci, class_name, method_name)
|
||||
if pk_ci != 0: esc_mask_ci = int(pk_ci & 4294967295)
|
||||
# 声明式指令最终裁决(@life(escape/noescape):unsafe 但强制),在推断/回退之后最后套用
|
||||
f_ci: int = GenApi.get_param_escape_force_method(pool, class_name, method_name)
|
||||
n_ci: int = GenApi.get_param_noescape_force_method(pool, class_name, method_name)
|
||||
if f_ci != 0 or n_ci != 0: esc_mask_ci = (esc_mask_ci | f_ci) & (~n_ci)
|
||||
if esc_mask_ci != 0:
|
||||
dummy_ptr_ci: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
can_ci: sizet = len(arg_nodes)
|
||||
@@ -565,6 +569,10 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
|
||||
if esc_mask_mc != 0:
|
||||
can_rf: sizet = len(cargs_mc)
|
||||
esc_mask_mc = GenApi.refine_escape_mask_method(pool, class_name, method_name, cargs_mc, can_rf, esc_mask_mc)
|
||||
# 声明式指令最终裁决(@life(escape/noescape):unsafe 但强制),在推断/回退之后最后套用
|
||||
f_mc: int = GenApi.get_param_escape_force_method(pool, class_name, method_name)
|
||||
n_mc: int = GenApi.get_param_noescape_force_method(pool, class_name, method_name)
|
||||
if f_mc != 0 or n_mc != 0: esc_mask_mc = (esc_mask_mc | f_mc) & (~n_mc)
|
||||
if esc_mask_mc != 0:
|
||||
dummy_ptr_mc: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
can_mc: sizet = len(cargs_mc)
|
||||
|
||||
@@ -511,6 +511,18 @@ def get_param_noescape_force(name: str) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def get_param_escape_force_method(pool: memhub.MemBuddy*, class_name: str, method_name: str) -> int:
|
||||
"""方法版 `@life(escape(...))` 掩码:查 "Class.method" 并沿 MRO 回退"""
|
||||
if _g_gen is not None: return _g_gen.StructGen.get_param_escape_force_method(pool, class_name, method_name)
|
||||
return 0
|
||||
|
||||
|
||||
def get_param_noescape_force_method(pool: memhub.MemBuddy*, class_name: str, method_name: str) -> int:
|
||||
"""方法版 `@life(noescape(...))` 掩码:查 "Class.method" 并沿 MRO 回退"""
|
||||
if _g_gen is not None: return _g_gen.StructGen.get_param_noescape_force_method(pool, class_name, method_name)
|
||||
return 0
|
||||
|
||||
|
||||
# escape_leak_line - **错误路径专用**:被调者第 want_pi 号形参的"首个逃逸写入点"行号。
|
||||
# 只在 fail-fast 报错时调用(会重扫一次被调者函数体);跨模块拿不到 AST 时返回 0。
|
||||
def escape_leak_line(name: str, want_pi: int) -> int:
|
||||
|
||||
@@ -553,7 +553,39 @@ novirtual class StructGenMixin:
|
||||
"""`@life(noescape(...))` 强制不逃逸位掩码;0 = 无该标注"""
|
||||
idx: int = self._DirLookup(name)
|
||||
if idx < 0: return 0
|
||||
return int(self.EscDirTable[idx * 3 + 2])
|
||||
return int(self.EscDirTable[idx * 3 + 2])
|
||||
|
||||
def _DirForceOf(self, name: str, noescape: int) -> int:
|
||||
"""按方向取指令位:noescape!=0 → 强制不逃逸槽,否则 → 强制逃逸槽"""
|
||||
if noescape != 0: return self.get_param_noescape_force(name)
|
||||
return self.get_param_escape_force(name)
|
||||
|
||||
# _DirForceMethod - 方法版指令掩码:查 "Class.method" 并沿 MRO 回退(口径同 get_param_escapes_method)
|
||||
def _DirForceMethod(self, pool: memhub.MemBuddy*, class_name: str, method_name: str, noescape: int) -> int:
|
||||
if method_name is None or class_name is None: return 0
|
||||
key_q: str = self._EscKey2(pool, class_name, method_name)
|
||||
if key_q is not None:
|
||||
m_q: int = self._DirForceOf(key_q, noescape)
|
||||
if m_q != 0: return m_q
|
||||
mro: sizet* = self.get_mro_chain(pool, class_name)
|
||||
mi2: int = 1
|
||||
while mro is not None and mro[mi2] != 0:
|
||||
anc_m: str = rawptr(mro[mi2])
|
||||
if anc_m is not None and string.strcmp(anc_m, class_name) != 0:
|
||||
key_a: str = self._EscKey2(pool, anc_m, method_name)
|
||||
if key_a is not None:
|
||||
m_a: int = self._DirForceOf(key_a, noescape)
|
||||
if m_a != 0: return m_a
|
||||
mi2 += 1
|
||||
return 0
|
||||
|
||||
def get_param_escape_force_method(self, pool: memhub.MemBuddy*, class_name: str, method_name: str) -> int:
|
||||
"""方法版 `@life(escape(...))` 掩码;0 = 无该标注"""
|
||||
return self._DirForceMethod(pool, class_name, method_name, 0)
|
||||
|
||||
def get_param_noescape_force_method(self, pool: memhub.MemBuddy*, class_name: str, method_name: str) -> int:
|
||||
"""方法版 `@life(noescape(...))` 掩码;0 = 无该标注"""
|
||||
return self._DirForceMethod(pool, class_name, method_name, 1)
|
||||
|
||||
# ---- P2 willFree:声明式标注表(直接来自 @life(willFree(...)) / @willFree(...),不做数据流) ----
|
||||
def _WillFreeLookup(self, name: str) -> int:
|
||||
|
||||
Reference in new issue
Block a user