mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: delete 真正删除属性(shape 链重建 + 数组元素 hole 标记)
字节码 delete 原先只清值为 undefined,属性残留在 shape 链,hasOwnProperty/ keys/枚举仍可见。统一走共享 delete_own_property(与 Reflect.deleteProperty 一致): - 命名属性经 shape 链重建移除,数组重建前保存并恢复元素区 - 数组下标元素标记为 hole(PropMetaEntry.hole),length 不变, 存在性检查(resolve_property/get_own_property_slot/ordinary_get/for-in) 判 hole,重赋值自动清除标记 - 不可配置属性统一返回 false(sloppy 语义,strict 抛错留待 emit 追踪严格模式) - set_or_create_prop_value 数组下标键路由元素区,修复 delete 后重赋值误入 shape 链 test262 Object +212 PASS/-102 FAIL,Array +149 PASS/-60 FAIL,无回归。
This commit is contained in:
@@ -170,7 +170,8 @@ impl Vm {
|
||||
let obj = unsafe { &*obj_ptr };
|
||||
let prop_name_si = self.property_key_si(self.regs[b]);
|
||||
let (cached_shape_id, cached_slot, cached_depth) = ic_helper::read_ic_entry(&self.bytecode, &mut self.pc);
|
||||
if obj.has_prop_meta() { let val = self.ordinary_get_with_target(obj, prop_name_si, val, a as u8)?;
|
||||
if obj.has_prop_meta() {
|
||||
let val = self.ordinary_get_with_target(obj, prop_name_si, val, a as u8)?;
|
||||
if self.accessor_frame_target_reg.take().is_none() {
|
||||
self.regs[a] = val;
|
||||
}
|
||||
@@ -412,17 +413,13 @@ impl Vm {
|
||||
let key_val = self.immutables().get(prop_idx).copied().unwrap_or_else(JsValue::undefined);
|
||||
let prop_name_si = self.property_key_si(key_val);
|
||||
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "delete on non-object")? else {
|
||||
return Ok(true);
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
return Ok(false);
|
||||
};
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
|
||||
let configurable = obj.prop_meta_at(pos).map(|m| m.attributes.configurable()).unwrap_or(true);
|
||||
if !configurable {
|
||||
return self.raise_type_error("cannot delete non-configurable property").map(|()| false);
|
||||
}
|
||||
obj.set_prop_shape(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
// 统一走共享删除逻辑(与 Reflect.deleteProperty 一致);不可配置返回 false。
|
||||
let deleted = oxide_builtins::object::delete_own_property(self, obj, prop_name_si);
|
||||
self.regs[rd] = JsValue::bool(deleted);
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
@@ -430,18 +427,13 @@ impl Vm {
|
||||
vm_trace!("DELETE_PROP_DYNAMIC rd={}", rd);
|
||||
let prop_name_si = self.property_key_si(self.regs[b]);
|
||||
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "delete on non-object")? else {
|
||||
return Ok(true);
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
return Ok(false);
|
||||
};
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
|
||||
let configurable = obj.prop_meta_at(pos).map(|m| m.attributes.configurable()).unwrap_or(true);
|
||||
if !configurable {
|
||||
return self.raise_type_error("cannot delete non-configurable property").map(|()| false);
|
||||
}
|
||||
obj.set_prop_shape(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
// 统一走共享删除逻辑(与 Reflect.deleteProperty 一致);不可配置返回 false。
|
||||
let deleted = oxide_builtins::object::delete_own_property(self, obj, prop_name_si);
|
||||
self.regs[rd] = JsValue::bool(deleted);
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user