Bug 958540 part 2. Rename the existing SetAs* methods on unions to RawSetAs* and add new SetAs* methods that ensure the right type for the union. r=dzbarsky
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 01 Apr 2014 01:58:27 -0400
changeset 194970 67819547c820df6a5989ddddc9f88b6059d61be0
parent 194969 5d14c9ea9a49ba5ce84b2a26695593228ea17dd2
child 194971 57553ed7b1400fc3413ccc2171f864b38213f5e4
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdzbarsky
bugs958540
milestone31.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 958540 part 2. Rename the existing SetAs* methods on unions to RawSetAs* and add new SetAs* methods that ensure the right type for the union. r=dzbarsky
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3463,19 +3463,18 @@ while (true) {
             constructHolder = None
 
         if defaultValue and not isinstance(defaultValue, IDLNullValue):
             tag = defaultValue.type.tag()
 
             if tag in numericSuffixes or tag is IDLType.Tags.bool:
                 defaultStr = getHandleDefault(defaultValue)
                 value = declLoc + (".Value()" if nullable else "")
-                default = CGGeneric("%s.SetAs%s() = %s;" % (value,
-                                                            defaultValue.type,
-                                                            defaultStr))
+                default = CGGeneric("%s.RawSetAs%s() = %s;" %
+                                    (value, defaultValue.type, defaultStr))
             else:
                 default = CGGeneric(
                     handleDefaultStringValue(
                         defaultValue, "%s.SetStringData" % unionArgumentObj) +
                     ";")
 
             templateBody = CGIfElseWrapper("!(${haveValue})", default, templateBody)
 
@@ -3496,17 +3495,17 @@ while (true) {
             assert type.hasDictionaryType
             assert defaultValue.type.isDictionary()
             if not isMember and typeNeedsRooting(defaultValue.type):
                 ctorArgs = "cx"
             else:
                 ctorArgs = ""
             initDictionaryWithNull = CGIfWrapper(
                 CGGeneric("return false;"),
-                ('!%s.SetAs%s(%s).Init(cx, JS::NullHandleValue, "Member of %s")'
+                ('!%s.RawSetAs%s(%s).Init(cx, JS::NullHandleValue, "Member of %s")'
                  % (declLoc, getUnionMemberName(defaultValue.type),
                     ctorArgs, type)))
             templateBody = CGIfElseWrapper("!(${haveValue})",
                                            initDictionaryWithNull,
                                            templateBody)
 
         templateBody = CGList([constructDecl, templateBody], "\n")
 
@@ -7062,17 +7061,17 @@ def getUnionTypeTemplateVars(unionType, 
                 "mutableVal": "pvalue",
                 "declName": "memberSlot",
                 "holderName": "m" + name + "Holder",
                 }
             )
         jsConversion = CGWrapper(CGIndenter(CGGeneric(jsConversion)),
                                  pre=("tryNext = false;\n"
                                       "{ // scope for memberSlot\n"
-                                      "  %s& memberSlot = SetAs%s(%s);\n"
+                                      "  %s& memberSlot = RawSetAs%s(%s);\n"
                                       % (structType, name, ctorArgs)),
                                  post=("\n"
                                        "}\n"
                                       "return true;"))
         setter = ClassMethod("TrySetTo" + name, "bool",
                               [Argument("JSContext*", "cx"),
                                Argument("JS::Handle<JS::Value>", "value"),
                                Argument("JS::MutableHandle<JS::Value>", "pvalue"),
@@ -7127,54 +7126,65 @@ class CGUnionStruct(CGThing):
         traceCases = []
         unionValues = []
         if self.type.hasNullableType:
             enumValues.append("eNull")
             methods.append(ClassMethod("IsNull", "bool", [], const=True, inline=True,
                                        body="return mType == eNull;",
                                        bodyInHeader=True))
             methods.append(ClassMethod("SetNull", "void", [], inline=True,
-                                       body=("MOZ_ASSERT(mType == eUninitialized);\n"
+                                       body=("Uninit();\n"
                                              "mType = eNull;"),
                                        bodyInHeader=True))
             destructorCases.append(CGCase("eNull", None))
             assignmentCases.append(CGCase("eNull",
                                           CGGeneric("MOZ_ASSERT(mType == eUninitialized);\n"
                                                     "mType = eNull;")))
             toJSValCases.append(CGCase("eNull", CGGeneric("rval.setNull();\n"
                                                           "return true;")))
 
+        hasObjectType = any(t.isObject() for t in self.type.flatMemberTypes)
         for t in self.type.flatMemberTypes:
             vars = getUnionTypeTemplateVars(self.type,
                                             t, self.descriptorProvider,
                                             ownsMembers=self.ownsMembers)
             if vars["name"] != "Object" or self.ownsMembers:
                 body=string.Template("if (mType == e${name}) {\n"
                                      "  return mValue.m${name}.Value();\n"
                                      "}\n"
-                                     "MOZ_ASSERT(mType == eUninitialized);\n"
+                                     "%s\n"
                                      "mType = e${name};\n"
                                      "return mValue.m${name}.SetValue(${ctorArgs});").substitute(vars)
                 # bodyInHeader must be false for return values because they own
                 # their union members and we don't want include headers in
                 # UnionTypes.h just to call Addref/Release
-                methods.append(ClassMethod("SetAs" + vars["name"],
-                                           vars["structType"] + "&",
-                                           vars["ctorArgList"],
-                                           bodyInHeader=not self.ownsMembers,
-                                           body=body))
+                methods.append(ClassMethod(
+                    "RawSetAs" + vars["name"],
+                    vars["structType"] + "&",
+                    vars["ctorArgList"],
+                    bodyInHeader=not self.ownsMembers,
+                    body=body % "MOZ_ASSERT(mType == eUninitialized);"))
+                uninit = "Uninit();"
+                if hasObjectType and not self.ownsMembers:
+                    uninit = 'MOZ_ASSERT(mType != eObject, "This will not play well with Rooted");\n' + uninit
+                methods.append(ClassMethod(
+                    "SetAs" + vars["name"],
+                    vars["structType"] + "&",
+                    vars["ctorArgList"],
+                    bodyInHeader=not self.ownsMembers,
+                    body=body % uninit))
                 if self.ownsMembers:
                     methods.append(vars["setter"])
                     if t.isString():
                         methods.append(
                             ClassMethod("SetStringData", "void",
                                 [Argument("const nsString::char_type*", "aData"),
                                  Argument("nsString::size_type", "aLength")],
                                 inline=True, bodyInHeader=True,
-                                body="SetAsString().Assign(aData, aLength);"))
+                                body="RawSetAsString().Assign(aData, aLength);"))
 
             body = string.Template('MOZ_ASSERT(Is${name}(), "Wrong type!");\n'
                                    'mValue.m${name}.Destroy();\n'
                                    'mType = eUninitialized;').substitute(vars)
             methods.append(ClassMethod("Destroy" + vars["name"],
                                        "void",
                                        [],
                                        visibility="private",
@@ -7207,17 +7217,17 @@ class CGUnionStruct(CGThing):
 
             toJSValCases.append(CGCase("e" + vars["name"],
                                        self.getConversionToJS(vars, t)))
             destructorCases.append(CGCase("e" + vars["name"],
                                           CGGeneric("Destroy%s();"
                                                      % vars["name"])))
             assignmentCases.append(
                 CGCase("e" + vars["name"],
-                       CGGeneric("SetAs%s() = aOther.GetAs%s();" %
+                       CGGeneric("RawSetAs%s() = aOther.GetAs%s();" %
                                  (vars["name"], vars["name"]))))
             if self.ownsMembers and typeNeedsRooting(t):
                 if t.isObject():
                     traceCases.append(
                         CGCase("e" + vars["name"],
                                CGGeneric('JS_CallObjectTracer(trc, %s, "%s");' %
                                          ("&mValue.m" + vars["name"] + ".Value()",
                                           "mValue.m" + vars["name"]))))
@@ -7359,28 +7369,28 @@ class CGUnionConversionStruct(CGThing):
         for t in self.type.flatMemberTypes:
             vars = getUnionTypeTemplateVars(self.type,
                                             t, self.descriptorProvider)
             methods.append(vars["setter"])
             if vars["name"] != "Object":
                 body=string.Template("MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);\n"
                                      "mUnion.mType = mUnion.e${name};\n"
                                      "return mUnion.mValue.m${name}.SetValue(${ctorArgs});").substitute(vars)
-                methods.append(ClassMethod("SetAs" + vars["name"],
+                methods.append(ClassMethod("RawSetAs" + vars["name"],
                                            vars["structType"] + "&",
                                            vars["ctorArgList"],
                                            bodyInHeader=True,
                                            body=body,
                                            visibility="private"))
                 if t.isString():
                     methods.append(ClassMethod("SetStringData", "void",
                                      [Argument("const nsDependentString::char_type*", "aData"),
                                       Argument("nsDependentString::size_type", "aLength")],
                                      inline=True, bodyInHeader=True,
-                                     body="SetAsString().SetData(aData, aLength);"))
+                                     body="RawSetAsString().SetData(aData, aLength);"))
 
             if vars["holderType"] is not None:
                 members.append(ClassMember("m%sHolder" % vars["name"],
                                            vars["holderType"]))
 
         return CGClass(structName + "Argument",
                        members=members,
                        constructors=[ctor],