Bug 888597 - Move IDBObjectStore to WebIDL, r=janv
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 31 Jul 2013 17:48:36 +0200
changeset 140794 947b4570fae6827474da90120767c7ef3218dc68
parent 140793 553bc5d3430b39be67ff138ed7600222b1681839
child 140795 afac636489dee5201f001d2c7153e24120856540
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjanv
bugs888597
milestone25.0a1
Bug 888597 - Move IDBObjectStore to WebIDL, r=janv
addon-sdk/source/lib/sdk/indexed-db.js
addon-sdk/source/test/test-indexed-db.js
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBCursor.h
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/KeyPath.cpp
dom/indexedDB/KeyPath.h
dom/indexedDB/ipc/IndexedDBParent.cpp
dom/indexedDB/moz.build
dom/indexedDB/nsIIDBDatabase.idl
dom/indexedDB/nsIIDBIndex.idl
dom/indexedDB/nsIIDBObjectStore.idl
dom/indexedDB/test/unit/head.js
dom/indexedDB/test/unit/test_complex_keyPaths.js
dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
dom/indexedDB/test/unit/test_objectStore_remove_values.js
dom/indexedDB/test/unit/test_open_objectStore.js
dom/indexedDB/test/unit/test_remove_index.js
dom/indexedDB/test/unit/test_remove_objectStore.js
dom/webidl/IDBCursor.webidl
dom/webidl/IDBIndex.webidl
dom/webidl/IDBObjectStore.webidl
dom/webidl/IDBTransaction.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/dictionary_helper_gen.conf
js/xpconnect/src/dom_quickstubs.qsconf
js/xpconnect/src/nsXPConnect.cpp
--- a/addon-sdk/source/lib/sdk/indexed-db.js
+++ b/addon-sdk/source/lib/sdk/indexed-db.js
@@ -52,10 +52,9 @@ exports.indexedDB = Object.freeze({
 });
 
 exports.IDBKeyRange = IDBKeyRange;
 exports.DOMException = Ci.nsIDOMDOMException;
 exports.IDBCursor = Ci.nsIIDBCursor;
 exports.IDBOpenDBRequest = Ci.nsIIDBOpenDBRequest;
 exports.IDBDatabase = Ci.nsIIDBDatabase;
 exports.IDBIndex = Ci.nsIIDBIndex;
-exports.IDBObjectStore = Ci.nsIIDBObjectStore;
 exports.IDBRequest = Ci.nsIIDBRequest;
--- a/addon-sdk/source/test/test-indexed-db.js
+++ b/addon-sdk/source/test/test-indexed-db.js
@@ -4,32 +4,32 @@
 
 "use strict";
 
 let xulApp = require("sdk/system/xul-app");
 if (xulApp.versionInRange(xulApp.platformVersion, "16.0a1", "*")) {
 new function tests() {
 
 const { indexedDB, IDBKeyRange, DOMException, IDBCursor,
-        IDBOpenDBRequest, IDBDatabase, IDBIndex, IDBObjectStore, IDBRequest
+        IDBOpenDBRequest, IDBDatabase, IDBIndex, IDBRequest
       } = require("sdk/indexed-db");
 
 exports["test indexedDB is frozen"] = function(assert){
   let original = indexedDB.open;
   let f = function(){};
   assert.throws(function(){indexedDB.open = f});
   assert.equal(indexedDB.open,original);
   assert.notEqual(indexedDB.open,f);
 
 };
 
 exports["test db variables"] = function(assert) {
   [ indexedDB, IDBKeyRange, DOMException, IDBCursor,
     IDBOpenDBRequest, IDBOpenDBRequest, IDBDatabase, IDBIndex,
-    IDBObjectStore, IDBRequest
+    IDBRequest
   ].forEach(function(value) {
     assert.notEqual(typeof(value), "undefined", "variable is defined");
   });
 }
 
 exports["test open"] = function(assert, done) {
   let request = indexedDB.open("MyTestDatabase");
   request.onerror = function(event) {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -199,17 +199,16 @@
 
 #include "nsIEventListenerService.h"
 #include "nsIMessageManager.h"
 #include "mozilla/dom/Element.h"
 
 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
 #include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBDatabase.h"
-#include "mozilla/dom/indexedDB/IDBObjectStore.h"
 #include "mozilla/dom/indexedDB/IDBCursor.h"
 #include "mozilla/dom/indexedDB/IDBKeyRange.h"
 #include "mozilla/dom/indexedDB/IDBIndex.h"
 
 using mozilla::dom::indexedDB::IDBWrapperCache;
 using mozilla::dom::workers::ResolveWorkerClasses;
 
 #include "nsIDOMMediaQueryList.h"
@@ -633,18 +632,16 @@ static nsDOMClassInfoData sClassInfoData
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(IDBRequest, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBDatabase, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBObjectStore, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursorWithValue, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBKeyRange, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBIndex, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1541,20 +1538,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(IDBDatabase, nsIIDBDatabase)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBDatabase)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(IDBObjectStore, nsIIDBObjectStore)
-    DOM_CLASSINFO_MAP_ENTRY(nsIIDBObjectStore)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(IDBCursor, nsIIDBCursor)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(IDBCursorWithValue, nsIIDBCursorWithValue)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursor)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursorWithValue)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -116,17 +116,16 @@ DOMCI_CLASS(DataTransfer)
 DOMCI_CLASS(EventListenerInfo)
 
 DOMCI_CLASS(ContentFrameMessageManager)
 DOMCI_CLASS(ChromeMessageBroadcaster)
 DOMCI_CLASS(ChromeMessageSender)
 
 DOMCI_CLASS(IDBRequest)
 DOMCI_CLASS(IDBDatabase)
-DOMCI_CLASS(IDBObjectStore)
 DOMCI_CLASS(IDBCursor)
 DOMCI_CLASS(IDBCursorWithValue)
 DOMCI_CLASS(IDBKeyRange)
 DOMCI_CLASS(IDBIndex)
 DOMCI_CLASS(IDBOpenDBRequest)
 
 
 DOMCI_CLASS(MozCSSKeyframeRule)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -541,16 +541,24 @@ DOMInterfaces = {
 'IDBFactory': {
     'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
 },
 
 'IDBFileHandle': {
     'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
 },
 
+'IDBObjectStore': {
+    'nativeType': 'mozilla::dom::indexedDB::IDBObjectStore',
+    'implicitJSContext': [ 'createIndex' ],
+    'binaryNames': {
+        'mozGetAll': 'getAll'
+    }
+},
+
 'IDBTransaction': {
     'nativeType': 'mozilla::dom::indexedDB::IDBTransaction',
 },
 
 'IDBVersionChangeEvent': {
     'nativeType': 'mozilla::dom::indexedDB::IDBVersionChangeEvent',
     'headerFile': 'IDBEvents.h',
 },
@@ -1655,18 +1663,19 @@ addExternalIface('mozIDOMApplication', n
 addExternalIface('CSSRuleList')
 addExternalIface('DOMStringList')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('File')
 addExternalIface('FileCallback', nativeType='nsIFileCallback',
                  headerFile='nsIDOMHTMLCanvasElement.h')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('IDBDatabase', nativeType='nsIIDBDatabase')
-addExternalIface('IDBObjectStore', nativeType='nsIIDBObjectStore')
+addExternalIface('IDBIndex', nativeType='nsIIDBIndex')
 addExternalIface('IDBOpenDBRequest', nativeType='nsIIDBOpenDBRequest')
+addExternalIface('IDBRequest', nativeType='nsIIDBRequest')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaList')
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('MozBluetoothManager', nativeType='nsIDOMBluetoothManager')
 addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
 addExternalIface('MozCellBroadcast')
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -291,16 +291,38 @@ IDBCursor::ParseDirection(const nsAStrin
   else {
     return NS_ERROR_TYPE_ERR;
   }
   
   return NS_OK;
 }
 
 // static
+IDBCursor::Direction
+IDBCursor::ConvertDirection(mozilla::dom::IDBCursorDirection aDirection)
+{
+  switch (aDirection) {
+    case mozilla::dom::IDBCursorDirection::Next:
+      return NEXT;
+
+    case mozilla::dom::IDBCursorDirection::Nextunique:
+      return NEXT_UNIQUE;
+
+    case mozilla::dom::IDBCursorDirection::Prev:
+      return PREV;
+
+    case mozilla::dom::IDBCursorDirection::Prevunique:
+      return PREV_UNIQUE;
+
+    default:
+      MOZ_CRASH("Unknown direction!");
+  }
+}
+
+// static
 already_AddRefed<IDBCursor>
 IDBCursor::CreateCommon(IDBRequest* aRequest,
                         IDBTransaction* aTransaction,
                         IDBObjectStore* aObjectStore,
                         Direction aDirection,
                         const Key& aRangeKey,
                         const nsACString& aContinueQuery,
                         const nsACString& aContinueToQuery)
@@ -727,29 +749,35 @@ IDBCursor::Update(const jsval& aValue,
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     if (key != objectKey) {
       return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
     }
 
-    rv = mObjectStore->Put(aValue, JSVAL_VOID, aCx, 0, getter_AddRefs(request));
-    if (NS_FAILED(rv)) {
-      return rv;
+    ErrorResult error;
+    JS::Rooted<JS::Value> value(aCx, aValue);
+    Optional<JS::Handle<JS::Value> > keyValue(aCx);
+    request = mObjectStore->Put(aCx, value, keyValue, error);
+    if (error.Failed()) {
+      return error.ErrorCode();
     }
   }
   else {
     JS::Rooted<JS::Value> keyVal(aCx);
     rv = objectKey.ToJSVal(aCx, &keyVal);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = mObjectStore->Put(aValue, keyVal, aCx, 1, getter_AddRefs(request));
-    if (NS_FAILED(rv)) {
-      return rv;
+    ErrorResult error;
+    JS::Rooted<JS::Value> value(aCx, aValue);
+    Optional<JS::Handle<JS::Value> > keyValue(aCx, keyVal);
+    request = mObjectStore->Put(aCx, value, keyValue, error);
+    if (error.Failed()) {
+      return error.ErrorCode();
     }
   }
 
 #ifdef IDB_PROFILER_USE_MARKS
   {
     uint64_t requestSerial =
       static_cast<IDBRequest*>(request.get())->GetSerialNumber();
     if (mType == OBJECTSTORE) {
@@ -808,20 +836,20 @@ IDBCursor::Delete(JSContext* aCx,
   NS_ASSERTION(!mKey.IsUnset() , "Bad key!");
 
   Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
 
   JS::Rooted<JS::Value> key(aCx);
   nsresult rv = objectKey.ToJSVal(aCx, &key);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIIDBRequest> request;
-  rv = mObjectStore->Delete(key, aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
+  ErrorResult error;
+  nsCOMPtr<nsIIDBRequest> request = mObjectStore->Delete(aCx, key, error);
+  if (error.Failed()) {
+    return error.ErrorCode();
   }
 
 #ifdef IDB_PROFILER_USE_MARKS
   {
     uint64_t requestSerial =
       static_cast<IDBRequest*>(request.get())->GetSerialNumber();
     if (mType == OBJECTSTORE) {
       IDB_PROFILER_MARK("IndexedDB Request %llu: "
--- a/dom/indexedDB/IDBCursor.h
+++ b/dom/indexedDB/IDBCursor.h
@@ -3,22 +3,25 @@
 /* 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 mozilla_dom_indexeddb_idbcursor_h__
 #define mozilla_dom_indexeddb_idbcursor_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
+
+#include "nsIIDBCursorWithValue.h"
+
+#include "mozilla/dom/IDBCursorBinding.h"
+#include "nsCycleCollectionParticipant.h"
+
 #include "mozilla/dom/indexedDB/IDBObjectStore.h"
 #include "mozilla/dom/indexedDB/Key.h"
 
-#include "nsIIDBCursorWithValue.h"
-
-#include "nsCycleCollectionParticipant.h"
 
 class nsIRunnable;
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class ContinueHelper;
@@ -108,18 +111,21 @@ public:
     return mTransaction;
   }
 
   IDBRequest* Request() const
   {
     return mRequest;
   }
 
-  static nsresult ParseDirection(const nsAString& aDirection,
-                                 Direction* aResult);
+  static nsresult
+  ParseDirection(const nsAString& aDirection, Direction* aResult);
+
+  static Direction
+  ConvertDirection(IDBCursorDirection aDirection);
 
   void
   SetActor(IndexedDBCursorChild* aActorChild)
   {
     NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
     mActorChild = aActorChild;
   }
 
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -520,17 +520,17 @@ IDBDatabase::GetObjectStoreNames(nsIDOMD
   list.forget(aObjectStores);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBDatabase::CreateObjectStore(const nsAString& aName,
                                const jsval& aOptions,
                                JSContext* aCx,
-                               nsIIDBObjectStore** _retval)
+                               nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
 
   if (!transaction ||
       transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -790,17 +790,18 @@ IDBIndex::GetName(nsAString& aName)
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::GetStoreName(nsAString& aStoreName)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  return mObjectStore->GetName(aStoreName);
+  aStoreName.Assign(mObjectStore->Name());
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::GetKeyPath(JSContext* aCx,
                      jsval* aVal)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
@@ -835,21 +836,21 @@ IDBIndex::GetMultiEntry(bool* aMultiEntr
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   *aMultiEntry = mMultiEntry;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-IDBIndex::GetObjectStore(nsIIDBObjectStore** aObjectStore)
+IDBIndex::GetObjectStore(nsISupports** aObjectStore)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  nsCOMPtr<nsIIDBObjectStore> objectStore(mObjectStore);
+  nsCOMPtr<nsISupports> objectStore(mObjectStore);
   objectStore.forget(aObjectStore);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::Get(const jsval& aKey,
               JSContext* aCx,
               nsIIDBRequest** _retval)
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -47,16 +47,17 @@
 #include "IndexedDatabaseInlines.h"
 
 #define FILE_COPY_BUFFER_SIZE 32768
 
 USING_INDEXEDDB_NAMESPACE
 using namespace mozilla::dom;
 using namespace mozilla::dom::indexedDB::ipc;
 using mozilla::dom::quota::FileOutputStream;
+using mozilla::ErrorResult;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 struct FileHandleData
 {
   nsString type;
   nsString name;
 };
@@ -1725,16 +1726,18 @@ IDBObjectStore::IDBObjectStore()
   mKeyPath(0),
   mCachedKeyPath(JSVAL_VOID),
   mRooted(false),
   mAutoIncrement(false),
   mActorChild(nullptr),
   mActorParent(nullptr)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  SetIsDOMBinding();
 }
 
 IDBObjectStore::~IDBObjectStore()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mActorParent, "Actor parent owns us, how can we be dying?!");
   if (mActorChild) {
     NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
@@ -1808,57 +1811,63 @@ IDBObjectStore::GetAddInfo(JSContext* aC
   }
   else {
     rv = GetAddInfoCallback(aCx, &data);
   }
 
   return rv;
 }
 
-nsresult
-IDBObjectStore::AddOrPut(const jsval& aValue,
-                         const jsval& aKey,
-                         JSContext* aCx,
-                         uint8_t aOptionalArgCount,
-                         bool aOverwrite,
-                         IDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
+                         const Optional<JS::Handle<JS::Value> >& aKey,
+                         bool aOverwrite, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   if (!IsWriteAllowed()) {
-    return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
+    return nullptr;
   }
 
-  JS::Rooted<JS::Value> keyval(aCx,
-    (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID);
+  JS::Rooted<JS::Value> keyval(aCx, aKey.WasPassed() ? aKey.Value()
+                                                     : JSVAL_VOID);
 
   StructuredCloneWriteInfo cloneWriteInfo;
   Key key;
   nsTArray<IndexUpdateInfo> updateInfo;
 
   JS::Rooted<JS::Value> value(aCx, aValue);
-  nsresult rv = GetAddInfo(aCx, value, keyval, cloneWriteInfo, key,
-                           updateInfo);
-  if (NS_FAILED(rv)) {
-    return rv;
+  aRv = GetAddInfo(aCx, value, keyval, cloneWriteInfo, key, updateInfo);
+  if (aRv.Failed()) {
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<AddHelper> helper =
     new AddHelper(mTransaction, request, this, cloneWriteInfo, key,
                   aOverwrite, updateInfo);
 
-  rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  nsresult rv = helper->DispatchToTransactionPool();
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
 #ifdef IDB_PROFILER_USE_MARKS
   if (aOverwrite) {
     IDB_PROFILER_MARK("IndexedDB Request %llu: "
                       "database(%s).transaction(%s).objectStore(%s).%s(%s)",
                       "IDBRequest[%llu] MT IDBObjectStore.put()",
                       request->GetSerialNumber(),
                       IDB_PROFILER_STRING(Transaction()->Database()),
@@ -1873,18 +1882,17 @@ IDBObjectStore::AddOrPut(const jsval& aV
                       request->GetSerialNumber(),
                       IDB_PROFILER_STRING(Transaction()->Database()),
                       IDB_PROFILER_STRING(Transaction()),
                       IDB_PROFILER_STRING(this),
                       key.IsUnset() ? "" : IDB_PROFILER_STRING(key));
   }
 #endif
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
 nsresult
 IDBObjectStore::AddOrPutInternal(
                       const SerializedStructuredCloneWriteInfo& aCloneWriteInfo,
                       const Key& aKey,
                       const InfallibleTArray<IndexUpdateInfo>& aUpdateInfoArray,
                       const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
@@ -1986,222 +1994,262 @@ IDBObjectStore::AddOrPutInternal(
                       key.IsUnset() ? "" : IDB_PROFILER_STRING(key));
   }
 #endif
 
   request.forget(_retval);
   return NS_OK;
 }
 
-nsresult
-IDBObjectStore::GetInternal(IDBKeyRange* aKeyRange,
-                            JSContext* aCx,
-                            IDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::GetInternal(IDBKeyRange* aKeyRange, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aKeyRange, "Null pointer!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<GetHelper> helper =
     new GetHelper(mTransaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s).get(%s)",
                     "IDBRequest[%llu] MT IDBObjectStore.get()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange));
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
-nsresult
+already_AddRefed<IDBRequest>
 IDBObjectStore::GetAllInternal(IDBKeyRange* aKeyRange,
-                               uint32_t aLimit,
-                               JSContext* aCx,
-                               IDBRequest** _retval)
+                               uint32_t aLimit, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<GetAllHelper> helper =
     new GetAllHelper(mTransaction, request, this, aKeyRange, aLimit);
 
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s)."
                     "getAll(%s, %lu)",
                     "IDBRequest[%llu] MT IDBObjectStore.getAll()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
                     aLimit);
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
-nsresult
+already_AddRefed<IDBRequest>
 IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange,
-                               JSContext* aCx,
-                               IDBRequest** _retval)
+                               ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aKeyRange, "Null key range!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   if (!IsWriteAllowed()) {
-    return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<DeleteHelper> helper =
     new DeleteHelper(mTransaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s).delete(%s)",
                     "IDBRequest[%llu] MT IDBObjectStore.delete()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange));
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
-nsresult
-IDBObjectStore::ClearInternal(JSContext* aCx,
-                              IDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::Clear(ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   if (!IsWriteAllowed()) {
-    return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<ClearHelper> helper(new ClearHelper(mTransaction, request, this));
 
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s).clear()",
                     "IDBRequest[%llu] MT IDBObjectStore.clear()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this));
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
-nsresult
-IDBObjectStore::CountInternal(IDBKeyRange* aKeyRange,
-                              JSContext* aCx,
-                              IDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::CountInternal(IDBKeyRange* aKeyRange, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<CountHelper> helper =
     new CountHelper(mTransaction, request, this, aKeyRange);
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s).count(%s)",
                     "IDBRequest[%llu] MT IDBObjectStore.count()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange));
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
-nsresult
+already_AddRefed<IDBRequest>
 IDBObjectStore::OpenCursorInternal(IDBKeyRange* aKeyRange,
-                                   size_t aDirection,
-                                   JSContext* aCx,
-                                   IDBRequest** _retval)
+                                   size_t aDirection, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   IDBCursor::Direction direction =
     static_cast<IDBCursor::Direction>(aDirection);
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
-  NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<OpenCursorHelper> helper =
     new OpenCursorHelper(mTransaction, request, this, aKeyRange, direction);
 
   nsresult rv = helper->DispatchToTransactionPool();
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Request %llu: "
                     "database(%s).transaction(%s).objectStore(%s)."
                     "openCursor(%s, %s)",
                     "IDBRequest[%llu] MT IDBObjectStore.openCursor()",
                     request->GetSerialNumber(),
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
                     IDB_PROFILER_STRING(direction));
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
 nsresult
 IDBObjectStore::OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
@@ -2240,19 +2288,18 @@ void
 IDBObjectStore::SetInfo(ObjectStoreInfo* aInfo)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
   NS_ASSERTION(aInfo != mInfo, "This is nonsense");
 
   mInfo = aInfo;
 }
 
-nsresult
-IDBObjectStore::CreateIndexInternal(const IndexInfo& aInfo,
-                                    IDBIndex** _retval)
+already_AddRefed<nsIIDBIndex>
+IDBObjectStore::CreateIndexInternal(const IndexInfo& aInfo, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IndexInfo* indexInfo = mInfo->indexes.AppendElement();
 
   indexInfo->name = aInfo.name;
   indexInfo->id = aInfo.id;
   indexInfo->keyPath = aInfo.keyPath;
@@ -2266,521 +2313,416 @@ IDBObjectStore::CreateIndexInternal(cons
 
   mCreatedIndexes.AppendElement(index);
 
   if (IndexedDatabaseManager::IsMainProcess()) {
     nsRefPtr<CreateIndexHelper> helper =
       new CreateIndexHelper(mTransaction, index);
 
     nsresult rv = helper->DispatchToTransactionPool();
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to dispatch!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
   }
 
   autoRemove.forget();
 
   IDB_PROFILER_MARK("IndexedDB Pseudo-request: "
                     "database(%s).transaction(%s).objectStore(%s)."
                     "createIndex(%s)",
                     "MT IDBObjectStore.createIndex()",
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(index));
 
-  index.forget(_retval);
-  return NS_OK;
+  return index.forget();
 }
 
-nsresult
-IDBObjectStore::IndexInternal(const nsAString& aName,
-                              IDBIndex** _retval)
+already_AddRefed<nsIIDBIndex>
+IDBObjectStore::Index(const nsAString& aName, ErrorResult &aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (mTransaction->IsFinished()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   IndexInfo* indexInfo = nullptr;
   uint32_t indexCount = mInfo->indexes.Length();
   for (uint32_t index = 0; index < indexCount; index++) {
     if (mInfo->indexes[index].name == aName) {
       indexInfo = &(mInfo->indexes[index]);
       break;
     }
   }
 
   if (!indexInfo) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBIndex> retval;
   for (uint32_t i = 0; i < mCreatedIndexes.Length(); i++) {
     nsRefPtr<IDBIndex>& index = mCreatedIndexes[i];
     if (index->Name() == aName) {
       retval = index;
       break;
     }
   }
 
   if (!retval) {
     retval = IDBIndex::Create(this, indexInfo, false);
-    NS_ENSURE_TRUE(retval, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    if (!retval) {
+      NS_WARNING("Failed to create index!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
 
     if (!mCreatedIndexes.AppendElement(retval)) {
       NS_WARNING("Out of memory!");
-      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
     }
   }
 
-  retval.forget(_retval);
-  return NS_OK;
+  return retval.forget();
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBObjectStore)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mCachedKeyPath)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
 
   for (uint32_t i = 0; i < tmp->mCreatedIndexes.Length(); i++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedIndexes[i]");
     cb.NoteXPCOMChild(static_cast<nsIIDBIndex*>(tmp->mCreatedIndexes[i].get()));
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+
   // Don't unlink mTransaction!
 
   tmp->mCreatedIndexes.Clear();
 
   tmp->mCachedKeyPath = JSVAL_VOID;
 
   if (tmp->mRooted) {
     NS_DROP_JS_OBJECTS(tmp, IDBObjectStore);
     tmp->mRooted = false;
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBObjectStore)
-  NS_INTERFACE_MAP_ENTRY(nsIIDBObjectStore)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBObjectStore)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBObjectStore)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBObjectStore)
 
-DOMCI_DATA(IDBObjectStore, IDBObjectStore)
-
-NS_IMETHODIMP
-IDBObjectStore::GetName(nsAString& aName)
+JSObject*
+IDBObjectStore::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  aName.Assign(mName);
-  return NS_OK;
+  return IDBObjectStoreBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMETHODIMP
-IDBObjectStore::GetKeyPath(JSContext* aCx,
-                           jsval* aVal)
+JS::Value
+IDBObjectStore::GetKeyPath(JSContext* aCx, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!JSVAL_IS_VOID(mCachedKeyPath)) {
-    *aVal = mCachedKeyPath;
-    return NS_OK;
+    return mCachedKeyPath;
   }
 
-  nsresult rv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
-  NS_ENSURE_SUCCESS(rv, rv);
+  aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
+  ENSURE_SUCCESS(aRv, JSVAL_VOID);
 
   if (JSVAL_IS_GCTHING(mCachedKeyPath)) {
     NS_HOLD_JS_OBJECTS(this, IDBObjectStore);
     mRooted = true;
   }
 
-  *aVal = mCachedKeyPath;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::GetTransaction(nsISupports** aTransaction)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  nsRefPtr<IDBWrapperCache> transaction(mTransaction);
-  transaction.forget(aTransaction);
-  return NS_OK;
+  return mCachedKeyPath;
 }
 
-NS_IMETHODIMP
-IDBObjectStore::GetAutoIncrement(bool* aAutoIncrement)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  *aAutoIncrement = mAutoIncrement;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::GetIndexNames(nsIDOMDOMStringList** aIndexNames)
+already_AddRefed<nsIDOMDOMStringList>
+IDBObjectStore::GetIndexNames(ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<nsDOMStringList> list(new nsDOMStringList());
 
   nsAutoTArray<nsString, 10> names;
   uint32_t count = mInfo->indexes.Length();
   names.SetCapacity(count);
 
   for (uint32_t index = 0; index < count; index++) {
     names.InsertElementSorted(mInfo->indexes[index].name);
   }
 
   for (uint32_t index = 0; index < count; index++) {
-    NS_ENSURE_TRUE(list->Add(names[index]),
-                   NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    if (!list->Add(names[index])) {
+      NS_WARNING("Failed to add element!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
   }
 
-  list.forget(aIndexNames);
-  return NS_OK;
+  return list.forget();
 }
 
-NS_IMETHODIMP
-IDBObjectStore::Get(const jsval& aKey,
-                    JSContext* aCx,
-                    nsIIDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::Get(JSContext* aCx, JS::Handle<JS::Value> aKey,
+                    ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
-  nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
-  NS_ENSURE_SUCCESS(rv, rv);
+  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  ENSURE_SUCCESS(aRv, nullptr);
 
   if (!keyRange) {
     // Must specify a key or keyRange for get().
-    return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
+    return nullptr;
   }
 
-  nsRefPtr<IDBRequest> request;
-  rv = GetInternal(keyRange, aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
+  return GetInternal(keyRange, aRv);
+}
+
+already_AddRefed<IDBRequest>
+IDBObjectStore::GetAll(JSContext* aCx,
+                       const Optional<JS::Handle<JS::Value> >& aKey,
+                       const Optional<uint32_t>& aLimit, ErrorResult& aRv)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  if (!mTransaction->IsOpen()) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
-  request.forget(_retval);
-  return NS_OK;
+  nsRefPtr<IDBKeyRange> keyRange;
+  if (aKey.WasPassed()) {
+    aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
+    ENSURE_SUCCESS(aRv, nullptr);
+  }
+
+  uint32_t limit = UINT32_MAX;
+  if (aLimit.WasPassed() && aLimit.Value() != 0) {
+    limit = aLimit.Value();
+  }
+
+  return GetAllInternal(keyRange, limit, aRv);
 }
 
-NS_IMETHODIMP
-IDBObjectStore::GetAll(const jsval& aKey,
-                       uint32_t aLimit,
-                       JSContext* aCx,
-                       uint8_t aOptionalArgCount,
-                       nsIIDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::Delete(JSContext* aCx, JS::Handle<JS::Value> aKey,
+                       ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
-  nsresult rv;
+  if (!IsWriteAllowed()) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
+    return nullptr;
+  }
 
   nsRefPtr<IDBKeyRange> keyRange;
-  if (aOptionalArgCount) {
-    rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (aOptionalArgCount < 2 || aLimit == 0) {
-    aLimit = UINT32_MAX;
+  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  ENSURE_SUCCESS(aRv, nullptr);
+
+  if (!keyRange) {
+    // Must specify a key or keyRange for delete().
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
+    return nullptr;
   }
 
-  nsRefPtr<IDBRequest> request;
-  rv = GetAllInternal(keyRange, aLimit, aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
+  return DeleteInternal(keyRange, aRv);
 }
 
-NS_IMETHODIMP
-IDBObjectStore::Add(const jsval& aValue,
-                    const jsval& aKey,
-                    JSContext* aCx,
-                    uint8_t aOptionalArgCount,
-                    nsIIDBRequest** _retval)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  nsRefPtr<IDBRequest> request;
-  nsresult rv = AddOrPut(aValue, aKey, aCx, aOptionalArgCount, false,
-                         getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::Put(const jsval& aValue,
-                    const jsval& aKey,
-                    JSContext* aCx,
-                    uint8_t aOptionalArgCount,
-                    nsIIDBRequest** _retval)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  nsRefPtr<IDBRequest> request;
-  nsresult rv = AddOrPut(aValue, aKey, aCx, aOptionalArgCount, true,
-                         getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::Delete(const jsval& aKey,
-                       JSContext* aCx,
-                       nsIIDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::OpenCursor(JSContext* aCx,
+                           const Optional<JS::Handle<JS::Value> >& aRange,
+                           IDBCursorDirection aDirection, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
-  }
-
-  if (!IsWriteAllowed()) {
-    return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
-  nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (!keyRange) {
-    // Must specify a key or keyRange for delete().
-    return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
+  if (aRange.WasPassed()) {
+    aRv = IDBKeyRange::FromJSVal(aCx, aRange.Value(), getter_AddRefs(keyRange));
+    ENSURE_SUCCESS(aRv, nullptr);
   }
 
-  nsRefPtr<IDBRequest> request;
-  rv = DeleteInternal(keyRange, aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
+  IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);
+  size_t argDirection = static_cast<size_t>(direction);
+
+  return OpenCursorInternal(keyRange, argDirection, aRv);
 }
 
-NS_IMETHODIMP
-IDBObjectStore::Clear(JSContext* aCx, nsIIDBRequest** _retval)
+already_AddRefed<nsIIDBIndex>
+IDBObjectStore::CreateIndex(JSContext* aCx, const nsAString& aName,
+                            const nsAString& aKeyPath,
+                            const IDBIndexParameters& aOptionalParameters,
+                            ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  nsRefPtr<IDBRequest> request;
-  nsresult rv = ClearInternal(aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::OpenCursor(const jsval& aKey,
-                           const nsAString& aDirection,
-                           JSContext* aCx,
-                           uint8_t aOptionalArgCount,
-                           nsIIDBRequest** _retval)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
-  }
-
-  nsresult rv;
-
-  IDBCursor::Direction direction = IDBCursor::NEXT;
-
-  nsRefPtr<IDBKeyRange> keyRange;
-  if (aOptionalArgCount) {
-    rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (aOptionalArgCount >= 2) {
-      rv = IDBCursor::ParseDirection(aDirection, &direction);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-  }
-
-  size_t argDirection = static_cast<size_t>(direction);
-
-  nsRefPtr<IDBRequest> request;
-  rv = OpenCursorInternal(keyRange, argDirection, aCx,
-                          getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::CreateIndex(const nsAString& aName,
-                            const jsval& aKeyPath,
-                            const jsval& aOptions,
-                            JSContext* aCx,
-                            nsIIDBIndex** _retval)
-{
-  NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
-
   KeyPath keyPath(0);
   if (NS_FAILED(KeyPath::Parse(aCx, aKeyPath, &keyPath)) ||
       !keyPath.IsValid()) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
   }
 
+  return CreateIndex(aCx, aName, keyPath, aOptionalParameters, aRv);
+}
+
+already_AddRefed<nsIIDBIndex>
+IDBObjectStore::CreateIndex(JSContext* aCx, const nsAString& aName,
+                            const Sequence<nsString >& aKeyPath,
+                            const IDBIndexParameters& aOptionalParameters,
+                            ErrorResult& aRv)
+{
+  NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
+
+  if (!aKeyPath.Length()) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
+  }
+
+  KeyPath keyPath(0);
+  if (NS_FAILED(KeyPath::Parse(aCx, aKeyPath, &keyPath))) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
+  }
+
+  return CreateIndex(aCx, aName, keyPath, aOptionalParameters, aRv);
+}
+
+already_AddRefed<nsIIDBIndex>
+IDBObjectStore::CreateIndex(JSContext* aCx, const nsAString& aName,
+                            KeyPath& aKeyPath,
+                            const IDBIndexParameters& aOptionalParameters,
+                            ErrorResult& aRv)
+{
   // Check name and current mode
   IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
 
   if (!transaction ||
       transaction != mTransaction ||
       mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
   }
 
   bool found = false;
   uint32_t indexCount = mInfo->indexes.Length();
   for (uint32_t index = 0; index < indexCount; index++) {
     if (mInfo->indexes[index].name == aName) {
       found = true;
       break;
     }
   }
 
   if (found) {
-    return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR);
+    return nullptr;
   }
 
   NS_ASSERTION(mTransaction->IsOpen(), "Impossible!");
 
 #ifdef DEBUG
   for (uint32_t index = 0; index < mCreatedIndexes.Length(); index++) {
     if (mCreatedIndexes[index]->Name() == aName) {
       NS_ERROR("Already created this one!");
     }
   }
 #endif
 
-  nsresult rv;
-  mozilla::idl::IDBIndexParameters params;
-
-  // Get optional arguments.
-  if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) {
-    rv = params.Init(aCx, &aOptions);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  if (params.multiEntry && keyPath.IsArray()) {
-    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+  if (aOptionalParameters.mMultiEntry && aKeyPath.IsArray()) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
+    return nullptr;
   }
 
   DatabaseInfo* databaseInfo = mTransaction->DBInfo();
 
   IndexInfo info;
 
   info.name = aName;
   info.id = databaseInfo->nextIndexId++;
-  info.keyPath = keyPath;
-  info.unique = params.unique;
-  info.multiEntry = params.multiEntry;
-
-  nsRefPtr<IDBIndex> index;
-  rv = CreateIndexInternal(info, getter_AddRefs(index));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  index.forget(_retval);
-  return NS_OK;
+  info.keyPath = aKeyPath;
+  info.unique = aOptionalParameters.mUnique;
+  info.multiEntry = aOptionalParameters.mMultiEntry;
+
+  return CreateIndexInternal(info, aRv);
 }
 
-NS_IMETHODIMP
-IDBObjectStore::Index(const nsAString& aName,
-                      nsIIDBIndex** _retval)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
-  nsRefPtr<IDBIndex> index;
-  nsresult rv = IndexInternal(aName, getter_AddRefs(index));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  index.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBObjectStore::DeleteIndex(const nsAString& aName)
+void
+IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
 
   if (!transaction ||
       transaction != mTransaction ||
       mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return;
   }
 
   NS_ASSERTION(mTransaction->IsOpen(), "Impossible!");
 
   uint32_t index = 0;
   for (; index < mInfo->indexes.Length(); index++) {
     if (mInfo->indexes[index].name == aName) {
       break;
     }
   }
 
   if (index == mInfo->indexes.Length()) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
+    return;
   }
 
-  nsresult rv;
-
   if (IndexedDatabaseManager::IsMainProcess()) {
     nsRefPtr<DeleteIndexHelper> helper =
       new DeleteIndexHelper(mTransaction, this, aName);
 
-    rv = helper->DispatchToTransactionPool();
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    nsresult rv = helper->DispatchToTransactionPool();
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to dispatch!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return;
+    }
   }
   else {
     NS_ASSERTION(mActorChild, "Must have an actor here!");
 
     mActorChild->SendDeleteIndex(nsString(aName));
   }
 
   mInfo->indexes.RemoveElementAt(index);
@@ -2795,46 +2737,35 @@ IDBObjectStore::DeleteIndex(const nsAStr
   IDB_PROFILER_MARK("IndexedDB Pseudo-request: "
                     "database(%s).transaction(%s).objectStore(%s)."
                     "deleteIndex(\"%s\")",
                     "MT IDBObjectStore.deleteIndex()",
                     IDB_PROFILER_STRING(Transaction()->Database()),
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this),
                     NS_ConvertUTF16toUTF8(aName).get());
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-IDBObjectStore::Count(const jsval& aKey,
-                      JSContext* aCx,
-                      uint8_t aOptionalArgCount,
-                      nsIIDBRequest** _retval)
+already_AddRefed<IDBRequest>
+IDBObjectStore::Count(JSContext* aCx,
+                      const Optional<JS::Handle<JS::Value> >& aKey,
+                      ErrorResult& aRv)
 {
   if (!mTransaction->IsOpen()) {
-    return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
-  nsresult rv;
-
   nsRefPtr<IDBKeyRange> keyRange;
-  if (aOptionalArgCount) {
-    rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
-    NS_ENSURE_SUCCESS(rv, rv);
+  if (aKey.WasPassed()) {
+    aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
+    ENSURE_SUCCESS(aRv, nullptr);
   }
 
-  nsRefPtr<IDBRequest> request;
-  rv = CountInternal(keyRange, aCx, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  request.forget(_retval);
-  return NS_OK;
+  return CountInternal(keyRange, aRv);
 }
 
 inline nsresult
 CopyData(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
 
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -4,26 +4,29 @@
  * 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 mozilla_dom_indexeddb_idbobjectstore_h__
 #define mozilla_dom_indexeddb_idbobjectstore_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
-#include "nsIIDBObjectStore.h"
-
+#include "mozilla/dom/IDBCursorBinding.h"
+#include "mozilla/dom/IDBIndexBinding.h"
+#include "mozilla/dom/IDBObjectStoreBinding.h"
 #include "nsCycleCollectionParticipant.h"
 
+#include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBTransaction.h"
 #include "mozilla/dom/indexedDB/KeyPath.h"
 
 class nsIDOMBlob;
 class nsIScriptContext;
 class nsPIDOMWindow;
+class nsIIDBIndex;
 
 namespace mozilla {
 namespace dom {
 class ContentParent;
 class PBlobChild;
 class PBlobParent;
 }
 }
@@ -41,22 +44,21 @@ class Key;
 
 struct IndexInfo;
 struct IndexUpdateInfo;
 struct ObjectStoreInfo;
 
 struct FileHandleData;
 struct BlobOrFileData;
 
-class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
+class IDBObjectStore MOZ_FINAL : public nsISupports,
+                                 public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_NSIIDBOBJECTSTORE
-
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
 
   static already_AddRefed<IDBObjectStore>
   Create(IDBTransaction* aTransaction,
          ObjectStoreInfo* aInfo,
          nsIAtom* aDatabaseId,
          bool aCreating);
 
@@ -192,87 +194,172 @@ public:
   }
 
   IndexedDBObjectStoreParent*
   GetActorParent() const
   {
     return mActorParent;
   }
 
-  nsresult
+  already_AddRefed<nsIIDBIndex>
   CreateIndexInternal(const IndexInfo& aInfo,
-                      IDBIndex** _retval);
-
-  nsresult
-  IndexInternal(const nsAString& aName,
-                IDBIndex** _retval);
+                      ErrorResult& aRv);
 
   nsresult AddOrPutInternal(
                       const SerializedStructuredCloneWriteInfo& aCloneWriteInfo,
                       const Key& aKey,
                       const InfallibleTArray<IndexUpdateInfo>& aUpdateInfoArray,
                       const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
                       bool aOverwrite,
                       IDBRequest** _retval);
 
-  nsresult GetInternal(IDBKeyRange* aKeyRange,
-                       JSContext* aCx,
-                       IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  GetInternal(IDBKeyRange* aKeyRange,
+              ErrorResult& aRv);
 
-  nsresult GetAllInternal(IDBKeyRange* aKeyRange,
-                          uint32_t aLimit,
-                          JSContext* aCx,
-                          IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  GetAllInternal(IDBKeyRange* aKeyRange,
+                 uint32_t aLimit,
+                 ErrorResult& aRv);
 
-  nsresult DeleteInternal(IDBKeyRange* aKeyRange,
-                          JSContext* aCx,
-                          IDBRequest** _retval);
-
-  nsresult ClearInternal(JSContext* aCx,
-                         IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  DeleteInternal(IDBKeyRange* aKeyRange,
+                 ErrorResult& aRv);
 
-  nsresult CountInternal(IDBKeyRange* aKeyRange,
-                         JSContext* aCx,
-                         IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  CountInternal(IDBKeyRange* aKeyRange,
+                ErrorResult& aRv);
 
-  nsresult OpenCursorInternal(IDBKeyRange* aKeyRange,
-                              size_t aDirection,
-                              JSContext* aCx,
-                              IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  OpenCursorInternal(IDBKeyRange* aKeyRange,
+                     size_t aDirection,
+                     ErrorResult& aRv);
 
   nsresult OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
                             nsTArray<StructuredCloneFile>& aBlobs,
                             IDBCursor** _retval);
 
   void
   SetInfo(ObjectStoreInfo* aInfo);
 
   static JSClass sDummyPropJSClass;
 
+  // nsWrapperCache
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  // WebIDL
+  IDBTransaction*
+  GetParentObject() const
+  {
+    return mTransaction;
+  }
+
+  void
+  GetName(nsString& aName) const
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    aName.Assign(mName);
+  }
+
+  JS::Value
+  GetKeyPath(JSContext* aCx, ErrorResult& aRv);
+
+  already_AddRefed<nsIDOMDOMStringList>
+  GetIndexNames(ErrorResult& aRv);
+
+  IDBTransaction*
+  Transaction() const
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    return mTransaction;
+  }
+
+  bool
+  AutoIncrement() const
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    return mAutoIncrement;
+  }
+
+  already_AddRefed<IDBRequest>
+  Put(JSContext* aCx, JS::Handle<JS::Value> aValue,
+      const Optional<JS::Handle<JS::Value> >& aKey, ErrorResult& aRv)
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    return AddOrPut(aCx, aValue, aKey, true, aRv);
+  }
+
+  already_AddRefed<IDBRequest>
+  Add(JSContext* aCx, JS::Handle<JS::Value> aValue,
+      const Optional<JS::Handle<JS::Value> >& aKey, ErrorResult& aRv)
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    return AddOrPut(aCx, aValue, aKey, false, aRv);
+  }
+
+  already_AddRefed<IDBRequest>
+  Delete(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  Get(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  Clear(ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  OpenCursor(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aRange,
+             IDBCursorDirection aDirection, ErrorResult& aRv);
+
+  already_AddRefed<nsIIDBIndex>
+  CreateIndex(JSContext* aCx, const nsAString& aName, const nsAString& aKeyPath,
+              const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
+
+  already_AddRefed<nsIIDBIndex>
+  CreateIndex(JSContext* aCx, const nsAString& aName,
+              const Sequence<nsString >& aKeyPath,
+              const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
+
+  already_AddRefed<nsIIDBIndex>
+  Index(const nsAString& aName, ErrorResult &aRv);
+
+  void
+  DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
+        ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
+         const Optional<uint32_t >& aLimit, ErrorResult& aRv);
+
 protected:
   IDBObjectStore();
   ~IDBObjectStore();
 
   nsresult GetAddInfo(JSContext* aCx,
                       JS::Handle<JS::Value> aValue,
                       JS::Handle<JS::Value> aKeyVal,
                       StructuredCloneWriteInfo& aCloneWriteInfo,
                       Key& aKey,
                       nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
 
-  nsresult AddOrPut(const jsval& aValue,
-                    const jsval& aKey,
-                    JSContext* aCx,
-                    uint8_t aOptionalArgCount,
-                    bool aOverwrite,
-                    IDBRequest** _retval);
+  already_AddRefed<IDBRequest>
+  AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
+           const Optional<JS::Handle<JS::Value> >& aKey, bool aOverwrite,
+           ErrorResult& aRv);
+
+  already_AddRefed<nsIIDBIndex>
+  CreateIndex(JSContext* aCx, const nsAString& aName, KeyPath& aKeyPath,
+              const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
 
   static void
   ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
 
   static bool
   ReadFileHandle(JSStructuredCloneReader* aReader,
                  FileHandleData* aRetval);
 
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -694,17 +694,17 @@ IDBTransaction::GetObjectStoreNames(Erro
       aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
       return nullptr;
     }
   }
 
   return list.forget();
 }
 
-already_AddRefed<nsIIDBObjectStore>
+already_AddRefed<IDBObjectStore>
 IDBTransaction::ObjectStore(const nsAString& aName, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (IsFinished()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
     return nullptr;
   }
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -235,17 +235,17 @@ public:
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     return mDatabase;
   }
 
   DOMError*
   GetError(ErrorResult& aRv);
 
-  already_AddRefed<nsIIDBObjectStore>
+  already_AddRefed<IDBObjectStore>
   ObjectStore(const nsAString& aName, ErrorResult& aRv);
 
   void
   Abort(ErrorResult& aRv)
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     aRv = AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
   }
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -7,16 +7,18 @@
 #include "KeyPath.h"
 #include "IDBObjectStore.h"
 #include "Key.h"
 
 #include "nsCharSeparatedTokenizer.h"
 #include "nsJSUtils.h"
 #include "xpcpublic.h"
 
+#include "mozilla/dom/BindingDeclarations.h"
+
 USING_INDEXEDDB_NAMESPACE
 
 namespace {
 
 inline
 bool
 IgnoreWhitespace(PRUnichar c)
 {
@@ -217,16 +219,49 @@ GetJSValFromKeyPathString(JSContext* aCx
   NS_ENSURE_SUCCESS(rv, rv);
   return rv;
 }
 
 } // anonymous namespace
 
 // static
 nsresult
+KeyPath::Parse(JSContext* aCx, const nsAString& aString, KeyPath* aKeyPath)
+{
+  KeyPath keyPath(0);
+  keyPath.SetType(STRING);
+
+  if (!keyPath.AppendStringWithValidation(aCx, aString)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *aKeyPath = keyPath;
+  return NS_OK;
+}
+
+//static
+nsresult
+KeyPath::Parse(JSContext* aCx, const mozilla::dom::Sequence<nsString>& aStrings,
+               KeyPath* aKeyPath)
+{
+  KeyPath keyPath(0);
+  keyPath.SetType(ARRAY);
+
+  for (uint32_t i = 0; i < aStrings.Length(); ++i) {
+    if (!keyPath.AppendStringWithValidation(aCx, aStrings[i])) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  *aKeyPath = keyPath;
+  return NS_OK;
+}
+
+// static
+nsresult
 KeyPath::Parse(JSContext* aCx, const JS::Value& aValue, KeyPath* aKeyPath)
 {
   KeyPath keyPath(0);
 
   aKeyPath->SetType(NONEXISTENT);
 
   // See if this is a JS array.
   if (!JSVAL_IS_PRIMITIVE(aValue) &&
--- a/dom/indexedDB/KeyPath.h
+++ b/dom/indexedDB/KeyPath.h
@@ -4,16 +4,18 @@
  * 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 mozilla_dom_indexeddb_keypath_h__
 #define mozilla_dom_indexeddb_keypath_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
+#include "mozilla/dom/BindingDeclarations.h"
+
 BEGIN_INDEXEDDB_NAMESPACE
 
 class Key;
 
 class KeyPath
 {
 public:
   enum KeyPathType {
@@ -41,16 +43,22 @@ public:
   }
 
   ~KeyPath()
   {
     MOZ_COUNT_DTOR(KeyPath);
   }
 
   static nsresult
+  Parse(JSContext* aCx, const nsAString& aString, KeyPath* aKeyPath);
+
+  static nsresult
+  Parse(JSContext* aCx, const Sequence<nsString>& aStrings, KeyPath* aKeyPath);
+
+  static nsresult
   Parse(JSContext* aCx, const JS::Value& aValue, KeyPath* aKeyPath);
 
   nsresult
   ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const;
 
   nsresult
   ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
                     JS::Value* aOutVal) const;
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -791,23 +791,19 @@ IndexedDBTransactionParent::RecvPIndexed
     const nsString& name = params.name();
 
     nsRefPtr<IDBObjectStore> objectStore;
 
     {
       AutoSetCurrentTransaction asct(mTransaction);
 
       ErrorResult rv;
-      nsCOMPtr<nsIIDBObjectStore> store = mTransaction->ObjectStore(name, rv);
-      if (rv.Failed()) {
-        NS_WARNING("Failed to get object store!");
-        return false;
-      }
-
-      objectStore = static_cast<IDBObjectStore*>(store.get());
+      objectStore = mTransaction->ObjectStore(name, rv);
+      ENSURE_SUCCESS(rv, false);
+
       actor->SetObjectStore(objectStore);
     }
 
     objectStore->SetActor(actor);
     return true;
   }
 
   if (aParams.type() ==
@@ -1148,19 +1144,21 @@ IndexedDBObjectStoreParent::RecvPIndexed
     const GetIndexParams& params = aParams.get_GetIndexParams();
     const nsString& name = params.name();
 
     nsRefPtr<IDBIndex> index;
 
     {
       AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-      nsresult rv = mObjectStore->IndexInternal(name, getter_AddRefs(index));
-      NS_ENSURE_SUCCESS(rv, false);
-
+      ErrorResult rv;
+      nsCOMPtr<nsIIDBIndex> obj = mObjectStore->Index(name, rv);
+      ENSURE_SUCCESS(rv, false);
+
+      index = static_cast<IDBIndex*>(obj.get());
       actor->SetIndex(index);
     }
 
     index->SetActor(actor);
     return true;
   }
 
   if (aParams.type() == IndexConstructorParams::TCreateIndexParams) {
@@ -1248,26 +1246,25 @@ IndexedDBVersionChangeObjectStoreParent:
   }
 
   if (mObjectStore->Transaction()->Database()->IsInvalidated()) {
     // If we've invalidated this database in the parent then we should bail out
     // now to avoid logic problems that could force-kill the child.
     return true;
   }
 
-  nsresult rv;
+  ErrorResult rv;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    rv = mObjectStore->DeleteIndex(aName);
+    mObjectStore->DeleteIndex(aName, rv);
   }
 
-  NS_ENSURE_SUCCESS(rv, false);
-
+  ENSURE_SUCCESS(rv, false);
   return true;
 }
 
 bool
 IndexedDBVersionChangeObjectStoreParent::RecvPIndexedDBIndexConstructor(
                                           PIndexedDBIndexParent* aActor,
                                           const IndexConstructorParams& aParams)
 {
@@ -1292,26 +1289,26 @@ IndexedDBVersionChangeObjectStoreParent:
     MOZ_ASSERT(mObjectStore->Transaction()->GetMode() ==
                IDBTransaction::VERSION_CHANGE);
 
     const CreateIndexParams& params = aParams.get_CreateIndexParams();
     const IndexInfo& info = params.info();
 
     nsRefPtr<IDBIndex> index;
 
-    nsresult rv;
-
     {
       AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-      rv = mObjectStore->CreateIndexInternal(info, getter_AddRefs(index));
+      ErrorResult rv;
+      nsCOMPtr<nsIIDBIndex> obj = mObjectStore->CreateIndexInternal(info, rv);
+      ENSURE_SUCCESS(rv, false);
+
+      index = static_cast<IDBIndex*>(obj.get());
     }
 
-    NS_ENSURE_SUCCESS(rv, false);
-
     actor->SetIndex(index);
     index->SetActor(actor);
     return true;
   }
 
   return IndexedDBObjectStoreParent::RecvPIndexedDBIndexConstructor(aActor,
                                                                     aParams);
 }
@@ -1508,19 +1505,19 @@ IndexedDBObjectStoreRequestParent::Get(c
 
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv = mObjectStore->GetInternal(keyRange, nullptr,
-                                            getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->GetInternal(keyRange, rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
 
   return true;
 }
 
@@ -1548,20 +1545,19 @@ IndexedDBObjectStoreRequestParent::GetAl
 
     default:
       MOZ_CRASH("Unknown param type!");
   }
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv = mObjectStore->GetAllInternal(keyRange, aParams.limit(),
-                                               nullptr,
-                                               getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->GetAllInternal(keyRange, aParams.limit(), rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 bool
@@ -1630,19 +1626,19 @@ IndexedDBObjectStoreRequestParent::Delet
 
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv =
-      mObjectStore->DeleteInternal(keyRange, nullptr, getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->DeleteInternal(keyRange, rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 bool
@@ -1651,18 +1647,19 @@ IndexedDBObjectStoreRequestParent::Clear
   MOZ_ASSERT(mRequestType == ParamsUnionType::TClearParams);
   MOZ_ASSERT(mObjectStore);
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv = mObjectStore->ClearInternal(nullptr, getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->Clear(rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 bool
@@ -1689,19 +1686,19 @@ IndexedDBObjectStoreRequestParent::Count
       MOZ_CRASH("Unknown param type!");
   }
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv =
-      mObjectStore->CountInternal(keyRange, nullptr, getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->CountInternal(keyRange, rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 bool
@@ -1730,20 +1727,19 @@ IndexedDBObjectStoreRequestParent::OpenC
 
   size_t direction = static_cast<size_t>(aParams.direction());
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv =
-      mObjectStore->OpenCursorInternal(keyRange, direction, nullptr,
-                                       getter_AddRefs(request));
-    NS_ENSURE_SUCCESS(rv, false);
+    ErrorResult rv;
+    request = mObjectStore->OpenCursorInternal(keyRange, direction, rv);
+    ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 /*******************************************************************************
--- a/dom/indexedDB/moz.build
+++ b/dom/indexedDB/moz.build
@@ -8,17 +8,16 @@ DIRS += ['ipc']
 TEST_DIRS += ['test']
 
 XPIDL_SOURCES += [
     'nsIIDBCursor.idl',
     'nsIIDBCursorWithValue.idl',
     'nsIIDBDatabase.idl',
     'nsIIDBIndex.idl',
     'nsIIDBKeyRange.idl',
-    'nsIIDBObjectStore.idl',
     'nsIIDBOpenDBRequest.idl',
     'nsIIDBRequest.idl',
     'nsIIndexedDatabaseManager.idl',
 ]
 
 XPIDL_MODULE = 'dom_indexeddb'
 
 XPIDL_FLAGS += [
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ b/dom/indexedDB/nsIIDBDatabase.idl
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 nsIIDBObjectStore;
 interface nsIIDBRequest;
 interface nsIDOMDOMStringList;
 interface nsIDOMEventListener;
 
 /**
  * IDBDatabase interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
  * for more information.
@@ -21,17 +20,17 @@ interface nsIIDBDatabase : nsISupports
 {
   readonly attribute DOMString name;
 
   readonly attribute unsigned long long version;
 
   readonly attribute nsIDOMDOMStringList objectStoreNames;
 
   [implicit_jscontext]
-  nsIIDBObjectStore
+  nsISupports // IDBObjectStore
   createObjectStore([Null(Stringify)] in DOMString name,
                     /* IDBObjectStoreParameters */
                     [optional /* none */] in jsval options);
 
   void
   deleteObjectStore([Null(Stringify)] in DOMString name);
 
   // mode can be either "readonly" or "readwrite"
--- a/dom/indexedDB/nsIIDBIndex.idl
+++ b/dom/indexedDB/nsIIDBIndex.idl
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 nsIIDBObjectStore;
 interface nsIIDBRequest;
 
 /**
  * IDBIndex interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBIndex for more
  * information.
  */
 [scriptable, builtinclass, uuid(a859747a-0f05-4dfb-8f42-05c61415d4e4)]
@@ -23,17 +22,18 @@ interface nsIIDBIndex : nsISupports
 
   [implicit_jscontext]
   readonly attribute jsval keyPath;
 
   readonly attribute boolean unique;
 
   readonly attribute boolean multiEntry;
 
-  readonly attribute nsIIDBObjectStore objectStore;
+  // This is a IDBObjectStore
+  readonly attribute nsISupports objectStore;
 
   [implicit_jscontext]
   nsIIDBRequest
   get(in jsval key);
 
   [implicit_jscontext]
   nsIIDBRequest
   getKey(in jsval key);
deleted file mode 100644
--- a/dom/indexedDB/nsIIDBObjectStore.idl
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* 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 nsIIDBIndex;
-interface nsIIDBKeyRange;
-interface nsIIDBRequest;
-interface nsIDOMDOMStringList;
-
-dictionary IDBIndexParameters
-{
-  boolean unique;
-  boolean multiEntry;
-};
-
-/**
- * nsIIDBObjectStore interface.  See
- * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
- * for more information.
- */
-[scriptable, builtinclass, uuid(dd189afd-e1b7-4496-bf8d-629c58709595)]
-interface nsIIDBObjectStore : nsISupports
-{
-  readonly attribute DOMString name;
-
-  [implicit_jscontext]
-  readonly attribute jsval keyPath;
-
-  readonly attribute nsIDOMDOMStringList indexNames;
-
-  // IDBTransaction
-  readonly attribute nsISupports transaction;
-
-  readonly attribute boolean autoIncrement;
-
-  // Success fires IDBTransactionEvent, result == value for key
-  [implicit_jscontext]
-  nsIIDBRequest
-  get(in jsval key);
-
-  // Success fires IDBTransactionEvent, result == array of values for given keys
-  [implicit_jscontext, optional_argc, binaryname(GetAll)]
-  nsIIDBRequest
-  mozGetAll([optional /* null */] in jsval key,
-            [optional /* unlimited */] in unsigned long limit);
-
-  // Success fires IDBTransactionEvent, result == key
-  [implicit_jscontext, optional_argc]
-  nsIIDBRequest
-  add(in jsval value,
-      [optional /* undefined */] in jsval key);
-
-  // Success fires IDBTransactionEvent, result == key
-  [implicit_jscontext, optional_argc]
-  nsIIDBRequest
-  put(in jsval value,
-      [optional /* undefined */] in jsval key);
-
-  // Success fires IDBTransactionEvent, result == null
-  [implicit_jscontext]
-  nsIIDBRequest
-  delete(in jsval key);
-
-  // Success fires IDBTransactionEvent, result == null
-  [implicit_jscontext]
-  nsIIDBRequest
-  clear();
-
-  // Success fires IDBTransactionEvent, result == IDBCursor or result == null if
-  // no match.
-  // direction can be "next", "nextunique", "prev" or "prevunique"
-  [implicit_jscontext, optional_argc]
-  nsIIDBRequest
-  openCursor([optional /* null */] in jsval range,
-             [optional /* "next" */] in DOMString direction);
-
-  [implicit_jscontext]
-  nsIIDBIndex
-  createIndex([Null(Stringify)] in DOMString name,
-              in jsval keyPath,
-              /* nsIIDBIndexParameters */
-              [optional /* none */] in jsval options);
-
-  // Returns object immediately
-  nsIIDBIndex
-  index([Null(Stringify)] in DOMString name);
-
-  void
-  deleteIndex([Null(Stringify)] in DOMString name);
-
-  // Accepts null, a key value, or a nsIIDBKeyRange object.
-  [implicit_jscontext, optional_argc]
-  nsIIDBRequest
-  count([optional] in jsval key);
-};
--- a/dom/indexedDB/test/unit/head.js
+++ b/dom/indexedDB/test/unit/head.js
@@ -5,17 +5,16 @@
 
 const { 'classes': Cc, 'interfaces': Ci } = Components;
 
 const DOMException = Ci.nsIDOMDOMException;
 const IDBCursor = Ci.nsIIDBCursor;
 const IDBOpenDBRequest = Ci.nsIIDBOpenDBRequest;
 const IDBDatabase = Ci.nsIIDBDatabase
 const IDBIndex = Ci.nsIIDBIndex
-const IDBObjectStore = Ci.nsIIDBObjectStore
 const IDBRequest = Ci.nsIIDBRequest
 
 function is(a, b, msg) {
   dump("is(" + a + ", " + b + ", \"" + msg + "\")");
   do_check_eq(a, b, Components.stack.caller);
 }
 
 function ok(cond, msg) {
--- a/dom/indexedDB/test/unit/test_complex_keyPaths.js
+++ b/dom/indexedDB/test/unit/test_complex_keyPaths.js
@@ -2,18 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
-
   // Test object stores
 
   const name = "test_complex_keyPaths";
   const keyPaths = [
     { keyPath: "id",      value: { id: 5 },                      key: 5 },
     { keyPath: "id",      value: { id: "14", iid: 12 },          key: "14" },
     { keyPath: "id",      value: { iid: "14", id: 12 },          key: 12 },
     { keyPath: "id",      value: {} },
--- a/dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
+++ b/dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
@@ -2,17 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
   const name = this.window ? window.location.pathname : "Splendid Test";
 
   var request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   var event = yield undefined;
 
   var db = event.target.result;
--- a/dom/indexedDB/test/unit/test_objectStore_remove_values.js
+++ b/dom/indexedDB/test/unit/test_objectStore_remove_values.js
@@ -2,17 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
   const name = this.window ? window.location.pathname : "Splendid Test";
 
   var data = [
     { name: "inline key; key generator",
       autoIncrement: true,
       storedObject: {name: "Lincoln"},
       keyName: "id",
       keyValue: undefined,
--- a/dom/indexedDB/test/unit/test_open_objectStore.js
+++ b/dom/indexedDB/test/unit/test_open_objectStore.js
@@ -2,17 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
   const name = this.window ? window.location.pathname : "Splendid Test";
   const objectStoreName = "Objects";
 
   let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield undefined;
--- a/dom/indexedDB/test/unit/test_remove_index.js
+++ b/dom/indexedDB/test/unit/test_remove_index.js
@@ -2,18 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
-
   const name = this.window ? window.location.pathname : "Splendid Test";
   const indexName = "My Test Index";
 
   let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield undefined;
 
--- a/dom/indexedDB/test/unit/test_remove_objectStore.js
+++ b/dom/indexedDB/test/unit/test_remove_objectStore.js
@@ -2,18 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
-
   const name = this.window ? window.location.pathname : "Splendid Test";
   const objectStoreName = "Objects";
 
   let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield undefined;
 
new file mode 100644
--- /dev/null
+++ b/dom/webidl/IDBCursor.webidl
@@ -0,0 +1,15 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBCursorDirection
+ */
+
+enum IDBCursorDirection {
+    "next",
+    "nextunique",
+    "prev",
+    "prevunique"
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/IDBIndex.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/.
+ *
+ * The origin of this IDL file is
+ * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBIndexParameters
+ */
+
+dictionary IDBIndexParameters {
+    boolean unique = false;
+    boolean multiEntry = false;
+};
+
new file mode 100644
--- /dev/null
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -0,0 +1,65 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStore
+ */
+
+interface IDBRequest;
+interface IDBIndex;
+
+interface IDBObjectStore {
+    readonly    attribute DOMString      name;
+
+    [Throws]
+    readonly    attribute any            keyPath;
+
+    [Throws]
+    readonly    attribute DOMStringList  indexNames;
+    readonly    attribute IDBTransaction transaction;
+    readonly    attribute boolean        autoIncrement;
+
+    [Throws]
+    IDBRequest put (any value, optional any key);
+
+    [Throws]
+    IDBRequest add (any value, optional any key);
+
+    [Throws]
+    IDBRequest delete (any key);
+
+    [Throws]
+    IDBRequest get (any key);
+
+    [Throws]
+    IDBRequest clear ();
+
+    [Throws]
+    IDBRequest openCursor (optional any range, optional IDBCursorDirection direction = "next");
+
+    // Bug 899972
+    // IDBIndex   createIndex (DOMString name, (DOMString or sequence<DOMString>) keyPath, optional IDBIndexParameters optionalParameters);
+
+    [Throws]
+    IDBIndex   createIndex (DOMString name, DOMString keyPath, optional IDBIndexParameters optionalParameters);
+
+    [Throws]
+    IDBIndex   createIndex (DOMString name, sequence<DOMString> keyPath, optional IDBIndexParameters optionalParameters);
+
+    [Throws]
+    IDBIndex   index (DOMString name);
+
+    [Throws]
+    void       deleteIndex (DOMString indexName);
+
+    [Throws]
+    IDBRequest count (optional any key);
+};
+
+partial interface IDBObjectStore {
+    // Success fires IDBTransactionEvent, result == array of values for given keys
+    [Throws]
+    IDBRequest mozGetAll (optional any key, optional unsigned long limit);
+};
--- a/dom/webidl/IDBTransaction.webidl
+++ b/dom/webidl/IDBTransaction.webidl
@@ -3,18 +3,16 @@
  * 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/.
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransaction
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransactionMode
  */
 
-interface IDBObjectStore;
-
 enum IDBTransactionMode {
     "readonly",
     "readwrite",
     "versionchange"
 };
 
 interface IDBTransaction : EventTarget {
     [Throws]
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -159,19 +159,22 @@ webidl_files = \
   HTMLTableSectionElement.webidl \
   HTMLTemplateElement.webidl \
   HTMLTextAreaElement.webidl \
   HTMLTimeElement.webidl \
   HTMLTitleElement.webidl \
   HTMLTrackElement.webidl \
   HTMLUListElement.webidl \
   HTMLVideoElement.webidl \
+  IDBCursor.webidl \
   IDBDatabase.webidl \
   IDBFactory.webidl \
   IDBFileHandle.webidl \
+  IDBIndex.webidl \
+  IDBObjectStore.webidl \
   IDBTransaction.webidl \
   IDBVersionChangeEvent.webidl \
   ImageData.webidl \
   ImageDocument.webidl \
   InspectorUtils.webidl \
   KeyboardEvent.webidl \
   KeyEvent.webidl \
   LinkStyle.webidl \
--- a/js/xpconnect/src/dictionary_helper_gen.conf
+++ b/js/xpconnect/src/dictionary_helper_gen.conf
@@ -1,15 +1,14 @@
 # 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 interface name, interface file name
 dictionaries = [
-     [ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
      [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ],
      [ 'DOMFileMetadataParameters', 'nsIDOMLockedFile.idl' ],
      [ 'CameraSize', 'nsIDOMCameraManager.idl' ],
      [ 'CameraRegion', 'nsIDOMCameraManager.idl' ],
      [ 'CameraPosition', 'nsIDOMCameraManager.idl' ],
      [ 'CameraSelector', 'nsIDOMCameraManager.idl' ],
      [ 'CameraRecordingOptions', 'nsIDOMCameraManager.idl' ],
      [ 'SmsThreadListItem', 'nsIMobileMessageCallback.idl' ],
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -84,17 +84,16 @@ members = [
     'nsIBoxObject.height',
 
     # dom/indexedDB
     'nsIIDBCursor.*',
     'nsIIDBCursorWithValue.*',
     'nsIIDBDatabase.*',
     'nsIIDBIndex.*',
     'nsIIDBKeyRange.*',
-    'nsIIDBObjectStore.*',
     'nsIIDBRequest.*',
     'nsIIDBOpenDBRequest.*',
     'nsIIndexedDatabaseManager.*',
 
     # dom/file
     'nsIDOMLockedFile.*',
 
     # dom/quota
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -30,16 +30,17 @@
 
 #ifdef MOZ_JSDEBUGGER
 #include "jsdIDebuggerService.h"
 #endif
 
 #include "XPCQuickStubs.h"
 
 #include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/IDBObjectStoreBinding.h"
 #include "mozilla/dom/IDBTransactionBinding.h"
 #include "mozilla/dom/IDBVersionChangeEventBinding.h"
 #include "mozilla/dom/TextDecoderBinding.h"
 #include "mozilla/dom/TextEncoderBinding.h"
 #include "mozilla/dom/DOMErrorBinding.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollectionNoteRootCallback.h"
@@ -539,17 +540,18 @@ nsXPConnect::InitClassesWithNewWrappedGl
     }
 
     // Stuff coming through this path always ends up as a DOM global.
     // XXX Someone who knows why we can assert this should re-check
     //     (after bug 720580).
     MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
 
     // Init WebIDL binding constructors wanted on all XPConnect globals.
-    if (!IDBTransactionBinding::GetConstructorObject(aJSContext, global) ||
+    if (!IDBObjectStoreBinding::GetConstructorObject(aJSContext, global) ||
+        !IDBTransactionBinding::GetConstructorObject(aJSContext, global) ||
         !IDBVersionChangeEventBinding::GetConstructorObject(aJSContext, global) ||
         !TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
         !TextEncoderBinding::GetConstructorObject(aJSContext, global) ||
         !DOMErrorBinding::GetConstructorObject(aJSContext, global)) {
         return UnexpectedFailure(NS_ERROR_FAILURE);
     }
 
     wrappedGlobal.forget(_retval);