diff --git a/boa/src/object/gcobject.rs b/boa/src/object/gcobject.rs index a138d7e098d..6df2fa994d4 100644 --- a/boa/src/object/gcobject.rs +++ b/boa/src/object/gcobject.rs @@ -534,12 +534,14 @@ impl GcObject { } Ok(AccessorDescriptor::new(get, set, attribute).into()) + } else if let Some(v) = value { + Ok(DataDescriptor::new(v, attribute).into()) } else { - Ok(DataDescriptor::new(value.unwrap_or_else(Value::undefined), attribute).into()) + Ok(DataDescriptor::new_without_value(attribute).into()) } } - /// Reeturn `true` if it is a native object and the native type is `T`. + /// Return `true` if it is a native object and the native type is `T`. /// /// # Panics /// diff --git a/boa/src/object/internal_methods.rs b/boa/src/object/internal_methods.rs index 3a6a1891b67..b71249bc09d 100644 --- a/boa/src/object/internal_methods.rs +++ b/boa/src/object/internal_methods.rs @@ -196,6 +196,7 @@ impl GcObject { } self.insert(key, desc); + return true; }; @@ -234,8 +235,8 @@ impl GcObject { return false; } - let current = DataDescriptor::new(value, current.attributes()); - self.insert(key, current); + self.insert(key, DataDescriptor::new(value, current.attributes())); + return true; } (PropertyDescriptor::Data(current), PropertyDescriptor::Data(desc)) => { @@ -268,7 +269,22 @@ impl GcObject { } } - self.insert(key, desc); + match (¤t, &desc) { + (PropertyDescriptor::Data(current_data), PropertyDescriptor::Data(desc_data)) => { + if desc_data.has_value() { + self.insert(key, desc); + } else { + self.insert( + key, + DataDescriptor::new(current_data.value.clone(), desc_data.attributes()), + ); + } + } + _ => { + self.insert(key, desc); + } + } + true } diff --git a/boa/src/property/mod.rs b/boa/src/property/mod.rs index b5411c6645d..d7dc93ec42f 100644 --- a/boa/src/property/mod.rs +++ b/boa/src/property/mod.rs @@ -36,6 +36,7 @@ pub use attribute::Attribute; pub struct DataDescriptor { pub(crate) value: Value, attributes: Attribute, + has_value: bool, } impl DataDescriptor { @@ -48,6 +49,17 @@ impl DataDescriptor { Self { value: value.into(), attributes, + has_value: true, + } + } + + /// Create a new `DataDescriptor` without a value. + #[inline] + pub fn new_without_value(attributes: Attribute) -> Self { + Self { + value: Value::undefined(), + attributes, + has_value: false, } } @@ -57,6 +69,12 @@ impl DataDescriptor { self.value.clone() } + /// Check whether the data descriptor has a value. + #[inline] + pub fn has_value(&self) -> bool { + self.has_value + } + /// Return the attributes of the descriptor. #[inline] pub fn attributes(&self) -> Attribute {