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 129994 f4449bddbbfa26a632df89de23cf4990ac0a8e77
parent 129993 3e7f89b3429bbd7b55b166aebbd2404134955120
child 129995 aaf01da4f4f7cfb1e99988a0cf5c49ebc9825521
push id1552
push userttaubert@mozilla.com
push dateSat, 27 Apr 2013 15:33:29 +0000
treeherderfx-team@40dafc376794 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs766583
milestone23.0a1
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