Actually change the key type of a record, and its corresponding conversion behavior, depending on what the IDL says

This commit is contained in:
JustOff 2019-03-13 20:17:36 +02:00 committed by Roy Tam
commit 8547419267
3 changed files with 41 additions and 11 deletions

View file

@ -4372,11 +4372,15 @@ def handleDefaultStringValue(defaultValue, method):
}
def recordKeyDeclType(recordType):
def recordKeyType(recordType):
assert recordType.keyType.isString()
if recordType.keyType.isByteString():
return CGGeneric("nsCString")
return CGGeneric("nsString")
return "nsCString"
return "nsString"
def recordKeyDeclType(recordType):
return CGGeneric(recordKeyType(recordType))
# If this function is modified, modify CGNativeMember.getArg and
@ -4786,6 +4790,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"passedToJSImpl": "${passedToJSImpl}"
})
keyType = recordKeyType(recordType)
if recordType.keyType.isDOMString():
keyConversionFunction = "ConvertJSValueToString"
elif recordType.keyType.isUSVString():
keyConversionFunction = "ConvertJSValueToUSVString"
else:
assert recordType.keyType.isByteString()
keyConversionFunction = "ConvertJSValueToByteString"
templateBody = fill(
"""
auto& recordEntries = ${recordRef}.Entries();
@ -4805,6 +4818,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
@ -4821,12 +4835,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
continue;
}
binding_detail::FakeString propName;
bool isSymbol;
if (!ConvertIdToString(cx, curId, propName, isSymbol)) {
idVal = js::IdToValue(curId);
${keyType} propName;
if (!${keyConversionFunction}(cx, idVal, propName)) {
$*{exceptionCode}
}
MOZ_ASSERT(!isSymbol, "We said, no symbols!");
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
$*{exceptionCode}
@ -4842,6 +4855,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
""",
exceptionCode=exceptionCode,
recordRef=recordRef,
keyType=keyType,
keyConversionFunction=keyConversionFunction,
typeName=typeName,
valueType=valueInfo.declType.define(),
valueConversion=valueConversion)
@ -6491,6 +6506,18 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
'typedArraysAreStructs': typedArraysAreStructs
})
recordWrapLevel -= 1
if type.keyType.isByteString():
# There is no length-taking JS_DefineProperty. So to keep
# things sane with embedded nulls, we want to byte-inflate
# to an nsAString. The only byte-inflation function we
# have around is AppendASCIItoUTF16, which luckily doesn't
# assert anything about the input being ASCII.
expandedKeyDecl = "NS_ConvertASCIItoUTF16 expandedKey(entry.mKey);\n"
keyName = "expandedKey"
else:
expandedKeyDecl = ""
keyName = "entry.mKey"
code = fill(
"""
@ -6508,9 +6535,10 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
do {
$*{innerTemplate}
} while (0);
$*{expandedKeyDecl}
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
${keyName}.BeginReading(),
${keyName}.Length(), tmp,
JSPROP_ENUMERATE)) {
$*{exceptionCode}
}
@ -6522,6 +6550,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
exceptionCode=exceptionCode,
valueName=valueName,
innerTemplate=innerTemplate,
expandedKeyDecl=expandedKeyDecl,
keyName=keyName,
set=setObject("*returnObj"))
return (code, False)

View file

@ -47,7 +47,7 @@ template<typename KeyType, typename ValueType>
class Record
{
public:
typedef typename binding_detail::RecordEntry<nsString, ValueType> EntryType;
typedef typename binding_detail::RecordEntry<KeyType, ValueType> EntryType;
typedef Record<KeyType, ValueType> SelfType;
Record()

View file

@ -317,7 +317,7 @@ void
InternalHeaders::Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv)
{
for (auto& entry : aInit.Entries()) {
Append(NS_ConvertUTF16toUTF8(entry.mKey), entry.mValue, aRv);
Append(entry.mKey, entry.mValue, aRv);
if (aRv.Failed()) {
return;
}