зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1007878 part 4. Add C++-to-JS conversion for MozMap. r=khuey
This commit is contained in:
Родитель
932dc0b698
Коммит
8a365e4f4d
|
@ -5062,6 +5062,7 @@ def getMaybeWrapValueFuncForType(type):
|
|||
|
||||
|
||||
sequenceWrapLevel = 0
|
||||
mozMapWrapLevel = 0
|
||||
|
||||
|
||||
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||
|
@ -5168,26 +5169,26 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
|||
if type.isArray():
|
||||
raise TypeError("Can't handle array return values yet")
|
||||
|
||||
if (type.isSequence() or type.isMozMap()) and type.nullable():
|
||||
# These are both wrapped in Nullable<>
|
||||
recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
|
||||
"%s.Value()" % result, successCode,
|
||||
returnsNewObject, exceptionCode,
|
||||
typedArraysAreStructs)
|
||||
code = fill(
|
||||
"""
|
||||
|
||||
if (${result}.IsNull()) {
|
||||
$*{setNull}
|
||||
}
|
||||
$*{recTemplate}
|
||||
""",
|
||||
result=result,
|
||||
setNull=setNull(),
|
||||
recTemplate=recTemplate)
|
||||
return code, recInfall
|
||||
|
||||
if type.isSequence():
|
||||
if type.nullable():
|
||||
# Nullable sequences are Nullable< nsTArray<T> >
|
||||
recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
|
||||
"%s.Value()" % result, successCode,
|
||||
returnsNewObject, exceptionCode,
|
||||
typedArraysAreStructs)
|
||||
code = fill(
|
||||
"""
|
||||
|
||||
if (${result}.IsNull()) {
|
||||
$*{setNull}
|
||||
}
|
||||
$*{recTemplate}
|
||||
""",
|
||||
result=result,
|
||||
setNull=setNull(),
|
||||
recTemplate=recTemplate)
|
||||
return code, recInfall
|
||||
|
||||
# Now do non-nullable sequences. Our success code is just to break to
|
||||
# where we set the element in the array. Note that we bump the
|
||||
# sequenceWrapLevel around this call so that nested sequence conversions
|
||||
|
@ -5240,6 +5241,62 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
|||
|
||||
return (code, False)
|
||||
|
||||
if type.isMozMap():
|
||||
# Now do non-nullable MozMap. Our success code is just to break to
|
||||
# where we define the property on the object. Note that we bump the
|
||||
# mozMapWrapLevel around this call so that nested MozMap conversions
|
||||
# will use different temp value names.
|
||||
global mozMapWrapLevel
|
||||
valueName = "mozMapValue%d" % mozMapWrapLevel
|
||||
mozMapWrapLevel += 1
|
||||
innerTemplate = wrapForType(
|
||||
type.inner, descriptorProvider,
|
||||
{
|
||||
'result': valueName,
|
||||
'successCode': "break;\n",
|
||||
'jsvalRef': "tmp",
|
||||
'jsvalHandle': "&tmp",
|
||||
'returnsNewObject': returnsNewObject,
|
||||
'exceptionCode': exceptionCode,
|
||||
'obj': "returnObj"
|
||||
})
|
||||
mozMapWrapLevel -= 1
|
||||
code = fill(
|
||||
"""
|
||||
|
||||
nsTArray<nsString> keys;
|
||||
${result}.GetKeys(keys);
|
||||
JS::Rooted<JSObject*> returnObj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
|
||||
if (!returnObj) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
// Scope for 'tmp'
|
||||
{
|
||||
JS::Rooted<JS::Value> tmp(cx);
|
||||
for (size_t idx = 0; idx < keys.Length(); ++idx) {
|
||||
auto& ${valueName} = ${result}.Get(keys[idx]);
|
||||
// Control block to let us common up the JS_DefineUCProperty calls when there
|
||||
// are different ways to succeed at wrapping the value.
|
||||
do {
|
||||
$*{innerTemplate}
|
||||
} while (0);
|
||||
if (!JS_DefineUCProperty(cx, returnObj, keys[idx].get(),
|
||||
keys[idx].Length(), tmp,
|
||||
JSPROP_ENUMERATE)) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
$*{set}
|
||||
""",
|
||||
result=result,
|
||||
exceptionCode=exceptionCode,
|
||||
valueName=valueName,
|
||||
innerTemplate=innerTemplate,
|
||||
set=setObject("*returnObj"))
|
||||
|
||||
return (code, False)
|
||||
|
||||
if type.isGeckoInterface() and not type.isCallbackInterface():
|
||||
descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
|
||||
if type.nullable():
|
||||
|
@ -5604,6 +5661,26 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
|
|||
if nullable:
|
||||
result = CGTemplatedType("Nullable", result)
|
||||
return result, True, rooter, None
|
||||
if returnType.isMozMap():
|
||||
nullable = returnType.nullable()
|
||||
if nullable:
|
||||
returnType = returnType.inner
|
||||
# If our result is already addrefed, use the right type in the
|
||||
# MozMap argument here.
|
||||
result, _, _, _ = getRetvalDeclarationForType(returnType.inner,
|
||||
descriptorProvider,
|
||||
resultAlreadyAddRefed,
|
||||
isMember="MozMap")
|
||||
# While we have our inner type, set up our rooter, if needed
|
||||
if not isMember and typeNeedsRooting(returnType):
|
||||
rooter = CGGeneric("MozMapRooter<%s> resultRooter(cx, &result);\n" %
|
||||
result.define())
|
||||
else:
|
||||
rooter = None
|
||||
result = CGTemplatedType("MozMap", result)
|
||||
if nullable:
|
||||
result = CGTemplatedType("Nullable", result)
|
||||
return result, True, rooter, None
|
||||
if returnType.isDictionary():
|
||||
nullable = returnType.nullable()
|
||||
dictName = CGDictionary.makeDictionaryName(returnType.unroll().inner)
|
||||
|
@ -7565,6 +7642,8 @@ class CGMemberJITInfo(CGThing):
|
|||
assert False
|
||||
if t.isSequence():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isMozMap():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isGeckoInterface():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isString():
|
||||
|
@ -11498,6 +11577,16 @@ class CGNativeMember(ClassMethod):
|
|||
if nullable:
|
||||
type = CGTemplatedType("Nullable", type)
|
||||
args.append(Argument("%s&" % type.define(), "aRetVal"))
|
||||
elif returnType.isMozMap():
|
||||
nullable = returnType.nullable()
|
||||
if nullable:
|
||||
returnType = returnType.inner
|
||||
# And now the actual underlying type
|
||||
elementDecl = self.getReturnType(returnType.inner, True)
|
||||
type = CGTemplatedType("MozMap", CGGeneric(elementDecl))
|
||||
if nullable:
|
||||
type = CGTemplatedType("Nullable", type)
|
||||
args.append(Argument("%s&" % type.define(), "aRetVal"))
|
||||
elif returnType.isDictionary():
|
||||
nullable = returnType.nullable()
|
||||
if nullable:
|
||||
|
|
|
@ -421,6 +421,12 @@ public:
|
|||
void PassStringMozMap(const MozMap<nsString>&);
|
||||
void PassByteStringMozMap(const MozMap<nsCString>&);
|
||||
void PassMozMapOfMozMaps(const MozMap< MozMap<int32_t> >&);
|
||||
void ReceiveMozMap(MozMap<int32_t>&);
|
||||
void ReceiveNullableMozMap(Nullable<MozMap<int32_t>>&);
|
||||
void ReceiveMozMapOfNullableInts(MozMap<Nullable<int32_t>>&);
|
||||
void ReceiveNullableMozMapOfNullableInts(Nullable<MozMap<Nullable<int32_t>>>&);
|
||||
void ReceiveMozMapOfMozMaps(MozMap<MozMap<int32_t>>&);
|
||||
void ReceiveAnyMozMap(JSContext*, MozMap<JS::Value>&);
|
||||
|
||||
// Typed array types
|
||||
void PassArrayBuffer(const ArrayBuffer&);
|
||||
|
|
|
@ -379,6 +379,12 @@ interface TestInterface {
|
|||
void passStringMozMap(MozMap<DOMString> arg);
|
||||
void passByteStringMozMap(MozMap<ByteString> arg);
|
||||
void passMozMapOfMozMaps(MozMap<MozMap<long>> arg);
|
||||
MozMap<long> receiveMozMap();
|
||||
MozMap<long>? receiveNullableMozMap();
|
||||
MozMap<long?> receiveMozMapOfNullableInts();
|
||||
MozMap<long?>? receiveNullableMozMapOfNullableInts();
|
||||
MozMap<MozMap<long>> receiveMozMapOfMozMaps();
|
||||
MozMap<any> receiveAnyMozMap();
|
||||
|
||||
// Typed array types
|
||||
void passArrayBuffer(ArrayBuffer arg);
|
||||
|
|
Загрузка…
Ссылка в новой задаче