Bug 1073124 part 2. Define Exposed=System things in BackstagePass::NewResolve as needed. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 17 Oct 2014 11:30:19 -0400
changeset 211055 06450cede5ecdf9c2a238ab71755c52301bc66fe
parent 211054 288827a46e4def427c5e17317928d7d5ba5629d9
child 211056 e6c58647bf2bf88772184ec674cdc3a21c31ad48
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbholley
bugs1073124
milestone36.0a1
Bug 1073124 part 2. Define Exposed=System things in BackstagePass::NewResolve as needed. r=bholley
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/mozwebidlcodegen/__init__.py
js/xpconnect/src/XPCRuntimeService.cpp
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -11914,16 +11914,73 @@ class CGRegisterWorkerBindings(CGAbstrac
                     + condition)
             conditions.append(condition)
         lines = [CGIfWrapper(CGGeneric("return false;\n"), condition) for
                  condition in conditions]
         lines.append(CGGeneric("return true;\n"))
         return CGList(lines, "\n").define()
 
 
+class CGResolveSystemBinding(CGAbstractMethod):
+    def __init__(self, config):
+        CGAbstractMethod.__init__(self, None, 'ResolveSystemBinding', 'bool',
+                                  [Argument('JSContext*', 'aCx'),
+                                   Argument('JS::Handle<JSObject*>', 'aObj'),
+                                   Argument('JS::Handle<jsid>', 'aId'),
+                                   Argument('JS::MutableHandle<JSObject*>',
+                                            'aObjp')])
+        self.config = config
+
+    def definition_body(self):
+        descriptors = self.config.getDescriptors(hasInterfaceObject=True,
+                                                 isExposedInSystemGlobals=True,
+                                                 register=True,
+                                                 skipGen=False)
+
+        def descNameToId(name):
+            return "s%s_id" % name
+        jsidNames = [descNameToId(desc.name) for desc in descriptors]
+        jsidDecls = CGList(CGGeneric("static jsid %s;\n" % name)
+                           for name in jsidNames)
+
+        jsidInits = CGList(
+            (CGIfWrapper(
+                CGGeneric("return false;\n"),
+                '!InternJSString(aCx, %s, "%s")' %
+                (descNameToId(desc.name), desc.interface.identifier.name))
+             for desc in descriptors),
+            "\n")
+        jsidInits.append(CGGeneric("idsInited = true;\n"))
+        jsidInits = CGIfWrapper(jsidInits, "!idsInited")
+        jsidInits = CGList([CGGeneric("static bool idsInited = false;\n"),
+                            jsidInits])
+
+        definitions = CGList([], "\n")
+        for desc in descriptors:
+            bindingNS = toBindingNamespace(desc.name)
+            defineCode = "!%s::GetConstructorObject(aCx, aObj)" % bindingNS
+            defineCode = CGIfWrapper(CGGeneric("return false;\n"), defineCode)
+            defineCode = CGList([defineCode,
+                                 CGGeneric("aObjp.set(aObj);\n"),
+                                 CGGeneric("return true;\n")])
+
+            condition = "JSID_IS_VOID(aId) || aId == %s" % descNameToId(desc.name)
+            if desc.isExposedConditionally():
+                condition = "(%s) && %s::ConstructorEnabled(aCx, aObj)" % (condition, bindingNS)
+
+            definitions.append(CGIfWrapper(defineCode, condition))
+
+        return CGList([CGGeneric("MOZ_ASSERT(NS_IsMainThread());\n"),
+                       jsidDecls,
+                       jsidInits,
+                       definitions,
+                       CGGeneric("return true;\n")],
+                      "\n").define()
+
+
 class CGRegisterProtos(CGAbstractMethod):
     def __init__(self, config):
         CGAbstractMethod.__init__(self, None, 'Register', 'void',
                                   [Argument('nsScriptNameSpaceManager*', 'aNameSpaceManager')])
         self.config = config
 
     def _defineMacro(self):
         return dedent("""
@@ -14336,17 +14393,16 @@ class GlobalGenRoots():
         curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
 
         # Done.
         return curr
 
     @staticmethod
     def RegisterBindings(config):
 
-        # TODO - Generate the methods we want
         curr = CGRegisterProtos(config)
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
@@ -14366,17 +14422,16 @@ class GlobalGenRoots():
         curr = CGIncludeGuard('RegisterBindings', curr)
 
         # Done.
         return curr
 
     @staticmethod
     def RegisterWorkerBindings(config):
 
-        # TODO - Generate the methods we want
         curr = CGRegisterWorkerBindings(config)
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
@@ -14391,16 +14446,45 @@ class GlobalGenRoots():
 
         # Add include guards.
         curr = CGIncludeGuard('RegisterWorkerBindings', curr)
 
         # Done.
         return curr
 
     @staticmethod
+    def ResolveSystemBinding(config):
+
+        curr = CGResolveSystemBinding(config)
+
+        # Wrap all of that in our namespaces.
+        curr = CGNamespace.build(['mozilla', 'dom'],
+                                 CGWrapper(curr, post='\n'))
+        curr = CGWrapper(curr, post='\n')
+
+        # Add the includes
+        defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
+                          for desc in config.getDescriptors(hasInterfaceObject=True,
+                                                            register=True,
+                                                            isExposedInSystemGlobals=True,
+                                                            skipGen=False)]
+        defineIncludes.append("nsThreadUtils.h") # For NS_IsMainThread
+        defineIncludes.append("js/Id.h") # For jsid
+        defineIncludes.append("mozilla/dom/BindingUtils.h") # InternJSString
+
+        curr = CGHeaders([], [], [], [], [], defineIncludes,
+                         'ResolveSystemBinding', curr)
+
+        # Add include guards.
+        curr = CGIncludeGuard('ResolveSystemBinding', curr)
+
+        # Done.
+        return curr
+
+    @staticmethod
     def UnionTypes(config):
 
         (includes, implincludes,
          declarations, unions) = UnionTypes(config.getDescriptors(),
                                             config.getDictionaries(),
                                             config.getCallbacks(),
                                             config)
         includes.add("mozilla/dom/OwningNonNull.h")
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -155,16 +155,19 @@ class Configuration:
                 getter = lambda x: x.interface.isExternal()
             elif key == 'isJSImplemented':
                 getter = lambda x: x.interface.isJSImplemented()
             elif key == 'isNavigatorProperty':
                 getter = lambda x: x.interface.getNavigatorProperty() != None
             elif key == 'isExposedInAnyWorker':
                 getter = lambda x: (not x.interface.isExternal() and
                                     x.interface.isExposedInAnyWorker())
+            elif key == 'isExposedInSystemGlobals':
+                getter = lambda x: (not x.interface.isExternal() and
+                                    x.interface.isExposedInSystemGlobals())
             else:
                 # Have to watch out: just closing over "key" is not enough,
                 # since we're about to mutate its value
                 getter = (lambda attrName: lambda x: getattr(x, attrName))(key)
             tofilter.append((getter, val))
         for f in tofilter:
             curr = filter(lambda x: f[0](x) == f[1], curr)
         return curr
--- a/dom/bindings/mozwebidlcodegen/__init__.py
+++ b/dom/bindings/mozwebidlcodegen/__init__.py
@@ -127,24 +127,26 @@ class WebIDLCodegenManager(LoggingMixin)
 
     # Global parser derived declaration files.
     GLOBAL_DECLARE_FILES = {
         'FeatureList.h',
         'GeneratedAtomList.h',
         'PrototypeList.h',
         'RegisterBindings.h',
         'RegisterWorkerBindings.h',
+        'ResolveSystemBinding.h',
         'UnionConversions.h',
         'UnionTypes.h',
     }
 
     # Global parser derived definition files.
     GLOBAL_DEFINE_FILES = {
         'RegisterBindings.cpp',
         'RegisterWorkerBindings.cpp',
+        'ResolveSystemBinding.cpp',
         'UnionTypes.cpp',
         'PrototypeList.cpp',
     }
 
     def __init__(self, config_path, inputs, exported_header_dir,
         codegen_dir, state_path, cache_dir=None, make_deps_path=None,
         make_deps_target=None):
         """Create an instance that manages WebIDLs in the build system.
--- a/js/xpconnect/src/XPCRuntimeService.cpp
+++ b/js/xpconnect/src/XPCRuntimeService.cpp
@@ -6,18 +6,20 @@
 
 #include "nsContentUtils.h"
 #include "BackstagePass.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsDOMClassInfo.h"
 #include "nsIPrincipal.h"
 
 #include "mozilla/dom/workers/Workers.h"
+#include "mozilla/dom/ResolveSystemBinding.h"
 
 using mozilla::dom::workers::ResolveWorkerClasses;
+using mozilla::dom::ResolveSystemBinding;
 
 NS_INTERFACE_MAP_BEGIN(BackstagePass)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable)
@@ -69,32 +71,43 @@ BackstagePass::NewResolve(nsIXPConnectWr
     *_retval = ResolveWorkerClasses(cx, obj, id, &objp);
     NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
 
     if (objp) {
         *objpArg = objp;
         return NS_OK;
     }
 
+    *_retval = ResolveSystemBinding(cx, obj, id, &objp);
+    NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
+
+    if (objp) {
+        *objpArg = objp;
+        return NS_OK;
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 BackstagePass::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *objArg, bool *_retval)
 {
     JS::RootedObject obj(cx, objArg);
 
     *_retval = JS_EnumerateStandardClasses(cx, obj);
     NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
 
     JS::RootedObject ignored(cx);
     *_retval = ResolveWorkerClasses(cx, obj, JSID_VOIDHANDLE, &ignored);
     NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
 
+    *_retval = ResolveSystemBinding(cx, obj, JSID_VOIDHANDLE, &ignored);
+    NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
+
     return NS_OK;
 }
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 BackstagePass::GetInterfaces(uint32_t *aCount, nsIID * **aArray)