Bug 766583 part 3. Stop declaring nullable things as const on the stack in bindings code. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 25 Apr 2013 19:03:06 -0400
changeset 140939 f4449bddbbfa26a632df89de23cf4990ac0a8e77
parent 140938 3e7f89b3429bbd7b55b166aebbd2404134955120
child 140940 aaf01da4f4f7cfb1e99988a0cf5c49ebc9825521
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs766583
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 766583 part 3. Stop declaring nullable things as const on the stack in bindings code. r=smaug
dom/bindings/Codegen.py
dom/bindings/test/TestBindingHeader.h
--- 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