mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 23:27:30 +09:00
Rename the MozMap C++ type to "record" and give it a template parameter for the key type
This commit is contained in:
parent
d9eeac26ef
commit
6196fdda47
7 changed files with 145 additions and 126 deletions
|
|
@ -49,7 +49,7 @@ namespace mozilla {
|
||||||
enum UseCounter : int16_t;
|
enum UseCounter : int16_t;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
template<typename DataType> class MozMap;
|
template<typename KeyType, typename ValueType> class Record;
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
UnwrapArgImpl(JS::Handle<JSObject*> src, const nsIID& iid, void** ppArg);
|
UnwrapArgImpl(JS::Handle<JSObject*> src, const nsIID& iid, void** ppArg);
|
||||||
|
|
@ -2293,25 +2293,26 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename K, typename V>
|
||||||
void TraceMozMap(JSTracer* trc, MozMap<T>& map)
|
void TraceRecord(JSTracer* trc, Record<K, V>& record)
|
||||||
{
|
{
|
||||||
for (auto& entry : map.Entries()) {
|
for (auto& entry : record.Entries()) {
|
||||||
// Act like it's a one-element sequence to leverage all that infrastructure.
|
// Act like it's a one-element sequence to leverage all that infrastructure.
|
||||||
SequenceTracer<T>::TraceSequence(trc, &entry.mValue, &entry.mValue + 1);
|
SequenceTracer<V>::TraceSequence(trc, &entry.mValue, &entry.mValue + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sequence<MozMap>
|
// sequence<record>
|
||||||
template<typename T>
|
template<typename K, typename V>
|
||||||
class SequenceTracer<MozMap<T>, false, false, false>
|
class SequenceTracer<Record<K, V>, false, false, false>
|
||||||
{
|
{
|
||||||
explicit SequenceTracer() = delete; // Should never be instantiated
|
explicit SequenceTracer() = delete; // Should never be instantiated
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void TraceSequence(JSTracer* trc, MozMap<T>* seqp, MozMap<T>* end) {
|
static void TraceSequence(JSTracer* trc, Record<K, V>* seqp,
|
||||||
|
Record<K, V>* end) {
|
||||||
for (; seqp != end; ++seqp) {
|
for (; seqp != end; ++seqp) {
|
||||||
TraceMozMap(trc, *seqp);
|
TraceRecord(trc, *seqp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2389,51 +2390,51 @@ public:
|
||||||
SequenceType mSequenceType;
|
SequenceType mSequenceType;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rooter class for MozMap; this is what we mostly use in the codegen.
|
// Rooter class for Record; this is what we mostly use in the codegen.
|
||||||
template<typename T>
|
template<typename K, typename V>
|
||||||
class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
|
class MOZ_RAII RecordRooter final : private JS::CustomAutoRooter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
|
RecordRooter(JSContext *aCx, Record<K, V>* aRecord
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
||||||
mMozMap(aMozMap),
|
mRecord(aRecord),
|
||||||
mMozMapType(eMozMap)
|
mRecordType(eRecord)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MozMapRooter(JSContext *aCx, Nullable<MozMap<T>>* aMozMap
|
RecordRooter(JSContext *aCx, Nullable<Record<K, V>>* aRecord
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
||||||
mNullableMozMap(aMozMap),
|
mNullableRecord(aRecord),
|
||||||
mMozMapType(eNullableMozMap)
|
mRecordType(eNullableRecord)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum MozMapType {
|
enum RecordType {
|
||||||
eMozMap,
|
eRecord,
|
||||||
eNullableMozMap
|
eNullableRecord
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void trace(JSTracer *trc) override
|
virtual void trace(JSTracer *trc) override
|
||||||
{
|
{
|
||||||
if (mMozMapType == eMozMap) {
|
if (mRecordType == eRecord) {
|
||||||
TraceMozMap(trc, *mMozMap);
|
TraceRecord(trc, *mRecord);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(mMozMapType == eNullableMozMap);
|
MOZ_ASSERT(mRecordType == eNullableRecord);
|
||||||
if (!mNullableMozMap->IsNull()) {
|
if (!mNullableRecord->IsNull()) {
|
||||||
TraceMozMap(trc, mNullableMozMap->Value());
|
TraceRecord(trc, mNullableRecord->Value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
MozMap<T>* mMozMap;
|
Record<K, V>* mRecord;
|
||||||
Nullable<MozMap<T>>* mNullableMozMap;
|
Nullable<Record<K, V>>* mNullableRecord;
|
||||||
};
|
};
|
||||||
|
|
||||||
MozMapType mMozMapType;
|
RecordType mRecordType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -996,6 +996,8 @@ class CGElseChain(CGThing):
|
||||||
|
|
||||||
class CGTemplatedType(CGWrapper):
|
class CGTemplatedType(CGWrapper):
|
||||||
def __init__(self, templateName, child, isConst=False, isReference=False):
|
def __init__(self, templateName, child, isConst=False, isReference=False):
|
||||||
|
if isinstance(child, list):
|
||||||
|
child = CGList(child, ", ")
|
||||||
const = "const " if isConst else ""
|
const = "const " if isConst else ""
|
||||||
pre = "%s%s<" % (const, templateName)
|
pre = "%s%s<" % (const, templateName)
|
||||||
ref = "&" if isReference else ""
|
ref = "&" if isReference else ""
|
||||||
|
|
@ -1173,10 +1175,10 @@ class CGHeaders(CGWrapper):
|
||||||
bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
|
bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
|
||||||
elif unrolled.isRecord():
|
elif unrolled.isRecord():
|
||||||
if dictionary or jsImplementedDescriptors:
|
if dictionary or jsImplementedDescriptors:
|
||||||
declareIncludes.add("mozilla/dom/MozMap.h")
|
declareIncludes.add("mozilla/dom/Record.h")
|
||||||
else:
|
else:
|
||||||
bindingHeaders.add("mozilla/dom/MozMap.h")
|
bindingHeaders.add("mozilla/dom/Record.h")
|
||||||
# Also add headers for the type the MozMap is
|
# Also add headers for the type the record is
|
||||||
# parametrized over, if needed.
|
# parametrized over, if needed.
|
||||||
addHeadersForType((t.inner, dictionary))
|
addHeadersForType((t.inner, dictionary))
|
||||||
|
|
||||||
|
|
@ -1389,7 +1391,7 @@ def UnionTypes(unionTypes, config):
|
||||||
# code.
|
# code.
|
||||||
headers.add(CGHeaders.getDeclarationFilename(f.callback))
|
headers.add(CGHeaders.getDeclarationFilename(f.callback))
|
||||||
elif f.isRecord():
|
elif f.isRecord():
|
||||||
headers.add("mozilla/dom/MozMap.h")
|
headers.add("mozilla/dom/Record.h")
|
||||||
# And add headers for the type we're parametrized over
|
# And add headers for the type we're parametrized over
|
||||||
addHeadersForType(f.inner)
|
addHeadersForType(f.inner)
|
||||||
|
|
||||||
|
|
@ -1449,8 +1451,8 @@ def UnionConversions(unionTypes, config):
|
||||||
elif f.isPrimitive():
|
elif f.isPrimitive():
|
||||||
headers.add("mozilla/dom/PrimitiveConversions.h")
|
headers.add("mozilla/dom/PrimitiveConversions.h")
|
||||||
elif f.isRecord():
|
elif f.isRecord():
|
||||||
headers.add("mozilla/dom/MozMap.h")
|
headers.add("mozilla/dom/Record.h")
|
||||||
# And the internal type of the MozMap
|
# And the internal type of the record
|
||||||
addHeadersForType(f.inner)
|
addHeadersForType(f.inner)
|
||||||
|
|
||||||
# We plan to include UnionTypes.h no matter what, so it's
|
# We plan to include UnionTypes.h no matter what, so it's
|
||||||
|
|
@ -4370,6 +4372,13 @@ def handleDefaultStringValue(defaultValue, method):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def recordKeyDeclType(recordType):
|
||||||
|
assert recordType.keyType.isString()
|
||||||
|
if recordType.keyType.isByteString():
|
||||||
|
return CGGeneric("nsCString")
|
||||||
|
return CGGeneric("nsString")
|
||||||
|
|
||||||
|
|
||||||
# If this function is modified, modify CGNativeMember.getArg and
|
# If this function is modified, modify CGNativeMember.getArg and
|
||||||
# CGNativeMember.getRetvalInfo accordingly. The latter cares about the decltype
|
# CGNativeMember.getRetvalInfo accordingly. The latter cares about the decltype
|
||||||
# and holdertype we end up using, because it needs to be able to return the code
|
# and holdertype we end up using, because it needs to be able to return the code
|
||||||
|
|
@ -4564,7 +4573,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
declArgs = "cx"
|
declArgs = "cx"
|
||||||
else:
|
else:
|
||||||
assert (isMember in
|
assert (isMember in
|
||||||
("Sequence", "Variadic", "Dictionary", "OwningUnion", "MozMap"))
|
("Sequence", "Variadic", "Dictionary", "OwningUnion", "Record"))
|
||||||
# We'll get traced by the sequence or dictionary or union tracer
|
# We'll get traced by the sequence or dictionary or union tracer
|
||||||
declType = CGGeneric("JSObject*")
|
declType = CGGeneric("JSObject*")
|
||||||
declArgs = None
|
declArgs = None
|
||||||
|
|
@ -4733,36 +4742,38 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.isRecord():
|
if type.isRecord():
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
if failureCode is None:
|
if failureCode is None:
|
||||||
notMozMap = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
|
notRecord = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
|
||||||
"%s" % (firstCap(sourceDescription), exceptionCode))
|
"%s" % (firstCap(sourceDescription), exceptionCode))
|
||||||
else:
|
else:
|
||||||
notMozMap = failureCode
|
notRecord = failureCode
|
||||||
|
|
||||||
nullable = type.nullable()
|
nullable = type.nullable()
|
||||||
# Be very careful not to change "type": we need it later
|
# Be very careful not to change "type": we need it later
|
||||||
if nullable:
|
if nullable:
|
||||||
valueType = type.inner.inner
|
recordType = type.inner
|
||||||
else:
|
else:
|
||||||
valueType = type.inner
|
recordType = type
|
||||||
|
valueType = recordType.inner
|
||||||
|
|
||||||
valueInfo = getJSToNativeConversionInfo(
|
valueInfo = getJSToNativeConversionInfo(
|
||||||
valueType, descriptorProvider, isMember="MozMap",
|
valueType, descriptorProvider, isMember="Record",
|
||||||
exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
|
exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
|
||||||
isCallbackReturnValue=isCallbackReturnValue,
|
isCallbackReturnValue=isCallbackReturnValue,
|
||||||
sourceDescription="value in %s" % sourceDescription,
|
sourceDescription="value in %s" % sourceDescription,
|
||||||
nestingLevel=incrementNestingLevel())
|
nestingLevel=incrementNestingLevel())
|
||||||
if valueInfo.dealWithOptional:
|
if valueInfo.dealWithOptional:
|
||||||
raise TypeError("Shouldn't have optional things in MozMap")
|
raise TypeError("Shouldn't have optional things in record")
|
||||||
if valueInfo.holderType is not None:
|
if valueInfo.holderType is not None:
|
||||||
raise TypeError("Shouldn't need holders for MozMap")
|
raise TypeError("Shouldn't need holders for record")
|
||||||
|
|
||||||
typeName = CGTemplatedType("MozMap", valueInfo.declType)
|
declType = CGTemplatedType("Record", [recordKeyDeclType(recordType),
|
||||||
mozMapType = typeName.define()
|
valueInfo.declType])
|
||||||
|
typeName = declType.define()
|
||||||
if nullable:
|
if nullable:
|
||||||
typeName = CGTemplatedType("Nullable", typeName)
|
declType = CGTemplatedType("Nullable", declType)
|
||||||
mozMapRef = "${declName}.SetValue()"
|
recordRef = "${declName}.SetValue()"
|
||||||
else:
|
else:
|
||||||
mozMapRef = "${declName}"
|
recordRef = "${declName}"
|
||||||
|
|
||||||
valueConversion = string.Template(valueInfo.template).substitute({
|
valueConversion = string.Template(valueInfo.template).substitute({
|
||||||
"val": "temp",
|
"val": "temp",
|
||||||
|
|
@ -4777,17 +4788,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
|
|
||||||
templateBody = fill(
|
templateBody = fill(
|
||||||
"""
|
"""
|
||||||
auto& mozMapEntries = ${mozMapRef}.Entries();
|
auto& recordEntries = ${recordRef}.Entries();
|
||||||
|
|
||||||
JS::Rooted<JSObject*> mozMapObj(cx, &$${val}.toObject());
|
JS::Rooted<JSObject*> recordObj(cx, &$${val}.toObject());
|
||||||
JS::AutoIdVector ids(cx);
|
JS::AutoIdVector ids(cx);
|
||||||
// Keep skipping symbols until
|
// Keep skipping symbols until
|
||||||
// https://github.com/heycam/webidl/issues/294 is sorted out.
|
// https://github.com/heycam/webidl/issues/294 is sorted out.
|
||||||
if (!js::GetPropertyKeys(cx, mozMapObj,
|
if (!js::GetPropertyKeys(cx, recordObj,
|
||||||
JSITER_OWNONLY | JSITER_HIDDEN, &ids)) {
|
JSITER_OWNONLY | JSITER_HIDDEN, &ids)) {
|
||||||
$*{exceptionCode}
|
$*{exceptionCode}
|
||||||
}
|
}
|
||||||
if (!mozMapEntries.SetCapacity(ids.length(), mozilla::fallible)) {
|
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
|
||||||
JS_ReportOutOfMemory(cx);
|
JS_ReportOutOfMemory(cx);
|
||||||
$*{exceptionCode}
|
$*{exceptionCode}
|
||||||
}
|
}
|
||||||
|
|
@ -4800,7 +4811,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
MOZ_ASSERT(!JSID_IS_SYMBOL(curId), "No symbols, we said!");
|
MOZ_ASSERT(!JSID_IS_SYMBOL(curId), "No symbols, we said!");
|
||||||
|
|
||||||
JS::Rooted<JS::PropertyDescriptor> desc(cx);
|
JS::Rooted<JS::PropertyDescriptor> desc(cx);
|
||||||
if (!JS_GetOwnPropertyDescriptorById(cx, mozMapObj, curId,
|
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
|
||||||
&desc)) {
|
&desc)) {
|
||||||
$*{exceptionCode}
|
$*{exceptionCode}
|
||||||
}
|
}
|
||||||
|
|
@ -4817,44 +4828,45 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!isSymbol, "We said, no symbols!");
|
MOZ_ASSERT(!isSymbol, "We said, no symbols!");
|
||||||
|
|
||||||
if (!JS_GetPropertyById(cx, mozMapObj, curId, &temp)) {
|
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
|
||||||
$*{exceptionCode}
|
$*{exceptionCode}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe to do an infallible append here, because we did a
|
// Safe to do an infallible append here, because we did a
|
||||||
// SetCapacity above to the right capacity.
|
// SetCapacity above to the right capacity.
|
||||||
${mozMapType}::EntryType* entry = mozMapEntries.AppendElement();
|
${typeName}::EntryType* entry = recordEntries.AppendElement();
|
||||||
entry->mKey = propName;
|
entry->mKey = propName;
|
||||||
${valueType}& slot = entry->mValue;
|
${valueType}& slot = entry->mValue;
|
||||||
$*{valueConversion}
|
$*{valueConversion}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
exceptionCode=exceptionCode,
|
exceptionCode=exceptionCode,
|
||||||
mozMapRef=mozMapRef,
|
recordRef=recordRef,
|
||||||
mozMapType=mozMapType,
|
typeName=typeName,
|
||||||
valueType=valueInfo.declType.define(),
|
valueType=valueInfo.declType.define(),
|
||||||
valueConversion=valueConversion)
|
valueConversion=valueConversion)
|
||||||
|
|
||||||
templateBody = wrapObjectTemplate(templateBody, type,
|
templateBody = wrapObjectTemplate(templateBody, type,
|
||||||
"${declName}.SetNull();\n",
|
"${declName}.SetNull();\n",
|
||||||
notMozMap)
|
notRecord)
|
||||||
|
|
||||||
declType = typeName
|
|
||||||
declArgs = None
|
declArgs = None
|
||||||
holderType = None
|
holderType = None
|
||||||
holderArgs = None
|
holderArgs = None
|
||||||
# MozMap arguments that might contain traceable things need
|
# record arguments that might contain traceable things need
|
||||||
# to get traced
|
# to get traced
|
||||||
if not isMember and isCallbackReturnValue:
|
if not isMember and isCallbackReturnValue:
|
||||||
# Go ahead and just convert directly into our actual return value
|
# Go ahead and just convert directly into our actual return value
|
||||||
declType = CGWrapper(declType, post="&")
|
declType = CGWrapper(declType, post="&")
|
||||||
declArgs = "aRetVal"
|
declArgs = "aRetVal"
|
||||||
elif not isMember and typeNeedsRooting(valueType):
|
elif not isMember and typeNeedsRooting(valueType):
|
||||||
holderType = CGTemplatedType("MozMapRooter", valueInfo.declType)
|
holderType = CGTemplatedType("RecordRooter",
|
||||||
# If our MozMap is nullable, this will set the Nullable to be
|
[recordKeyDeclType(recordType),
|
||||||
|
valueInfo.declType])
|
||||||
|
# If our record is nullable, this will set the Nullable to be
|
||||||
# not-null, but that's ok because we make an explicit SetNull() call
|
# not-null, but that's ok because we make an explicit SetNull() call
|
||||||
# on it as needed if our JS value is actually null.
|
# on it as needed if our JS value is actually null.
|
||||||
holderArgs = "cx, &%s" % mozMapRef
|
holderArgs = "cx, &%s" % recordRef
|
||||||
|
|
||||||
return JSToNativeConversionInfo(templateBody, declType=declType,
|
return JSToNativeConversionInfo(templateBody, declType=declType,
|
||||||
declArgs=declArgs,
|
declArgs=declArgs,
|
||||||
|
|
@ -4937,16 +4949,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
else:
|
else:
|
||||||
setDictionary = None
|
setDictionary = None
|
||||||
|
|
||||||
mozMapMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
|
recordMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
|
||||||
if len(mozMapMemberTypes) > 0:
|
if len(recordMemberTypes) > 0:
|
||||||
assert len(mozMapMemberTypes) == 1
|
assert len(recordMemberTypes) == 1
|
||||||
name = getUnionMemberName(mozMapMemberTypes[0])
|
name = getUnionMemberName(recordMemberTypes[0])
|
||||||
mozMapObject = CGGeneric(
|
recordObject = CGGeneric(
|
||||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||||
(unionArgumentObj, name))
|
(unionArgumentObj, name))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
else:
|
else:
|
||||||
mozMapObject = None
|
recordObject = None
|
||||||
|
|
||||||
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
|
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
|
||||||
if len(objectMemberTypes) > 0:
|
if len(objectMemberTypes) > 0:
|
||||||
|
|
@ -4962,10 +4974,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
else:
|
else:
|
||||||
object = None
|
object = None
|
||||||
|
|
||||||
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or mozMapObject
|
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or recordObject
|
||||||
if hasObjectTypes:
|
if hasObjectTypes:
|
||||||
# "object" is not distinguishable from other types
|
# "object" is not distinguishable from other types
|
||||||
assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or mozMapObject)
|
assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or recordObject)
|
||||||
if sequenceObject or dateObject or callbackObject:
|
if sequenceObject or dateObject or callbackObject:
|
||||||
# An object can be both an sequence object and a callback or
|
# An object can be both an sequence object and a callback or
|
||||||
# dictionary, but we shouldn't have both in the union's members
|
# dictionary, but we shouldn't have both in the union's members
|
||||||
|
|
@ -4985,9 +4997,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if dateObject:
|
if dateObject:
|
||||||
templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
|
templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
|
||||||
|
|
||||||
if mozMapObject:
|
if recordObject:
|
||||||
templateBody = CGList([templateBody,
|
templateBody = CGList([templateBody,
|
||||||
CGIfWrapper(mozMapObject, "!done")])
|
CGIfWrapper(recordObject, "!done")])
|
||||||
|
|
||||||
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
|
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
|
||||||
else:
|
else:
|
||||||
|
|
@ -5747,7 +5759,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
|
|
||||||
declArgs = None
|
declArgs = None
|
||||||
if isMember in ("Variadic", "Sequence", "Dictionary", "MozMap"):
|
if isMember in ("Variadic", "Sequence", "Dictionary", "Record"):
|
||||||
# Rooting is handled by the sequence and dictionary tracers.
|
# Rooting is handled by the sequence and dictionary tracers.
|
||||||
declType = "JS::Value"
|
declType = "JS::Value"
|
||||||
else:
|
else:
|
||||||
|
|
@ -6280,7 +6292,7 @@ def getMaybeWrapValueFuncForType(type):
|
||||||
|
|
||||||
|
|
||||||
sequenceWrapLevel = 0
|
sequenceWrapLevel = 0
|
||||||
mozMapWrapLevel = 0
|
recordWrapLevel = 0
|
||||||
|
|
||||||
|
|
||||||
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||||
|
|
@ -6459,13 +6471,13 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||||
return (code, False)
|
return (code, False)
|
||||||
|
|
||||||
if type.isRecord():
|
if type.isRecord():
|
||||||
# Now do non-nullable MozMap. Our success code is just to break to
|
# Now do non-nullable record. Our success code is just to break to
|
||||||
# where we define the property on the object. Note that we bump the
|
# where we define the property on the object. Note that we bump the
|
||||||
# mozMapWrapLevel around this call so that nested MozMap conversions
|
# recordWrapLevel around this call so that nested record conversions
|
||||||
# will use different temp value names.
|
# will use different temp value names.
|
||||||
global mozMapWrapLevel
|
global recordWrapLevel
|
||||||
valueName = "mozMapValue%d" % mozMapWrapLevel
|
valueName = "recordValue%d" % recordWrapLevel
|
||||||
mozMapWrapLevel += 1
|
recordWrapLevel += 1
|
||||||
innerTemplate = wrapForType(
|
innerTemplate = wrapForType(
|
||||||
type.inner, descriptorProvider,
|
type.inner, descriptorProvider,
|
||||||
{
|
{
|
||||||
|
|
@ -6478,7 +6490,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||||
'obj': "returnObj",
|
'obj': "returnObj",
|
||||||
'typedArraysAreStructs': typedArraysAreStructs
|
'typedArraysAreStructs': typedArraysAreStructs
|
||||||
})
|
})
|
||||||
mozMapWrapLevel -= 1
|
recordWrapLevel -= 1
|
||||||
code = fill(
|
code = fill(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -6895,14 +6907,15 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
|
||||||
returnType = returnType.inner
|
returnType = returnType.inner
|
||||||
result, _, _, _, _ = getRetvalDeclarationForType(returnType.inner,
|
result, _, _, _, _ = getRetvalDeclarationForType(returnType.inner,
|
||||||
descriptorProvider,
|
descriptorProvider,
|
||||||
isMember="MozMap")
|
isMember="Record")
|
||||||
# While we have our inner type, set up our rooter, if needed
|
# While we have our inner type, set up our rooter, if needed
|
||||||
if not isMember and typeNeedsRooting(returnType):
|
if not isMember and typeNeedsRooting(returnType):
|
||||||
rooter = CGGeneric("MozMapRooter<%s> resultRooter(cx, &result);\n" %
|
rooter = CGGeneric("RecordRooter<%s> resultRooter(cx, &result);\n" %
|
||||||
result.define())
|
("nsString, " + result.define()))
|
||||||
else:
|
else:
|
||||||
rooter = None
|
rooter = None
|
||||||
result = CGTemplatedType("MozMap", result)
|
result = CGTemplatedType("Record", [recordKeyDeclType(returnType),
|
||||||
|
result])
|
||||||
if nullable:
|
if nullable:
|
||||||
result = CGTemplatedType("Nullable", result)
|
result = CGTemplatedType("Nullable", result)
|
||||||
return result, "ref", rooter, None, None
|
return result, "ref", rooter, None, None
|
||||||
|
|
@ -7161,7 +7174,7 @@ class MethodNotNewObjectError(Exception):
|
||||||
# nested sequences we don't use the same variable name to iterate over
|
# nested sequences we don't use the same variable name to iterate over
|
||||||
# different sequences.
|
# different sequences.
|
||||||
sequenceWrapLevel = 0
|
sequenceWrapLevel = 0
|
||||||
mapWrapLevel = 0
|
recordWrapLevel = 0
|
||||||
|
|
||||||
|
|
||||||
def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
|
def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
|
||||||
|
|
@ -7226,20 +7239,20 @@ def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
|
||||||
origType = type
|
origType = type
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
type = type.inner
|
type = type.inner
|
||||||
mozMapRef = "%s.Value()" % value
|
recordRef = "%s.Value()" % value
|
||||||
else:
|
else:
|
||||||
mozMapRef = value
|
recordRef = value
|
||||||
global mapWrapLevel
|
global recordWrapLevel
|
||||||
entryRef = "mapEntry%d" % mapWrapLevel
|
entryRef = "mapEntry%d" % recordWrapLevel
|
||||||
mapWrapLevel += 1
|
recordWrapLevel += 1
|
||||||
wrapElement = wrapTypeIntoCurrentCompartment(type.inner,
|
wrapElement = wrapTypeIntoCurrentCompartment(type.inner,
|
||||||
"%s.mValue" % entryRef)
|
"%s.mValue" % entryRef)
|
||||||
mapWrapLevel -= 1
|
recordWrapLevel -= 1
|
||||||
if not wrapElement:
|
if not wrapElement:
|
||||||
return None
|
return None
|
||||||
wrapCode = CGWrapper(CGIndenter(wrapElement),
|
wrapCode = CGWrapper(CGIndenter(wrapElement),
|
||||||
pre=("for (auto& %s : %s.Entries()) {\n" %
|
pre=("for (auto& %s : %s.Entries()) {\n" %
|
||||||
(entryRef, mozMapRef)),
|
(entryRef, recordRef)),
|
||||||
post="}\n")
|
post="}\n")
|
||||||
if origType.nullable():
|
if origType.nullable():
|
||||||
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % value)
|
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % value)
|
||||||
|
|
@ -8131,7 +8144,7 @@ class CGMethodCall(CGThing):
|
||||||
if distinguishingType(s).isSequence())
|
if distinguishingType(s).isSequence())
|
||||||
|
|
||||||
# Now append all the overloads that take a dictionary or callback
|
# Now append all the overloads that take a dictionary or callback
|
||||||
# interface or MozMap. There should be only one of these!
|
# interface or record. There should be only one of these!
|
||||||
genericObjectSigs = [
|
genericObjectSigs = [
|
||||||
s for s in possibleSignatures
|
s for s in possibleSignatures
|
||||||
if (distinguishingType(s).isDictionary() or
|
if (distinguishingType(s).isDictionary() or
|
||||||
|
|
@ -9694,13 +9707,18 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
|
||||||
if type.isSequence():
|
if type.isSequence():
|
||||||
wrapperType = "Sequence"
|
wrapperType = "Sequence"
|
||||||
else:
|
else:
|
||||||
wrapperType = "MozMap"
|
wrapperType = "Record"
|
||||||
# We don't use the returned template here, so it's OK to just pass no
|
# We don't use the returned template here, so it's OK to just pass no
|
||||||
# sourceDescription.
|
# sourceDescription.
|
||||||
elementInfo = getJSToNativeConversionInfo(type.inner,
|
elementInfo = getJSToNativeConversionInfo(type.inner,
|
||||||
descriptorProvider,
|
descriptorProvider,
|
||||||
isMember=wrapperType)
|
isMember=wrapperType)
|
||||||
return CGTemplatedType(wrapperType, elementInfo.declType,
|
if wrapperType == "Sequence":
|
||||||
|
innerType = elementInfo.declType
|
||||||
|
else:
|
||||||
|
innerType = [recordKeyDeclType(type), elementInfo.declType]
|
||||||
|
|
||||||
|
return CGTemplatedType(wrapperType, innerType,
|
||||||
isConst=True, isReference=True)
|
isConst=True, isReference=True)
|
||||||
|
|
||||||
# Nested unions are unwrapped automatically into our flatMemberTypes.
|
# Nested unions are unwrapped automatically into our flatMemberTypes.
|
||||||
|
|
@ -10064,7 +10082,7 @@ class CGUnionStruct(CGThing):
|
||||||
elif t.isRecord():
|
elif t.isRecord():
|
||||||
traceCases.append(
|
traceCases.append(
|
||||||
CGCase("e" + vars["name"],
|
CGCase("e" + vars["name"],
|
||||||
CGGeneric("TraceMozMap(trc, mValue.m%s.Value());\n" %
|
CGGeneric("TraceRecord(trc, mValue.m%s.Value());\n" %
|
||||||
vars["name"])))
|
vars["name"])))
|
||||||
else:
|
else:
|
||||||
assert t.isSpiderMonkeyInterface()
|
assert t.isSpiderMonkeyInterface()
|
||||||
|
|
@ -13194,7 +13212,7 @@ class CGDictionary(CGThing):
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
|
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
|
||||||
elif type.isRecord():
|
elif type.isRecord():
|
||||||
# If you implement this, add a MozMap<object> to
|
# If you implement this, add a record<DOMString, object> to
|
||||||
# TestInterfaceJSDictionary and test it in test_bug1036214.html
|
# TestInterfaceJSDictionary and test it in test_bug1036214.html
|
||||||
# to make sure we end up with the correct security properties.
|
# to make sure we end up with the correct security properties.
|
||||||
assert False
|
assert False
|
||||||
|
|
@ -14111,8 +14129,8 @@ class CGNativeMember(ClassMethod):
|
||||||
returnCode = "aRetVal.SwapElements(${declName});\n"
|
returnCode = "aRetVal.SwapElements(${declName});\n"
|
||||||
return "void", "", returnCode
|
return "void", "", returnCode
|
||||||
if type.isRecord():
|
if type.isRecord():
|
||||||
# If we want to handle MozMap-of-MozMap return values, we're
|
# If we want to handle record-of-record return values, we're
|
||||||
# going to need to fix example codegen to not produce MozMap<void>
|
# going to need to fix example codegen to not produce record<void>
|
||||||
# for the relevant argument...
|
# for the relevant argument...
|
||||||
assert not isMember
|
assert not isMember
|
||||||
# In this case we convert directly into our outparam to start with
|
# In this case we convert directly into our outparam to start with
|
||||||
|
|
@ -14166,7 +14184,8 @@ class CGNativeMember(ClassMethod):
|
||||||
returnType = returnType.inner
|
returnType = returnType.inner
|
||||||
# And now the actual underlying type
|
# And now the actual underlying type
|
||||||
elementDecl = self.getReturnType(returnType.inner, True)
|
elementDecl = self.getReturnType(returnType.inner, True)
|
||||||
type = CGTemplatedType("MozMap", CGGeneric(elementDecl))
|
type = CGTemplatedType("Record", [recordKeyDeclType(returnType),
|
||||||
|
CGGeneric(elementDecl)])
|
||||||
if nullable:
|
if nullable:
|
||||||
type = CGTemplatedType("Nullable", type)
|
type = CGTemplatedType("Nullable", type)
|
||||||
args.append(Argument("%s&" % type.define(), "aRetVal"))
|
args.append(Argument("%s&" % type.define(), "aRetVal"))
|
||||||
|
|
@ -14227,7 +14246,7 @@ class CGNativeMember(ClassMethod):
|
||||||
Nullable as needed.
|
Nullable as needed.
|
||||||
|
|
||||||
isMember can be false or one of the strings "Sequence", "Variadic",
|
isMember can be false or one of the strings "Sequence", "Variadic",
|
||||||
"MozMap"
|
"Record"
|
||||||
"""
|
"""
|
||||||
if type.isSequence():
|
if type.isSequence():
|
||||||
nullable = type.nullable()
|
nullable = type.nullable()
|
||||||
|
|
@ -14243,8 +14262,8 @@ class CGNativeMember(ClassMethod):
|
||||||
if nullable:
|
if nullable:
|
||||||
type = type.inner
|
type = type.inner
|
||||||
elementType = type.inner
|
elementType = type.inner
|
||||||
argType = self.getArgType(elementType, False, "MozMap")[0]
|
argType = self.getArgType(elementType, False, "Record")[0]
|
||||||
decl = CGTemplatedType("MozMap", argType)
|
decl = CGTemplatedType("Record", [recordKeyDeclType(type), argType])
|
||||||
return decl.define(), True, True
|
return decl.define(), True, True
|
||||||
|
|
||||||
if type.isUnion():
|
if type.isUnion():
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for representing MozMap arguments. Basically an array under the hood.
|
* Class for representing record arguments. Basically an array under the hood.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef mozilla_dom_MozMap_h
|
#ifndef mozilla_dom_Record_h
|
||||||
#define mozilla_dom_MozMap_h
|
#define mozilla_dom_Record_h
|
||||||
|
|
||||||
#include "nsTHashtable.h"
|
#include "nsTHashtable.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
|
|
@ -23,15 +23,15 @@ namespace dom {
|
||||||
|
|
||||||
namespace binding_detail {
|
namespace binding_detail {
|
||||||
template<typename KeyType, typename ValueType>
|
template<typename KeyType, typename ValueType>
|
||||||
class MozMapEntry
|
class RecordEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MozMapEntry()
|
RecordEntry()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move constructor so we can do MozMaps of MozMaps.
|
// Move constructor so we can do Records of Records.
|
||||||
MozMapEntry(MozMapEntry<KeyType, ValueType>&& aOther)
|
RecordEntry(RecordEntry<KeyType, ValueType>&& aOther)
|
||||||
: mKey(Move(aOther.mKey)),
|
: mKey(Move(aOther.mKey)),
|
||||||
mValue(Move(aOther.mValue))
|
mValue(Move(aOther.mValue))
|
||||||
{
|
{
|
||||||
|
|
@ -43,20 +43,19 @@ public:
|
||||||
|
|
||||||
} // namespace binding_detail
|
} // namespace binding_detail
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename KeyType, typename ValueType>
|
||||||
class MozMap
|
class Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef nsString KeyType;
|
typedef typename binding_detail::RecordEntry<nsString, ValueType> EntryType;
|
||||||
typedef typename binding_detail::MozMapEntry<KeyType, ValueType> EntryType;
|
typedef Record<KeyType, ValueType> SelfType;
|
||||||
typedef MozMap<ValueType> SelfType;
|
|
||||||
|
|
||||||
MozMap()
|
Record()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move constructor so we can do MozMap of MozMap.
|
// Move constructor so we can do Record of Record.
|
||||||
MozMap(SelfType&& aOther) :
|
Record(SelfType&& aOther) :
|
||||||
mEntries(Move(aOther.mEntries))
|
mEntries(Move(aOther.mEntries))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -78,4 +77,4 @@ private:
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_MozMap_h
|
#endif // mozilla_dom_Record_h
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ EXPORTS.mozilla.dom += [
|
||||||
'FakeString.h',
|
'FakeString.h',
|
||||||
'IterableIterator.h',
|
'IterableIterator.h',
|
||||||
'JSSlots.h',
|
'JSSlots.h',
|
||||||
'MozMap.h',
|
|
||||||
'NonRefcountedDOMObject.h',
|
'NonRefcountedDOMObject.h',
|
||||||
'Nullable.h',
|
'Nullable.h',
|
||||||
'PrimitiveConversions.h',
|
'PrimitiveConversions.h',
|
||||||
|
'Record.h',
|
||||||
'RootedDictionary.h',
|
'RootedDictionary.h',
|
||||||
'SimpleGlobalObject.h',
|
'SimpleGlobalObject.h',
|
||||||
'StructuredClone.h',
|
'StructuredClone.h',
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
template<typename T> class MozMap;
|
template<typename K, typename V> class Record;
|
||||||
class HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
|
class HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
|
||||||
class OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
|
class OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ InternalHeaders::Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& a
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InternalHeaders::Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv)
|
InternalHeaders::Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
for (auto& entry : aInit.Entries()) {
|
for (auto& entry : aInit.Entries()) {
|
||||||
Append(NS_ConvertUTF16toUTF8(entry.mKey), entry.mValue, aRv);
|
Append(NS_ConvertUTF16toUTF8(entry.mKey), entry.mValue, aRv);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
template<typename T> class MozMap;
|
template<typename K, typename V> class Record;
|
||||||
class HeadersEntry;
|
class HeadersEntry;
|
||||||
|
|
||||||
class InternalHeaders final
|
class InternalHeaders final
|
||||||
|
|
@ -113,7 +113,7 @@ public:
|
||||||
|
|
||||||
void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
|
void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
|
||||||
void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
|
void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
|
||||||
void Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv);
|
void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
|
||||||
|
|
||||||
bool HasOnlySimpleHeaders() const;
|
bool HasOnlySimpleHeaders() const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue