Bug 767924 part 1. Add support for holders with nonempty holderArgs in unions. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 23 Jun 2014 16:03:57 -0400
changeset 190312 4b2ade04c59ba35cbe91dca571606697c5fe08cd
parent 190311 015ae88823dd3cf29cb59ad201768999b0dadd3e
child 190313 4db2e66252d4bea08e26d67700edbdafc7073e74
push id27004
push useremorley@mozilla.com
push dateTue, 24 Jun 2014 15:52:34 +0000
treeherdermozilla-central@7b174d47f3cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs767924
milestone33.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 767924 part 1. Add support for holders with nonempty holderArgs in unions. r=peterv
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8024,30 +8024,39 @@ def getUnionTypeTemplateVars(unionType, 
     # For dictionaries and sequences we need to pass None as the failureCode
     # for getJSToNativeConversionInfo.
     # Also, for dictionaries we would need to handle conversion of
     # null/undefined to the dictionary correctly.
     if type.isSequence():
         raise TypeError("Can't handle sequences in unions")
 
     name = getUnionMemberName(type)
+    holderName = "m" + name + "Holder"
 
     # By the time tryNextCode is invoked, we're guaranteed the union has been
     # constructed as some type, since we've been trying to convert into the
     # corresponding member.
     prefix = "" if ownsMembers else "mUnion."
-    tryNextCode = ("%sDestroy%s();\n"
+    tryNextCode = ("$*{destroyHolder}\n"
+                   "%sDestroy%s();\n"
                    "tryNext = true;\n"
                    "return true;\n" % (prefix, name))
+
     conversionInfo = getJSToNativeConversionInfo(
         type, descriptorProvider, failureCode=tryNextCode,
         isDefinitelyObject=not type.isDictionary(),
         isMember=("OwningUnion" if ownsMembers else None),
         sourceDescription="member of %s" % unionType)
 
+    if conversionInfo.holderType is not None:
+        assert not ownsMembers
+        destroyHolder = "%s.destroy();\n" % holderName
+    else:
+        destroyHolder = ""
+
     ctorNeedsCx = conversionInfo.declArgs == "cx"
     ctorArgs = "cx" if ctorNeedsCx else ""
 
     # This is ugly, but UnionMember needs to call a constructor with no
     # arguments so the type can't be const.
     structType = conversionInfo.declType.define()
     if structType.startswith("const "):
         structType = structType[6:]
@@ -8070,22 +8079,32 @@ def getUnionTypeTemplateVars(unionType, 
                              [Argument("JSContext*", "cx"),
                               Argument("JSObject*", "obj")],
                              inline=True, bodyInHeader=True,
                              body=body)
 
     else:
         # Important: we need to not have our declName involve
         # maybe-GCing operations.
-        jsConversion = string.Template(conversionInfo.template).substitute({
-            "val": "value",
-            "mutableVal": "pvalue",
-            "declName": "memberSlot",
-            "holderName": "m" + name + "Holder",
-        })
+        if conversionInfo.holderType is not None:
+            holderArgs = conversionInfo.holderArgs
+            if holderArgs is None:
+                holderArgs = ""
+            initHolder = "%s.construct(%s);\n" % (holderName, holderArgs)
+        else:
+            initHolder = ""
+
+        jsConversion = fill(
+            initHolder + conversionInfo.template,
+            val="value",
+            mutableVal="pvalue",
+            declName="memberSlot",
+            holderName=(holderName if ownsMembers else "%s.ref()" % holderName),
+            destroyHolder=destroyHolder)
+
         jsConversion = fill(
             """
             tryNext = false;
             { // scope for memberSlot
               ${structType}& memberSlot = RawSetAs${name}(${ctorArgs});
               $*{jsConversion}
             }
             return true;
@@ -8445,18 +8464,20 @@ class CGUnionConversionStruct(CGThing):
                     methods.append(
                         ClassMethod("SetStringData", "void",
                                     [Argument("const nsDependentString::char_type*", "aData"),
                                      Argument("nsDependentString::size_type", "aLength")],
                                     inline=True, bodyInHeader=True,
                                     body="RawSetAs%s().SetData(aData, aLength);\n" % t.name))
 
             if vars["holderType"] is not None:
+                holderType = CGTemplatedType("Maybe",
+                                             CGGeneric(vars["holderType"])).define()
                 members.append(ClassMember("m%sHolder" % vars["name"],
-                                           vars["holderType"]))
+                                           holderType))
 
         return CGClass(structName + "Argument",
                        members=members,
                        constructors=[ctor],
                        methods=methods,
                        disallowCopyConstruction=True).declare()
 
     def define(self):