Bug 1007878 part 4. Add C++-to-JS conversion for MozMap. r=khuey

This commit is contained in:
Boris Zbarsky 2014-05-23 17:32:38 -04:00
parent 03d472073c
commit d5a8585aec
3 changed files with 120 additions and 19 deletions

View File

@ -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:

View File

@ -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&);

View File

@ -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);