diff options
author | 2023-05-20 22:01:26 -0700 | |
---|---|---|
committer | 2023-05-20 22:02:09 -0700 | |
commit | ee40d9c3b49465563d53c3e1ff8d909aa7c7e4b3 (patch) | |
tree | 35f702b9a096e9ad58a22480ef5edacc144aafb1 /src/bun.js/bindings/bindings.cpp | |
parent | cd28c2cd2b722e1e1b7195d6a8f9e458bdaa2bdf (diff) | |
download | bun-ee40d9c3b49465563d53c3e1ff8d909aa7c7e4b3.tar.gz bun-ee40d9c3b49465563d53c3e1ff8d909aa7c7e4b3.tar.zst bun-ee40d9c3b49465563d53c3e1ff8d909aa7c7e4b3.zip |
[bun:test] Make forEachPropertyOrdered behave closer to forEachProperty
When diffing, we were missing some properties due to not calling getters and other types of properties
This led to situations where Bun.deepEquals would report false and then display no difference
This aligns the behavior closer to forEachProperty
cc @dylan-conway please let me know if this is going to break anything
Diffstat (limited to 'src/bun.js/bindings/bindings.cpp')
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index e76f75205..a72fba992 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -3882,17 +3882,54 @@ void JSC__JSValue__forEachPropertyOrdered(JSC__JSValue JSValue0, JSC__JSGlobalOb const WTF::StringImpl* bImpl = b.isSymbol() && !b.isPrivateName() ? b.impl() : b.string().impl(); return codePointCompare(aImpl, bImpl) < 0; }); + auto clientData = WebCore::clientData(vm); for (auto property : vector) { - const WTF::StringImpl* name = property.isSymbol() && !property.isPrivateName() ? property.impl() : property.string().impl(); - ZigString key = toZigString(name); + if (UNLIKELY(property.isEmpty() || property.isNull())) + continue; + + // ignore constructor + if (property == vm.propertyNames->constructor || clientData->builtinNames().bunNativePtrPrivateName() == property) + continue; + + JSC::PropertySlot slot(object, PropertySlot::InternalMethodType::Get); + if (!object->getPropertySlot(globalObject, property, slot)) + continue; + + if ((slot.attributes() & PropertyAttribute::DontEnum) != 0) { + if (property == vm.propertyNames->underscoreProto + || property == vm.propertyNames->toStringTagSymbol) + continue; + } + + JSC::JSValue propertyValue = jsUndefined(); auto scope = DECLARE_CATCH_SCOPE(vm); - JSValue propertyValue = object->get(globalObject, property); - if (scope.exception()) { + if ((slot.attributes() & PropertyAttribute::DontEnum) != 0) { + if ((slot.attributes() & PropertyAttribute::Accessor) != 0) { + propertyValue = slot.getPureResult(); + } else if (slot.attributes() & PropertyAttribute::BuiltinOrFunction) { + propertyValue = slot.getValue(globalObject, property); + } else if (slot.isCustom()) { + propertyValue = slot.getValue(globalObject, property); + } else if (slot.isValue()) { + propertyValue = slot.getValue(globalObject, property); + } else if (object->getOwnPropertySlot(object, globalObject, property, slot)) { + propertyValue = slot.getValue(globalObject, property); + } + } else if ((slot.attributes() & PropertyAttribute::Accessor) != 0) { + propertyValue = slot.getPureResult(); + } else { + propertyValue = slot.getValue(globalObject, property); + } + + if (UNLIKELY(scope.exception())) { scope.clearException(); propertyValue = jsUndefined(); } + const WTF::StringImpl* name = property.isSymbol() && !property.isPrivateName() ? property.impl() : property.string().impl(); + ZigString key = toZigString(name); + JSC::EnsureStillAliveScope ensureStillAliveScope(propertyValue); iter(globalObject, arg2, &key, JSC::JSValue::encode(propertyValue), property.isSymbol()); } |