Bug 1104955 part 2. Make codegen output a list of unscopable names that we can then pass to CreateInterfaceObjects. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 29 Mar 2016 15:49:48 -0400
changeset 290961 75898c3d4bb2ba2557ee90c895bebf110bdaa9dd
parent 290960 483533fede8d48bcbd06a5541758c81af0c4385c
child 290962 2fde05270e2574ca3ccbf64108a1032e46d46e80
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs1104955
milestone48.0a1
Bug 1104955 part 2. Make codegen output a list of unscopable names that we can then pass to CreateInterfaceObjects. r=khuey Note that this does not take into account the exposed/enabled state of the relevant properties. This should be OK, I hope. Taking that state into account would be rather annoying, unfortunately. We could make codegen fail if something is conditionally exposed and unscopable, if desired...
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -11830,28 +11830,32 @@ class CGDescriptor(CGThing):
                                       toBindingNamespace(descriptor.parentPrototypeName)))
 
         # These are set to true if at least one non-static
         # method/getter/setter or jsonifier exist on the interface.
         (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter,
             hasPromiseReturningMethod) = False, False, False, False, False, False
         jsonifierMethod = None
         crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
+        unscopableNames = list()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,
                                                NamedConstructorName(n)))
         for m in descriptor.interface.members:
             if m.isMethod() and m.identifier.name == 'queryInterface':
                 continue
             if not isMaybeExposedIn(m, descriptor):
                 continue
 
             props = memberProperties(m, descriptor)
 
             if m.isMethod():
+                if m.getExtendedAttribute("Unscopable"):
+                    assert not m.isStatic()
+                    unscopableNames.append(m.identifier.name)
                 if props.isJsonifier:
                     jsonifierMethod = m
                 elif not m.isIdentifierLess() or m == descriptor.operations['Stringifier']:
                     if m.isStatic():
                         assert descriptor.interface.hasInterfaceObject()
                         cgThings.append(CGStaticMethod(descriptor, m))
                         if m.returnsPromise():
                             cgThings.append(CGStaticMethodJitinfo(m))
@@ -11867,16 +11871,19 @@ class CGDescriptor(CGThing):
             # generate its convenience functions.
             elif m.isMaplikeOrSetlike():
                 cgThings.append(CGMaplikeOrSetlikeHelperGenerator(descriptor, m))
             elif m.isAttr():
                 if m.stringifier:
                     raise TypeError("Stringifier attributes not supported yet. "
                                     "See bug 824857.\n"
                                     "%s" % m.location)
+                if m.getExtendedAttribute("Unscopable"):
+                    assert not m.isStatic()
+                    unscopableNames.append(m.identifier.name)
                 if m.isStatic():
                     assert descriptor.interface.hasInterfaceObject()
                     cgThings.append(CGStaticGetter(descriptor, m))
                 elif descriptor.interface.hasInterfacePrototypeObject():
                     cgThings.append(CGSpecializedGetter(descriptor, m))
                     if props.isCrossOriginGetter:
                         crossOriginGetters.add(m.identifier.name)
                 if not m.readonly:
@@ -12054,18 +12061,28 @@ class CGDescriptor(CGThing):
                                                             properties))
 
         # If we're not wrappercached, we don't know how to clear our
         # cached values, since we can't get at the JSObject.
         if descriptor.wrapperCache:
             cgThings.extend(CGClearCachedValueMethod(descriptor, m) for
                             m in clearableCachedAttrs(descriptor))
 
+        haveUnscopables = (len(unscopableNames) != 0 and
+                           descriptor.interface.hasInterfacePrototypeObject())
+        if haveUnscopables:
+            cgThings.append(
+                CGList([CGGeneric("static const char* const unscopableNames[] = {"),
+                        CGIndenter(CGList([CGGeneric('"%s"' % name) for
+                                           name in unscopableNames] +
+                                          [CGGeneric("nullptr")], ",\n")),
+                        CGGeneric("};\n")], "\n"))
+
         # CGCreateInterfaceObjectsMethod needs to come after our
-        # CGDOMJSClass, if any.
+        # CGDOMJSClass and unscopables, if any.
         cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
 
         # CGGetProtoObjectMethod and CGGetConstructorObjectMethod need
         # to come after CGCreateInterfaceObjectsMethod.
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGGetProtoObjectHandleMethod(descriptor))
             if descriptor.interface.hasChildInterfaces():
                 cgThings.append(CGGetProtoObjectMethod(descriptor))