@@ -1699,6 +1699,10 @@ using namespace Js;
1699
1699
template <bool unscopables>
1700
1700
BOOL JavascriptOperators::GetProperty_Internal(Var instance, RecyclableObject* propertyObject, const bool isRoot, PropertyId propertyId, Var* value, ScriptContext* requestContext, PropertyValueInfo* info)
1701
1701
{
1702
+ #if ENABLE_FIXED_FIELDS && DBG
1703
+ DynamicTypeHandler *dynamicTypeHandler = nullptr;
1704
+ #endif
1705
+
1702
1706
if (TaggedNumber::Is(instance))
1703
1707
{
1704
1708
PropertyValueInfo::ClearCacheInfo(info);
@@ -1721,6 +1725,9 @@ using namespace Js;
1721
1725
}
1722
1726
else
1723
1727
{
1728
+ #if ENABLE_FIXED_FIELDS && DBG
1729
+ dynamicTypeHandler = VarIs<DynamicObject>(object) ? VarTo<DynamicObject>(object)->GetTypeHandler() : nullptr;
1730
+ #endif
1724
1731
PropertyQueryFlags result = object->GetPropertyQuery(instance, propertyId, value, info, requestContext);
1725
1732
if (result != PropertyQueryFlags::Property_NotFound)
1726
1733
{
@@ -1740,10 +1747,10 @@ using namespace Js;
1740
1747
if (foundProperty)
1741
1748
{
1742
1749
#if ENABLE_FIXED_FIELDS && DBG
1743
- if (DynamicObject::IsBaseDynamicObject(object))
1750
+ // Note: It's valid to check this for the original type handler but not for a new type handler that may have been installed
1751
+ // by a getter that, for instance, deleted and re-added the property.
1752
+ if (dynamicTypeHandler)
1744
1753
{
1745
- DynamicObject* dynamicObject = (DynamicObject*)object;
1746
- DynamicTypeHandler* dynamicTypeHandler = dynamicObject->GetDynamicType()->GetTypeHandler();
1747
1754
Var property;
1748
1755
if (dynamicTypeHandler->CheckFixedProperty(requestContext->GetPropertyName(propertyId), &property, requestContext))
1749
1756
{
@@ -8846,23 +8853,18 @@ using namespace Js;
8846
8853
// ES5 8.12.9.9.c: Convert the property named P of object O from an accessor property to a data property.
8847
8854
// Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes
8848
8855
// and set the rest of the property's attributes to their default values.
8849
- // Note: avoid using SetProperty/SetPropertyWithAttributes here because they has undesired side-effects:
8850
- // it calls previous setter and in some cases of attribute values throws.
8851
- // To walk around, call DeleteProperty and then AddProperty.
8852
8856
PropertyAttributes preserveFromObject = currentDescriptor->GetAttributes() & (PropertyConfigurable | PropertyEnumerable);
8853
8857
8854
8858
tempDescriptor.SetAttributes(preserveFromObject, PropertyConfigurable | PropertyEnumerable);
8855
8859
tempDescriptor.MergeFrom(descriptor); // Update only fields specified in 'descriptor'.
8856
8860
Var descriptorValue = descriptor.ValueSpecified() ? descriptor.GetValue() : defaultDataValue;
8857
8861
8858
- // Note: HostDispath'es implementation of DeleteProperty currently throws E_NOTIMPL.
8859
- obj->DeleteProperty(propId, PropertyOperation_None);
8860
- BOOL tempResult = obj->SetPropertyWithAttributes(propId, descriptorValue, tempDescriptor.GetAttributes(), NULL, PropertyOperation_Force);
8861
- Assert(tempResult);
8862
+ BOOL result = VarTo<DynamicObject>(obj)->ConvertAccessorToData(propId, descriptorValue, tempDescriptor.GetAttributes());
8862
8863
8863
8864
// At this time we already set value and attributes to desired values,
8864
8865
// thus we can skip step ES5 8.12.9.12 and simply return true.
8865
- return TRUE;
8866
+ Assert(result);
8867
+ return result;
8866
8868
}
8867
8869
}
8868
8870
}
0 commit comments