From ace6bea2c4ef16cc733b0187ddb37cccce629d10 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 14 Aug 2026 06:14:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=BF=E9=97=AE=E5=99=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=90=88=E5=B9=B6=E5=AE=9A=E4=B9=89=E6=97=B6=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E6=9C=AA=E6=8F=90=E4=BE=9B=E5=8D=8A=E8=BE=B9=EF=BC=8C?= =?UTF-8?q?=E9=98=B2=20get/set=20=E4=BA=92=E7=9B=B8=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/vm_dispatch_ctrl.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/oxide_vm/src/vm_dispatch_ctrl.rs b/crates/oxide_vm/src/vm_dispatch_ctrl.rs index 24afe2f0..25a5078e 100644 --- a/crates/oxide_vm/src/vm_dispatch_ctrl.rs +++ b/crates/oxide_vm/src/vm_dispatch_ctrl.rs @@ -196,7 +196,9 @@ impl Vm { } /// define 数据属性并指定描述符:ext 字为 attrs(bit0=writable, bit1=enumerable, bit2=configurable,与 PropAttributes 位一致)。 - pub(crate) fn dispatch_define_prop_attrs(&mut self, rd: usize, a: usize, b: usize, attrs: u8) -> Result<(), String> { + pub(crate) fn dispatch_define_prop_attrs( + &mut self, rd: usize, a: usize, b: usize, attrs: u8, + ) -> Result<(), String> { vm_trace!("DEFINE_PROP_ATTRS rd={} value={} key={} attrs={:#04b}", rd, a, b, attrs); let obj_val = self.regs[rd]; if !obj_val.is_object() { @@ -233,7 +235,23 @@ impl Vm { let getter = self.regs[a]; let setter = self.regs[b]; let obj = unsafe { &mut *obj_val.as_js_object_ptr() }; - match self.define_accessor_property(obj, prop_name_si, getter, setter, PropAttributes(attrs)) { + // 类内 get x 与 set x 分两条指令定义同一属性:第二次到达时已存在访问器, + // 未提供的半边(undefined)须继承既有值,否则后定义覆盖前定义的 get/set。 + let existing = self + .get_own_property_slot(obj, prop_name_si) + .and_then(|pos| obj.prop_meta_at(pos)) + .filter(|meta| meta.is_accessor); + let get = if getter.is_undefined() { + existing.map(|meta| meta.get).unwrap_or(JsValue::undefined()) + } else { + getter + }; + let set = if setter.is_undefined() { + existing.map(|meta| meta.set).unwrap_or(JsValue::undefined()) + } else { + setter + }; + match self.define_accessor_property(obj, prop_name_si, get, set, PropAttributes(attrs)) { Ok(()) => Ok(()), Err(msg) => self.raise_error_kind("TypeError", &msg), }