fix: defineProperty 内部错误不触发 unwind + enumerable/configurable 缺省回填

This commit is contained in:
爱特每羊队
2026-08-08 01:18:21 +08:00
parent d36949aa00
commit 3b13b111c4
4 changed files with 51 additions and 49 deletions
+8 -2
View File
@@ -157,12 +157,18 @@ impl Vm {
// length:实参个数,可写、不可枚举、可配置。
let length_si = self.kernel_core.perm_interner().intern("length").0;
self.define_data_property(obj, length_si, JsValue::int(count as i32), PropAttributes::new(true, false, true))?;
if let Err(msg) =
self.define_data_property(obj, length_si, JsValue::int(count as i32), PropAttributes::new(true, false, true))
{
return self.raise_error_kind("TypeError", &msg);
}
// callee:当前执行函数,可写、不可枚举、可配置(严格模式应抛 TypeError,未支持)。
let callee_si = self.kernel_core.perm_interner().intern("callee").0;
let callee = self.current_callee().unwrap_or(JsValue::undefined());
self.define_data_property(obj, callee_si, callee, PropAttributes::new(true, false, true))?;
if let Err(msg) = self.define_data_property(obj, callee_si, callee, PropAttributes::new(true, false, true)) {
return self.raise_error_kind("TypeError", &msg);
}
self.regs[rd] = JsValue::from_js_object(obj_ptr);
Ok(())
+4 -1
View File
@@ -118,7 +118,10 @@ impl Vm {
} else {
setter
};
self.define_accessor_property(obj, prop_name_si, get, set, PropAttributes::DEFAULT_DATA)
match self.define_accessor_property(obj, prop_name_si, get, set, PropAttributes::DEFAULT_DATA) {
Ok(()) => Ok(()),
Err(msg) => self.raise_error_kind("TypeError", &msg),
}
}
pub(crate) fn dispatch_return(&mut self, rd: usize) -> Result<Option<JsValue>, String> {
+11 -11
View File
@@ -346,18 +346,18 @@ impl Vm {
if let Some(current) = obj.prop_meta_at(pos) {
if !current.attributes.configurable() {
if current.is_accessor {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if current.attributes.enumerable() != attributes.enumerable() {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if !current.attributes.writable()
&& (attributes.writable() || !coercion::same_value(obj.get_prop_at(pos), val))
{
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if current.attributes.configurable() != attributes.configurable() {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
}
}
@@ -399,7 +399,7 @@ impl Vm {
|| current.get != get
|| current.set != set)
{
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
}
obj.set_prop_storage(pos, JsValue::undefined());
@@ -422,28 +422,28 @@ impl Vm {
) -> Result<(), String> {
let pos = index as usize;
if pos > oxide_types::object::MAX_DENSE_PROPS {
return self.raise_type_error("array index out of dense range");
return Err("array index out of dense range".to_string());
}
let pos = pos as u32;
if let Some(current) = obj.prop_meta_at(pos) {
if !current.attributes.configurable() {
if current.is_accessor != is_accessor {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if current.attributes.enumerable() != attributes.enumerable() {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if current.attributes.configurable() != attributes.configurable() {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
if is_accessor {
if current.get != get || current.set != set {
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
} else if !current.attributes.writable()
&& (attributes.writable() || !coercion::same_value(obj.get_prop_at(pos), val))
{
return self.raise_type_error("cannot redefine non-configurable property");
return Err("cannot redefine non-configurable property".to_string());
}
}
}