fix(ClassGenMixin): register_method_meta 按位或合并装饰器元数据

同一属性名先 @property 再 @x.setter/@x.deleter 时整值替换覆盖 GETTER 位,property 拦截失效导致属性访问落空返回 None,llvmlite 收到 NULL Value 段错误(BuiltinDecoratorTest Phase A 崩溃)。改为 flags |= meta 合并,getter/setter/deleter 位共存。
This commit is contained in:
TermiNexus committed 2026-08-11 01:34:04 +08:00
1 parent 65d7342d0b
commit 5c6ba308ae
1 file changed
+20 -1
+20 -1
View File
@@ -312,7 +312,12 @@ class ClassGenMixin:
if string.strcmp(self.MethodMetaKeys + i * META_KEY_LEN, key_buf) == 0:
flags_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(
t.CUInt64T(self.MethodMetaFlags) + i * 4, t.CPtr))
flags_ptr[0] = meta
# 按位或合并:同一属性名先 @property(getter=4) 再 @x.setter(8)/
# @x.deleter(16) 会多次注册(如 Config.value / Counter.value)。
# 若整值替换,后注册的位会覆盖 GETTER 位 → _try_property_getter_attr
# 不再拦截 obj.prop → 落入字段查找失败返回 None → 上游 llvmlite
# 收到 NULL Value → 编译器进程段错误(BuiltinDecoratorTest Phase A 崩溃)。
flags_ptr[0] = flags_ptr[0] | meta
stdlib.free(key_buf)
return
if self.MethodMetaCount < META_MAX:
@@ -3218,6 +3223,20 @@ class ClassGenMixin:
# mark_only 模式:只设置标志,不翻译方法体
if mark_only != 0:
# Phase 1a 预注册也收集 vtable 元数据(VTableMethods/VTableMethodCount)。
# 根因:Phase 1b 中依赖模块可能先于其依赖类全量翻译(如 tokens.vp 先于
# memhub 生成 text.ll),此时调用方查到 entry 有 HasVTable=1 但
# VTableMethods=None → _translate_method_call 虚分派条件
# (VTableMethods is not None)不成立 → pool.alloc 被静态绑定到
# MemManager.alloc(默认返回 None)→ KwEntry.__new__ 返回 null →
# __before_init__ 写 null 崩溃。
# 短名顺序与 Phase 1b 全量收集一致(父类方法在前 + 本类方法,确定性),
# 多遍扫描重复收集时用新缓冲区覆盖(stdlib 泄漏可忽略,Phase 1b 重译幂等)。
mk_has_vt: int = 0
if oop_entry is not None:
mk_has_vt = oop_entry.HasVTable
if mk_has_vt == 1:
self._collect_vtable_methods(trans, cd, class_name)
return 0
# 防重入:方法体翻译前先标记 MethodsEmitted=1。