summaryrefslogtreecommitdiffstats
path: root/dom/bindings/Codegen.py
diff options
context:
space:
mode:
Diffstat (limited to 'dom/bindings/Codegen.py')
-rw-r--r--dom/bindings/Codegen.py45
1 files changed, 34 insertions, 11 deletions
diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py
index 9415c0b..f5c1a0e 100644
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4642,6 +4642,22 @@ def recordKeyDeclType(recordType):
return CGGeneric(recordKeyType(recordType))
+def initializerForType(type):
+ """
+ Get the right initializer for the given type for a data location where we
+ plan to then initialize it from a JS::Value. Some types need to always be
+ initialized even before we start the JS::Value-to-IDL-value conversion.
+
+ Returns a string or None if no initialization is needed.
+ """
+ if type.isObject():
+ return "nullptr"
+ # We could probably return CGDictionary.getNonInitializingCtorArg() for the
+ # dictionary case, but code outside DictionaryBase subclasses can't use
+ # that, so we can't do it across the board.
+ return None
+
+
# If this function is modified, modify CGNativeMember.getArg and
# 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
@@ -4949,6 +4965,12 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"passedToJSImpl": "${passedToJSImpl}"
})
+ elementInitializer = initializerForType(elementType)
+ if elementInitializer is None:
+ elementInitializer = ""
+ else:
+ elementInitializer = elementInitializer + ", "
+
# NOTE: Keep this in sync with variadic conversions as needed
templateBody = fill(
"""
@@ -4969,7 +4991,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if (done${nestingLevel}) {
break;
}
- ${elementType}* slotPtr${nestingLevel} = arr${nestingLevel}.AppendElement(mozilla::fallible);
+ ${elementType}* slotPtr${nestingLevel} = arr${nestingLevel}.AppendElement(${elementInitializer}mozilla::fallible);
if (!slotPtr${nestingLevel}) {
JS_ReportOutOfMemory(cx);
$*{exceptionCode}
@@ -4984,6 +5006,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
arrayRef=arrayRef,
elementType=elementInfo.declType.define(),
elementConversion=elementConversion,
+ elementInitializer=elementInitializer,
nestingLevel=str(nestingLevel))
templateBody = wrapObjectTemplate(templateBody, type,
@@ -6528,6 +6551,8 @@ class CGArgumentConverter(CGThing):
rooterDecl = ""
replacer["elemType"] = typeConversion.declType.define()
+ replacer["elementInitializer"] = initializerForType(self.argument.type) or ""
+
# NOTE: Keep this in sync with sequence conversions as needed
variadicConversion = string.Template(
"${seqType} ${declName};\n" +
@@ -6539,7 +6564,8 @@ class CGArgumentConverter(CGThing):
return false;
}
for (uint32_t variadicArg = ${index}; variadicArg < ${argc}; ++variadicArg) {
- ${elemType}& slot = *${declName}.AppendElement(mozilla::fallible);
+ // OK to do infallible append here, since we ensured capacity already.
+ ${elemType}& slot = *${declName}.AppendElement(${elementInitializer});
""")
).substitute(replacer)
@@ -13689,8 +13715,9 @@ class CGDictionary(CGThing):
def getMemberInitializer(self, memberInfo):
"""
Get the right initializer for the member. Most members don't need one,
- but we need to pre-initialize 'any' and 'object' that have a default
- value, so they're safe to trace at all times.
+ but we need to pre-initialize 'object' that have a default value or are
+ required (and hence are not inside Optional), so they're safe to trace
+ at all times. And we can optimize a bit for dictionary-typed members.
"""
member, _ = memberInfo
if member.canHaveMissingValue():
@@ -13699,17 +13726,13 @@ class CGDictionary(CGThing):
# up.
return None
type = member.type
- if type.isAny():
- return "JS::UndefinedValue()"
- if type.isObject():
- return "nullptr"
if type.isDictionary():
# When we construct ourselves, we don't want to init our member
# dictionaries. Either we're being constructed-but-not-initialized
# ourselves (and then we don't want to init them) or we're about to
# init ourselves and then we'll init them anyway.
return CGDictionary.getNonInitializingCtorArg()
- return None
+ return initializerForType(type)
def getMemberSourceDescription(self, member):
return ("'%s' member of %s" %
@@ -16324,7 +16347,7 @@ class CallbackMethod(CallbackMember):
spiderMonkeyInterfacesAreStructs=spiderMonkeyInterfacesAreStructs)
def getRvalDecl(self):
- return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
+ return "JS::Rooted<JS::Value> rval(cx);\n"
def getCall(self):
if self.argCount > 0:
@@ -16480,7 +16503,7 @@ class CallbackGetter(CallbackAccessor):
spiderMonkeyInterfacesAreStructs)
def getRvalDecl(self):
- return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
+ return "JS::Rooted<JS::Value> rval(cx);\n"
def getCall(self):
return fill(