Bug 1029933 - Give BackstagePass an Enumerate hook to match its NewResolve hook. r=Waldo
authorBobby Holley <bobbyholley@gmail.com>
Fri, 04 Jul 2014 12:41:27 -0700
changeset 213255 4ec31a870cb0b33cc247dc50c5b8cffe8b474d5b
parent 213254 dba3ded2ebc026d70419c0a7556da4bf91d62026
child 213256 650197ade3b341e9f5f2a61d4684a500c9f17ee6
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1029933
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 1029933 - Give BackstagePass an Enumerate hook to match its NewResolve hook. r=Waldo This is required in order to avoid exposing resolve hook effects when Object.freeze() is invoked on the global. The freeze() call first enumerates the object, after which point any lazy properties need to be resolve so that we can safely mark the object as non-extensible.
dom/workers/RuntimeService.cpp
dom/workers/Workers.h
js/xpconnect/src/XPCRuntimeService.cpp
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1072,22 +1072,24 @@ ResolveWorkerClasses(JSContext* aCx, JS:
           gStringIDs[--i] = JSID_VOID;
         }
         return false;
       }
       gStringIDs[i] = INTERNED_STRING_TO_JSID(aCx, str);
     }
   }
 
-  bool shouldResolve = false;
-
-  for (uint32_t i = 0; i < ID_COUNT; i++) {
-    if (gStringIDs[i] == aId) {
-      shouldResolve = true;
-      break;
+  // Invoking this function with JSID_VOID means "always resolve".
+  bool shouldResolve = JSID_IS_VOID(aId);
+  if (!shouldResolve) {
+    for (uint32_t i = 0; i < ID_COUNT; i++) {
+      if (gStringIDs[i] == aId) {
+        shouldResolve = true;
+        break;
+      }
     }
   }
 
   if (!shouldResolve) {
     aObjp.set(nullptr);
     return true;
   }
 
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -165,16 +165,19 @@ struct JSSettings
 
 enum WorkerPreference
 {
   WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
   WORKERPREF_COUNT
 };
 
 // All of these are implemented in RuntimeService.cpp
+
+// Resolves all of the worker classes onto |aObjp| if one of them matches |aId|
+// or if |aId| is JSID_VOID.
 bool
 ResolveWorkerClasses(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
                      JS::MutableHandle<JSObject*> aObjp);
 
 void
 CancelWorkersForWindow(nsPIDOMWindow* aWindow);
 
 void
--- a/js/xpconnect/src/XPCRuntimeService.cpp
+++ b/js/xpconnect/src/XPCRuntimeService.cpp
@@ -25,16 +25,17 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(BackstagePass)
 NS_IMPL_RELEASE(BackstagePass)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           BackstagePass
 #define XPC_MAP_QUOTED_CLASSNAME   "BackstagePass"
 #define                             XPC_MAP_WANT_NEWRESOLVE
+#define                             XPC_MAP_WANT_ENUMERATE
 #define                             XPC_MAP_WANT_FINALIZE
 #define                             XPC_MAP_WANT_PRECREATE
 
 #define XPC_MAP_FLAGS       nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY   |  \
                             nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY   |  \
                             nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY   |  \
                             nsIXPCScriptable::DONT_ENUM_STATIC_PROPS       |  \
                             nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE    |  \
@@ -71,16 +72,32 @@ BackstagePass::NewResolve(nsIXPConnectWr
     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);
+
+    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)
 {
     const uint32_t count = 2;
     *aCount = count;