mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Implement the spec provision for handling repeated keys in records by updating the existing value
This commit is contained in:
parent
8547419267
commit
5755645f0d
2 changed files with 46 additions and 9 deletions
|
|
@ -4791,13 +4791,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
})
|
||||
|
||||
keyType = recordKeyType(recordType)
|
||||
if recordType.keyType.isDOMString():
|
||||
keyConversionFunction = "ConvertJSValueToString"
|
||||
elif recordType.keyType.isUSVString():
|
||||
keyConversionFunction = "ConvertJSValueToUSVString"
|
||||
else:
|
||||
assert recordType.keyType.isByteString()
|
||||
if recordType.keyType.isByteString():
|
||||
keyConversionFunction = "ConvertJSValueToByteString"
|
||||
hashKeyType = "nsCStringHashKey"
|
||||
else:
|
||||
hashKeyType = "nsStringHashKey"
|
||||
if recordType.keyType.isDOMString():
|
||||
keyConversionFunction = "ConvertJSValueToString"
|
||||
else:
|
||||
assert recordType.keyType.isUSVString()
|
||||
keyConversionFunction = "ConvertJSValueToUSVString"
|
||||
|
||||
templateBody = fill(
|
||||
"""
|
||||
|
|
@ -4819,6 +4822,12 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
JS::Rooted<JS::Value> temp(cx);
|
||||
JS::Rooted<jsid> curId(cx);
|
||||
JS::Rooted<JS::Value> idVal(cx);
|
||||
// Use a hashset to keep track of ids seen, to avoid
|
||||
// introducing nasty O(N^2) behavior scanning for them all the
|
||||
// time. Ideally we'd use a data structure with O(1) lookup
|
||||
// _and_ ordering for the MozMap, but we don't have one lying
|
||||
// around.
|
||||
nsTHashtable<${hashKeyType}> idsSeen;
|
||||
for (size_t i = 0; i < ids.length(); ++i) {
|
||||
curId = ids[i];
|
||||
|
||||
|
|
@ -4845,9 +4854,25 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
$*{exceptionCode}
|
||||
}
|
||||
|
||||
// Safe to do an infallible append here, because we did a
|
||||
// SetCapacity above to the right capacity.
|
||||
${typeName}::EntryType* entry = recordEntries.AppendElement();
|
||||
${typeName}::EntryType* entry;
|
||||
if (idsSeen.Contains(propName)) {
|
||||
// Find the existing entry.
|
||||
auto idx = recordEntries.IndexOf(propName);
|
||||
MOZ_ASSERT(idx != recordEntries.NoIndex,
|
||||
"Why is it not found?");
|
||||
// Now blow it away to make it look like it was just added
|
||||
// to the array, because it's not obvious that it's
|
||||
// safe to write to its already-initialized mValue via our
|
||||
// normal codegen conversions. For example, the value
|
||||
// could be a union and this would change its type, but
|
||||
// codegen assumes we won't do that.
|
||||
entry = recordEntries.ReconstructElementAt(idx);
|
||||
} else {
|
||||
// Safe to do an infallible append here, because we did a
|
||||
// SetCapacity above to the right capacity.
|
||||
entry = recordEntries.AppendElement();
|
||||
idsSeen.PutEntry(propName);
|
||||
}
|
||||
entry->mKey = propName;
|
||||
${valueType}& slot = entry->mValue;
|
||||
$*{valueConversion}
|
||||
|
|
@ -4855,6 +4880,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
""",
|
||||
exceptionCode=exceptionCode,
|
||||
recordRef=recordRef,
|
||||
hashKeyType=hashKeyType,
|
||||
keyType=keyType,
|
||||
keyConversionFunction=keyConversionFunction,
|
||||
typeName=typeName,
|
||||
|
|
|
|||
|
|
@ -77,4 +77,15 @@ private:
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
template<typename K, typename V>
|
||||
class nsDefaultComparator<mozilla::dom::binding_detail::RecordEntry<K, V>, K>
|
||||
{
|
||||
public:
|
||||
bool Equals(const mozilla::dom::binding_detail::RecordEntry<K, V>& aEntry,
|
||||
const K& aKey) const
|
||||
{
|
||||
return aEntry.mKey == aKey;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // mozilla_dom_Record_h
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue