Backout 3044539fec87 (bug 799465),2dbcd6d16b43 (bug 798264), f7019f73a5f0 (bug 711628), a484a3a904da, 7154061ddc00 & 7e7fc42021c1 (bug 799465) for burning
authorEd Morley <emorley@mozilla.com>
Fri, 12 Oct 2012 14:45:38 +0100
changeset 110218 5540b310d435b0616b878b5a279f9ae65c2baa3f
parent 110217 31bebe4cdeede3e717a021aef7c0007389bec00f
child 110219 b2d8835eb55ffb81f1ce00ccd0061e97d3c61bd5
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
bugs799465, 798264, 711628
milestone19.0a1
backs out3044539fec87be189addde74159b93293c6301cb
Backout 3044539fec87 (bug 799465),2dbcd6d16b43 (bug 798264), f7019f73a5f0 (bug 711628), a484a3a904da, 7154061ddc00 & 7e7fc42021c1 (bug 799465) for burning
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/media/webaudio/AudioBuffer.cpp
content/media/webaudio/AudioContext.cpp
content/media/webaudio/AudioContext.h
content/media/webaudio/AudioNode.cpp
dom/base/nsWrapperCache.h
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/DOMJSClass.h
dom/bindings/Makefile.in
dom/media/PeerConnection.js
dom/media/bridge/IPeerConnection.idl
dom/webidl/MediaStreamList.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/nsXPConnect.cpp
media/webrtc/signaling/signaling.gyp
media/webrtc/signaling/src/peerconnection/MediaStreamList.cpp
media/webrtc/signaling/src/peerconnection/MediaStreamList.h
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1290,48 +1290,39 @@ public:
    * @param aScriptObjectHolder the object that holds JS objects that we want to
    *                            drop
    */
   static nsresult DropJSObjects(void* aScriptObjectHolder);
 
 #ifdef DEBUG
   static bool AreJSObjectsHeld(void* aScriptObjectHolder); 
 
-  static void CheckCCWrapperTraversal(void* aScriptObjectHolder,
-                                      nsWrapperCache* aCache,
-                                      nsScriptObjectTracer* aTracer);
+  static void CheckCCWrapperTraversal(nsISupports* aScriptObjectHolder,
+                                      nsWrapperCache* aCache);
 #endif
 
   static void PreserveWrapper(nsISupports* aScriptObjectHolder,
                               nsWrapperCache* aCache)
   {
     if (!aCache->PreservingWrapper()) {
       nsISupports *ccISupports;
       aScriptObjectHolder->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
                                           reinterpret_cast<void**>(&ccISupports));
       MOZ_ASSERT(ccISupports);
       nsXPCOMCycleCollectionParticipant* participant;
       CallQueryInterface(ccISupports, &participant);
-      PreserveWrapper(ccISupports, aCache, participant);
-    }
-  }
-  static void PreserveWrapper(void* aScriptObjectHolder,
-                              nsWrapperCache* aCache,
-                              nsScriptObjectTracer* aTracer)
-  {
-    if (!aCache->PreservingWrapper()) {
-      HoldJSObjects(aScriptObjectHolder, aTracer);
+      HoldJSObjects(ccISupports, participant);
       aCache->SetPreservingWrapper(true);
 #ifdef DEBUG
       // Make sure the cycle collector will be able to traverse to the wrapper.
-      CheckCCWrapperTraversal(aScriptObjectHolder, aCache, aTracer);
+      CheckCCWrapperTraversal(ccISupports, aCache);
 #endif
     }
   }
-  static void ReleaseWrapper(void* aScriptObjectHolder,
+  static void ReleaseWrapper(nsISupports* aScriptObjectHolder,
                              nsWrapperCache* aCache);
   static void TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback,
                            void *aClosure);
 
   /*
    * Notify when the first XUL menu is opened and when the all XUL menus are
    * closed. At opening, aInstalling should be TRUE, otherwise, it should be
    * FALSE.
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6389,34 +6389,36 @@ DebugWrapperTraceCallback(void *p, const
 {
   DebugWrapperTraversalCallback* callback =
     static_cast<DebugWrapperTraversalCallback*>(closure);
   callback->NoteJSChild(p);
 }
 
 // static
 void
-nsContentUtils::CheckCCWrapperTraversal(void* aScriptObjectHolder,
-                                        nsWrapperCache* aCache,
-                                        nsScriptObjectTracer* aTracer)
+nsContentUtils::CheckCCWrapperTraversal(nsISupports* aScriptObjectHolder,
+                                        nsWrapperCache* aCache)
 {
   JSObject* wrapper = aCache->GetWrapper();
   if (!wrapper) {
     return;
   }
 
+  nsXPCOMCycleCollectionParticipant* participant;
+  CallQueryInterface(aScriptObjectHolder, &participant);
+
   DebugWrapperTraversalCallback callback(wrapper);
 
-  aTracer->Traverse(aScriptObjectHolder, callback);
+  participant->Traverse(aScriptObjectHolder, callback);
   NS_ASSERTION(callback.mFound,
                "Cycle collection participant didn't traverse to preserved "
                "wrapper! This will probably crash.");
 
   callback.mFound = false;
-  aTracer->Trace(aScriptObjectHolder, DebugWrapperTraceCallback, &callback);
+  participant->Trace(aScriptObjectHolder, DebugWrapperTraceCallback, &callback);
   NS_ASSERTION(callback.mFound,
                "Cycle collection participant didn't trace preserved wrapper! "
                "This will probably crash.");
 }
 #endif
 
 // static
 bool
@@ -6925,17 +6927,17 @@ nsContentUtils::GetRootDocument(nsIDocum
   while (doc->GetParentDocument()) {
     doc = doc->GetParentDocument();
   }
   return doc;
 }
 
 // static
 void
-nsContentUtils::ReleaseWrapper(void* aScriptObjectHolder,
+nsContentUtils::ReleaseWrapper(nsISupports* aScriptObjectHolder,
                                nsWrapperCache* aCache)
 {
   if (aCache->PreservingWrapper()) {
     // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
     // can also be in the DOM expando hash, so we need to try to remove them
     // from both here.
     JSObject* obj = aCache->GetWrapperPreserveColor();
     if (aCache->IsDOMBinding() && obj) {
--- a/content/media/webaudio/AudioBuffer.cpp
+++ b/content/media/webaudio/AudioBuffer.cpp
@@ -19,17 +19,17 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBuff
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBuffer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChannels)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   NS_DROP_JS_OBJECTS(tmp, AudioBuffer);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioBuffer)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mContext, AudioContext)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(AudioBuffer)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   for (uint32_t i = 0; i < tmp->mChannels.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mChannels[i])
   }
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -11,32 +11,23 @@
 #include "mozilla/dom/AudioContextBinding.h"
 #include "AudioDestinationNode.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioBuffer.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(AudioContext)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(AudioContext)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDestination)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER_NATIVE
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(AudioContext)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDestination)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(AudioContext)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioContext, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioContext, Release)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(AudioContext, mWindow, mDestination)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioContext)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioContext)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioContext)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
 
 AudioContext::AudioContext(nsIDOMWindow* aWindow)
   : mWindow(aWindow)
   , mDestination(new AudioDestinationNode(this))
 {
   SetIsDOMBinding();
 }
 
--- a/content/media/webaudio/AudioContext.h
+++ b/content/media/webaudio/AudioContext.h
@@ -21,26 +21,27 @@ namespace mozilla {
 class ErrorResult;
 
 namespace dom {
 
 class AudioDestinationNode;
 class AudioBufferSourceNode;
 class AudioBuffer;
 
-class AudioContext MOZ_FINAL : public nsWrapperCache,
+class AudioContext MOZ_FINAL : public nsISupports,
+                               public nsWrapperCache,
                                public EnableWebAudioCheck
 {
   explicit AudioContext(nsIDOMWindow* aParentWindow);
 
 public:
   virtual ~AudioContext();
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioContext)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioContext)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AudioContext)
 
   nsIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
                                bool* aTriedToWrap);
--- a/content/media/webaudio/AudioNode.cpp
+++ b/content/media/webaudio/AudioNode.cpp
@@ -30,17 +30,17 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(AudioNode
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mInputs)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mOutputs)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioNode)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mContext, AudioContext)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
   TraverseElements(cb, tmp->mInputs, "mInputs[i]");
   TraverseElements(cb, tmp->mOutputs, "mOutputs[i]");
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioNode)
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -221,19 +221,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperC
 // Cycle collector macros for wrapper caches.
 
 #define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
   nsContentUtils::TraceWrapper(tmp, aCallback, aClosure);
 
 #define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
   nsContentUtils::ReleaseWrapper(s, tmp);
 
-#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER_NATIVE \
-  nsContentUtils::ReleaseWrapper(tmp, tmp);
-
 #define NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) \
   NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)              \
     NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER        \
   NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(_class) \
   NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                \
   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)         \
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdarg.h>
 
 #include "BindingUtils.h"
 
-#include "AccessCheck.h"
 #include "WrapperFactory.h"
 #include "xpcprivate.h"
 #include "XPCQuickStubs.h"
 #include "nsIXPConnect.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -136,18 +135,18 @@ InterfaceObjectToString(JSContext* cx, u
 
   return xpc::NonVoidStringToJsval(cx, str, vp);
 }
 
 static JSObject*
 CreateInterfaceObject(JSContext* cx, JSObject* global, JSObject* receiver,
                       JSClass* constructorClass, JSNative constructorNative,
                       unsigned ctorNargs, JSObject* proto,
-                      const NativeProperties* properties,
-                      const NativeProperties* chromeOnlyProperties,
+                      Prefable<JSFunctionSpec>* staticMethods,
+                      Prefable<ConstantSpec>* constants,
                       const char* name)
 {
   JSObject* constructor;
   if (constructorClass) {
     JSObject* functionProto = JS_GetFunctionPrototype(cx, global);
     if (!functionProto) {
       return NULL;
     }
@@ -160,16 +159,20 @@ CreateInterfaceObject(JSContext* cx, JSO
       return NULL;
     }
     constructor = JS_GetFunctionObject(fun);
   }
   if (!constructor) {
     return NULL;
   }
 
+  if (staticMethods && !DefinePrefable(cx, constructor, staticMethods)) {
+    return NULL;
+  }
+
   if (constructorClass) {
     JSFunction* toString = js::DefineFunctionWithReserved(cx, constructor,
                                                           "toString",
                                                           InterfaceObjectToString,
                                                           0, 0);
     if (!toString) {
       return NULL;
     }
@@ -181,38 +184,18 @@ CreateInterfaceObject(JSContext* cx, JSO
     JSString *str = ::JS_InternString(cx, name);
     if (!str) {
       return NULL;
     }
     js::SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
                                   STRING_TO_JSVAL(str));
   }
 
-  if (properties) {
-    if (properties->staticMethods &&
-        !DefinePrefable(cx, constructor, properties->staticMethods)) {
-      return nullptr;
-    }
-
-    if (properties->constants &&
-        !DefinePrefable(cx, constructor, properties->constants)) {
-      return nullptr;
-    }
-  }
-
-  if (chromeOnlyProperties) {
-    if (chromeOnlyProperties->staticMethods &&
-        !DefinePrefable(cx, constructor, chromeOnlyProperties->staticMethods)) {
-      return nullptr;
-    }
-
-    if (chromeOnlyProperties->constants &&
-        !DefinePrefable(cx, constructor, chromeOnlyProperties->constants)) {
-      return nullptr;
-    }
+  if (constants && !DefinePrefable(cx, constructor, constants)) {
+    return NULL;
   }
 
   if (proto && !JS_LinkConstructorAndPrototype(cx, constructor, proto)) {
     return NULL;
   }
 
   JSBool alreadyDefined;
   if (!JS_AlreadyHasOwnProperty(cx, receiver, name, &alreadyDefined)) {
@@ -227,107 +210,81 @@ CreateInterfaceObject(JSContext* cx, JSO
   }
 
   return constructor;
 }
 
 static JSObject*
 CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
                                JSObject* parentProto, JSClass* protoClass,
-                               const NativeProperties* properties,
-                               const NativeProperties* chromeOnlyProperties)
+                               Prefable<JSFunctionSpec>* methods,
+                               Prefable<JSPropertySpec>* properties,
+                               Prefable<ConstantSpec>* constants)
 {
   JSObject* ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto,
                                                   global);
   if (!ourProto) {
     return NULL;
   }
 
-  if (properties) {
-    if (properties->methods &&
-        !DefinePrefable(cx, ourProto, properties->methods)) {
-      return nullptr;
-    }
-
-    if (properties->attributes &&
-        !DefinePrefable(cx, ourProto, properties->attributes)) {
-      return nullptr;
-    }
-
-    if (properties->constants &&
-        !DefinePrefable(cx, ourProto, properties->constants)) {
-      return nullptr;
-    }
+  if (methods && !DefinePrefable(cx, ourProto, methods)) {
+    return NULL;
   }
 
-  if (chromeOnlyProperties) {
-    if (chromeOnlyProperties->methods &&
-        !DefinePrefable(cx, ourProto, chromeOnlyProperties->methods)) {
-      return nullptr;
-    }
+  if (properties && !DefinePrefable(cx, ourProto, properties)) {
+    return NULL;
+  }
 
-    if (chromeOnlyProperties->attributes &&
-        !DefinePrefable(cx, ourProto, chromeOnlyProperties->attributes)) {
-      return nullptr;
-    }
-
-    if (chromeOnlyProperties->constants &&
-        !DefinePrefable(cx, ourProto, chromeOnlyProperties->constants)) {
-      return nullptr;
-    }
+  if (constants && !DefinePrefable(cx, ourProto, constants)) {
+    return NULL;
   }
 
   return ourProto;
 }
 
 JSObject*
 CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
                        JSObject* protoProto, JSClass* protoClass,
                        JSClass* constructorClass, JSNative constructor,
                        unsigned ctorNargs, const DOMClass* domClass,
-                       const NativeProperties* properties,
-                       const NativeProperties* chromeOnlyProperties,
-                       const char* name)
+                       Prefable<JSFunctionSpec>* methods,
+                       Prefable<JSPropertySpec>* properties,
+                       Prefable<ConstantSpec>* constants,
+                       Prefable<JSFunctionSpec>* staticMethods, const char* name)
 {
   MOZ_ASSERT(protoClass || constructorClass || constructor,
              "Need at least one class or a constructor!");
-  MOZ_ASSERT(!((properties &&
-                (properties->methods || properties->attributes)) ||
-               (chromeOnlyProperties &&
-                (chromeOnlyProperties->methods ||
-                 chromeOnlyProperties->attributes))) || protoClass,
+  MOZ_ASSERT(!(methods || properties) || protoClass,
              "Methods or properties but no protoClass!");
-  MOZ_ASSERT(!((properties && properties->staticMethods) ||
-               (chromeOnlyProperties && chromeOnlyProperties->staticMethods)) ||
-             constructorClass || constructor,
+  MOZ_ASSERT(!staticMethods || constructorClass || constructor,
              "Static methods but no constructorClass or constructor!");
   MOZ_ASSERT(bool(name) == bool(constructorClass || constructor),
              "Must have name precisely when we have an interface object");
   MOZ_ASSERT(!constructorClass || !constructor);
 
   JSObject* proto;
   if (protoClass) {
     proto = CreateInterfacePrototypeObject(cx, global, protoProto, protoClass,
-                                           properties, chromeOnlyProperties);
+                                           methods, properties, constants);
     if (!proto) {
       return NULL;
     }
 
     js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
                         JS::PrivateValue(const_cast<DOMClass*>(domClass)));
   }
   else {
     proto = NULL;
   }
 
   JSObject* interface;
   if (constructorClass || constructor) {
     interface = CreateInterfaceObject(cx, global, receiver, constructorClass,
                                       constructor, ctorNargs, proto,
-                                      properties, chromeOnlyProperties, name);
+                                      staticMethods, constants, name);
     if (!interface) {
       return NULL;
     }
   }
 
   return protoClass ? proto : interface;
 }
 
@@ -458,217 +415,185 @@ QueryInterface(JSContext* cx, unsigned a
 }
 
 JSBool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
 }
 
-static bool
+bool
 XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
                     JSPropertyDescriptor* desc,
-                    const NativeProperties* nativeProperties)
+                    // And the things we need to determine the descriptor
+                    Prefable<JSFunctionSpec>* methods,
+                    jsid* methodIds,
+                    JSFunctionSpec* methodSpecs,
+                    size_t methodCount,
+                    Prefable<JSPropertySpec>* attributes,
+                    jsid* attributeIds,
+                    JSPropertySpec* attributeSpecs,
+                    size_t attributeCount,
+                    Prefable<ConstantSpec>* constants,
+                    jsid* constantIds,
+                    ConstantSpec* constantSpecs,
+                    size_t constantCount)
 {
-  if (nativeProperties->methods) {
-    Prefable<JSFunctionSpec>* method;
-    for (method = nativeProperties->methods; method->specs; ++method) {
-      if (method->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = method->specs - nativeProperties->methodsSpecs;
-        for ( ; nativeProperties->methodIds[i] != JSID_VOID; ++i) {
-          if (id == nativeProperties->methodIds[i]) {
-            JSFunctionSpec& methodSpec = nativeProperties->methodsSpecs[i];
-            JSFunction *fun = JS_NewFunctionById(cx, methodSpec.call.op,
-                                                 methodSpec.nargs, 0,
-                                                 wrapper, id);
-            if (!fun) {
-              return false;
-            }
-            SET_JITINFO(fun, methodSpec.call.info);
-            JSObject *funobj = JS_GetFunctionObject(fun);
-            desc->value.setObject(*funobj);
-            desc->attrs = methodSpec.flags;
-            desc->obj = wrapper;
-            desc->setter = nullptr;
-            desc->getter = nullptr;
-           return true;
+  for (size_t prefIdx = 0; prefIdx < methodCount; ++prefIdx) {
+    MOZ_ASSERT(methods[prefIdx].specs);
+    if (methods[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = methods[prefIdx].specs - methodSpecs;
+      for ( ; methodIds[i] != JSID_VOID; ++i) {
+        if (id == methodIds[i]) {
+          JSFunction *fun = JS_NewFunctionById(cx, methodSpecs[i].call.op,
+                                               methodSpecs[i].nargs, 0,
+                                               wrapper, id);
+          if (!fun) {
+            return false;
           }
+          SET_JITINFO(fun, methodSpecs[i].call.info);
+          JSObject *funobj = JS_GetFunctionObject(fun);
+          desc->value.setObject(*funobj);
+          desc->attrs = methodSpecs[i].flags;
+          desc->obj = wrapper;
+          desc->setter = nullptr;
+          desc->getter = nullptr;
+          return true;
         }
       }
     }
   }
 
-  if (nativeProperties->attributes) {
-    Prefable<JSPropertySpec>* attr;
-    for (attr = nativeProperties->attributes; attr->specs; ++attr) {
-      if (attr->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = attr->specs - nativeProperties->attributeSpecs;
-        for ( ; nativeProperties->attributeIds[i] != JSID_VOID; ++i) {
-          if (id == nativeProperties->attributeIds[i]) {
-            JSPropertySpec& attrSpec = nativeProperties->attributeSpecs[i];
-            // Because of centralization, we need to make sure we fault in the
-            // JitInfos as well. At present, until the JSAPI changes, the easiest
-            // way to do this is wrap them up as functions ourselves.
-            desc->attrs = attrSpec.flags & ~JSPROP_NATIVE_ACCESSORS;
-            // They all have getters, so we can just make it.
-            JSObject *global = JS_GetGlobalForObject(cx, wrapper);
-            JSFunction *fun = JS_NewFunction(cx, (JSNative)attrSpec.getter.op,
-                                             0, 0, global, nullptr);
+  for (size_t prefIdx = 0; prefIdx < attributeCount; ++prefIdx) {
+    MOZ_ASSERT(attributes[prefIdx].specs);
+    if (attributes[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = attributes[prefIdx].specs - attributeSpecs;
+      for ( ; attributeIds[i] != JSID_VOID; ++i) {
+        if (id == attributeIds[i]) {
+          // Because of centralization, we need to make sure we fault in the
+          // JitInfos as well. At present, until the JSAPI changes, the easiest
+          // way to do this is wrap them up as functions ourselves.
+          desc->attrs = attributeSpecs[i].flags & ~JSPROP_NATIVE_ACCESSORS;
+          // They all have getters, so we can just make it.
+          JSObject *global = JS_GetGlobalForObject(cx, wrapper);
+          JSFunction *fun = JS_NewFunction(cx, (JSNative)attributeSpecs[i].getter.op,
+                                           0, 0, global, NULL);
+          if (!fun)
+            return false;
+          SET_JITINFO(fun, attributeSpecs[i].getter.info);
+          JSObject *funobj = JS_GetFunctionObject(fun);
+          desc->getter = js::CastAsJSPropertyOp(funobj);
+          desc->attrs |= JSPROP_GETTER;
+          if (attributeSpecs[i].setter.op) {
+            // We have a setter! Make it.
+            fun = JS_NewFunction(cx, (JSNative)attributeSpecs[i].setter.op,
+                                 1, 0, global, NULL);
             if (!fun)
               return false;
-            SET_JITINFO(fun, attrSpec.getter.info);
-            JSObject *funobj = JS_GetFunctionObject(fun);
-            desc->getter = js::CastAsJSPropertyOp(funobj);
-            desc->attrs |= JSPROP_GETTER;
-            if (attrSpec.setter.op) {
-              // We have a setter! Make it.
-              fun = JS_NewFunction(cx, (JSNative)attrSpec.setter.op, 1, 0,
-                                   global, nullptr);
-              if (!fun)
-                return false;
-              SET_JITINFO(fun, attrSpec.setter.info);
-              funobj = JS_GetFunctionObject(fun);
-              desc->setter = js::CastAsJSStrictPropertyOp(funobj);
-              desc->attrs |= JSPROP_SETTER;
-            } else {
-              desc->setter = nullptr;
-            }
-            desc->obj = wrapper;
-            return true;
+            SET_JITINFO(fun, attributeSpecs[i].setter.info);
+            funobj = JS_GetFunctionObject(fun);
+            desc->setter = js::CastAsJSStrictPropertyOp(funobj);
+            desc->attrs |= JSPROP_SETTER;
+          } else {
+            desc->setter = NULL;
           }
+          desc->obj = wrapper;
+          return true;
         }
       }
     }
   }
 
-  if (nativeProperties->constants) {
-    Prefable<ConstantSpec>* constant;
-    for (constant = nativeProperties->constants; constant->specs; ++constant) {
-      if (constant->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = constant->specs - nativeProperties->constantSpecs;
-        for ( ; nativeProperties->constantIds[i] != JSID_VOID; ++i) {
-          if (id == nativeProperties->constantIds[i]) {
-            desc->attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
-            desc->obj = wrapper;
-            desc->value = nativeProperties->constantSpecs[i].value;
-            return true;
-          }
+  for (size_t prefIdx = 0; prefIdx < constantCount; ++prefIdx) {
+    MOZ_ASSERT(constants[prefIdx].specs);
+    if (constants[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = constants[prefIdx].specs - constantSpecs;
+      for ( ; constantIds[i] != JSID_VOID; ++i) {
+        if (id == constantIds[i]) {
+          desc->attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
+          desc->obj = wrapper;
+          desc->value = constantSpecs[i].value;
+          return true;
         }
       }
     }
   }
 
   return true;
 }
 
 bool
-XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
-                    JSPropertyDescriptor* desc,
-                    const NativeProperties* nativeProperties,
-                    const NativeProperties* chromeOnlyNativeProperties)
+XrayEnumerateProperties(JS::AutoIdVector& props,
+                        Prefable<JSFunctionSpec>* methods,
+                        jsid* methodIds,
+                        JSFunctionSpec* methodSpecs,
+                        size_t methodCount,
+                        Prefable<JSPropertySpec>* attributes,
+                        jsid* attributeIds,
+                        JSPropertySpec* attributeSpecs,
+                        size_t attributeCount,
+                        Prefable<ConstantSpec>* constants,
+                        jsid* constantIds,
+                        ConstantSpec* constantSpecs,
+                        size_t constantCount)
 {
-  if (nativeProperties &&
-      !XrayResolveProperty(cx, wrapper, id, desc, nativeProperties)) {
-    return false;
-  }
-
-  if (!desc->obj &&
-      chromeOnlyNativeProperties &&
-      xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrapper)) &&
-      !XrayResolveProperty(cx, wrapper, id, desc, chromeOnlyNativeProperties)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool
-XrayEnumerateProperties(JS::AutoIdVector& props,
-                        const NativeProperties* nativeProperties)
-{
-  if (nativeProperties->methods) {
-    Prefable<JSFunctionSpec>* method;
-    for (method = nativeProperties->methods; method->specs; ++method) {
-      if (method->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = method->specs - nativeProperties->methodsSpecs;
-        for ( ; nativeProperties->methodIds[i] != JSID_VOID; ++i) {
-          if ((nativeProperties->methodsSpecs[i].flags & JSPROP_ENUMERATE) &&
-              !props.append(nativeProperties->methodIds[i])) {
-            return false;
-          }
+  for (size_t prefIdx = 0; prefIdx < methodCount; ++prefIdx) {
+    MOZ_ASSERT(methods[prefIdx].specs);
+    if (methods[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = methods[prefIdx].specs - methodSpecs;
+      for ( ; methodIds[i] != JSID_VOID; ++i) {
+        if ((methodSpecs[i].flags & JSPROP_ENUMERATE) &&
+            !props.append(methodIds[i])) {
+          return false;
         }
       }
     }
   }
 
-  if (nativeProperties->attributes) {
-    Prefable<JSPropertySpec>* attr;
-    for (attr = nativeProperties->attributes; attr->specs; ++attr) {
-      if (attr->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = attr->specs - nativeProperties->attributeSpecs;
-        for ( ; nativeProperties->attributeIds[i] != JSID_VOID; ++i) {
-          if ((nativeProperties->attributeSpecs[i].flags & JSPROP_ENUMERATE) &&
-              !props.append(nativeProperties->attributeIds[i])) {
-            return false;
-          }
+  for (size_t prefIdx = 0; prefIdx < attributeCount; ++prefIdx) {
+    MOZ_ASSERT(attributes[prefIdx].specs);
+    if (attributes[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = attributes[prefIdx].specs - attributeSpecs;
+      for ( ; attributeIds[i] != JSID_VOID; ++i) {
+        if ((attributeSpecs[i].flags & JSPROP_ENUMERATE) &&
+            !props.append(attributeIds[i])) {
+          return false;
         }
       }
     }
   }
 
-  if (nativeProperties->constants) {
-    Prefable<ConstantSpec>* constant;
-    for (constant = nativeProperties->constants; constant->specs; ++constant) {
-      if (constant->enabled) {
-        // Set i to be the index into our full list of ids/specs that we're
-        // looking at now.
-        size_t i = constant->specs - nativeProperties->constantSpecs;
-        for ( ; nativeProperties->constantIds[i] != JSID_VOID; ++i) {
-          if (!props.append(nativeProperties->constantIds[i])) {
-            return false;
-          }
+  for (size_t prefIdx = 0; prefIdx < constantCount; ++prefIdx) {
+    MOZ_ASSERT(constants[prefIdx].specs);
+    if (constants[prefIdx].enabled) {
+      // Set i to be the index into our full list of ids/specs that we're
+      // looking at now.
+      size_t i = constants[prefIdx].specs - constantSpecs;
+      for ( ; constantIds[i] != JSID_VOID; ++i) {
+        if (!props.append(constantIds[i])) {
+          return false;
         }
       }
     }
   }
 
   return true;
 }
 
 bool
-XrayEnumerateProperties(JSObject* wrapper,
-                        JS::AutoIdVector& props,
-                        const NativeProperties* nativeProperties,
-                        const NativeProperties* chromeOnlyNativeProperties)
-{
-  if (nativeProperties &&
-      !XrayEnumerateProperties(props, nativeProperties)) {
-    return false;
-  }
-
-  if (chromeOnlyNativeProperties &&
-      xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrapper)) &&
-      !XrayEnumerateProperties(props, chromeOnlyNativeProperties)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool
 GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
                        JS::Value* vp)
 {
   JSObject* proto;
   if (!js::GetObjectProto(cx, proxy, &proto)) {
     return false;
   }
   if (!proto) {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -339,32 +339,16 @@ struct Prefable {
   // A boolean indicating whether this set of specs is enabled
   bool enabled;
   // Array of specs, terminated in whatever way is customary for T.
   // Null to indicate a end-of-array for Prefable, when such an
   // indicator is needed.
   T* specs;
 };
 
-struct NativeProperties
-{
-  Prefable<JSFunctionSpec>* staticMethods;
-  jsid* staticMethodIds;
-  JSFunctionSpec* staticMethodsSpecs;
-  Prefable<JSFunctionSpec>* methods;
-  jsid* methodIds;
-  JSFunctionSpec* methodsSpecs;
-  Prefable<JSPropertySpec>* attributes;
-  jsid* attributeIds;
-  JSPropertySpec* attributeSpecs;
-  Prefable<ConstantSpec>* constants;
-  jsid* constantIds;
-  ConstantSpec* constantSpecs;
-};
-
 /*
  * Create a DOM interface object (if constructorClass is non-null) and/or a
  * DOM interface prototype object (if protoClass is non-null).
  *
  * global is used as the parent of the interface object and the interface
  *        prototype object
  * receiver is the object on which we need to define the interface object as a
  *          property
@@ -376,41 +360,43 @@ struct NativeProperties
  *                  This is null if we should not create an interface object or
  *                  if it should be a function object.
  * constructor is the JSNative to use as a constructor.  If this is non-null, it
  *             should be used as a JSNative to back the interface object, which
  *             should be a Function.  If this is null, then we should create an
  *             object of constructorClass, unless that's also null, in which
  *             case we should not create an interface object at all.
  * ctorNargs is the length of the constructor function; 0 if no constructor
- * domClass is the DOMClass of instance objects for this class.  This can be
- *          null if this is not a concrete proto.
- * properties contains the methods, attributes and constants to be defined on
- *            objects in any compartment.
- * chromeProperties contains the methods, attributes and constants to be defined
- *                  on objects in chrome compartments. This must be null if the
- *                  interface doesn't have any ChromeOnly properties or if the
- *                  object is being created in non-chrome compartment.
+ * instanceClass is the JSClass of instance objects for this class.  This can
+ *               be null if this is not a concrete proto.
+ * methods and properties are to be defined on the interface prototype object;
+ *                        these arguments are allowed to be null if there are no
+ *                        methods or properties respectively.
+ * constants are to be defined on the interface object and on the interface
+ *           prototype object; allowed to be null if there are no constants.
+ * staticMethods are to be defined on the interface object; allowed to be null
+ *               if there are no static methods.
  *
  * At least one of protoClass and constructorClass should be non-null.
  * If constructorClass is non-null, the resulting interface object will be
  * defined on the given global with property name |name|, which must also be
  * non-null.
  *
  * returns the interface prototype object if protoClass is non-null, else it
  * returns the interface object.
  */
 JSObject*
 CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* receiver,
                        JSObject* protoProto, JSClass* protoClass,
                        JSClass* constructorClass, JSNative constructor,
                        unsigned ctorNargs, const DOMClass* domClass,
-                       const NativeProperties* properties,
-                       const NativeProperties* chromeProperties,
-                       const char* name);
+                       Prefable<JSFunctionSpec>* methods,
+                       Prefable<JSPropertySpec>* properties,
+                       Prefable<ConstantSpec>* constants,
+                       Prefable<JSFunctionSpec>* staticMethods, const char* name);
 
 template <class T>
 inline bool
 WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
 {
   JSObject* obj = value->GetWrapper();
   if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) {
     *vp = JS::ObjectValue(*obj);
@@ -630,26 +616,26 @@ struct ParentObject {
 
 inline nsWrapperCache*
 GetWrapperCache(const ParentObject& aParentObject)
 {
   return aParentObject.mWrapperCache;
 }
 
 template<class T>
-inline T*
+inline nsISupports*
 GetParentPointer(T* aObject)
 {
-  return aObject;
+  return ToSupports(aObject);
 }
 
 inline nsISupports*
 GetParentPointer(const ParentObject& aObject)
 {
-  return aObject.mObject;
+  return ToSupports(aObject.mObject);
 }
 
 template<class T>
 inline void
 ClearWrapper(T* p, nsWrapperCache* cache)
 {
   cache->ClearWrapper();
 }
@@ -738,99 +724,42 @@ WrapObject<JSObject>(JSContext* cx, JSOb
   vp->setObjectOrNull(p);
   return true;
 }
 
 bool
 WrapCallbackInterface(JSContext *cx, JSObject *scope, nsISupports* callback,
                       JS::Value* vp);
 
-// This checks whether class T implements WrapObject itself, if so then
-// HasWrapObject<T>::Value will be true. Note that if T inherits WrapObject from
-// a base class but doesn't override it then HasWrapObject<T>::Value will be
-// false. This is a little annoying in some cases (multiple C++ classes using
-// the same binding), but it saves us in the case where a class inherits from
-// nsWrapperCache but doesn't actually override WrapObject. For now we assume
-// that HasWrapObject<T>::Value being false means we have an nsISupports object.
-template<typename T>
-struct HasWrapObject
-{
-private:
-  typedef char yes[1];
-  typedef char no[2];
-  typedef JSObject* (T::*WrapObject)(JSContext*, JSObject*, bool*);
-  template<typename U, U> struct SFINAE;
-  template <typename V> static yes& Check(SFINAE<WrapObject, &V::WrapObject>*);
-  template <typename V> static no& Check(...);
-
-public:
-  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);
-};
-
-template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
-struct WrapNativeParentHelper
-{
-  static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
-                               nsWrapperCache* cache)
-  {
-    MOZ_ASSERT(cache);
-
-    JSObject* obj;
-    if ((obj = cache->GetWrapper())) {
-      return obj;
-    }
-
-    bool triedToWrap;
-    return parent->WrapObject(cx, scope, &triedToWrap);
-  }
-};
-
-template<typename T>
-struct WrapNativeParentHelper<T, false>
-{
-  static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
-                               nsWrapperCache* cache)
-  {
-    JSObject* obj;
-    if (cache && (obj = cache->GetWrapper())) {
-#ifdef DEBUG
-      qsObjectHelper helper(ToSupports(parent), cache);
-      JS::Value debugVal;
-
-      bool ok = XPCOMObjectToJsval(cx, scope, helper, NULL, false, &debugVal);
-      NS_ASSERTION(ok && JSVAL_TO_OBJECT(debugVal) == obj,
-                   "Unexpected object in nsWrapperCache");
-#endif
-      return obj;
-    }
-
-    qsObjectHelper helper(ToSupports(parent), cache);
-    JS::Value v;
-    return XPCOMObjectToJsval(cx, scope, helper, NULL, false, &v) ?
-           JSVAL_TO_OBJECT(v) :
-           NULL;
-  }
-};
-
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JSObject* scope, T* p, nsWrapperCache* cache)
-{
-  if (!p) {
-    return scope;
-  }
-
-  return WrapNativeParentHelper<T>::Wrap(cx, scope, p, cache);
-}
-
 template<typename T>
 static inline JSObject*
 WrapNativeParent(JSContext* cx, JSObject* scope, const T& p)
 {
-  return WrapNativeParent(cx, scope, GetParentPointer(p), GetWrapperCache(p));
+  if (!GetParentPointer(p))
+    return scope;
+
+  nsWrapperCache* cache = GetWrapperCache(p);
+  JSObject* obj;
+  if (cache && (obj = cache->GetWrapper())) {
+#ifdef DEBUG
+    qsObjectHelper helper(GetParentPointer(p), cache);
+    JS::Value debugVal;
+
+    bool ok = XPCOMObjectToJsval(cx, scope, helper, NULL, false, &debugVal);
+    NS_ASSERTION(ok && JSVAL_TO_OBJECT(debugVal) == obj,
+                 "Unexpected object in nsWrapperCache");
+#endif
+    return obj;
+  }
+
+  qsObjectHelper helper(GetParentPointer(p), cache);
+  JS::Value v;
+  return XPCOMObjectToJsval(cx, scope, helper, NULL, false, &v) ?
+         JSVAL_TO_OBJECT(v) :
+         NULL;
 }
 
 static inline bool
 InternJSString(JSContext* cx, jsid& id, const char* chars)
 {
   if (JSString *str = ::JS_InternString(cx, chars)) {
     id = INTERNED_STRING_TO_JSID(cx, str);
     return true;
@@ -1187,24 +1116,44 @@ public:
       storage.addr()->~T();
     }
 };
 
 // Implementation of the bits that XrayWrapper needs
 bool
 XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
                     JSPropertyDescriptor* desc,
-                    const NativeProperties* nativeProperties,
-                    const NativeProperties* chromeOnlyNativeProperties);
+                    // And the things we need to determine the descriptor
+                    Prefable<JSFunctionSpec>* methods,
+                    jsid* methodIds,
+                    JSFunctionSpec* methodSpecs,
+                    size_t methodCount,
+                    Prefable<JSPropertySpec>* attributes,
+                    jsid* attributeIds,
+                    JSPropertySpec* attributeSpecs,
+                    size_t attributeCount,
+                    Prefable<ConstantSpec>* constants,
+                    jsid* constantIds,
+                    ConstantSpec* constantSpecs,
+                    size_t constantCount);
 
 bool
-XrayEnumerateProperties(JSObject* wrapper,
-                        JS::AutoIdVector& props,
-                        const NativeProperties* nativeProperties,
-                        const NativeProperties* chromeOnlyNativeProperties);
+XrayEnumerateProperties(JS::AutoIdVector& props,
+                        Prefable<JSFunctionSpec>* methods,
+                        jsid* methodIds,
+                        JSFunctionSpec* methodSpecs,
+                        size_t methodCount,
+                        Prefable<JSPropertySpec>* attributes,
+                        jsid* attributeIds,
+                        JSPropertySpec* attributeSpecs,
+                        size_t attributeCount,
+                        Prefable<ConstantSpec>* constants,
+                        jsid* constantIds,
+                        ConstantSpec* constantSpecs,
+                        size_t constantCount);
 
 // Transfer reference in ptr to smartPtr.
 template<class T>
 inline void
 Take(nsRefPtr<T>& smartPtr, T* ptr)
 {
   smartPtr = dont_AddRef(ptr);
 }
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -84,17 +84,16 @@
 #   * resultNotAddRefed - attributes and methods specified in the .webidl file
 #                         that do not AddRef the return value
 
 DOMInterfaces = {
 
 'mozAudioContext': {
     'nativeType': 'AudioContext',
     'implicitJSContext': [ 'createBuffer' ],
-    'nativeOwnership': 'refcounted'
 },
 
 'AudioNode' : {
     'concrete': False,
 },
 
 'AudioSourceNode': {
     'concrete': False,
@@ -242,24 +241,16 @@ DOMInterfaces = {
 {
     'nativeType': 'nsIInputStream',
     'notflattened': True
 },
 {
     'workers': True,
 }],
 
-'MediaStreamList': {
-    'headerFile': 'MediaStreamList.h',
-    'wrapperCache': False,
-    'nativeOwnership': 'owned',
-    'resultNotAddRefed': [ '__indexedGetter' ],
-    'binaryNames': { '__indexedGetter': 'IndexedGetter' }
-},
-
 'MozChannel': [
 {
     'nativeType': 'nsIChannel',
     'notflattened': True
 },
 {
     'workers': True,
 }],
@@ -611,17 +602,16 @@ addExternalIface('CSSRule')
 addExternalIface('CSSValue')
 addExternalIface('DOMStringList', nativeType='nsDOMStringList',
                  headerFile='nsDOMLists.h')
 addExternalIface('Element', nativeType='nsGenericElement')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLElement')
 addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
-addExternalIface('MediaStream')
 addExternalIface('Node', nativeType='nsINode')
 addExternalIface('PaintRequest')
 addExternalIface('SVGLength')
 addExternalIface('SVGMatrix')
 addExternalIface('SVGNumber')
 addExternalIface('SVGPathSeg')
 addExternalIface('SVGPoint')
 addExternalIface('SVGTransform')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -88,26 +88,21 @@ def DOMClass(descriptor):
         protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
         # Pad out the list to the right length with _ID_Count so we
         # guarantee that all the lists are the same length.  _ID_Count
         # is never the ID of any prototype, so it's safe to use as
         # padding.
         protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
         prototypeChainString = ', '.join(protoList)
         nativeHooks = "NULL" if descriptor.workers else "&NativeHooks"
-        if descriptor.workers or descriptor.nativeOwnership != 'refcounted':
-            participant = "nullptr"
-        else:
-            participant = "NS_CYCLE_COLLECTION_PARTICIPANT(%s)" % descriptor.nativeType
         return """{
   { %s },
-  %s, %s, %s
+  %s, %s
 }""" % (prototypeChainString, toStringBool(descriptor.nativeOwnership == 'nsisupports'),
-        nativeHooks,
-        participant)
+          nativeHooks)
 
 class CGDOMJSClass(CGThing):
     """
     Generate a DOMJSClass for a given descriptor
     """
     def __init__(self, descriptor):
         CGThing.__init__(self)
         self.descriptor = descriptor
@@ -633,23 +628,22 @@ class CGAddPropertyHook(CGAbstractClassH
     """
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
                 Argument('JSHandleId', 'id'), Argument('JSMutableHandleValue', 'vp')]
         CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
                                      'JSBool', args)
 
     def generate_code(self):
-        assert not self.descriptor.workers and self.descriptor.wrapperCache
-        if self.descriptor.nativeOwnership == 'nsisupports':
-            preserveArgs = "reinterpret_cast<nsISupports*>(self), self"
-        else:
-            preserveArgs = "self, self, NS_CYCLE_COLLECTION_PARTICIPANT(%s)" % self.descriptor.nativeType
-        return """  nsContentUtils::PreserveWrapper(%s);
-  return true;""" % preserveArgs
+        # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=774279
+        # Using a real trace hook might enable us to deal with non-nsISupports
+        # wrappercached things here.
+        assert self.descriptor.nativeOwnership == 'nsisupports'
+        return """  nsContentUtils::PreserveWrapper(reinterpret_cast<nsISupports*>(self), self);
+  return true;"""
 
 def DeferredFinalizeSmartPtr(descriptor):
     if descriptor.nativeOwnership == 'owned':
         smartPtr = 'nsAutoPtr<%s>'
     else:
         assert descriptor.nativeOwnership == 'refcounted'
         smartPtr = 'nsRefPtr<%s>'
     return smartPtr % descriptor.nativeType
@@ -861,52 +855,55 @@ def isChromeOnly(m):
     return m.getExtendedAttribute("ChromeOnly")
 
 class PropertyDefiner:
     """
     A common superclass for defining things on prototype objects.
 
     Subclasses should implement generateArray to generate the actual arrays of
     things we're defining.  They should also set self.chrome to the list of
-    things only exposed to chrome and self.regular to the list of things exposed
-    to both chrome and web pages.
+    things exposed to chrome and self.regular to the list of things exposed to
+    web pages.  self.chrome must be a superset of self.regular but also include
+    all the ChromeOnly stuff.
     """
     def __init__(self, descriptor, name):
         self.descriptor = descriptor
         self.name = name
         # self.prefCacheData will store an array of (prefname, bool*)
         # pairs for our bool var caches.  generateArray will fill it
         # in as needed.
         self.prefCacheData = []
     def hasChromeOnly(self):
-        return len(self.chrome) > 0
+        return len(self.chrome) > len(self.regular)
     def hasNonChromeOnly(self):
         return len(self.regular) > 0
     def variableName(self, chrome):
-        if chrome:
-            if self.hasChromeOnly():
-                return "sChrome" + self.name
-        else:
-            if self.hasNonChromeOnly():
-                return "s" + self.name
-        return "nullptr"
-    def usedForXrays(self):
-        # We only need Xrays for methods, attributes and constants, but in
-        # workers there are no Xrays.
-        return (self.name is "Methods" or self.name is "Attributes" or
-                self.name is "Constants") and not self.descriptor.workers
+        if chrome and self.hasChromeOnly():
+            return "sChrome" + self.name
+        if self.hasNonChromeOnly():
+            return "s" + self.name
+        return "NULL"
+    def usedForXrays(self, chrome):
+        # We only need Xrays for methods, attributes and constants.  And we only
+        # need them for the non-chrome ones if we have no chromeonly things.
+        # Otherwise (we have chromeonly attributes) we need Xrays for the chrome
+        # methods/attributes/constants.  Finally, in workers there are no Xrays.
+        return ((self.name is "Methods" or self.name is "Attributes" or
+                 self.name is "Constants") and
+                chrome == self.hasChromeOnly() and
+                not self.descriptor.workers)
 
     def __str__(self):
         # We only need to generate id arrays for things that will end
         # up used via ResolveProperty or EnumerateProperties.
         str = self.generateArray(self.regular, self.variableName(False),
-                                 self.usedForXrays())
+                                 self.usedForXrays(False))
         if self.hasChromeOnly():
             str += self.generateArray(self.chrome, self.variableName(True),
-                                      self.usedForXrays())
+                                      self.usedForXrays(True))
         return str
 
     @staticmethod
     def getControllingPref(interfaceMember):
         prefName = interfaceMember.getExtendedAttribute("Pref")
         if prefName is None:
             return None
         # It's a list of strings
@@ -1010,25 +1007,31 @@ class MethodDefiner(PropertyDefiner):
         #       identifier. For now we check if the name starts with __
         methods = [m for m in descriptor.interface.members if
                    m.isMethod() and m.isStatic() == static and
                    not m.isIdentifierLess()]
         self.chrome = [{"name": m.identifier.name,
                         "length": methodLength(m),
                         "flags": "JSPROP_ENUMERATE",
                         "pref": PropertyDefiner.getControllingPref(m) }
-                       for m in methods if isChromeOnly(m)]
+                       for m in methods]
         self.regular = [{"name": m.identifier.name,
                          "length": methodLength(m),
                          "flags": "JSPROP_ENUMERATE",
                          "pref": PropertyDefiner.getControllingPref(m) }
                         for m in methods if not isChromeOnly(m)]
 
         # FIXME Check for an existing iterator on the interface first.
         if any(m.isGetter() and m.isIndexed() for m in methods):
+            self.chrome.append({"name": 'iterator',
+                                "methodInfo": False,
+                                "nativeName": "JS_ArrayIterator",
+                                "length": 0,
+                                "flags": "JSPROP_ENUMERATE",
+                                "pref": None })
             self.regular.append({"name": 'iterator',
                                  "methodInfo": False,
                                  "nativeName": "JS_ArrayIterator",
                                  "length": 0,
                                  "flags": "JSPROP_ENUMERATE",
                                  "pref": None })
 
         if not descriptor.interface.parent and not static and descriptor.nativeOwnership == 'nsisupports':
@@ -1069,19 +1072,18 @@ class MethodDefiner(PropertyDefiner):
             '  JS_FS_END',
             'JSFunctionSpec',
             pref, specData, doIdArrays)
 
 class AttrDefiner(PropertyDefiner):
     def __init__(self, descriptor, name):
         PropertyDefiner.__init__(self, descriptor, name)
         self.name = name
-        attributes = [m for m in descriptor.interface.members if m.isAttr()]
-        self.chrome = [m for m in attributes if isChromeOnly(m)]
-        self.regular = [m for m in attributes if not isChromeOnly(m)]
+        self.chrome = [m for m in descriptor.interface.members if m.isAttr()]
+        self.regular = [m for m in self.chrome if not isChromeOnly(m)]
 
     def generateArray(self, array, name, doIdArrays):
         if len(array) == 0:
             return ""
 
         def flags(attr):
             return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS"
 
@@ -1114,19 +1116,18 @@ class AttrDefiner(PropertyDefiner):
 
 class ConstDefiner(PropertyDefiner):
     """
     A class for definining constants on the interface object
     """
     def __init__(self, descriptor, name):
         PropertyDefiner.__init__(self, descriptor, name)
         self.name = name
-        constants = [m for m in descriptor.interface.members if m.isConst()]
-        self.chrome = [m for m in constants if isChromeOnly(m)]
-        self.regular = [m for m in constants if not isChromeOnly(m)]
+        self.chrome = [m for m in descriptor.interface.members if m.isConst()]
+        self.regular = [m for m in self.chrome if not isChromeOnly(m)]
 
     def generateArray(self, array, name, doIdArrays):
         if len(array) == 0:
             return ""
 
         def specData(const):
             return (const.identifier.name,
                     convertConstIDLValueToJSVal(const.value))
@@ -1149,59 +1150,29 @@ class PropertyArrays():
     def arrayNames():
         return [ "staticMethods", "methods", "attrs", "consts" ]
 
     @staticmethod
     def xrayRelevantArrayNames():
         return [ "methods", "attrs", "consts" ]
 
     def hasChromeOnly(self):
-        return any(getattr(self, a).hasChromeOnly() for a in self.arrayNames())
-    def hasNonChromeOnly(self):
-        return any(getattr(self, a).hasNonChromeOnly() for a in self.arrayNames())
+        return reduce(lambda b, a: b or getattr(self, a).hasChromeOnly(),
+                      self.arrayNames(), False)
+    def variableNames(self, chrome):
+        names = {}
+        for array in self.arrayNames():
+            names[array] = getattr(self, array).variableName(chrome)
+        return names
     def __str__(self):
         define = ""
         for array in self.arrayNames():
             define += str(getattr(self, array))
         return define
 
-class CGNativeProperties(CGList):
-    def __init__(self, descriptor, properties):
-        def generateNativeProperties(name, chrome):
-            def check(p):
-                return p.hasChromeOnly() if chrome else p.hasNonChromeOnly()
-
-            nativeProps = []
-            for array in properties.arrayNames():
-                propertyArray = getattr(properties, array)
-                if check(propertyArray):
-                    if descriptor.workers:
-                        props = "%(name)s, nullptr, %(name)s_specs"
-                    else:
-                        if propertyArray.usedForXrays():
-                            ids = "%(name)s_ids"
-                        else:
-                            ids = "nullptr"
-                        props = "%(name)s, " + ids + ", %(name)s_specs"
-                    props = (props %
-                             { 'name': propertyArray.variableName(chrome) })
-                else:
-                    props = "nullptr, nullptr, nullptr"
-                nativeProps.append(CGGeneric(props))
-            return CGWrapper(CGIndenter(CGList(nativeProps, ",\n")),
-                             pre="static const NativeProperties %s = {\n" % name,
-                             post="\n};")
-        
-        regular = generateNativeProperties("sNativeProperties", False)
-        chrome = generateNativeProperties("sChromeOnlyNativeProperties", True)
-        CGList.__init__(self, [regular, chrome], "\n\n")
-
-    def declare(self):
-        return ""
-
 class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
     """
     Generate the CreateInterfaceObjects method for an interface descriptor.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
@@ -1227,17 +1198,17 @@ class CGCreateInterfaceObjectsMethod(CGA
         # There is no need to init any IDs in workers, because worker bindings
         # don't have Xrays.
         if not self.descriptor.workers:
             for var in self.properties.xrayRelevantArrayNames():
                 props = getattr(self.properties, var)
                 # We only have non-chrome ids to init if we have no chrome ids.
                 if props.hasChromeOnly():
                     idsToInit.append(props.variableName(True))
-                if props.hasNonChromeOnly():
+                elif props.hasNonChromeOnly():
                     idsToInit.append(props.variableName(False))
         if len(idsToInit) > 0:
             initIds = CGList(
                 [CGGeneric("!InitIds(aCx, %s, %s_ids)" % (varname, varname)) for
                  varname in idsToInit], ' ||\n')
             if len(idsToInit) > 1:
                 initIds = CGWrapper(initIds, pre="(", post=")", reindent=True)
             initIds = CGList(
@@ -1288,44 +1259,42 @@ class CGCreateInterfaceObjectsMethod(CGA
         if self.descriptor.concrete:
             if self.descriptor.proxy:
                 domClass = "&Class"
             else:
                 domClass = "&Class.mClass"
         else:
             domClass = "nullptr"
 
-        if self.properties.hasNonChromeOnly():
-            properties = "&sNativeProperties"
-        else:
-            properties = "nullptr"
-        if self.properties.hasChromeOnly():
-            if self.descriptor.workers:
-                accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
-            else:
-                accessCheck = "xpc::AccessCheck::isChrome(aGlobal)"
-            chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
-        else:
-            chromeProperties = "nullptr"
         call = """return dom::CreateInterfaceObjects(aCx, aGlobal, aReceiver, parentProto,
                                    %s, %s, %s, %d,
                                    %s,
-                                   %s,
-                                   %s,
+                                   %%(methods)s, %%(attrs)s,
+                                   %%(consts)s, %%(staticMethods)s,
                                    %s);""" % (
             "&PrototypeClass" if needInterfacePrototypeObject else "NULL",
             "&InterfaceObjectClass" if needInterfaceObjectClass else "NULL",
             constructHook if needConstructor else "NULL",
             constructArgs,
             domClass,
-            properties,
-            chromeProperties,
             '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL")
+        if self.properties.hasChromeOnly():
+            if self.descriptor.workers:
+                accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
+            else:
+                accessCheck = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))"
+            chrome = CGIfWrapper(CGGeneric(call % self.properties.variableNames(True)),
+                                 accessCheck)
+            chrome = CGWrapper(chrome, pre="\n\n")
+        else:
+            chrome = None
+
         functionBody = CGList(
-            [CGGeneric(getParentProto), initIds, prefCache, CGGeneric(call)],
+            [CGGeneric(getParentProto), initIds, prefCache, chrome,
+             CGGeneric(call % self.properties.variableNames(False))],
             "\n\n")
         return CGIndenter(functionBody).define()
 
 class CGGetPerInterfaceObject(CGAbstractMethod):
     """
     A method for getting a per-interface object (a prototype object or interface
     constructor object).
     """
@@ -4561,30 +4530,46 @@ class CGEnumerateOwnProperties(CGAbstrac
 """
 
 class CGXrayHelper(CGAbstractMethod):
     def __init__(self, descriptor, name, args, properties):
         CGAbstractMethod.__init__(self, descriptor, name, "bool", args)
         self.properties = properties
 
     def definition_body(self):
-        prefixArgs = CGGeneric(self.getPrefixArgs())
-        if self.properties.hasNonChromeOnly():
-            regular = "&sNativeProperties"
+        varNames = self.properties.variableNames(True)
+
+        methods = self.properties.methods
+        if methods.hasNonChromeOnly() or methods.hasChromeOnly():
+            methodArgs = """// %(methods)s has an end-of-list marker at the end that we ignore
+%(methods)s, %(methods)s_ids, %(methods)s_specs, ArrayLength(%(methods)s) - 1""" % varNames
         else:
-            regular = "nullptr"
-        regular = CGGeneric(regular)
-        if self.properties.hasChromeOnly():
-            chrome = "&sChromeOnlyNativeProperties"
+            methodArgs = "NULL, NULL, NULL, 0"
+        methodArgs = CGGeneric(methodArgs)
+
+        attrs = self.properties.attrs
+        if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
+            attrArgs = """// %(attrs)s has an end-of-list marker at the end that we ignore
+%(attrs)s, %(attrs)s_ids, %(attrs)s_specs, ArrayLength(%(attrs)s) - 1""" % varNames
         else:
-            chrome = "nullptr"
-        chrome = CGGeneric(chrome)
+            attrArgs = "NULL, NULL, NULL, 0"
+        attrArgs = CGGeneric(attrArgs)
+
+        consts = self.properties.consts
+        if consts.hasNonChromeOnly() or consts.hasChromeOnly():
+            constArgs = """// %(consts)s has an end-of-list marker at the end that we ignore
+%(consts)s, %(consts)s_ids, %(consts)s_specs, ArrayLength(%(consts)s) - 1""" % varNames
+        else:
+            constArgs = "NULL, NULL, NULL, 0"
+        constArgs = CGGeneric(constArgs)
+
+        prefixArgs = CGGeneric(self.getPrefixArgs())
 
         return CGIndenter(
-            CGWrapper(CGList([prefixArgs, regular, chrome], ",\n"),
+            CGWrapper(CGList([prefixArgs, methodArgs, attrArgs, constArgs], ",\n"),
                       pre=("return Xray%s(" % self.name),
                       post=");",
                       reindent=True)).define()
 
 class CGResolveProperty(CGXrayHelper):
     def __init__(self, descriptor, properties):
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
                 Argument('jsid', 'id'), Argument('bool', 'set'),
@@ -4599,17 +4584,17 @@ class CGResolveProperty(CGXrayHelper):
 class CGEnumerateProperties(CGXrayHelper):
     def __init__(self, descriptor, properties):
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
                 Argument('JS::AutoIdVector&', 'props')]
         CGXrayHelper.__init__(self, descriptor, "EnumerateProperties", args,
                               properties)
 
     def getPrefixArgs(self):
-        return "wrapper, props"
+        return "props"
 
 class CGPrototypeTraitsClass(CGClass):
     def __init__(self, descriptor, indent=''):
         templateArgs = [Argument('prototypes::ID', 'PrototypeID')]
         templateSpecialization = ['prototypes::id::' + descriptor.name]
         enums = [ClassEnum('', ['Depth'],
                            [descriptor.interface.inheritanceDepth()])]
         typedefs = [ClassTypedef('NativeType', descriptor.nativeType)]
@@ -5252,17 +5237,16 @@ class CGDescriptor(CGThing):
             cgThings.append(CGClassHasInstanceHook(descriptor))
             cgThings.append(CGInterfaceObjectJSClass(descriptor))
 
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGPrototypeJSClass(descriptor))
 
         properties = PropertyArrays(descriptor)
         cgThings.append(CGGeneric(define=str(properties)))
-        cgThings.append(CGNativeProperties(descriptor, properties))
         cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGGetProtoObjectMethod(descriptor))
         else:
             cgThings.append(CGGetConstructorObjectMethod(descriptor))
 
         # Set up our Xray callbacks as needed.  Note that we don't need to do
         # it in workers.
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -261,19 +261,17 @@ class Descriptor(DescriptorProvider):
             self.nativeOwnership = desc.get('nativeOwnership', 'nsisupports')
             if not self.nativeOwnership in ['owned', 'refcounted', 'nsisupports']:
                 raise TypeError("Descriptor for %s has unrecognized value (%s) "
                                 "for nativeOwnership" %
                                 (self.interface.identifier.name, self.nativeOwnership))
         self.customTrace = desc.get('customTrace', self.workers)
         self.customFinalize = desc.get('customFinalize', self.workers)
         self.wrapperCache = (not self.interface.isCallback() and
-                             (self.workers or
-                              (self.nativeOwnership != 'owned' and
-                               desc.get('wrapperCache', True))))
+                             (self.workers or desc.get('wrapperCache', True)))
 
         if not self.wrapperCache and self.prefable:
             raise TypeError("Descriptor for %s is prefable but not wrappercached" %
                             self.interface.identifier.name)
 
         def make_name(name):
             return name + "_workers" if self.workers else name
         self.name = make_name(interface.identifier.name)
--- a/dom/bindings/DOMJSClass.h
+++ b/dom/bindings/DOMJSClass.h
@@ -6,18 +6,16 @@
 #ifndef mozilla_dom_DOMJSClass_h
 #define mozilla_dom_DOMJSClass_h
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/dom/PrototypeList.h" // auto-generated
 
-class nsCycleCollectionParticipant;
-
 // We use slot 0 for holding the raw object.  This is safe for both
 // globals and non-globals.
 #define DOM_OBJECT_SLOT 0
 
 // We use slot 1 for holding the expando object. This is not safe for globals
 // until bug 760095 is fixed, so that bug blocks converting Window to new
 // bindings.
 #define DOM_XRAY_EXPANDO_SLOT 1
@@ -63,21 +61,16 @@ struct DOMClass
 
   // We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
   // the proxy private if we use a proxy object.
   // Sometimes it's an nsISupports and sometimes it's not; this class tells
   // us which it is.
   const bool mDOMObjectIsISupports;
 
   const NativePropertyHooks* mNativeHooks;
-
-  // This stores the CC participant for the native, null if this class is for a
-  // worker or for a native inheriting from nsISupports (we can get the CC
-  // participant by QI'ing in that case).
-  nsCycleCollectionParticipant* mParticipant;
 };
 
 // Special JSClass for reflected DOM objects.
 struct DOMJSClass
 {
   // It would be nice to just inherit from JSClass, but that precludes pure
   // compile-time initialization of the form |DOMJSClass = {...};|, since C++
   // only allows brace initialization for aggregate/POD types.
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -67,18 +67,17 @@ EXPORTS_$(binding_include_path) = \
   UnionConversions.h \
   UnionTypes.h \
   $(exported_binding_headers) \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
   -I$(topsrcdir)/js/xpconnect/wrappers \
   -I$(topsrcdir)/content/canvas/src \
-  -I$(topsrcdir)/content/html/content/src \
-  -I$(topsrcdir)/media/webrtc/signaling/src/peerconnection
+  -I$(topsrcdir)/content/html/content/src
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
   Bindings.conf \
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -399,23 +399,16 @@ PeerConnection.prototype = {
   close: function() {
     this._queueOrRun({
       func: this._pc.close,
       args: [],
       wait: false
     });
   },
 
-  get localStreams() {
-    return this._pc.localStreams;
-  },
-  get remoteStreams() {
-    return this._pc.remoteStreams;
-  },
-
   createDataChannel: function(label, dict) {
     if (dict &&
         dict.maxRetransmitTime != undefined &&
         dict.maxRetransmitNum != undefined) {
       throw new Error("Both maxRetransmitTime and maxRetransmitNum cannot be provided");
     }
 
     // Must determine the type where we still know if entries are undefined.
--- a/dom/media/bridge/IPeerConnection.idl
+++ b/dom/media/bridge/IPeerConnection.idl
@@ -78,19 +78,16 @@ interface IPeerConnection : nsISupports
   void setLocalDescription(in long action, in string sdp);
   void setRemoteDescription(in long action, in string sdp);
 
   /* Adds the stream created by GetUserMedia */
   void addStream(in nsIDOMMediaStream stream);
   void removeStream(in nsIDOMMediaStream stream);
   void closeStreams();
 
-  [implicit_jscontext] readonly attribute jsval localStreams; // MediaStream[]
-  [implicit_jscontext] readonly attribute jsval remoteStreams; // MediaStream[]
-
   /* As the ICE candidates roll in this one should be called each time
    * in order to keep the candidate list up-to-date for the next SDP-related
    * call PeerConnectionImpl does not parse ICE candidates, just sticks them
    * into the SDP.
    */
   void addIceCandidate(in string candidate, in string mid, in unsigned short level);
 
   /* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
deleted file mode 100644
--- a/dom/webidl/MediaStreamList.webidl
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-interface MediaStream;
-
-[NoInterfaceObject]
-interface MediaStreamList {
-  getter MediaStream? (unsigned long index);
-  readonly attribute unsigned long length;
-};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -25,17 +25,16 @@ webidl_files = \
   EventHandler.webidl \
   EventListener.webidl \
   EventTarget.webidl \
   FileList.webidl \
   FileReaderSync.webidl \
   HTMLCollection.webidl \
   HTMLOptionsCollection.webidl \
   HTMLPropertiesCollection.webidl \
-  MediaStreamList.webidl \
   NodeList.webidl \
   PaintRequestList.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
   SVGLengthList.webidl \
   SVGNumberList.webidl \
   SVGPathSegList.webidl \
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -842,26 +842,20 @@ NoteGCThingXPCOMChildren(js::Class *clas
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "xpc_GetJSPrivate(obj)");
         cb.NoteXPCOMChild(static_cast<nsISupports*>(xpc_GetJSPrivate(obj)));
     } else if (oldproxybindings::instanceIsProxy(obj)) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "js::GetProxyPrivate(obj)");
         nsISupports *identity =
             static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
         cb.NoteXPCOMChild(identity);
     } else {
-        const DOMClass* domClass;
-        DOMObjectSlot slot = GetDOMClass(obj, domClass);
-        if (slot != eNonDOMObject) {
+        nsISupports *identity;
+        if (UnwrapDOMObjectToISupports(obj, identity)) {
             NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "UnwrapDOMObject(obj)");
-            if (domClass->mDOMObjectIsISupports) {
-                cb.NoteXPCOMChild(UnwrapDOMObject<nsISupports>(obj, slot));
-            } else if (domClass->mParticipant) {
-                cb.NoteNativeChild(UnwrapDOMObject<void>(obj, slot),
-                                   domClass->mParticipant);
-            }
+            cb.NoteXPCOMChild(identity);
         }
     }
 }
 
 enum TraverseSelect {
     TRAVERSE_CPP,
     TRAVERSE_FULL
 };
--- a/media/webrtc/signaling/signaling.gyp
+++ b/media/webrtc/signaling/signaling.gyp
@@ -123,18 +123,16 @@
         './src/softphonewrapper/CC_SIPCCCallServerInfo.h',
         './src/softphonewrapper/CC_SIPCCDevice.h',
         './src/softphonewrapper/CC_SIPCCDeviceInfo.h',
         './src/softphonewrapper/CC_SIPCCFeatureInfo.h',
         './src/softphonewrapper/CC_SIPCCLine.h',
         './src/softphonewrapper/CC_SIPCCLineInfo.h',
         './src/softphonewrapper/CC_SIPCCService.h',
         # PeerConnection
-        './src/peerconnection/MediaStreamList.cpp',
-        './src/peerconnection/MediaStreamList.h',
         './src/peerconnection/PeerConnectionCtx.cpp',
         './src/peerconnection/PeerConnectionCtx.h',
         './src/peerconnection/PeerConnectionImpl.cpp',
         './src/peerconnection/PeerConnectionImpl.h',
         # Media pipeline
         './src/mediapipeline/MediaPipeline.h',
         './src/mediapipeline/MediaPipeline.cpp',
         './src/mediapipeline/SrtpFlow.h',
deleted file mode 100644
--- a/media/webrtc/signaling/src/peerconnection/MediaStreamList.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "base/basictypes.h"
-#include "MediaStreamList.h"
-#ifdef MOZILLA_INTERNAL_API
-#include "mozilla/dom/MediaStreamListBinding.h"
-#endif
-#include "nsIScriptGlobalObject.h"
-#include "PeerConnectionImpl.h"
-
-namespace mozilla {
-namespace dom {
-
-MediaStreamList::MediaStreamList(sipcc::PeerConnectionImpl* peerConnection,
-                                 StreamType type)
-  : mPeerConnection(peerConnection),
-    mType(type)
-{
-  MOZ_COUNT_CTOR(mozilla::dom::MediaStreamList);
-}
-
-MediaStreamList::~MediaStreamList()
-{
-  MOZ_COUNT_DTOR(mozilla::dom::MediaStreamList);
-}
-
-JSObject*
-MediaStreamList::WrapObject(JSContext* cx, ErrorResult& error)
-{
-#ifdef MOZILLA_INTERNAL_API
-  nsCOMPtr<nsIScriptGlobalObject> global =
-    do_QueryInterface(mPeerConnection->GetWindow());
-  JSObject* scope = global->GetGlobalJSObject();
-  if (!scope) {
-    error.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  JSAutoCompartment ac(cx, scope);
-  JSObject* obj = MediaStreamListBinding::Wrap(cx, scope, this);
-  if (!obj) {
-    error.Throw(NS_ERROR_FAILURE);
-  }
-  return obj;
-#else
-  return nullptr;
-#endif
-}
-
-template<class T>
-static nsIDOMMediaStream*
-GetStreamFromInfo(T* info, bool& found)
-{
-  if (!info) {
-    found = false;
-    return nullptr;
-  }
-
-  found = true;
-  return info->GetMediaStream();
-}
-
-nsIDOMMediaStream*
-MediaStreamList::IndexedGetter(uint32_t index, bool& found)
-{
-  if (mType == Local) {
-    return GetStreamFromInfo(mPeerConnection->GetLocalStream(index), found);
-  }
-
-  return GetStreamFromInfo(mPeerConnection->GetRemoteStream(index), found);
-}
-
-uint32_t
-MediaStreamList::Length()
-{
-  return mType == Local ? mPeerConnection->LocalStreamsLength() :
-                          mPeerConnection->RemoteStreamsLength();
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/media/webrtc/signaling/src/peerconnection/MediaStreamList.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MediaStreamList_h__
-#define MediaStreamList_h__
-
-#include "mozilla/ErrorResult.h"
-#include "nsISupportsImpl.h"
-#include "nsAutoPtr.h"
-#include "jspubtd.h"
-#include "mozilla/dom/NonRefcountedDOMObject.h"
-
-class nsIDOMMediaStream;
-namespace sipcc {
-class PeerConnectionImpl;
-} // namespace sipcc
-
-namespace mozilla {
-namespace dom {
-
-class MediaStreamList : public NonRefcountedDOMObject
-{
-public:
-  enum StreamType {
-    Local,
-    Remote
-  };
-
-  MediaStreamList(sipcc::PeerConnectionImpl* peerConnection, StreamType type);
-  ~MediaStreamList();
-
-  JSObject* WrapObject(JSContext* cx, ErrorResult& error);
-
-  nsIDOMMediaStream* IndexedGetter(uint32_t index, bool& found);
-  uint32_t Length();
-
-private:
-  nsRefPtr<sipcc::PeerConnectionImpl> mPeerConnection;
-  StreamType mType;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // MediaStreamList_h__
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -26,21 +26,16 @@
 #include "nsProxyRelease.h"
 
 #include "runnable_utils.h"
 #include "PeerConnectionCtx.h"
 #include "PeerConnectionImpl.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsDOMDataChannel.h"
-#ifdef MOZILLA_INTERNAL_API
-#include "MediaStreamList.h"
-#include "nsIScriptGlobalObject.h"
-#include "jsapi.h"
-#endif
 
 #ifndef USE_FAKE_MEDIA_STREAMS
 #include "MediaSegment.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -1130,28 +1125,28 @@ PeerConnectionImpl::IceCompleted(NrIceCt
 void
 PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
 {
   MOZ_ASSERT(aStream);
 
   CSFLogDebugS(logTag, __FUNCTION__ << ": "  << aStream->name().c_str());
 }
 
-LocalSourceStreamInfo*
+nsRefPtr<LocalSourceStreamInfo>
 PeerConnectionImpl::GetLocalStream(int aIndex)
 {
   if(aIndex < 0 || aIndex >= (int) mLocalSourceStreams.Length()) {
     return NULL;
   }
 
   MOZ_ASSERT(mLocalSourceStreams[aIndex]);
   return mLocalSourceStreams[aIndex];
 }
 
-RemoteSourceStreamInfo*
+nsRefPtr<RemoteSourceStreamInfo>
 PeerConnectionImpl::GetRemoteStream(int aIndex)
 {
   if(aIndex < 0 || aIndex >= (int) mRemoteSourceStreams.Length()) {
     return NULL;
   }
 
   MOZ_ASSERT(mRemoteSourceStreams[aIndex]);
   return mRemoteSourceStreams[aIndex];
@@ -1165,57 +1160,16 @@ PeerConnectionImpl::AddRemoteStream(nsRe
 
   *aIndex = mRemoteSourceStreams.Length();
 
   mRemoteSourceStreams.AppendElement(aInfo);
 
   return NS_OK;
 }
 
-#ifdef MOZILLA_INTERNAL_API
-static nsresult
-GetStreams(JSContext* cx, PeerConnectionImpl* peerConnection,
-           MediaStreamList::StreamType type, JS::Value* streams)
-{
-  nsAutoPtr<MediaStreamList> list(new MediaStreamList(peerConnection, type));
-
-  ErrorResult rv;
-  JSObject* obj = list->WrapObject(cx, rv);
-  if (rv.Failed()) {
-    streams->setNull();
-    return rv.ErrorCode();
-  }
-
-  // Transfer ownership to the binding.
-  streams->setObject(*obj);
-  list.forget();
-  return NS_OK;
-}
-#endif
-
-NS_IMETHODIMP
-PeerConnectionImpl::GetLocalStreams(JSContext* cx, JS::Value* streams)
-{
-#ifdef MOZILLA_INTERNAL_API
-  return GetStreams(cx, this, MediaStreamList::Local, streams);
-#else
-  return NS_ERROR_FAILURE;
-#endif
-}
-
-NS_IMETHODIMP
-PeerConnectionImpl::GetRemoteStreams(JSContext* cx, JS::Value* streams)
-{
-#ifdef MOZILLA_INTERNAL_API
-  return GetStreams(cx, this, MediaStreamList::Remote, streams);
-#else
-  return NS_ERROR_FAILURE;
-#endif
-}
-
 void
 LocalSourceStreamInfo::StorePipeline(int aTrack,
   mozilla::RefPtr<mozilla::MediaPipeline> aPipeline)
 {
   MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end());
   if (mPipelines.find(aTrack) != mPipelines.end()) {
     CSFLogErrorS(logTag, __FUNCTION__ << ": Storing duplicate track");
     return;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -324,28 +324,20 @@ public:
     // make one.
     if (i >= mIceStreams.size()) {
       return NULL;
     }
     return mIceStreams[i];
   }
 
   // Get a specific local stream
-  uint32_t LocalStreamsLength()
-  {
-    return mLocalSourceStreams.Length();
-  }
-  LocalSourceStreamInfo* GetLocalStream(int index);
+  nsRefPtr<LocalSourceStreamInfo> GetLocalStream(int aIndex);
 
   // Get a specific remote stream
-  uint32_t RemoteStreamsLength()
-  {
-    return mRemoteSourceStreams.Length();
-  }
-  RemoteSourceStreamInfo* GetRemoteStream(int index);
+  nsRefPtr<RemoteSourceStreamInfo> GetRemoteStream(int aIndex);
 
   // Add a remote stream. Returns the index in index
   nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, int *aIndex);
 
   // Get a transport flow either RTP/RTCP for a particular stream
   // A stream can be of audio/video/datachannel/budled(?) types
   mozilla::RefPtr<TransportFlow> GetTransportFlow(int aStreamIndex, bool aIsRtcp) {
     int index_inner = aStreamIndex * 2 + (aIsRtcp ? 1 : 0);
@@ -373,18 +365,16 @@ public:
   nsCOMPtr<nsIEventTarget> GetSTSThread() { return mSTSThread; }
 
   // Get the DTLS identity
   mozilla::RefPtr<DtlsIdentity> const GetIdentity() { return mIdentity; }
 
   // Create a fake media stream
   nsresult CreateFakeMediaStream(uint32_t hint, nsIDOMMediaStream** retval);
 
-  nsPIDOMWindow* GetWindow() const { return mWindow; }
-
 private:
   PeerConnectionImpl(const PeerConnectionImpl&rhs);
   PeerConnectionImpl& operator=(PeerConnectionImpl);
 
   void ChangeReadyState(ReadyState aReadyState);
   void CheckIceState() {
     PR_ASSERT(mIceState != kIceGathering);
   }