Bug 766583 part 3. Stop declaring nullable things as const on the stack in bindings code. r=smaug
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3021,17 +3021,17 @@ for (uint32_t i = 0; i < length; ++i) {
if type.isEnum():
assert not isEnforceRange and not isClamp
enumName = type.unroll().inner.identifier.name
declType = CGGeneric(enumName)
if type.nullable():
declType = CGTemplatedType("Nullable", declType)
declType = declType.define()
- enumLoc = "const_cast<%s&>(${declName}).SetValue()" % declType
+ enumLoc = "${declName}.SetValue()"
else:
enumLoc = "${declName}"
declType = declType.define()
if invalidEnumValueFatal:
handleInvalidEnumValueCode = " MOZ_ASSERT(index >= 0);\n"
else:
# invalidEnumValueFatal is false only for attributes. So we won't
@@ -3056,36 +3056,33 @@ for (uint32_t i = 0; i < length; ++i) {
"}" % { "enumtype" : enumName,
"values" : enumName + "Values::strings",
"invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
"handleInvalidEnumValueCode" : handleInvalidEnumValueCode,
"exceptionCode" : CGIndenter(exceptionCodeIndented).define(),
"enumLoc" : enumLoc,
})
- setNull = "const_cast<%s&>(${declName}).SetNull();" % declType
+ setNull = "${declName}.SetNull();"
if type.nullable():
template = CGIfElseWrapper("${val}.isNullOrUndefined()",
CGGeneric(setNull),
CGGeneric(template)).define()
if defaultValue is not None:
if isinstance(defaultValue, IDLNullValue):
assert type.nullable()
template = handleDefault(template, setNull)
else:
assert(defaultValue.type.tag() == IDLType.Tags.domstring)
template = handleDefault(template,
("%s = %sValues::%s" %
(enumLoc, enumName,
getEnumValueName(defaultValue.value))))
- if type.nullable() and not isOptional:
- # isOptional will handle the const bits itself
- declType = "const " + declType
return (template, CGGeneric(declType), None, isOptional)
if type.isCallback():
assert not isEnforceRange and not isClamp
assert not type.treatNonCallableAsNull() or type.nullable()
if descriptorProvider.workers:
if isMember:
@@ -3249,30 +3246,27 @@ for (uint32_t i = 0; i < length; ++i) {
assert type.isInteger()
conversionBehavior = "eEnforceRange"
elif isClamp:
assert type.isInteger()
conversionBehavior = "eClamp"
if type.nullable():
declType = CGGeneric("Nullable<" + typeName + ">")
- mutableType = declType.define() + "&"
- if not isOptional and not isMember:
- declType = CGWrapper(declType, pre="const ")
- writeLoc = ("const_cast< %s >(${declName}).SetValue()" % mutableType)
+ writeLoc = "${declName}.SetValue()"
readLoc = "${declName}.Value()"
nullCondition = "${val}.isNullOrUndefined()"
if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
nullCondition = "!(${haveValue}) || " + nullCondition
template = (
"if (%s) {\n"
- " const_cast< %s >(${declName}).SetNull();\n"
+ " ${declName}.SetNull();\n"
"} else if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
"%s\n"
- "}" % (nullCondition, mutableType, typeName, conversionBehavior,
+ "}" % (nullCondition, typeName, conversionBehavior,
writeLoc, exceptionCodeIndented.define()))
else:
assert(defaultValue is None or
not isinstance(defaultValue, IDLNullValue))
writeLoc = "${declName}"
readLoc = writeLoc
template = (
"if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
@@ -3982,16 +3976,18 @@ class CGCallGenerator(CGThing):
name = "(JSObject&)" + name
arg = CGGeneric(name)
# Now constify the things that need it
def needsConst(a):
if a.type.isDictionary():
return True
if a.type.isSequence():
return True
+ if a.type.nullable():
+ return True
return False
if needsConst(a):
arg = CGWrapper(arg, pre="Constify(", post=")")
args.append(arg)
# Return values that go in outparams go here
if resultOutParam:
args.append(CGGeneric("result"))
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -701,16 +701,19 @@ private:
// Make sure dictionary arguments are always const
void PassDictionary(JSContext*, Dict&) MOZ_DELETE;
void PassOtherDictionary(GrandparentDict&) MOZ_DELETE;
void PassSequenceOfDictionaries(JSContext*, Sequence<Dict>&) MOZ_DELETE;
void PassDictionaryOrLong(JSContext*, Dict&) MOZ_DELETE;
void PassDictContainingDict(JSContext*, DictContainingDict&) MOZ_DELETE;
void PassDictContainingSequence(DictContainingSequence&) MOZ_DELETE;
+
+ // Make sure various nullable things are always const
+ void PassNullableEnum(Nullable<TestEnum>&) MOZ_DELETE;
};
class TestIndexedGetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS