From 5c6ba308aea6628d261b74d70bfe27078e0bcd5d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 11 Aug 2026 01:34:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(ClassGenMixin):=20register=5Fmethod=5Fmeta?= =?UTF-8?q?=20=E6=8C=89=E4=BD=8D=E6=88=96=E5=90=88=E5=B9=B6=E8=A3=85?= =?UTF-8?q?=E9=A5=B0=E5=99=A8=E5=85=83=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同一属性名先 @property 再 @x.setter/@x.deleter 时整值替换覆盖 GETTER 位,property 拦截失效导致属性访问落空返回 None,llvmlite 收到 NULL Value 段错误(BuiltinDecoratorTest Phase A 崩溃)。改为 flags |= meta 合并,getter/setter/deleter 位共存。 --- App/lib/core/Gen/ClassGenMixin.vp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/App/lib/core/Gen/ClassGenMixin.vp b/App/lib/core/Gen/ClassGenMixin.vp index f0bab3f..b4903ce 100644 --- a/App/lib/core/Gen/ClassGenMixin.vp +++ b/App/lib/core/Gen/ClassGenMixin.vp @@ -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。