From 3dee6fa21ca14192362f6b1fb19ea4f4bd5339e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Fri, 7 Aug 2026 17:50:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(vm):=20REST=5FOBJECT=20=E5=AF=B9=E5=8E=9F?= =?UTF-8?q?=E5=A7=8B=E7=B1=BB=E5=9E=8B=20ToObject=EF=BC=88number/boolean/s?= =?UTF-8?q?ymbol=20=E7=A9=BA=E5=AF=B9=E8=B1=A1=EF=BC=8Cstring=20=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E5=AD=97=E7=AC=A6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/vm_dispatch_misc.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/oxide_vm/src/vm_dispatch_misc.rs b/crates/oxide_vm/src/vm_dispatch_misc.rs index 84e6f34..f702efc 100644 --- a/crates/oxide_vm/src/vm_dispatch_misc.rs +++ b/crates/oxide_vm/src/vm_dispatch_misc.rs @@ -563,7 +563,28 @@ impl Vm { vm_trace!("REST_OBJECT rd={}", rd); let src = self.regs[a]; if !src.is_object() { - return self.raise_type_error("Cannot destructure property of null/undefined"); + // ToObject:null/undefined 抛;number/boolean/symbol 无自有属性 → 空对象; + // string 的索引字符(UTF-16 code unit)是可枚举自有属性。 + if src.is_null() || src.is_undefined() { + return self.raise_type_error("Cannot destructure property of null/undefined"); + } + let proto_ptr = self.session.builtin_world().object_proto.as_ptr() as *mut JsObject; + let rest_ptr = self.alloc_object(JsObject::new_empty( + oxide_kernel::shape_forge::EMPTY_SHAPE_ID, + JsValue::from_js_object(proto_ptr), + )); + if src.is_string() { + let code_units: Vec = unsafe { (*src.as_string_ptr()).data.encode_utf16().collect() }; + for (i, unit) in code_units.iter().enumerate() { + let s = char::from_u32(*unit as u32).map(|c| c.to_string()).unwrap_or_default(); + let si = self.kernel_core.perm_interner().intern(&i.to_string()).0; + let ch_val = self.new_string(&s); + let rest = unsafe { &mut *rest_ptr }; + self.set_or_create_prop_value(rest, si, ch_val); + } + } + self.regs[rd] = JsValue::from_js_object(rest_ptr); + return Ok(()); } let excluded_idx = self.bytecode[self.pc] as usize; self.pc += 1;