Bug 868312 finale: finish rooting dom/ code. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 17 May 2013 21:48:25 -0400
changeset 132297 9fcdf0c1c59816aefd92fa9381da07a621d0ba37
parent 132296 13b24e2f631900a95eab175368279763a3216953
child 132298 84f2c5b57c009da299e913003d114f8b9f99912e
push id24693
push userphilringnalda@gmail.com
push dateSun, 19 May 2013 01:08:22 +0000
treeherdermozilla-central@317fe0f314ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs868312
milestone24.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 868312 finale: finish rooting dom/ code. r=smaug
content/base/src/nsDocument.cpp
dom/base/DOMCursor.cpp
dom/base/DOMRequest.cpp
dom/base/DOMRequest.h
dom/bindings/BindingUtils.h
dom/bindings/CallbackFunction.h
dom/bindings/Codegen.py
dom/camera/DOMCameraControl.cpp
dom/camera/nsIDOMCameraManager.idl
dom/devicestorage/DeviceStorageRequestChild.cpp
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/test/test_enumerateOptions.html
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/nsIIDBDatabase.idl
dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
dom/mobilemessage/src/MobileMessageCallback.cpp
dom/mobilemessage/src/MobileMessageCallback.h
dom/mobilemessage/src/ipc/SmsIPCService.cpp
dom/webidl/CameraManager.webidl
dom/webidl/DeviceStorage.webidl
dom/webidl/DummyBinding.webidl
dom/webidl/IDBDatabase.webidl
dom/webidl/MobileMessageManager.webidl
dom/webidl/MozMmsMessage.webidl
dom/webidl/WebIDL.mk
dom/workers/EventListenerManager.cpp
dom/workers/EventListenerManager.h
dom/workers/EventTarget.cpp
dom/workers/EventTarget.h
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
dom/workers/XMLHttpRequest.h
dom/workers/XMLHttpRequestEventTarget.h
js/xpconnect/src/dictionary_helper_gen.conf
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -5071,18 +5071,17 @@ nsDocument::RegisterEnabled()
   return sPrefValue;
 }
 
 NS_IMETHODIMP
 nsDocument::Register(const nsAString& aName, const JS::Value& aOptions,
                      JSContext* aCx, uint8_t aOptionalArgc,
                      jsval* aConstructor /* out param */)
 {
-  ElementRegistrationOptions options;
-  DictionaryRooter<ElementRegistrationOptions> optionsRooter(aCx, &options);
+  RootedDictionary<ElementRegistrationOptions> options(aCx);
   if (aOptionalArgc > 0) {
     JSAutoCompartment ac(aCx, GetWrapper());
     JS::Rooted<JS::Value> opts(aCx, aOptions);
     NS_ENSURE_TRUE(JS_WrapValue(aCx, opts.address()),
                    NS_ERROR_UNEXPECTED);
     NS_ENSURE_TRUE(options.Init(aCx, opts),
                    NS_ERROR_UNEXPECTED);
   }
--- a/dom/base/DOMCursor.cpp
+++ b/dom/base/DOMCursor.cpp
@@ -50,17 +50,17 @@ DOMCursor::Reset()
   mDone = false;
 }
 
 void
 DOMCursor::FireDone()
 {
   Reset();
   mFinished = true;
-  FireSuccess(JSVAL_VOID);
+  FireSuccess(JS::UndefinedHandleValue);
 }
 
 NS_IMETHODIMP
 DOMCursor::GetDone(bool *aDone)
 {
   *aDone = Done();
   return NS_OK;
 }
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -110,17 +110,17 @@ DOMRequest::GetResult(JS::Value* aResult
 NS_IMETHODIMP
 DOMRequest::GetError(nsIDOMDOMError** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
 }
 
 void
-DOMRequest::FireSuccess(JS::Value aResult)
+DOMRequest::FireSuccess(JS::Handle<JS::Value> aResult)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
   NS_ASSERTION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
 
   mDone = true;
   if (JSVAL_IS_GCTHING(aResult)) {
     RootResultVal();
@@ -217,17 +217,18 @@ DOMRequestService::CreateCursor(nsIDOMWi
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireSuccess(nsIDOMDOMRequest* aRequest,
                                const JS::Value& aResult)
 {
   NS_ENSURE_STATE(aRequest);
-  static_cast<DOMRequest*>(aRequest)->FireSuccess(aResult);
+  static_cast<DOMRequest*>(aRequest)->
+    FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(&aResult));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireError(nsIDOMDOMRequest* aRequest,
                              const nsAString& aError)
 {
@@ -284,17 +285,17 @@ public:
       return NS_ERROR_FAILURE;
     }
     return NS_OK;
   }
 
   NS_IMETHODIMP
   Run()
   {
-    mReq->FireSuccess(mResult);
+    mReq->FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(&mResult));
     return NS_OK;
   }
 
   ~FireSuccessAsyncTask()
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     if(!mIsSetup) {
       // If we never set up, no reason to unroot
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -64,17 +64,17 @@ public:
                  "Error should be null when pending");
     return mError;
   }
 
   IMPL_EVENT_HANDLER(success)
   IMPL_EVENT_HANDLER(error)
 
 
-  void FireSuccess(JS::Value aResult);
+  void FireSuccess(JS::Handle<JS::Value> aResult);
   void FireError(const nsAString& aError);
   void FireError(nsresult aError);
 
   DOMRequest(nsIDOMWindow* aWindow);
   DOMRequest();
 
   virtual ~DOMRequest()
   {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1754,58 +1754,49 @@ public:
     FallibleTArray<T>* mFallibleArray;
     Nullable<nsTArray<T> >* mNullableArray;
   };
 
   SequenceType mSequenceType;
 };
 
 template<typename T>
-class MOZ_STACK_CLASS DictionaryRooter : JS::CustomAutoRooter
+class MOZ_STACK_CLASS RootedDictionary : public T,
+                                         private JS::CustomAutoRooter
 {
 public:
-  DictionaryRooter(JSContext *aCx, T* aDictionary
-                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mDictionary(aDictionary),
-      mDictionaryType(eDictionary)
-  {
-  }
-
-  DictionaryRooter(JSContext *aCx, Nullable<T>* aDictionary
-                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mNullableDictionary(aDictionary),
-      mDictionaryType(eNullableDictionary)
+  RootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
+    T(),
+    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
   {
   }
 
-private:
-  enum DictionaryType {
-    eDictionary,
-    eNullableDictionary
-  };
+  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
+  {
+    this->TraceDictionary(trc);
+  }
+};
 
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE {
-    if (mDictionaryType == eDictionary) {
-      mDictionary->TraceDictionary(trc);
-    } else {
-      MOZ_ASSERT(mDictionaryType == eNullableDictionary);
-      if (!mNullableDictionary->IsNull()) {
-        mNullableDictionary->Value().TraceDictionary(trc);
-      }
+template<typename T>
+class MOZ_STACK_CLASS NullableRootedDictionary : public Nullable<T>,
+                                                 private JS::CustomAutoRooter
+{
+public:
+  NullableRootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
+    Nullable<T>(),
+    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
+  {
+  }
+
+  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
+  {
+    if (!this->IsNull()) {
+      this->Value().TraceDictionary(trc);
     }
   }
-
-  union {
-    T* mDictionary;
-    Nullable<T>* mNullableDictionary;
-  };
-
-  DictionaryType mDictionaryType;
 };
 
 inline bool
 IdEquals(jsid id, const char* string)
 {
   return JSID_IS_STRING(id) &&
          JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), string);
 }
--- a/dom/bindings/CallbackFunction.h
+++ b/dom/bindings/CallbackFunction.h
@@ -23,17 +23,17 @@ namespace mozilla {
 namespace dom {
 
 class CallbackFunction : public CallbackObject
 {
 public:
   explicit CallbackFunction(JSObject* aCallable)
     : CallbackObject(aCallable)
   {
-    MOZ_ASSERT(JS_ObjectIsCallable(nullptr, aCallable));
+    MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));
   }
 
   JS::Handle<JSObject*> Callable() const
   {
     return Callback();
   }
 
   bool HasGrayCallable() const
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2959,16 +2959,21 @@ for (uint32_t i = 0; i < length; ++i) {
                                         dealWithOptional=isOptional and not nullable)
 
     if type.isGeckoInterface():
         assert not isEnforceRange and not isClamp
 
         descriptor = descriptorProvider.getDescriptor(
             type.unroll().inner.identifier.name)
 
+        if descriptor.nativeType == 'JSObject':
+            # XXXbz Workers code does this sometimes
+            assert descriptor.workers
+            return handleJSObjectType(type, isMember, failureCode)
+
         if (descriptor.interface.isCallback() and
             descriptor.interface.identifier.name != "EventListener"):
             if descriptor.workers:
                 return handleJSObjectType(type, isMember, failureCode)
 
             name = descriptor.interface.identifier.name
             if type.nullable() or isCallbackReturnValue:
                 declType = CGGeneric("nsRefPtr<%s>" % name);
@@ -3283,29 +3288,28 @@ for (uint32_t i = 0; i < length; ++i) {
         assert not isEnforceRange and not isClamp
         assert not type.treatNonCallableAsNull() or type.nullable()
 
         if descriptorProvider.workers:
             if isMember:
                 raise NoSuchDescriptorError("Can't handle member callbacks in "
                                             "workers; need to sort out rooting"
                                             "issues")
-            if type.nullable():
-                declType = CGGeneric("JSObject*")
-            else:
-                declType = CGGeneric("NonNull<JSObject>")
-            conversion = "  ${declName} = &${val}.toObject();\n"
+            declType = CGGeneric("JS::Rooted<JSObject*>")
+            conversion = "  ${declName} = &${valHandle}.toObject();\n"
+            declArgs = "cx"
         else:
             name = type.unroll().identifier.name
             if type.nullable():
                 declType = CGGeneric("nsRefPtr<%s>" % name);
             else:
                 declType = CGGeneric("OwningNonNull<%s>" % name)
             conversion = (
                 "  ${declName} = new %s(&${val}.toObject());\n" % name)
+            declArgs = None
 
         if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
             haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
             if not isDefinitelyObject:
                 haveCallable = "${val}.isObject() && " + haveCallable
             if defaultValue is not None:
                 assert(isinstance(defaultValue, IDLNullValue))
                 haveCallable = "${haveValue} && " + haveCallable
@@ -3321,17 +3325,18 @@ for (uint32_t i = 0; i < length; ++i) {
                 conversion +
                 "} else {\n"
                 "%s"
                 "}" % CGIndenter(onFailureNotCallable(failureCode)).define(),
                 type,
                 "${declName} = nullptr",
                 failureCode)
         return JSToNativeConversionInfo(template, declType=declType,
-                                        dealWithOptional=isOptional)
+                                        dealWithOptional=isOptional,
+                                        declArgs=declArgs)
 
     if type.isAny():
         assert not isEnforceRange and not isClamp
 
         declArgs = None
         if (isMember == "Variadic" or isMember == "Sequence" or
             isMember == "Dictionary"):
             # Rooting is handled by the sequence and dictionary tracers.
@@ -3400,25 +3405,23 @@ for (uint32_t i = 0; i < length; ++i) {
 
         template += ("if (!${declName}.Init(cx, %s)) {\n"
                      "%s\n"
                      "}" % (val, exceptionCodeIndented.define()))
 
         # Dictionary arguments that might contain traceable things need to get
         # traced
         if not isMember and typeNeedsCx(type, descriptorProvider):
-            holderType = CGTemplatedType("DictionaryRooter", declType);
-            holderArgs = "cx, &${declName}"
-        else:
-            holderType = None
-            holderArgs = None
+            declType = CGTemplatedType("RootedDictionary", declType);
+            declArgs = "cx"
+        else:
+            declArgs = None
 
         return JSToNativeConversionInfo(template, declType=declType,
-                                        holderType=holderType,
-                                        holderArgs=holderArgs)
+                                        declArgs=declArgs)
 
     if type.isVoid():
         assert not isOptional
         # This one only happens for return values, and its easy: Just
         # ignore the jsval.
         return JSToNativeConversionInfo("")
 
     if type.isDate():
@@ -4108,105 +4111,110 @@ def dictionaryNeedsCx(dictionary, descri
         (dictionary.parent and dictionaryNeedsCx(dictionary.parent, descriptorProvider)))
 
 # Whenever this is modified, please update CGNativeMember.getRetvalInfo as
 # needed to keep the types compatible.
 def getRetvalDeclarationForType(returnType, descriptorProvider,
                                 resultAlreadyAddRefed,
                                 isMember=False):
     """
-    Returns a tuple containing three things:
+    Returns a tuple containing four things:
 
     1) A CGThing for the type of the return value, or None if there is no need
        for a return value.
 
     2) A boolean indicating whether the return value is passed as an out
        parameter.
 
     3) A CGThing for a tracer for the return value, or None if no tracing is
        needed.
+
+    4) An argument string to pass to the retval declaration
+       constructor or None if there are no arguments.
     """
     if returnType is None or returnType.isVoid():
         # Nothing to declare
-        return None, False, None
+        return None, False, None, None
     if returnType.isPrimitive() and returnType.tag() in builtinNames:
         result = CGGeneric(builtinNames[returnType.tag()])
         if returnType.nullable():
             result = CGTemplatedType("Nullable", result)
-        return result, False, None
+        return result, False, None, None
     if returnType.isString():
         if isMember:
-            return CGGeneric("nsString"), True, None
-        return CGGeneric("DOMString"), True, None
+            return CGGeneric("nsString"), True, None, None
+        return CGGeneric("DOMString"), True, None, None
     if returnType.isEnum():
         result = CGGeneric(returnType.unroll().inner.identifier.name)
         if returnType.nullable():
             result = CGTemplatedType("Nullable", result)
-        return result, False, None
+        return result, False, None, None
     if returnType.isGeckoInterface():
         result = CGGeneric(descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeType)
         if resultAlreadyAddRefed:
             result = CGTemplatedType("nsRefPtr", result)
         elif descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeOwnership == 'owned':
             result = CGTemplatedType("nsAutoPtr", result)
         else:
             result = CGWrapper(result, post="*")
-        return result, False, None
+        return result, False, None, None
     if returnType.isCallback():
         name = returnType.unroll().identifier.name
         if descriptorProvider.workers:
-            return CGGeneric("JSObject*"), False, None
-        return CGGeneric("nsRefPtr<%s>" % name), False, None
+            return CGGeneric("JSObject*"), False, None, None
+        return CGGeneric("nsRefPtr<%s>" % name), False, None, None
     if returnType.isAny():
-        return CGGeneric("JS::Value"), False, None
+        return CGGeneric("JS::Value"), False, None, None
     if returnType.isObject() or returnType.isSpiderMonkeyInterface():
-        return CGGeneric("JSObject*"), False, None
+        return CGGeneric("JSObject*"), False, None, None
     if returnType.isSequence():
         nullable = returnType.nullable()
         if nullable:
             returnType = returnType.inner
         # If our result is already addrefed, use the right type in the
         # sequence argument here.
-        (result, _, _) = getRetvalDeclarationForType(returnType.inner,
-                                                     descriptorProvider,
-                                                     resultAlreadyAddRefed,
-                                                     isMember="Sequence")
+        (result, _, _, _) = getRetvalDeclarationForType(returnType.inner,
+                                                        descriptorProvider,
+                                                        resultAlreadyAddRefed,
+                                                        isMember="Sequence")
         # While we have our inner type, set up our rooter, if needed
         if not isMember and typeNeedsCx(returnType, descriptorProvider):
             rooter = CGGeneric("SequenceRooter<%s > resultRooter(cx, &result);" %
                                result.define())
         else:
             rooter = None
         result = CGTemplatedType("nsTArray", result)
         if nullable:
             result = CGTemplatedType("Nullable", result)
-        return result, True, rooter
+        return result, True, rooter, None
     if returnType.isDictionary():
         nullable = returnType.nullable()
         dictName = (CGDictionary.makeDictionaryName(returnType.unroll().inner,
                                                     descriptorProvider.workers) +
                     "Initializer")
         result = CGGeneric(dictName)
         if not isMember and typeNeedsCx(returnType, descriptorProvider):
-            rooter = CGGeneric("DictionaryRooter<%s> resultRooter(cx, &result);\n" %
-                               dictName)
-        else:
-            rooter = None
-        if nullable:
+            if nullable:
+                result = CGTemplatedType("NullableRootedDictionary", result)
+            else:
+                result = CGTemplatedType("RootedDictionary", result)
+            resultArgs = "cx"
+        elif nullable:
             result = CGTemplatedType("Nullable", result)
-        return result, True, rooter
+            resultArgs = None
+        return result, True, None, resultArgs
     if returnType.isUnion():
         raise TypeError("Need to sort out ownership model for union retvals");
     if returnType.isDate():
         result = CGGeneric("Date")
         if returnType.nullable():
             result = CGTemplatedType("Nullable", result)
-        return result, False, None
+        return result, False, None, None
     raise TypeError("Don't know how to declare return value for %s" %
                     returnType)
 
 def isResultAlreadyAddRefed(descriptor, extendedAttributes):
     # Default to already_AddRefed on the main thread, raw pointer in workers
     return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
 
 def needCx(returnType, arguments, extendedAttributes, descriptorProvider,
@@ -4230,17 +4238,18 @@ class CGCallGenerator(CGThing):
         CGThing.__init__(self)
 
         assert errorReport is None or isinstance(errorReport, CGThing)
 
         isFallible = errorReport is not None
 
         resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
                                                         extendedAttributes)
-        (result, resultOutParam, resultRooter) = getRetvalDeclarationForType(
+        (result, resultOutParam,
+         resultRooter, resultArgs) = getRetvalDeclarationForType(
             returnType, descriptorProvider, resultAlreadyAddRefed)
 
         args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
         for (a, name) in arguments:
             arg = CGGeneric(name)
             # Now constify the things that need it
             def needsConst(a):
                 if a.type.isDictionary():
@@ -4279,17 +4288,21 @@ class CGCallGenerator(CGThing):
 
         call = CGGeneric(nativeMethodName)
         if not static:
             call = CGWrapper(call, pre="%s->" % object)
         call = CGList([call, CGWrapper(args, pre="(", post=");")])
         if result is not None:
             if resultRooter is not None:
                 self.cgRoot.prepend(resultRooter)
-            result = CGWrapper(result, post=" result;")
+            if resultArgs is not None:
+                resultArgs = "(%s)" % resultArgs
+            else:
+                resultArgs = ""
+            result = CGWrapper(result, post=(" result%s;" % resultArgs))
             self.cgRoot.prepend(result)
             if not resultOutParam:
                 call = CGWrapper(call, pre="result = ")
 
         call = CGWrapper(call)
         self.cgRoot.append(call)
 
         if isFallible:
@@ -5201,19 +5214,19 @@ class CGSpecializedGetter(CGAbstractStat
         return CGIndenter(CGGetterCall(self.attr.type, nativeName,
                                        self.descriptor, self.attr)).define()
 
     @staticmethod
     def makeNativeName(descriptor, attr):
         name = attr.identifier.name
         nativeName = MakeNativeName(descriptor.binaryNames.get(name, name))
         # resultOutParam does not depend on whether resultAlreadyAddRefed is set
-        (_, resultOutParam, _) = getRetvalDeclarationForType(attr.type,
-                                                             descriptor,
-                                                             False)
+        (_, resultOutParam, _, _) = getRetvalDeclarationForType(attr.type,
+                                                                descriptor,
+                                                                False)
         infallible = ('infallible' in
                       descriptor.getExtendedAttributes(attr, getter=True))
         if resultOutParam or attr.type.nullable() or not infallible:
             nativeName = "Get" + nativeName
         return nativeName
 
 class CGStaticGetter(CGAbstractStaticBindingMethod):
     """
@@ -7991,17 +8004,17 @@ class ForwardDeclarationBuilder:
         return self._build(atTopLevel=True)
 
 
 class CGForwardDeclarations(CGWrapper):
     """
     Code generate the forward declarations for a header file.
     """
     def __init__(self, config, descriptors, mainCallbacks, workerCallbacks,
-                 callbackInterfaces):
+                 mainDictionaries, workerDictionaries, callbackInterfaces):
         builder = ForwardDeclarationBuilder()
 
         def forwardDeclareForType(t, workerness='both'):
             t = t.unroll()
             if t.isGeckoInterface():
                 name = t.inner.identifier.name
                 # Find and add the non-worker implementation, if any.
                 if workerness != 'workeronly':
@@ -8042,20 +8055,23 @@ class CGForwardDeclarations(CGWrapper):
             for t in getTypesFromCallback(callback):
                 forwardDeclareForType(t, workerness='workeronly')
 
         for d in callbackInterfaces:
             builder.add(d.nativeType)
             for t in getTypesFromDescriptor(d):
                 forwardDeclareForType(t)
 
-        # Dictionaries add a header for each type they contain, so no
-        # need for forward declarations.  However, they may refer to
-        # declarations made later in this file, which is why we
-        # forward declare everything that is declared in this file.
+        for d in mainDictionaries:
+            for t in getTypesFromDictionary(d):
+                forwardDeclareForType(t, workerness='mainthreadonly')
+
+        for d in workerDictionaries:
+            for t in getTypesFromDictionary(d):
+                forwardDeclareForType(t, workerness='workeronly')
 
         CGWrapper.__init__(self, builder.build())
 
 
 class CGBindingRoot(CGThing):
     """
     Root codegen class for binding generation. Instantiate the class, and call
     declare or define to generate header or cpp code (respectively).
@@ -8157,16 +8173,17 @@ class CGBindingRoot(CGThing):
         curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, pre="\n"))
 
         curr = CGList([CGForwardDeclarations(config, descriptors,
                                              mainCallbacks, workerCallbacks,
+                                             mainDictionaries, workerDictionaries,
                                              callbackDescriptors + jsImplemented),
                        CGWrapper(CGGeneric("using namespace mozilla::dom;"),
                                  defineOnly=True),
                        traitsClasses, curr],
                       "\n")
 
         # Add header includes.
         curr = CGHeaders(descriptors,
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -12,19 +12,21 @@
 #include "mozilla/unused.h"
 #include "nsIObserverService.h"
 #include "nsIDOMDeviceStorage.h"
 #include "nsXULAppAPI.h"
 #include "DOMCameraManager.h"
 #include "DOMCameraCapabilities.h"
 #include "DOMCameraControl.h"
 #include "CameraCommon.h"
+#include "mozilla/dom/CameraManagerBinding.h"
+#include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
-using namespace dom;
+using namespace mozilla::dom;
 
 DOMCI_DATA(CameraControl, nsICameraControl)
 
 NS_IMPL_CYCLE_COLLECTION_1(nsDOMCameraControl,
                            mDOMCapabilities)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCameraControl)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -345,38 +347,40 @@ nsDOMCameraControl::AutoFocus(nsICameraA
 }
 
 /* void takePicture (in jsval aOptions, in nsICameraTakePictureCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
 NS_IMETHODIMP
 nsDOMCameraControl::TakePicture(const JS::Value& aOptions, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError, JSContext* cx)
 {
   NS_ENSURE_TRUE(onSuccess, NS_ERROR_INVALID_ARG);
 
-  mozilla::idl::CameraPictureOptions options;
+  RootedDictionary<CameraPictureOptions> options(cx);
   mozilla::idl::CameraSize           size;
   mozilla::idl::CameraPosition       pos;
 
-  nsresult rv = options.Init(cx, &aOptions);
-  NS_ENSURE_SUCCESS(rv, rv);
+  JS::Rooted<JS::Value> optionVal(cx, aOptions);
+  if (!options.Init(cx, optionVal)) {
+    return NS_ERROR_FAILURE;
+  }
 
-  rv = size.Init(cx, &options.pictureSize);
+  nsresult rv = size.Init(cx, &options.mPictureSize);
   NS_ENSURE_SUCCESS(rv, rv);
 
   /**
    * Default values, until the dictionary parser can handle them.
    * NaN indicates no value provided.
    */
   pos.latitude = NAN;
   pos.longitude = NAN;
   pos.altitude = NAN;
   pos.timestamp = NAN;
-  rv = pos.Init(cx, &options.position);
+  rv = pos.Init(cx, &options.mPosition);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return mCameraControl->TakePicture(size, options.rotation, options.fileFormat, pos, options.dateTime, onSuccess, onError);
+  return mCameraControl->TakePicture(size, options.mRotation, options.mFileFormat, pos, options.mDateTime, onSuccess, onError);
 }
 
 /* [implicit_jscontext] void GetPreviewStreamVideoMode (in jsval aOptions, in nsICameraPreviewStreamCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
 NS_IMETHODIMP
 nsDOMCameraControl::GetPreviewStreamVideoMode(const JS::Value& aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError, JSContext* cx)
 {
   NS_ENSURE_TRUE(onSuccess, NS_ERROR_INVALID_ARG);
 
--- a/dom/camera/nsIDOMCameraManager.idl
+++ b/dom/camera/nsIDOMCameraManager.idl
@@ -110,57 +110,16 @@ interface nsICameraCapabilities : nsISup
 
     /* an object with attributes for each of the supported recorder
        profiles, e.g. recorderProfiles.cif, recorderProfiles.qvga,
        etc. */
     [implicit_jscontext]
     readonly attribute jsval        recorderProfiles;
 };
 
-/* These properties only affect the captured image;
-   invalid property settings are ignored. */
-dictionary CameraPictureOptions
-{
-    /* an object with a combination of 'height' and 'width' properties
-       chosen from nsICameraCapabilities.pictureSizes */
-    jsval     pictureSize;
-
-    /* one of the file formats chosen from
-       nsICameraCapabilities.fileFormats */
-    DOMString fileFormat;
-
-    /* the rotation of the image in degrees, from 0 to 270 in
-       steps of 90; this doesn't affect the image, only the
-       rotation recorded in the image header.*/
-    long      rotation;
-
-    /* an object containing any or all of 'latitude', 'longitude',
-       'altitude', and 'timestamp', used to record when and where
-       the image was taken.  e.g.
-        {
-            latitude:  43.647118,
-            longitude: -79.3943,
-            altitude:  500
-            // timestamp not specified, in this case, and
-            // won't be included in the image header
-        }
-
-        can be null in the case where position information isn't
-        available/desired.
-
-        'altitude' is in metres; 'timestamp' is UTC, in seconds from
-        January 1, 1970.
-    */
-    jsval     position;
-
-    /* the number of seconds from January 1, 1970 UTC.  This can be
-       different from the positional timestamp (above). */
-    long long dateTime;
-};
-
 /* These properties affect the video recording preview, e.g.
       {
          profile: "1080p",
          rotation: 0
       }
 
    'profile' is one of the profiles returned by
    nsICameraCapabilities.recorderProfiles'; if this profile is missing,
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -48,54 +48,61 @@ DeviceStorageRequestChild::Recv__delete_
       mRequest->FireError(r.error());
       break;
     }
 
     case DeviceStorageResponseValue::TSuccessResponse:
     {
       nsString compositePath;
       mFile->GetCompositePath(compositePath);
-      JS::Value result = StringToJsval(mRequest->GetOwner(), compositePath);
+      AutoJSContext cx;
+      JS::Rooted<JS::Value> result(cx,
+        StringToJsval(mRequest->GetOwner(), compositePath));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TBlobResponse:
     {
       BlobResponse r = aValue;
       BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
       nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
 
       nsCOMPtr<nsIDOMFile> file = do_QueryInterface(blob);
-      JS::Value result = InterfaceToJsval(mRequest->GetOwner(), file,
-                                          &NS_GET_IID(nsIDOMFile));
+      AutoJSContext cx;
+      JS::Rooted<JS::Value> result(cx,
+        InterfaceToJsval(mRequest->GetOwner(), file, &NS_GET_IID(nsIDOMFile)));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TFreeSpaceStorageResponse:
     {
       FreeSpaceStorageResponse r = aValue;
-      JS::Value result = JS_NumberValue(double(r.freeBytes()));
+      AutoJSContext cx;
+      JS::Rooted<JS::Value> result(cx, JS_NumberValue(double(r.freeBytes())));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TUsedSpaceStorageResponse:
     {
       UsedSpaceStorageResponse r = aValue;
-      JS::Value result = JS_NumberValue(double(r.usedBytes()));
+      AutoJSContext cx;
+      JS::Rooted<JS::Value> result(cx, JS_NumberValue(double(r.usedBytes())));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TAvailableStorageResponse:
     {
       AvailableStorageResponse r = aValue;
-      JS::Value result = StringToJsval(mRequest->GetOwner(), r.mountState());
+      AutoJSContext cx;
+      JS::Rooted<JS::Value> result(
+        cx, StringToJsval(mRequest->GetOwner(), r.mountState()));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TEnumerationResponse:
     {
       EnumerationResponse r = aValue;
       nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -42,16 +42,18 @@
 #include "nsIObserverService.h"
 #include "GeneratedEvents.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsIPermissionManager.h"
 #include "nsIStringBundle.h"
 #include <algorithm>
 
+#include "mozilla/dom/DeviceStorageBinding.h"
+
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsIVolume.h"
 #include "nsIVolumeService.h"
 #endif
 
@@ -1581,17 +1583,19 @@ ContinueCursorEvent::Continue()
 }
 
 NS_IMETHODIMP
 ContinueCursorEvent::Run()
 {
   nsRefPtr<DeviceStorageFile> file = GetNextFile();
 
   nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
-  JS::Value val = nsIFileToJsval(cursor->GetOwner(), file);
+
+  AutoJSContext cx;
+  JS::Rooted<JS::Value> val(cx, nsIFileToJsval(cursor->GetOwner(), file));
 
   if (file) {
     cursor->mOkToCallContinue = true;
     cursor->FireSuccess(val);
   } else {
     cursor->FireDone();
   }
   mRequest = nullptr;
@@ -1798,17 +1802,18 @@ public:
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
     nsString state = NS_LITERAL_STRING("unavailable");
     if (mFile) {
       mFile->GetStatus(state);
     }
 
-    JS::Value result = StringToJsval(mRequest->GetOwner(), state);
+    AutoJSContext cx;
+    JS::Rooted<JS::Value> result(cx, StringToJsval(mRequest->GetOwner(), state));
     mRequest->FireSuccess(result);
     mRequest = nullptr;
     return NS_OK;
   }
 
 private:
   nsRefPtr<DeviceStorageFile> mFile;
   nsRefPtr<DOMRequest> mRequest;
@@ -1836,17 +1841,18 @@ public:
     }
 
   ~PostResultEvent() {}
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-    JS::Value result = JSVAL_NULL;
+    AutoJSContext cx;
+    JS::Rooted<JS::Value> result(cx, JSVAL_NULL);
     nsPIDOMWindow* window = mRequest->GetOwner();
 
     if (mFile) {
       result = nsIFileToJsval(window, mFile);
     } else if (mPath.Length()) {
       result = StringToJsval(window, mPath);
     }
     else {
@@ -3035,31 +3041,30 @@ nsDOMDeviceStorage::EnumerateEditable(co
                                      JSContext* aCx,
                                      uint8_t aArgc,
                                      nsIDOMDOMCursor** aRetval)
 {
   return EnumerateInternal(aName, aOptions, aCx, aArgc, true, aRetval);
 }
 
 
-static PRTime
-ExtractDateFromOptions(JSContext* aCx, const JS::Value& aOptions)
+static bool
+ExtractDateFromOptions(JSContext* aCx, const JS::Value& aOptions, PRTime* aTime)
 {
-  PRTime result = 0;
-  mozilla::idl::DeviceStorageEnumerationParameters params;
-  if (!JSVAL_IS_VOID(aOptions) && !aOptions.isNull()) {
-    nsresult rv = params.Init(aCx, &aOptions);
-    if (NS_SUCCEEDED(rv) && !JSVAL_IS_VOID(params.since) && !params.since.isNull() && params.since.isObject()) {
-      JS::Rooted<JSObject*> obj(aCx, JSVAL_TO_OBJECT(params.since));
-      if (JS_ObjectIsDate(aCx, obj) && js_DateIsValid(obj)) {
-        result = js_DateGetMsecSinceEpoch(obj);
-      }
-    }
+  JS::Rooted<JS::Value> options(aCx, aOptions);
+  RootedDictionary<DeviceStorageEnumerationParameters> params(aCx);
+  if (!params.Init(aCx, options)) {
+    return false;
   }
-  return result;
+  if (params.mSince.WasPassed() && !params.mSince.Value().IsUndefined()) {
+    *aTime = params.mSince.Value().TimeStamp();
+  } else {
+    *aTime = 0;
+  }
+  return true;
 }
 
 nsresult
 nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName,
                                      const JS::Value & aOptions,
                                      JSContext* aCx,
                                      uint8_t aArgc,
                                      bool aEditable,
@@ -3077,25 +3082,29 @@ nsDOMDeviceStorage::EnumerateInternal(co
     // inspect the first value to see if it is a string
     if (JSVAL_IS_STRING(aName)) {
       JSString* jsstr = JS_ValueToString(aCx, aName);
       nsDependentJSString jspath;
       jspath.init(aCx, jsstr);
       path.Assign(jspath);
     } else if (!JSVAL_IS_PRIMITIVE(aName)) {
       // it also might be an options object
-      since = ExtractDateFromOptions(aCx, aName);
+      if (!ExtractDateFromOptions(aCx, aName, &since)) {
+        return NS_ERROR_FAILURE;
+      }
     } else {
       return NS_ERROR_FAILURE;
     }
 
     if (aArgc == 2 && (JSVAL_IS_VOID(aOptions) || aOptions.isNull() || !aOptions.isObject())) {
       return NS_ERROR_FAILURE;
     }
-    since = ExtractDateFromOptions(aCx, aOptions);
+    if (!ExtractDateFromOptions(aCx, aOptions, &since)) {
+      return NS_ERROR_FAILURE;
+    }
   }
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
                                                           mStorageName,
                                                           path,
                                                           NS_LITERAL_STRING(""));
   dsf->SetEditable(aEditable);
 
--- a/dom/devicestorage/test/test_enumerateOptions.html
+++ b/dom/devicestorage/test/test_enumerateOptions.html
@@ -43,17 +43,17 @@ ok(!throws, "enumerate one string parame
 throws = false;
 try {
 var cursor = storage.enumerate("string", "string2");
 } catch(e) {throws = true}
 ok(throws, "enumerate two string parameter");
 
 throws = false;
 try {
-var cursor = storage.enumerate("string", {"since": 1});
+var cursor = storage.enumerate("string", {"since": new Date(1)});
 } catch(e) {throws = true}
 ok(!throws, "enumerate a string and object parameter");
 
 throws = false;
 try {
 var cursor = storage.enumerate({"path": "a"});
 } catch(e) {throws = true}
 ok(!throws, "enumerate object parameter with path");
@@ -61,17 +61,17 @@ ok(!throws, "enumerate object parameter 
 throws = false;
 try {
 var cursor = storage.enumerate({}, "string");
 } catch(e) {throws = true}
 ok(throws, "enumerate object then a string");
 
 throws = false;
 try {
-var cursor = storage.enumerate({"path": "a", "since": 0});
+var cursor = storage.enumerate({"path": "a", "since": new Date(0) });
 } catch(e) {throws = true}
 ok(!throws, "enumerate object parameter with path");
 
 
 
 
 devicestorage_cleanup()
 </script>
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -31,20 +31,23 @@
 #include "IDBTransaction.h"
 #include "IDBFactory.h"
 #include "ProfilerHelpers.h"
 #include "TransactionThreadPool.h"
 
 #include "ipc/IndexedDBChild.h"
 #include "ipc/IndexedDBParent.h"
 
+#include "mozilla/dom/IDBDatabaseBinding.h"
+
 USING_INDEXEDDB_NAMESPACE
 using mozilla::dom::ContentParent;
 using mozilla::dom::quota::Client;
 using mozilla::dom::quota::QuotaManager;
+using namespace mozilla::dom;
 
 namespace {
 
 class NoRequestDatabaseHelper : public AsyncConnectionHelper
 {
 public:
   NoRequestDatabaseHelper(IDBTransaction* aTransaction)
   : AsyncConnectionHelper(aTransaction, nullptr)
@@ -523,59 +526,45 @@ IDBDatabase::CreateObjectStore(const nsA
 
   if (!transaction ||
       transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   DatabaseInfo* databaseInfo = transaction->DBInfo();
 
-  mozilla::idl::IDBObjectStoreParameters params;
-  KeyPath keyPath(0);
-
-  nsresult rv;
-
-  if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) {
-    rv = params.Init(aCx, &aOptions);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
+  RootedDictionary<IDBObjectStoreParameters> params(aCx);
+  JS::Rooted<JS::Value> options(aCx, aOptions);
+  if (!params.Init(aCx, options)) {
+    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
 
-    // We need a default value here, which the XPIDL dictionary stuff doesn't
-    // support.  WebIDL shall save us all!
-    JSBool hasProp = false;
-    JSObject* obj = JSVAL_TO_OBJECT(aOptions);
-    if (!JS_HasProperty(aCx, obj, "keyPath", &hasProp)) {
-      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-    }
-
-    if (NS_FAILED(KeyPath::Parse(aCx, hasProp ? params.keyPath : JSVAL_NULL,
-                                 &keyPath))) {
-      return NS_ERROR_DOM_SYNTAX_ERR;
-    }
+  KeyPath keyPath(0);
+  if (NS_FAILED(KeyPath::Parse(aCx, params.mKeyPath, &keyPath))) {
+    return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   if (databaseInfo->ContainsStoreName(aName)) {
     return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
   }
 
-  if (!keyPath.IsAllowedForObjectStore(params.autoIncrement)) {
+  if (!keyPath.IsAllowedForObjectStore(params.mAutoIncrement)) {
     return NS_ERROR_DOM_INVALID_ACCESS_ERR;
   }
 
   ObjectStoreInfoGuts guts;
 
   guts.name = aName;
   guts.id = databaseInfo->nextObjectStoreId++;
   guts.keyPath = keyPath;
-  guts.autoIncrement = params.autoIncrement;
+  guts.autoIncrement = params.mAutoIncrement;
 
   nsRefPtr<IDBObjectStore> objectStore;
-  rv = CreateObjectStoreInternal(transaction, guts,
-                                 getter_AddRefs(objectStore));
+  nsresult rv = CreateObjectStoreInternal(transaction, guts,
+                                          getter_AddRefs(objectStore));
   NS_ENSURE_SUCCESS(rv, rv);
 
   objectStore.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBDatabase::DeleteObjectStore(const nsAString& aName)
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ b/dom/indexedDB/nsIIDBDatabase.idl
@@ -7,22 +7,16 @@
 #include "nsISupports.idl"
 
 interface nsIIDBObjectStore;
 interface nsIIDBRequest;
 interface nsIIDBTransaction;
 interface nsIDOMDOMStringList;
 interface nsIDOMEventListener;
 
-dictionary IDBObjectStoreParameters
-{
-  jsval keyPath;
-  boolean autoIncrement;
-};
-
 /**
  * IDBDatabase interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
  * for more information.
  */
 [scriptable, builtinclass, uuid(89299bf8-e078-4ebc-abda-d97fe5618602)]
 interface nsIIDBDatabase : nsISupports
 {
--- a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
+++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
@@ -6,21 +6,16 @@
 #include "nsIDOMEventTarget.idl"
 interface nsIDOMBlob;
 interface nsIDOMDOMRequest;
 interface nsIDOMDOMCursor;
 interface nsIDOMDeviceStorageChangeEvent;
 interface nsIDOMEventListener;
 interface nsIFile;
 
-dictionary DeviceStorageEnumerationParameters
-{
-  jsval since;
-};
-
 [scriptable, uuid(be690a9b-f0b4-4cde-a505-0b442abe2109), builtinclass]
 interface nsIDOMDeviceStorage : nsIDOMEventTarget
 {
     [implicit_jscontext] attribute jsval onchange;
     nsIDOMDOMRequest add(in nsIDOMBlob aBlob);
     nsIDOMDOMRequest addNamed(in nsIDOMBlob aBlob, in DOMString aName);
 
     [implicit_jscontext]
--- a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
@@ -6,24 +6,16 @@
 
 interface nsIDOMEventListener;
 interface nsIDOMMozSmsFilter;
 interface nsIDOMMozSmsSegmentInfo;
 interface nsIDOMDOMCursor;
 interface nsIDOMDOMRequest;
 interface nsIDOMBlob;
 
-dictionary MmsParameters
-{
-  jsval      receivers; // DOMString[]
-  DOMString? subject;
-  DOMString? smil;
-  jsval      attachments; // MmsAttachment[]
-};
-
 [scriptable, builtinclass, uuid(a7984cb3-27c8-4e3d-82a4-01553e93c078)]
 interface nsIDOMMozMobileMessageManager : nsIDOMEventTarget
 {
   nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text);
 
   // The first parameter can be either a DOMString (only one number) or an array
   // of DOMStrings.
   // The method returns a DOMRequest object if one number has been passed.
--- a/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
@@ -1,16 +1,17 @@
 /* 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 "nsISupports.idl"
 
 interface nsIDOMBlob;
 
+// If this is changed, change the WebIDL dictionary as well.
 dictionary MmsAttachment
 {
   DOMString? id;
   DOMString? location;
   nsIDOMBlob content;
 };
 
 [scriptable, builtinclass, uuid(2e5e1c16-b7af-11e2-af04-8f4b1610a600)]
--- a/dom/mobilemessage/src/MobileMessageCallback.cpp
+++ b/dom/mobilemessage/src/MobileMessageCallback.cpp
@@ -33,17 +33,17 @@ MobileMessageCallback::MobileMessageCall
 }
 
 MobileMessageCallback::~MobileMessageCallback()
 {
 }
 
 
 nsresult
-MobileMessageCallback::NotifySuccess(const JS::Value& aResult)
+MobileMessageCallback::NotifySuccess(JS::Handle<JS::Value> aResult)
 {
   mDOMRequest->FireSuccess(aResult);
   return NS_OK;
 }
 
 nsresult
 MobileMessageCallback::NotifySuccess(nsISupports *aMessage)
 {
@@ -116,17 +116,19 @@ MobileMessageCallback::NotifyGetMessageF
 {
   return NotifyError(aError);
 }
 
 NS_IMETHODIMP
 MobileMessageCallback::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
 {
   if (aSize == 1) {
-    return NotifySuccess(aDeleted[0] ? JSVAL_TRUE : JSVAL_FALSE);
+    AutoJSContext cx;
+    JS::Rooted<JS::Value> val(cx, aDeleted[0] ? JSVAL_TRUE : JSVAL_FALSE);
+    return NotifySuccess(val);
   }
 
   nsresult rv;
   nsIScriptContext* sc = mDOMRequest->GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
 
   AutoPushJSContext cx(sc->GetNativeContext());
@@ -135,29 +137,32 @@ MobileMessageCallback::NotifyMessageDele
   JS::Rooted<JSObject*> deleteArrayObj(cx, JS_NewArrayObject(cx, aSize, NULL));
   JS::Value jsValTrue = BOOLEAN_TO_JSVAL(1);
   JS::Value jsValFalse = BOOLEAN_TO_JSVAL(0);
   for (uint32_t i = 0; i < aSize; i++) {
     JS_SetElement(cx, deleteArrayObj, i,
                   aDeleted[i] ? &jsValTrue : &jsValFalse);
   }
 
-  return NotifySuccess(OBJECT_TO_JSVAL(deleteArrayObj));
+  JS::Rooted<JS::Value> deleteArrayVal(cx, JS::ObjectValue(*deleteArrayObj));
+  return NotifySuccess(deleteArrayVal);
 }
 
 NS_IMETHODIMP
 MobileMessageCallback::NotifyDeleteMessageFailed(int32_t aError)
 {
   return NotifyError(aError);
 }
 
 NS_IMETHODIMP
 MobileMessageCallback::NotifyMessageMarkedRead(bool aRead)
 {
-  return NotifySuccess(aRead ? JSVAL_TRUE : JSVAL_FALSE);
+  AutoJSContext cx;
+  JS::Rooted<JS::Value> val(cx, aRead ? JSVAL_TRUE : JSVAL_FALSE);
+  return NotifySuccess(val);
 }
 
 NS_IMETHODIMP
 MobileMessageCallback::NotifyMarkMessageReadFailed(int32_t aError)
 {
   return NotifyError(aError);
 }
 
--- a/dom/mobilemessage/src/MobileMessageCallback.h
+++ b/dom/mobilemessage/src/MobileMessageCallback.h
@@ -24,17 +24,17 @@ public:
 
   MobileMessageCallback(DOMRequest* aDOMRequest);
 
 private:
   ~MobileMessageCallback();
 
   nsRefPtr<DOMRequest> mDOMRequest;
 
-  nsresult NotifySuccess(const JS::Value& aResult);
+  nsresult NotifySuccess(JS::Handle<JS::Value> aResult);
   nsresult NotifySuccess(nsISupports *aMessage);
   nsresult NotifyError(int32_t aError);
 };
 
 } // namespace mobilemessage
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp
@@ -9,16 +9,19 @@
 #include "jsapi.h"
 #include "mozilla/dom/mobilemessage/SmsChild.h"
 #include "SmsMessage.h"
 #include "SmsFilter.h"
 #include "SmsSegmentInfo.h"
 #include "DictionaryHelpers.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/MobileMessageManagerBinding.h"
+#include "mozilla/dom/MozMmsMessageBinding.h"
+#include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::mobilemessage;
 
 namespace {
 
 // TODO: Bug 767082 - WebSMS: sSmsChild leaks at shutdown
 PSmsChild* gSmsChild;
@@ -169,85 +172,49 @@ SmsIPCService::CreateThreadCursor(nsIMob
 bool
 GetSendMmsMessageRequestFromParams(const JS::Value& aParam,
                                    SendMmsMessageRequest& request) {
   if (aParam.isUndefined() || aParam.isNull() || !aParam.isObject()) {
     return false;
   }
 
   mozilla::AutoJSContext cx;
-  mozilla::idl::MmsParameters params;
-  nsresult rv = params.Init(cx, &aParam);
-  NS_ENSURE_SUCCESS(rv, false);
-
-  uint32_t len;
-
-  // SendMobileMessageRequest.receivers
-  if (!params.receivers.isObject()) {
-    return false;
-  }
-  JS::Rooted<JSObject*> receiversObj(cx, &params.receivers.toObject());
-  if (!JS_GetArrayLength(cx, receiversObj, &len)) {
+  JS::Rooted<JS::Value> param(cx, aParam);
+  RootedDictionary<MmsParameters> params(cx);
+  if (!params.Init(cx, param)) {
     return false;
   }
 
-  request.receivers().SetCapacity(len);
-
-  for (uint32_t i = 0; i < len; i++) {
-    JS::Rooted<JS::Value> val(cx);
-    if (!JS_GetElement(cx, receiversObj, i, val.address())) {
-      return false;
-    }
-
-    if (!val.isString()) {
-      return false;
-    }
-
-    nsDependentJSString str;
-    if (!str.init(cx, val.toString())) {
-      return false;
-    }
-
-    request.receivers().AppendElement(str);
+  // SendMobileMessageRequest.receivers
+  if (!params.mReceivers.WasPassed()) {
+    return false;
   }
+  request.receivers().AppendElements(params.mReceivers.Value());
 
   // SendMobileMessageRequest.attachments
   mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
 
-  if (!params.attachments.isObject()) {
-    return false;
-  }
-  JS::Rooted<JSObject*> attachmentsObj(cx, &params.attachments.toObject());
-  if (!JS_GetArrayLength(cx, attachmentsObj, &len)) {
+  if (!params.mAttachments.WasPassed()) {
     return false;
   }
-  request.attachments().SetCapacity(len);
 
-  for (uint32_t i = 0; i < len; i++) {
-    JS::Rooted<JS::Value> val(cx);
-    if (!JS_GetElement(cx, attachmentsObj, i, val.address())) {
-      return false;
-    }
-
-    mozilla::idl::MmsAttachment attachment;
-    rv = attachment.Init(cx, val.address());
-    NS_ENSURE_SUCCESS(rv, false);
-
+  for (uint32_t i = 0; i < params.mAttachments.Value().Length(); i++) {
+    MmsAttachment& attachment = params.mAttachments.Value()[i];
     MmsAttachmentData mmsAttachment;
-    mmsAttachment.id().Assign(attachment.id);
-    mmsAttachment.location().Assign(attachment.location);
-    mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.content);
+    mmsAttachment.id().Assign(attachment.mId);
+    mmsAttachment.location().Assign(attachment.mLocation);
+    mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.mContent);
     if (!mmsAttachment.contentChild()) {
       return false;
     }
     request.attachments().AppendElement(mmsAttachment);
   }
 
-  request.smil() = params.smil;
-  request.subject() = params.subject;
+  request.smil() = params.mSmil;
+  request.subject() = params.mSubject;
 
   return true;
 }
 
 NS_IMETHODIMP
 SmsIPCService::Send(const JS::Value& aParameters,
                     nsIMobileMessageCallback *aRequest)
 {
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CameraManager.webidl
@@ -0,0 +1,48 @@
+/* -*- 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/.
+ */
+
+dictionary CameraPictureOptions {
+
+  /* an object with a combination of 'height' and 'width' properties
+     chosen from nsICameraCapabilities.pictureSizes */
+  // XXXbz this should be a CameraSize dictionary, but we don't have that yet.
+  any pictureSize = null;
+
+  /* one of the file formats chosen from
+     nsICameraCapabilities.fileFormats */
+  DOMString fileFormat = "";
+
+  /* the rotation of the image in degrees, from 0 to 270 in
+     steps of 90; this doesn't affect the image, only the
+     rotation recorded in the image header.*/
+  long rotation = 0;
+
+  /* an object containing any or all of 'latitude', 'longitude',
+     'altitude', and 'timestamp', used to record when and where
+     the image was taken.  e.g.
+     {
+         latitude:  43.647118,
+         longitude: -79.3943,
+         altitude:  500
+         // timestamp not specified, in this case, and
+         // won't be included in the image header
+     }
+
+     can be null in the case where position information isn't
+     available/desired.
+
+     'altitude' is in metres; 'timestamp' is UTC, in seconds from
+     January 1, 1970.
+  */
+  any position = null;
+
+  /* the number of seconds from January 1, 1970 UTC.  This can be
+     different from the positional timestamp (above). */
+  // XXXbz this should really accept a date too, no?
+  long long dateTime = 0;
+};
+
+// If we start using CameraPictureOptions here, remove it from DummyBinding.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/DeviceStorage.webidl
@@ -0,0 +1,12 @@
+/* -*- 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/.
+ */
+
+dictionary DeviceStorageEnumerationParameters {
+  Date since;
+};
+
+// If we start using DeviceStorageEnumerationParameters here, remove
+// it from DummyBinding.
--- a/dom/webidl/DummyBinding.webidl
+++ b/dom/webidl/DummyBinding.webidl
@@ -14,13 +14,18 @@ interface DummyInterface {
   USSDReceivedEventDict ussdReceivedEvent();
   InspectorRGBTriple rgbTriple();
   Function getFunction();
   void funcSocketsDict(optional SocketsDict arg);
   void funcHttpConnDict(optional HttpConnDict arg);
   void funcWebSocketDict(optional WebSocketDict arg);
   void funcDNSCacheDict(optional DNSCacheDict arg);
   void frameRequestCallback(FrameRequestCallback arg);
+  void idbObjectStoreParams(optional IDBObjectStoreParameters arg);
+  void DeviceStorageEnumerationParameters(optional DeviceStorageEnumerationParameters arg);
+  void CameraPictureOptions(optional CameraPictureOptions arg);
+  void MmsParameters(optional MmsParameters arg);
+  void MmsAttachment(optional MmsAttachment arg);
 };
 
 interface DummyInterfaceWorkers {
   BlobPropertyBag blobBag();
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/IDBDatabase.webidl
@@ -0,0 +1,14 @@
+/* -*- 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/.
+ */
+
+dictionary IDBObjectStoreParameters {
+  // XXXbz this should be "(DOMString or sequence<DOMString>)?", but
+  // we don't support unions in dictionaries yet.  See bug 767926.
+  any keyPath = null;
+  boolean autoIncrement = false;
+};
+
+// If we start using IDBObjectStoreParameters here, remove it from DummyBinding.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MobileMessageManager.webidl
@@ -0,0 +1,14 @@
+/* -*- 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/.
+ */
+
+dictionary MmsParameters {
+  sequence<DOMString> receivers;
+  DOMString? subject = null;
+  DOMString? smil = null;
+  sequence<MmsAttachment> attachments;
+};
+
+// If we start using MmsParameters here, remove it from DummyBinding.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MozMmsMessage.webidl
@@ -0,0 +1,14 @@
+/* -*- 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/.
+ */
+
+// If this is changed, change the XPIDL dictionary as well.
+dictionary MmsAttachment {
+  DOMString? id = null;
+  DOMString? location = null;
+  Blob? content = null;
+};
+
+// If we start using MmsParameters here, remove it from DummyBinding.
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -33,30 +33,32 @@ webidl_files = \
   CFStateChangeEvent.webidl \
   ChannelMergerNode.webidl \
   ChannelSplitterNode.webidl \
   CharacterData.webidl \
   ChildNode.webidl \
   ClientRect.webidl \
   ClientRectList.webidl \
   ClipboardEvent.webidl \
+  CameraManager.webidl \
   CommandEvent.webidl \
   Comment.webidl \
   CompositionEvent.webidl \
   Coordinates.webidl \
   CSS.webidl \
   CSSPrimitiveValue.webidl \
   CSSStyleDeclaration.webidl \
   CSSStyleSheet.webidl \
   CSSValue.webidl \
   CSSValueList.webidl \
   DataContainerEvent.webidl \
   DelayNode.webidl \
   DesktopNotification.webidl \
   DeviceMotionEvent.webidl \
+  DeviceStorage.webidl \
   Document.webidl \
   DocumentFragment.webidl \
   DocumentType.webidl \
   DOMCursor.webidl \
   DOMImplementation.webidl \
   DOMParser.webidl \
   DOMRequest.webidl \
   DOMSettableTokenList.webidl \
@@ -146,33 +148,36 @@ webidl_files = \
   HTMLTableRowElement.webidl \
   HTMLTableSectionElement.webidl \
   HTMLTemplateElement.webidl \
   HTMLTextAreaElement.webidl \
   HTMLTimeElement.webidl \
   HTMLTitleElement.webidl \
   HTMLUListElement.webidl \
   HTMLVideoElement.webidl \
+  IDBDatabase.webidl \
   IDBFactory.webidl \
   IDBVersionChangeEvent.webidl \
   ImageData.webidl \
   ImageDocument.webidl \
   InspectorUtils.webidl \
   KeyboardEvent.webidl \
   LinkStyle.webidl \
   LocalMediaStream.webidl \
   Location.webidl \
   MediaError.webidl \
   MediaStream.webidl \
   MediaStreamEvent.webidl \
   MediaStreamTrack.webidl \
   MessageEvent.webidl \
+  MobileMessageManager.webidl \
   MouseEvent.webidl \
   MouseScrollEvent.webidl \
   MozActivity.webidl \
+  MozMmsMessage.webidl \
   MozNamedAttrMap.webidl \
   MutationEvent.webidl \
   MutationObserver.webidl \
   NetDashboard.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeIterator.webidl \
   NodeList.webidl \
--- a/dom/workers/EventListenerManager.cpp
+++ b/dom/workers/EventListenerManager.cpp
@@ -204,17 +204,17 @@ EventListenerManager::FinalizeInternal(J
 
   DestroyList(aFop, mCollections);
 
   MOZ_ASSERT(mCollections.isEmpty());
 }
 
 void
 EventListenerManager::Add(JSContext* aCx, const jsid& aType,
-                          JSObject* aListener, Phase aPhase,
+                          JS::Handle<JSObject*> aListener, Phase aPhase,
                           bool aWantsUntrusted, ErrorResult& aRv)
 {
   MOZ_ASSERT(aListener);
 
   ListenerCollection* collection =
     GetCollectionForType(mCollections, aType);
   if (!collection) {
     collection = ListenerCollection::Add(aCx, mCollections, aType);
@@ -239,17 +239,17 @@ EventListenerManager::Add(JSContext* aCx
   if (!listenerData) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 }
 
 void
 EventListenerManager::Remove(JSContext* aCx, const jsid& aType,
-                             JSObject* aListener, Phase aPhase,
+                             JS::Handle<JSObject*> aListener, Phase aPhase,
                              bool aClearEmpty)
 {
   MOZ_ASSERT(aListener);
 
   ListenerCollection* collection =
     GetCollectionForType(mCollections, aType);
   if (collection) {
     for (ListenerData* listenerData = collection->mListeners.getFirst();
--- a/dom/workers/EventListenerManager.h
+++ b/dom/workers/EventListenerManager.h
@@ -55,45 +55,47 @@ public:
   {
     All = 0,
     Capturing,
     Onfoo,
     Bubbling
   };
 
   void
-  AddEventListener(JSContext* aCx, const jsid& aType, JSObject* aListener,
+  AddEventListener(JSContext* aCx, const jsid& aType,
+                   JS::Handle<JSObject*> aListener,
                    bool aCapturing, bool aWantsUntrusted, ErrorResult& aRv)
   {
     Add(aCx, aType, aListener, aCapturing ? Capturing : Bubbling,
         aWantsUntrusted, aRv);
   }
 
   void
-  RemoveEventListener(JSContext* aCx, const jsid& aType, JSObject* aListener,
-                      bool aCapturing)
+  RemoveEventListener(JSContext* aCx, const jsid& aType,
+                      JS::Handle<JSObject*> aListener, bool aCapturing)
   {
     if (mCollections.isEmpty()) {
       return;
     }
     Remove(aCx, aType, aListener, aCapturing ? Capturing : Bubbling, true);
   }
 
   bool
   DispatchEvent(JSContext* aCx, const EventTarget& aTarget, JSObject* aEvent,
                 ErrorResult& aRv) const;
 
   JSObject*
   GetEventListener(const jsid& aType) const;
 
   void
-  SetEventListener(JSContext* aCx, const jsid& aType, JSObject* aListener,
+  SetEventListener(JSContext* aCx, const jsid& aType,
+                   JS::Handle<JSObject*> aListener,
                    ErrorResult& aRv)
   {
-    JSObject* existing = GetEventListener(aType);
+    JS::Rooted<JSObject*> existing(aCx, GetEventListener(aType));
     if (existing) {
       Remove(aCx, aType, existing, Onfoo, false);
     }
 
     if (aListener) {
       Add(aCx, aType, aListener, Onfoo, false, aRv);
     }
   }
@@ -113,22 +115,22 @@ public:
 private:
   void
   TraceInternal(JSTracer* aTrc) const;
 
   void
   FinalizeInternal(JSFreeOp* aFop);
 
   void
-  Add(JSContext* aCx, const jsid& aType, JSObject* aListener, Phase aPhase,
-      bool aWantsUntrusted, ErrorResult& aRv);
+  Add(JSContext* aCx, const jsid& aType, JS::Handle<JSObject*> aListener,
+      Phase aPhase, bool aWantsUntrusted, ErrorResult& aRv);
 
   void
-  Remove(JSContext* aCx, const jsid& aType, JSObject* aListener, Phase aPhase,
-         bool aClearEmpty);
+  Remove(JSContext* aCx, const jsid& aType, JS::Handle<JSObject*> aListener,
+         Phase aPhase, bool aClearEmpty);
 
   bool
   HasListenersForTypeInternal(JSContext* aCx, const jsid& aType) const;
 };
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_listenermanager_h__ */
--- a/dom/workers/EventTarget.cpp
+++ b/dom/workers/EventTarget.cpp
@@ -34,68 +34,68 @@ EventTarget::GetEventListener(const nsAS
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return NULL;
   }
 
   return mListenerManager.GetEventListener(INTERNED_STRING_TO_JSID(cx, type));
 }
 
 void
-EventTarget::SetEventListener(const nsAString& aType, JSObject* aListener_,
+EventTarget::SetEventListener(const nsAString& aType,
+                              JS::Handle<JSObject*> aListener,
                               ErrorResult& aRv)
 {
   JSContext* cx = GetJSContext();
-  JS::Rooted<JSObject*> aListener(cx, aListener_);
 
   JSString* type =
     JS_NewUCStringCopyN(cx, aType.BeginReading(), aType.Length());
   if (!type || !(type = JS_InternJSString(cx, type))) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   mListenerManager.SetEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
                                     aListener, aRv);
 }
 
 void
-EventTarget::AddEventListener(const nsAString& aType, JSObject* aListener_,
+EventTarget::AddEventListener(const nsAString& aType,
+                              JS::Handle<JSObject*> aListener,
                               bool aCapturing, Nullable<bool> aWantsUntrusted,
                               ErrorResult& aRv)
 {
-  if (!aListener_) {
+  if (!aListener) {
     return;
   }
 
   JSContext* cx = GetJSContext();
-  JS::Rooted<JSObject*> aListener(cx, aListener_);
 
   JSString* type =
     JS_NewUCStringCopyN(cx, aType.BeginReading(), aType.Length());
   if (!type || !(type = JS_InternJSString(cx, type))) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value();
   mListenerManager.AddEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
                                     aListener, aCapturing, wantsUntrusted,
                                     aRv);
 }
 
 void
-EventTarget::RemoveEventListener(const nsAString& aType, JSObject* aListener_,
+EventTarget::RemoveEventListener(const nsAString& aType,
+                                 JS::Handle<JSObject*> aListener,
                                  bool aCapturing, ErrorResult& aRv)
 {
-  if (!aListener_) {
+  if (!aListener) {
     return;
   }
 
   JSContext* cx = GetJSContext();
-  JS::Rooted<JSObject*> aListener(cx, aListener_);
 
   JSString* type =
     JS_NewUCStringCopyN(cx, aType.BeginReading(), aType.Length());
   if (!type || !(type = JS_InternJSString(cx, type))) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -32,35 +32,35 @@ protected:
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   void
-  AddEventListener(const nsAString& aType, JSObject* aListener,
+  AddEventListener(const nsAString& aType, JS::Handle<JSObject*> aListener,
                    bool aCapture, Nullable<bool> aWantsUntrusted,
                    ErrorResult& aRv);
 
   void
-  RemoveEventListener(const nsAString& aType, JSObject* aListener,
+  RemoveEventListener(const nsAString& aType, JS::Handle<JSObject*> aListener,
                       bool aCapture, ErrorResult& aRv);
 
   bool
   DispatchEvent(JS::Handle<JSObject*> aEvent, ErrorResult& aRv) const
   {
     return mListenerManager.DispatchEvent(GetJSContext(), *this, aEvent, aRv);
   }
 
   JSObject*
   GetEventListener(const nsAString& aType, ErrorResult& aRv) const;
 
   void
-  SetEventListener(const nsAString& aType, JSObject* aListener,
+  SetEventListener(const nsAString& aType, JS::Handle<JSObject*> aListener,
                    ErrorResult& aRv);
 
   bool
   HasListeners() const
   {
     return mListenerManager.HasListeners();
   }
 
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -181,18 +181,19 @@ private:
     }
 
     if (JSVAL_IS_PRIMITIVE(aVp)) {
       JS_ReportError(aCx, "Not an event listener!");
       return false;
     }
 
     ErrorResult rv;
+    JS::Rooted<JSObject*> listenerObj(aCx, JSVAL_TO_OBJECT(aVp));
     scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2),
-                            JSVAL_TO_OBJECT(aVp), rv);
+                            listenerObj, rv);
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
     return true;
   }
 
@@ -355,17 +356,17 @@ private:
 
     JSFunction* adaptor =
       js::NewFunctionWithReserved(aCx, UnwrapErrorEvent, 1, 0,
                                   JS_GetGlobalForScopeChain(aCx), "unwrap");
     if (!adaptor) {
       return false;
     }
 
-    JSObject* listener = JS_GetFunctionObject(adaptor);
+    JS::Rooted<JSObject*> listener(aCx, JS_GetFunctionObject(adaptor));
     if (!listener) {
       return false;
     }
 
     js::SetFunctionNativeReserved(listener, SLOT_wrappedScope,
                                   OBJECT_TO_JSVAL(aObj));
     js::SetFunctionNativeReserved(listener, SLOT_wrappedFunction, aVp);
 
@@ -771,18 +772,19 @@ private:
 
     if (JSVAL_IS_PRIMITIVE(aVp)) {
       JS_ReportError(aCx, "Not an event listener!");
       return false;
     }
 
     ErrorResult rv;
 
+    JS::Rooted<JSObject*> listenerObj(aCx, JSVAL_TO_OBJECT(aVp));
     scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2),
-                            JSVAL_TO_OBJECT(aVp), rv);
+                            listenerObj, rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
     return true;
   }
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -660,16 +660,18 @@ public:
       else {
         mProxy->mLastLengthComputable = mLengthComputable;
         mProxy->mLastLoaded = mLoaded;
         mProxy->mLastTotal = mTotal;
       }
     }
 
     XMLHttpRequest::StateData state;
+    // XXXbz there is no AutoValueRooter anymore?
+    JS::AutoArrayRooter rooter(aCx, 1, &state.mResponse);
 
     state.mResponseTextResult = mResponseTextResult;
     state.mResponseText = mResponseText;
 
     if (NS_SUCCEEDED(mResponseTextResult)) {
       MOZ_ASSERT(JSVAL_IS_VOID(mResponse) || JSVAL_IS_NULL(mResponse));
       state.mResponseResult = mResponseTextResult;
       state.mResponse = mResponse;
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -100,17 +100,18 @@ public:
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \
   GetOn##_type(JSContext* /* unused */, ErrorResult& aRv)                      \
   {                                                                            \
     return GetEventListener(NS_LITERAL_STRING(#_type), aRv);                   \
   }                                                                            \
                                                                                \
   void                                                                         \
-  SetOn##_type(JSContext* /* unused */, JSObject* aListener, ErrorResult& aRv) \
+  SetOn##_type(JSContext* /* unused */,  JS::Handle<JSObject*> aListener,      \
+               ErrorResult& aRv)                                               \
   {                                                                            \
     SetEventListener(NS_LITERAL_STRING(#_type), aListener, aRv);               \
   }
 
   IMPL_GETTER_AND_SETTER(readystatechange)
 
 #undef IMPL_GETTER_AND_SETTER
 
--- a/dom/workers/XMLHttpRequestEventTarget.h
+++ b/dom/workers/XMLHttpRequestEventTarget.h
@@ -30,17 +30,18 @@ public:
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \
   GetOn##_type(JSContext* /* unused */, ErrorResult& aRv)                      \
   {                                                                            \
     return GetEventListener(NS_LITERAL_STRING(#_type), aRv);                   \
   }                                                                            \
                                                                                \
   void                                                                         \
-  SetOn##_type(JSContext* /* unused */, JSObject* aListener, ErrorResult& aRv) \
+  SetOn##_type(JSContext* /* unused */, JS::Handle<JSObject*> aListener,       \
+               ErrorResult& aRv)                                               \
   {                                                                            \
     SetEventListener(NS_LITERAL_STRING(#_type), aListener, aRv);               \
   }
 
   IMPL_GETTER_AND_SETTER(loadstart)
   IMPL_GETTER_AND_SETTER(progress)
   IMPL_GETTER_AND_SETTER(abort)
   IMPL_GETTER_AND_SETTER(error)
--- a/js/xpconnect/src/dictionary_helper_gen.conf
+++ b/js/xpconnect/src/dictionary_helper_gen.conf
@@ -4,30 +4,26 @@
 
 # Dictionary interface name, interface file name
 dictionaries = [
      [ 'EventInit', 'nsIDOMEvent.idl' ],
      [ 'UIEventInit', 'nsIDOMUIEvent.idl' ],
      [ 'MouseEventInit', 'nsIDOMMouseEvent.idl' ],
      [ 'ClipboardEventInit', 'nsIDOMClipboardEvent.idl' ],
      [ 'WheelEventInit', 'nsIDOMWheelEvent.idl' ],
-     [ 'IDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
      [ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
      [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ],
      [ 'DOMFileMetadataParameters', 'nsIDOMLockedFile.idl' ],
-     [ 'DeviceStorageEnumerationParameters', 'nsIDOMDeviceStorage.idl' ],
      [ 'CameraSize', 'nsIDOMCameraManager.idl' ],
      [ 'CameraRegion', 'nsIDOMCameraManager.idl' ],
      [ 'CameraPosition', 'nsIDOMCameraManager.idl' ],
      [ 'CameraSelector', 'nsIDOMCameraManager.idl' ],
-     [ 'CameraPictureOptions', 'nsIDOMCameraManager.idl' ],
      [ 'CameraRecordingOptions', 'nsIDOMCameraManager.idl' ],
      [ 'SmsThreadListItem', 'nsIMobileMessageCallback.idl' ],
-     [ 'MmsAttachment', 'nsIDOMMozMmsMessage.idl' ],
-     [ 'MmsParameters', 'nsIDOMMobileMessageManager.idl' ]
+     [ 'MmsAttachment', 'nsIDOMMozMmsMessage.idl' ]
    ]
 
 # include file names
 special_includes = [
     'nsContentUtils.h',
     'XPCQuickStubs.h',
     'nsIDOMApplicationRegistry.h',
     'nsIDOMFile.h'