Bug 820665 part 2. WebIDL spec updates to changes in how callback functions work. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 03 Jan 2013 14:03:06 -0500
changeset 126579 e78f9e6ea4d9977c9b1e98f7e9a3fa65ee971459
parent 126578 cc603feaa2862586bfc2c5eefdfdadf70401d09b
child 126580 ed9af04edd8c73649151ad77fd5458943b9ba668
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs820665
milestone20.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 820665 part 2. WebIDL spec updates to changes in how callback functions work. r=khuey Specifically, all callables can be converted to a callback, including in overload resolution and union conversions. We already did this for normal callback arguments, but not the overload/union case.
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2343,22 +2343,20 @@ for (uint32_t i = 0; i < length; ++i) {
             assert len(callbackMemberTypes) == 1
             memberType = callbackMemberTypes[0]
             name = memberType.name
             callbackObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${obj}, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
             names.append(name)
         else:
             callbackObject = None
 
-        if callbackObject:
+        if callbackObject and callbackMemberTypes[0].isCallbackInterface():
             callbackObject = CGWrapper(CGIndenter(callbackObject),
                                        pre="if (!IsPlatformObject(cx, &argObj)) {\n",
                                        post="\n}")
-        else:
-            callbackObject = None
 
         dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
         if len(dictionaryMemberTypes) > 0:
             raise TypeError("No support for unwrapping dictionaries as member "
                             "of a union")
         else:
             dictionaryObject = None
 
@@ -4027,42 +4025,47 @@ class CGMethodCall(CGThing):
                 caseBody.append(CGGeneric("}"))
 
             # Now check for distinguishingArg being various kinds of objects.
             # The spec says to check for the following things in order:
             # 1)  A platform object that's not a platform array object, being
             #     passed to an interface or "object" arg.
             # 2)  A Date object being passed to a Date or "object" arg.
             # 3)  A RegExp object being passed to a RegExp or "object" arg.
-            # 4)  Any non-Date and non-RegExp object being passed to a
+            # 4)  A callable object being passed to a callback or "object" arg.
+            # 5)  Any non-Date and non-RegExp object being passed to a
             #     dictionary or array or sequence or "object" arg.
-            # 5)  Some other kind of object being passed to a callback
-            #     interface, callback function, or "object" arg.
+            # 6)  Some other kind of object being passed to a callback
+            #     interface or "object" arg.
             #
             # Unfortunately, we cannot push the "some other kind of object"
-            # check down into case 5, because callbacks _can_ normally be
+            # check down into case 6, because callbacks interfaces _can_ normally be
             # initialized from platform objects. But we can coalesce the other
-            # four cases together, as long as we make sure to check whether our
+            # five cases together, as long as we make sure to check whether our
             # object works as an interface argument before checking whether it
-            # works as an arraylike or dictionary.
+            # works as an arraylike or dictionary or callback function.
 
             # First grab all the overloads that have a non-callback interface
             # (which includes typed arrays and arraybuffers) at the
             # distinguishing index.  We can also include the ones that have an
             # "object" here, since if those are present no other object-typed
             # argument will be.
             objectSigs = [
                 s for s in possibleSignatures
                 if (distinguishingType(s).isObject() or
                     distinguishingType(s).isNonCallbackInterface()) ]
 
             # And all the overloads that take Date
             objectSigs.extend(s for s in possibleSignatures
                               if distinguishingType(s).isDate())
 
+            # And all the overloads that take callbacks
+            objectSigs.extend(s for s in possibleSignatures
+                              if distinguishingType(s).isCallback())
+
             # Now append all the overloads that take an array or sequence or
             # dictionary:
             objectSigs.extend(s for s in possibleSignatures
                               if (distinguishingType(s).isArray() or
                                   distinguishingType(s).isSequence() or
                                   distinguishingType(s).isDictionary()))
 
             # There might be more than one thing in objectSigs; we need to check
@@ -4087,18 +4090,17 @@ class CGMethodCall(CGThing):
                     tryCall(sig, 4, isDefinitelyObject=True)
                     caseBody.append(CGIndenter(CGGeneric("} while (0);")))
 
                 caseBody.append(CGGeneric("}"))
 
             # Check for vanilla JS objects
             pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
                                (distinguishingArg, distinguishingArg),
-                               lambda s: (distinguishingType(s).isCallback() or
-                                          distinguishingType(s).isCallbackInterface()))
+                               lambda s: distinguishingType(s).isCallbackInterface())
 
             # The remaining cases are mutually exclusive.  The
             # pickFirstSignature calls are what change caseBody
             # Check for strings or enums
             if pickFirstSignature(None,
                                   lambda s: (distinguishingType(s).isString() or
                                              distinguishingType(s).isEnum())):
                 pass