@@ -1696,6 +1696,10 @@ using namespace Js;
16961696 template <bool unscopables>
16971697 BOOL JavascriptOperators::GetProperty_Internal(Var instance, RecyclableObject* propertyObject, const bool isRoot, PropertyId propertyId, Var* value, ScriptContext* requestContext, PropertyValueInfo* info)
16981698 {
1699+ #if ENABLE_FIXED_FIELDS && DBG
1700+ DynamicTypeHandler *dynamicTypeHandler = nullptr;
1701+ #endif
1702+
16991703 if (TaggedNumber::Is(instance))
17001704 {
17011705 PropertyValueInfo::ClearCacheInfo(info);
@@ -1718,6 +1722,9 @@ using namespace Js;
17181722 }
17191723 else
17201724 {
1725+ #if ENABLE_FIXED_FIELDS && DBG
1726+ dynamicTypeHandler = DynamicObject::Is(object) ? DynamicObject::FromVar(object)->GetTypeHandler() : nullptr;
1727+ #endif
17211728 PropertyQueryFlags result = object->GetPropertyQuery(instance, propertyId, value, info, requestContext);
17221729 if (result != PropertyQueryFlags::Property_NotFound)
17231730 {
@@ -1737,10 +1744,10 @@ using namespace Js;
17371744 if (foundProperty)
17381745 {
17391746#if ENABLE_FIXED_FIELDS && DBG
1740- if (DynamicObject::Is(object))
1747+ // Note: It's valid to check this for the original type handler but not for a new type handler that may have been installed
1748+ // by a getter that, for instance, deleted and re-added the property.
1749+ if (dynamicTypeHandler)
17411750 {
1742- DynamicObject* dynamicObject = (DynamicObject*)object;
1743- DynamicTypeHandler* dynamicTypeHandler = dynamicObject->GetDynamicType()->GetTypeHandler();
17441751 Var property;
17451752 if (dynamicTypeHandler->CheckFixedProperty(requestContext->GetPropertyName(propertyId), &property, requestContext))
17461753 {
@@ -8825,23 +8832,18 @@ using namespace Js;
88258832 // ES5 8.12.9.9.c: Convert the property named P of object O from an accessor property to a data property.
88268833 // Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes
88278834 // and set the rest of the property's attributes to their default values.
8828- // Note: avoid using SetProperty/SetPropertyWithAttributes here because they has undesired side-effects:
8829- // it calls previous setter and in some cases of attribute values throws.
8830- // To walk around, call DeleteProperty and then AddProperty.
88318835 PropertyAttributes preserveFromObject = currentDescriptor->GetAttributes() & (PropertyConfigurable | PropertyEnumerable);
88328836
88338837 tempDescriptor.SetAttributes(preserveFromObject, PropertyConfigurable | PropertyEnumerable);
88348838 tempDescriptor.MergeFrom(descriptor); // Update only fields specified in 'descriptor'.
88358839 Var descriptorValue = descriptor.ValueSpecified() ? descriptor.GetValue() : defaultDataValue;
88368840
8837- // Note: HostDispath'es implementation of DeleteProperty currently throws E_NOTIMPL.
8838- obj->DeleteProperty(propId, PropertyOperation_None);
8839- BOOL tempResult = obj->SetPropertyWithAttributes(propId, descriptorValue, tempDescriptor.GetAttributes(), NULL, PropertyOperation_Force);
8840- Assert(tempResult);
8841+ BOOL result = DynamicObject::FromVar(obj)->ConvertAccessorToData(propId, descriptorValue, tempDescriptor.GetAttributes());
88418842
88428843 // At this time we already set value and attributes to desired values,
88438844 // thus we can skip step ES5 8.12.9.12 and simply return true.
8844- return TRUE;
8845+ Assert(result);
8846+ return result;
88458847 }
88468848 }
88478849 }
0 commit comments