diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 0c844510eef1..8e85b7dc290b 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -5454,8 +5454,9 @@ public: } NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void* child) { - if (langID == nsIProgrammingLanguage::JAVASCRIPT) { - mFound = child == mWrapper; + if (langID == nsIProgrammingLanguage::JAVASCRIPT && + child == mWrapper) { + mFound = true; } } NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index ca54654c6f18..6038457903d9 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -490,6 +490,7 @@ #include "DOMSVGPointList.h" #include "DOMSVGTransformList.h" +#include "mozilla/dom/indexedDB/IDBWrapperCache.h" #include "mozilla/dom/indexedDB/IDBFactory.h" #include "mozilla/dom/indexedDB/IDBRequest.h" #include "mozilla/dom/indexedDB/IDBDatabase.h" @@ -501,6 +502,8 @@ #include "mozilla/dom/indexedDB/IDBIndex.h" #include "nsIIDBDatabaseException.h" +using mozilla::dom::indexedDB::IDBWrapperCache; + #include "nsIDOMMediaQueryList.h" #include "nsDOMTouchEvent.h" @@ -595,6 +598,10 @@ static const char kDOMStringBundleURL[] = (DOM_DEFAULT_SCRIPTABLE_FLAGS | \ nsIXPCScriptable::WANT_ADDPROPERTY) +#define IDBEVENTTARGET_SCRIPTABLE_FLAGS \ + (EVENTTARGET_SCRIPTABLE_FLAGS | \ + nsIXPCScriptable::WANT_POSTCREATE) + #define DOMCLASSINFO_STANDARD_FLAGS \ (nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT) @@ -656,6 +663,37 @@ DOMCI_DATA(DOMConstructor, void) NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA_WITH_NAME(_class, _class, _helper, \ _flags) +namespace { + +class IDBEventTargetSH : public nsEventTargetSH +{ +protected: + IDBEventTargetSH(nsDOMClassInfoData* aData) : nsEventTargetSH(aData) + { } + + virtual ~IDBEventTargetSH() + { } + +public: + NS_IMETHOD PreCreate(nsISupports *aNativeObj, JSContext *aCx, + JSObject *aGlobalObj, JSObject **aParentObj); + + NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *aQrapper, JSContext *aCx, + JSObject *aObj); + + NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCx, + JSObject *aObj, jsid aId, jsval *aVp, bool *aRetval); + + virtual void PreserveWrapper(nsISupports *aNative); + + static nsIClassInfo *doCreate(nsDOMClassInfoData *aData) + { + return new IDBEventTargetSH(aData); + } +}; + +} // anonymous namespace + // This list of NS_DEFINE_CLASSINFO_DATA macros is what gives the DOM // classes their correct behavior when used through XPConnect. The // arguments that are passed to NS_DEFINE_CLASSINFO_DATA are @@ -1539,14 +1577,14 @@ static nsDOMClassInfoData sClassInfoData[] = { NS_DEFINE_CLASSINFO_DATA(IDBFactory, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(IDBRequest, nsEventTargetSH, - EVENTTARGET_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(IDBDatabase, 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(IDBTransaction, nsDOMGenericSH, - DOM_DEFAULT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(IDBTransaction, IDBEventTargetSH, + IDBEVENTTARGET_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(IDBCursorWithValue, nsDOMGenericSH, @@ -1557,8 +1595,8 @@ static nsDOMClassInfoData sClassInfoData[] = { DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, nsDOMGenericSH, - DOM_DEFAULT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH, + IDBEVENTTARGET_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(IDBDatabaseException, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) @@ -7621,6 +7659,46 @@ nsEventTargetSH::PreserveWrapper(nsISupports *aNative) nsContentUtils::PreserveWrapper(aNative, target); } +// IDBEventTarget helper + +NS_IMETHODIMP +IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx, + JSObject *aGlobalObj, JSObject **aParentObj) +{ + IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNativeObj); + JSObject *parent = target->GetParentObject(); + *aParentObj = parent ? parent : aGlobalObj; + return NS_OK; +} + +NS_IMETHODIMP +IDBEventTargetSH::PostCreate(nsIXPConnectWrappedNative *aWrapper, + JSContext *aCx, JSObject *aObj) +{ + IDBWrapperCache *target = IDBWrapperCache::FromSupports(aWrapper->Native()); + target->OnWrapperCreated(); + return NS_OK; +} + +NS_IMETHODIMP +IDBEventTargetSH::AddProperty(nsIXPConnectWrappedNative *aWrapper, + JSContext *aCx, JSObject *aObj, jsid aId, + jsval *aVp, bool *aRetval) +{ + if (aId == sAddEventListener_id) { + return nsEventTargetSH::AddProperty(aWrapper, aCx, aObj, aId, aVp, aRetval); + } + + IDBEventTargetSH::PreserveWrapper(GetNative(aWrapper, aObj)); + return NS_OK; +} + +void +IDBEventTargetSH::PreserveWrapper(nsISupports *aNative) +{ + IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNative); + nsContentUtils::PreserveWrapper(aNative, target); +} // Element helper diff --git a/dom/indexedDB/AsyncConnectionHelper.cpp b/dom/indexedDB/AsyncConnectionHelper.cpp index 03713ace5bf8..26cfa17d4ffb 100644 --- a/dom/indexedDB/AsyncConnectionHelper.cpp +++ b/dom/indexedDB/AsyncConnectionHelper.cpp @@ -146,18 +146,11 @@ HelperBase::WrapNative(JSContext* aCx, NS_ASSERTION(aResult, "Null pointer!"); NS_ASSERTION(mRequest, "Null request!"); - JSObject* obj; - if (mRequest->ScriptContext()) { - obj = mRequest->ScriptContext()->GetNativeGlobal(); - } - else { - obj = mRequest->GetWrapper(); - } - - NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + JSObject* global = mRequest->GetParentObject(); + NS_ASSERTION(global, "This should never be null!"); nsresult rv = - nsContentUtils::WrapNative(aCx, obj, aNative, aResult); + nsContentUtils::WrapNative(aCx, global, aNative, aResult); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return NS_OK; @@ -288,7 +281,7 @@ AsyncConnectionHelper::Run() if (NS_SUCCEEDED(rv)) { bool hasSavepoint = false; if (mDatabase) { - IndexedDatabaseManager::SetCurrentWindow(mDatabase->Owner()); + IndexedDatabaseManager::SetCurrentWindow(mDatabase->GetOwner()); // Make the first savepoint. if (mTransaction) { diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index 0d3985d578da..c614edfbea73 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -64,8 +64,7 @@ GenerateRequest(IDBCursor* aCursor) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); IDBDatabase* database = aCursor->Transaction()->Database(); - return IDBRequest::Create(aCursor, database->ScriptContext(), - database->Owner(), aCursor->Transaction()); + return IDBRequest::Create(aCursor, database, aCursor->Transaction()); } } // anonymous namespace @@ -262,11 +261,14 @@ IDBCursor::CreateCommon(IDBRequest* aRequest, nsRefPtr cursor = new IDBCursor(); + IDBDatabase* database = aTransaction->Database(); + cursor->mScriptContext = database->GetScriptContext(); + cursor->mOwner = database->GetOwner(); + cursor->mScriptOwner = database->GetScriptOwner(); + cursor->mRequest = aRequest; cursor->mTransaction = aTransaction; cursor->mObjectStore = aObjectStore; - cursor->mScriptContext = aTransaction->Database()->ScriptContext(); - cursor->mOwner = aTransaction->Database()->Owner(); cursor->mDirection = aDirection; cursor->mContinueQuery = aContinueQuery; cursor->mContinueToQuery = aContinueToQuery; @@ -276,7 +278,8 @@ IDBCursor::CreateCommon(IDBRequest* aRequest, } IDBCursor::IDBCursor() -: mType(OBJECTSTORE), +: mScriptOwner(nsnull), + mType(OBJECTSTORE), mDirection(nsIIDBCursor::NEXT), mCachedKey(JSVAL_VOID), mCachedPrimaryKey(JSVAL_VOID), @@ -377,6 +380,10 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor) "Should have a cached primary key"); NS_ASSERTION(tmp->mHaveCachedValue || JSVAL_IS_VOID(tmp->mCachedValue), "Should have a cached value"); + if (tmp->mScriptOwner) { + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner, + "mScriptOwner") + } if (JSVAL_IS_GCTHING(tmp->mCachedKey)) { void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedKey); NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedKey") @@ -395,6 +402,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor) // Don't unlink mObjectStore, mIndex, or mTransaction! if (tmp->mRooted) { NS_DROP_JS_OBJECTS(tmp, IDBCursor); + tmp->mScriptOwner = nsnull; tmp->mCachedKey = JSVAL_VOID; tmp->mCachedPrimaryKey = JSVAL_VOID; tmp->mCachedValue = JSVAL_VOID; diff --git a/dom/indexedDB/IDBCursor.h b/dom/indexedDB/IDBCursor.h index 4cc6f74525e8..00a3fa4c7baf 100644 --- a/dom/indexedDB/IDBCursor.h +++ b/dom/indexedDB/IDBCursor.h @@ -154,6 +154,7 @@ protected: nsCOMPtr mScriptContext; nsCOMPtr mOwner; + JSObject* mScriptOwner; Type mType; PRUint16 mDirection; diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index d3ed92f9d36c..a97a0ea0aacc 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -148,8 +148,7 @@ private: // static already_AddRefed -IDBDatabase::Create(nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner, +IDBDatabase::Create(IDBWrapperCache* aOwnerCache, already_AddRefed aDatabaseInfo, const nsACString& aASCIIOrigin, FileManager* aFileManager) @@ -162,8 +161,9 @@ IDBDatabase::Create(nsIScriptContext* aScriptContext, nsRefPtr db(new IDBDatabase()); - db->mScriptContext = aScriptContext; - db->mOwner = aOwner; + db->mScriptContext = aOwnerCache->GetScriptContext(); + db->mOwner = aOwnerCache->GetOwner(); + db->mScriptOwner = aOwnerCache->GetScriptOwner(); db->mDatabaseId = databaseInfo->id; db->mName = databaseInfo->name; @@ -205,6 +205,8 @@ IDBDatabase::~IDBDatabase() mgr->UnregisterDatabase(this); } } + + nsContentUtils::ReleaseWrapper(static_cast(this), this); } void @@ -218,7 +220,7 @@ IDBDatabase::Invalidate() // When the IndexedDatabaseManager needs to invalidate databases, all it has // is an origin, so we call back into the manager to cancel any prompts for // our owner. - IndexedDatabaseManager::CancelPromptsForWindow(Owner()); + IndexedDatabaseManager::CancelPromptsForWindow(GetOwner()); mInvalidated = true; } @@ -280,7 +282,8 @@ void IDBDatabase::OnUnlink() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - NS_ASSERTION(!mOwner, "Should have been cleared already!"); + NS_ASSERTION(!GetOwner() && !GetScriptOwner(), + "Should have been cleared already!"); // We've been unlinked, at the very least we should be able to prevent further // transactions from starting and unblock any other SetVersion callers. @@ -298,18 +301,16 @@ IDBDatabase::OnUnlink() NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, - nsDOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnVersionChangeListener) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(versionchange) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, - nsDOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnVersionChangeListener) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(versionchange) // Do some cleanup. tmp->OnUnlink(); @@ -318,13 +319,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase) NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase) -NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) +NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache) -NS_IMPL_ADDREF_INHERITED(IDBDatabase, nsDOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(IDBDatabase, nsDOMEventTargetHelper) +NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache) +NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache) DOMCI_DATA(IDBDatabase, IDBDatabase) +NS_IMPL_EVENT_HANDLER(IDBDatabase, abort); +NS_IMPL_EVENT_HANDLER(IDBDatabase, error); +NS_IMPL_EVENT_HANDLER(IDBDatabase, versionchange); + NS_IMETHODIMP IDBDatabase::GetName(nsAString& aName) { @@ -668,47 +673,6 @@ IDBDatabase::Close() return NS_OK; } -NS_IMETHODIMP -IDBDatabase::SetOnabort(nsIDOMEventListener* aAbortListener) -{ - return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR), - mOnAbortListener, aAbortListener); -} - -NS_IMETHODIMP -IDBDatabase::GetOnabort(nsIDOMEventListener** aAbortListener) -{ - return GetInnerEventListener(mOnAbortListener, aAbortListener); -} - -NS_IMETHODIMP -IDBDatabase::SetOnerror(nsIDOMEventListener* aErrorListener) -{ - return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR), - mOnErrorListener, aErrorListener); -} - -NS_IMETHODIMP -IDBDatabase::GetOnerror(nsIDOMEventListener** aErrorListener) -{ - return GetInnerEventListener(mOnErrorListener, aErrorListener); -} - -NS_IMETHODIMP -IDBDatabase::SetOnversionchange(nsIDOMEventListener* aVersionChangeListener) -{ - return RemoveAddEventListener(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR), - mOnVersionChangeListener, - aVersionChangeListener); -} - -NS_IMETHODIMP -IDBDatabase::GetOnversionchange(nsIDOMEventListener** aVersionChangeListener) -{ - return GetInnerEventListener(mOnVersionChangeListener, - aVersionChangeListener); -} - nsresult IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor) { diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h index 574b4ff59ea4..dcc2253f17f5 100644 --- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -41,13 +41,12 @@ #define mozilla_dom_indexeddb_idbdatabase_h__ #include "mozilla/dom/indexedDB/IndexedDatabase.h" -#include "mozilla/dom/indexedDB/FileManager.h" +#include "nsIDocument.h" #include "nsIIDBDatabase.h" -#include "nsCycleCollectionParticipant.h" -#include "nsDOMEventTargetHelper.h" -#include "nsIDocument.h" +#include "mozilla/dom/indexedDB/IDBWrapperCache.h" +#include "mozilla/dom/indexedDB/FileManager.h" class nsIScriptContext; class nsPIDOMWindow; @@ -61,7 +60,7 @@ class IDBObjectStore; class IDBTransaction; class IndexedDatabaseManager; -class IDBDatabase : public nsDOMEventTargetHelper, +class IDBDatabase : public IDBWrapperCache, public nsIIDBDatabase { friend class AsyncConnectionHelper; @@ -71,12 +70,10 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIIDBDATABASE - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache) static already_AddRefed - Create(nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner, + Create(IDBWrapperCache* aOwnerCache, already_AddRefed aDatabaseInfo, const nsACString& aASCIIOrigin, FileManager* aFileManager); @@ -104,16 +101,6 @@ public: return mFilePath; } - nsIScriptContext* ScriptContext() - { - return mScriptContext; - } - - nsPIDOMWindow* Owner() - { - return mOwner; - } - already_AddRefed GetOwnerDocument() { if (!mOwner) { @@ -168,9 +155,9 @@ private: nsRefPtr mFileManager; // Only touched on the main thread. - nsRefPtr mOnAbortListener; - nsRefPtr mOnErrorListener; - nsRefPtr mOnVersionChangeListener; + NS_DECL_EVENT_HANDLER(abort); + NS_DECL_EVENT_HANDLER(error); + NS_DECL_EVENT_HANDLER(versionchange); }; END_INDEXEDDB_NAMESPACE diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 404db4076679..a545aac74beb 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -69,7 +69,6 @@ #include "IDBKeyRange.h" #include "IndexedDatabaseManager.h" #include "Key.h" -#include "nsIScriptSecurityManager.h" using namespace mozilla; @@ -91,28 +90,49 @@ struct ObjectStoreInfoMap } // anonymous namespace IDBFactory::IDBFactory() +: mOwningObject(nsnull) { IDBFactory::NoteUsedByProcessType(XRE_GetProcessType()); } +IDBFactory::~IDBFactory() +{ + if (mOwningObject) { + NS_DROP_JS_OBJECTS(this, IDBFactory); + } +} + // static already_AddRefed IDBFactory::Create(nsPIDOMWindow* aWindow) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - if (aWindow && aWindow->IsOuterWindow()) { + NS_ENSURE_TRUE(aWindow, nsnull); + + if (aWindow->IsOuterWindow()) { aWindow = aWindow->GetCurrentInnerWindow(); NS_ENSURE_TRUE(aWindow, nsnull); } nsRefPtr factory = new IDBFactory(); + factory->mWindow = aWindow; + return factory.forget(); +} - if (aWindow) { - factory->mWindow = do_GetWeakReference(aWindow); - NS_ENSURE_TRUE(factory->mWindow, nsnull); - } +// static +already_AddRefed +IDBFactory::Create(JSContext* aCx, + JSObject* aOwningObject) +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + NS_ASSERTION(aCx, "Null context!"); + NS_ASSERTION(aOwningObject, "Null object!"); + NS_ASSERTION(JS_GetGlobalForObject(aCx, aOwningObject) == aOwningObject, + "Not a global object!"); + nsRefPtr factory = new IDBFactory(); + factory->mOwningObject = aOwningObject; return factory.forget(); } @@ -400,15 +420,36 @@ IDBFactory::SetDatabaseMetadata(DatabaseInfo* aDatabaseInfo, return NS_OK; } -NS_IMPL_ADDREF(IDBFactory) -NS_IMPL_RELEASE(IDBFactory) +NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFactory) -NS_INTERFACE_MAP_BEGIN(IDBFactory) +NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBFactory) +NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBFactory) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBFactory) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIIDBFactory) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBFactory) NS_INTERFACE_MAP_END +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBFactory) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBFactory) + if (tmp->mOwningObject) { + tmp->mOwningObject = nsnull; + } + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBFactory) + if (tmp->mOwningObject) { + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mOwningObject, + "mOwningObject") + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + DOMCI_DATA(IDBFactory, IDBFactory) nsresult @@ -418,6 +459,7 @@ IDBFactory::OpenCommon(const nsAString& aName, nsIIDBOpenDBRequest** _retval) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + NS_ASSERTION(mWindow || mOwningObject, "Must have one of these!"); if (XRE_GetProcessType() == GeckoProcessType_Content) { // Force ContentChild to cache the path from the parent, so that @@ -430,16 +472,19 @@ IDBFactory::OpenCommon(const nsAString& aName, nsCOMPtr window; nsCOMPtr sgo; nsIScriptContext* context = nsnull; + JSObject* scriptOwner = nsnull; if (mWindow) { - window = do_QueryReferent(mWindow); - NS_ENSURE_TRUE(window, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - sgo = do_QueryInterface(window); + sgo = do_QueryInterface(mWindow); NS_ENSURE_TRUE(sgo, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - + context = sgo->GetContext(); NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + window = mWindow; + } + else { + scriptOwner = mOwningObject; } nsCString origin; @@ -448,7 +493,7 @@ IDBFactory::OpenCommon(const nsAString& aName, NS_ENSURE_SUCCESS(rv, rv); nsRefPtr request = - IDBOpenDBRequest::Create(context, window); + IDBOpenDBRequest::Create(context, window, scriptOwner); NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); nsRefPtr openHelper = diff --git a/dom/indexedDB/IDBFactory.h b/dom/indexedDB/IDBFactory.h index 8a1871fe180c..6144330692e7 100644 --- a/dom/indexedDB/IDBFactory.h +++ b/dom/indexedDB/IDBFactory.h @@ -45,11 +45,11 @@ #include "mozIStorageConnection.h" #include "nsIIDBFactory.h" -#include "nsIWeakReferenceUtils.h" +#include "nsCycleCollectionParticipant.h" #include "nsXULAppAPI.h" -class nsPIDOMWindow; class nsIAtom; +class nsPIDOMWindow; BEGIN_INDEXEDDB_NAMESPACE @@ -60,12 +60,17 @@ struct ObjectStoreInfo; class IDBFactory : public nsIIDBFactory { typedef nsTArray > ObjectStoreInfoArray; + public: - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory) NS_DECL_NSIIDBFACTORY static already_AddRefed Create(nsPIDOMWindow* aWindow); + static already_AddRefed Create(JSContext* aCx, + JSObject* aOwningObject); + static already_AddRefed GetConnection(const nsAString& aDatabaseFilePath); @@ -96,7 +101,7 @@ public: private: IDBFactory(); - ~IDBFactory() { } + ~IDBFactory(); nsresult OpenCommon(const nsAString& aName, @@ -104,7 +109,10 @@ private: bool aDeleting, nsIIDBOpenDBRequest** _retval); - nsCOMPtr mWindow; + // If this factory lives on a window then mWindow must be non-null. Otherwise + // mOwningObject must be non-null. + nsCOMPtr mWindow; + JSObject* mOwningObject; }; END_INDEXEDDB_NAMESPACE diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index 73c93d7e8db7..52e89c4223c2 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -294,8 +294,7 @@ GenerateRequest(IDBIndex* aIndex) NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); IDBTransaction* transaction = aIndex->ObjectStore()->Transaction(); IDBDatabase* database = transaction->Database(); - return IDBRequest::Create(aIndex, database->ScriptContext(), - database->Owner(), transaction); + return IDBRequest::Create(aIndex, database, transaction); } } // anonymous namespace @@ -313,9 +312,6 @@ IDBIndex::Create(IDBObjectStore* aObjectStore, nsRefPtr index = new IDBIndex(); - index->mScriptContext = database->ScriptContext(); - index->mOwner = database->Owner(); - index->mObjectStore = aObjectStore; index->mId = aIndexInfo->id; index->mName = aIndexInfo->name; @@ -343,14 +339,10 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBIndex) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBIndex) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mObjectStore) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBIndex) // Don't unlink mObjectStore! - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBIndex) diff --git a/dom/indexedDB/IDBIndex.h b/dom/indexedDB/IDBIndex.h index 8f6b65a356cb..1f08de79a64c 100644 --- a/dom/indexedDB/IDBIndex.h +++ b/dom/indexedDB/IDBIndex.h @@ -113,9 +113,6 @@ private: nsRefPtr mObjectStore; - nsCOMPtr mScriptContext; - nsCOMPtr mOwner; - PRInt64 mId; nsString mName; nsString mKeyPath; diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 3c23eb83ec38..30f15d7d1b6f 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -507,8 +507,8 @@ GenerateRequest(IDBObjectStore* aObjectStore) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); IDBDatabase* database = aObjectStore->Transaction()->Database(); - return IDBRequest::Create(aObjectStore, database->ScriptContext(), - database->Owner(), aObjectStore->Transaction()); + return IDBRequest::Create(aObjectStore, database, + aObjectStore->Transaction()); } JSClass gDummyPropClass = { @@ -532,9 +532,6 @@ IDBObjectStore::Create(IDBTransaction* aTransaction, nsRefPtr objectStore = new IDBObjectStore(); - objectStore->mScriptContext = aTransaction->Database()->ScriptContext(); - objectStore->mOwner = aTransaction->Database()->Owner(); - objectStore->mTransaction = aTransaction; objectStore->mName = aStoreInfo->name; objectStore->mId = aStoreInfo->id; @@ -1376,8 +1373,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBObjectStore) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction, nsIDOMEventTarget) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext) for (PRUint32 i = 0; i < tmp->mCreatedIndexes.Length(); i++) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedIndexes[i]"); @@ -1387,8 +1382,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore) // Don't unlink mTransaction! - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext) tmp->mCreatedIndexes.Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index 861a5a306a81..0ddfef459e76 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -41,13 +41,14 @@ #define mozilla_dom_indexeddb_idbobjectstore_h__ #include "mozilla/dom/indexedDB/IndexedDatabase.h" -#include "mozilla/dom/indexedDB/IDBTransaction.h" #include "nsIIDBObjectStore.h" #include "nsIIDBTransaction.h" #include "nsCycleCollectionParticipant.h" +#include "mozilla/dom/indexedDB/IDBTransaction.h" + class nsIScriptContext; class nsPIDOMWindow; @@ -204,9 +205,6 @@ protected: private: nsRefPtr mTransaction; - nsCOMPtr mScriptContext; - nsCOMPtr mOwner; - PRInt64 mId; nsString mName; nsString mKeyPath; diff --git a/dom/indexedDB/IDBRequest.cpp b/dom/indexedDB/IDBRequest.cpp index 1088844583e0..e04a1f1a2083 100644 --- a/dom/indexedDB/IDBRequest.cpp +++ b/dom/indexedDB/IDBRequest.cpp @@ -62,8 +62,8 @@ USING_INDEXEDDB_NAMESPACE IDBRequest::IDBRequest() : mResultVal(JSVAL_VOID), mErrorCode(0), - mResultValRooted(false), - mHaveResultOrErrorCode(false) + mHaveResultOrErrorCode(false), + mManuallyRooted(false) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); } @@ -72,19 +72,13 @@ IDBRequest::~IDBRequest() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - if (mResultValRooted) { - // Calling a virtual from the destructor is bad... But we know that we won't - // call a subclass' implementation because mResultValRooted will be set to - // false. - UnrootResultVal(); - } + UnrootResultVal(); } // static already_AddRefed IDBRequest::Create(nsISupports* aSource, - nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner, + IDBWrapperCache* aOwnerCache, IDBTransaction* aTransaction) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); @@ -92,8 +86,9 @@ IDBRequest::Create(nsISupports* aSource, request->mSource = aSource; request->mTransaction = aTransaction; - request->mScriptContext = aScriptContext; - request->mOwner = aOwner; + request->mScriptContext = aOwnerCache->GetScriptContext(); + request->mOwner = aOwnerCache->GetOwner(); + request->mScriptOwner = aOwnerCache->GetScriptOwner(); return request.forget(); } @@ -105,9 +100,7 @@ IDBRequest::Reset() mResultVal = JSVAL_VOID; mHaveResultOrErrorCode = false; mErrorCode = 0; - if (mResultValRooted) { - UnrootResultVal(); - } + UnrootResultVal(); } nsresult @@ -115,7 +108,7 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); - NS_ASSERTION(!mResultValRooted, "Already rooted?!"); + NS_ASSERTION(!PreservingWrapper(), "Already rooted?!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); // See if our window is still valid. If not then we're going to pretend that @@ -135,45 +128,40 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper) } // Otherwise we need to get the result from the helper. - JSContext* cx = nsnull; - JSObject* obj = nsnull; - if (mScriptContext) { - cx = mScriptContext->GetNativeContext(); - NS_ASSERTION(cx, "Failed to get a context!"); - - obj = mScriptContext->GetNativeGlobal(); - NS_ASSERTION(obj, "Failed to get global object!"); - } - else { + JSContext* cx; + if (mScriptOwner) { nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack(); NS_ASSERTION(cxStack, "Failed to get thread context stack!"); - NS_ENSURE_SUCCESS(cxStack->GetSafeJSContext(&cx), - NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - obj = GetWrapper(); - NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) { + NS_WARNING("Failed to get safe JSContext!"); + rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + mErrorCode = NS_ERROR_GET_CODE(rv); + return rv; + } } + else { + cx = mScriptContext->GetNativeContext(); + NS_ASSERTION(cx, "Failed to get a context!"); + } + + JSObject* global = GetParentObject(); + NS_ASSERTION(global, "This should never be null!"); JSAutoRequest ar(cx); JSAutoEnterCompartment ac; - if (!ac.enter(cx, obj)) { - rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; - } - else { + if (ac.enter(cx, global)) { RootResultVal(); rv = aHelper->GetSuccessResult(cx, &mResultVal); - if (NS_SUCCEEDED(rv)) { - // Unroot if we don't really need to be rooted. - if (!JSVAL_IS_GCTHING(mResultVal)) { - UnrootResultVal(); - } - } - else { + if (NS_FAILED(rv)) { NS_WARNING("GetSuccessResult failed!"); } } + else { + NS_WARNING("Failed to enter correct compartment!"); + rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } if (NS_SUCCEEDED(rv)) { mErrorCode = 0; @@ -189,17 +177,47 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper) void IDBRequest::RootResultVal() { - NS_ASSERTION(!mResultValRooted, "This should be false!"); - NS_HOLD_JS_OBJECTS(this, IDBRequest); - mResultValRooted = true; + // We want to use the preserved wrapper to keep our result alive, but we don't + // always get a wrapper right away. Manually root if we don't have a wrapper. + if (!PreservingWrapper() && GetWrapperPreserveColor()) { + NS_ASSERTION(!mManuallyRooted, "Should not be manually rooted here!"); + nsContentUtils::PreserveWrapper(static_cast(this), + this); + } + else if (!mManuallyRooted) { + NS_HOLD_JS_OBJECTS(this, IDBRequest); + mManuallyRooted = true; + } } void IDBRequest::UnrootResultVal() { - NS_ASSERTION(mResultValRooted, "This should be true!"); - NS_DROP_JS_OBJECTS(this, IDBRequest); - mResultValRooted = false; + if (mManuallyRooted) { + NS_ASSERTION(!PreservingWrapper(), "Shouldn't have a wrapper here!"); + NS_DROP_JS_OBJECTS(this, IDBRequest); + mManuallyRooted = false; + } + else if (PreservingWrapper()) { + nsContentUtils::ReleaseWrapper(static_cast(this), this); + } +} + +void +IDBRequest::OnWrapperCreated() +{ + NS_ASSERTION(!PreservingWrapper(), + "Shouldn't have had a wrapper before now!"); + + // Update our rooting strategy to accommodate new wrapper if needed. We have + // to unroot the old way first. This is annoying because XPConnect uses a hash + // table to store these so we could be just fine adding an entry for a second + // time... However nsContentUtils keeps a counter that will get out of sync if + // we do. Safest to just remove the old holder and then add a new one. + if (mManuallyRooted) { + UnrootResultVal(); + RootResultVal(); + } } NS_IMETHODIMP @@ -262,66 +280,32 @@ IDBRequest::GetErrorCode(PRUint16* aErrorCode) return NS_OK; } -NS_IMETHODIMP -IDBRequest::SetOnsuccess(nsIDOMEventListener* aSuccessListener) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return RemoveAddEventListener(NS_LITERAL_STRING(SUCCESS_EVT_STR), - mOnSuccessListener, aSuccessListener); -} - -NS_IMETHODIMP -IDBRequest::GetOnsuccess(nsIDOMEventListener** aSuccessListener) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return GetInnerEventListener(mOnSuccessListener, aSuccessListener); -} - -NS_IMETHODIMP -IDBRequest::SetOnerror(nsIDOMEventListener* aErrorListener) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR), - mOnErrorListener, aErrorListener); -} - -NS_IMETHODIMP -IDBRequest::GetOnerror(nsIDOMEventListener** aErrorListener) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return GetInnerEventListener(mOnErrorListener, aErrorListener); -} - NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, - nsDOMEventTargetWrapperCache) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache) + // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because + // nsDOMEventTargetHelper does it for us. + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction, nsPIDOMEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, - nsDOMEventTargetWrapperCache) - if (tmp->mResultValRooted) { - tmp->mResultVal = JSVAL_VOID; +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache) + tmp->mResultVal = JSVAL_VOID; + if (tmp->mManuallyRooted) { tmp->UnrootResultVal(); } - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction) NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, - nsDOMEventTargetWrapperCache) +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache) + // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because + // nsDOMEventTargetHelper does it for us. if (JSVAL_IS_GCTHING(tmp->mResultVal)) { void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal); NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResultVal") @@ -331,13 +315,16 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest) NS_INTERFACE_MAP_ENTRY(nsIIDBRequest) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest) -NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache) +NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache) -NS_IMPL_ADDREF_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache) -NS_IMPL_RELEASE_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache) +NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache) +NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache) DOMCI_DATA(IDBRequest, IDBRequest) +NS_IMPL_EVENT_HANDLER(IDBRequest, success); +NS_IMPL_EVENT_HANDLER(IDBRequest, error); + nsresult IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor) { @@ -352,21 +339,21 @@ IDBOpenDBRequest::~IDBOpenDBRequest() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - if (mResultValRooted) { - UnrootResultVal(); - } + UnrootResultVal(); } // static already_AddRefed IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner) + nsPIDOMWindow* aOwner, + JSObject* aScriptOwner) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsRefPtr request(new IDBOpenDBRequest()); request->mScriptContext = aScriptContext; request->mOwner = aOwner; + request->mScriptOwner = aScriptOwner; return request.forget(); } @@ -377,37 +364,18 @@ IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction) mTransaction = aTransaction; } -void -IDBOpenDBRequest::RootResultVal() -{ - NS_ASSERTION(!mResultValRooted, "This should be false!"); - NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest); - mResultValRooted = true; -} - -void -IDBOpenDBRequest::UnrootResultVal() -{ - NS_ASSERTION(mResultValRooted, "This should be true!"); - NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest); - mResultValRooted = false; -} - -NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked) -NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded) - NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest, IDBRequest) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnupgradeneededListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnblockedListener) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(upgradeneeded) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(blocked) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest, IDBRequest) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnupgradeneededListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnblockedListener) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(upgradeneeded) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(blocked) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest) @@ -419,3 +387,6 @@ NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest) NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest) DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest) + +NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked); +NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded); diff --git a/dom/indexedDB/IDBRequest.h b/dom/indexedDB/IDBRequest.h index 9ab2fbaa4a19..3d5d960c5640 100644 --- a/dom/indexedDB/IDBRequest.h +++ b/dom/indexedDB/IDBRequest.h @@ -46,8 +46,7 @@ #include "nsIIDBRequest.h" #include "nsIIDBOpenDBRequest.h" -#include "nsDOMEventTargetWrapperCache.h" -#include "nsCycleCollectionParticipant.h" +#include "mozilla/dom/indexedDB/IDBWrapperCache.h" class nsIScriptContext; class nsPIDOMWindow; @@ -57,19 +56,18 @@ BEGIN_INDEXEDDB_NAMESPACE class HelperBase; class IDBTransaction; -class IDBRequest : public nsDOMEventTargetWrapperCache, +class IDBRequest : public IDBWrapperCache, public nsIIDBRequest { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIIDBREQUEST NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest, - nsDOMEventTargetWrapperCache) + IDBWrapperCache) static already_AddRefed Create(nsISupports* aSource, - nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner, + IDBWrapperCache* aOwnerCache, IDBTransaction* aTransaction); // nsIDOMEventTarget @@ -92,18 +90,10 @@ public: mErrorCode = rv; } - nsIScriptContext* ScriptContext() - { - return mScriptContext; - } + void RootResultVal(); + void UnrootResultVal(); - nsPIDOMWindow* Owner() - { - return mOwner; - } - - virtual void RootResultVal(); - virtual void UnrootResultVal(); + virtual void OnWrapperCreated(); protected: IDBRequest(); @@ -112,14 +102,14 @@ protected: nsCOMPtr mSource; nsRefPtr mTransaction; - nsRefPtr mOnSuccessListener; - nsRefPtr mOnErrorListener; + NS_DECL_EVENT_HANDLER(success); + NS_DECL_EVENT_HANDLER(error); jsval mResultVal; PRUint16 mErrorCode; - bool mResultValRooted; bool mHaveResultOrErrorCode; + bool mManuallyRooted; }; class IDBOpenDBRequest : public IDBRequest, @@ -129,24 +119,30 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_NSIIDBREQUEST(IDBRequest::) NS_DECL_NSIIDBOPENDBREQUEST - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, - IDBRequest) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest) static already_AddRefed Create(nsIScriptContext* aScriptContext, - nsPIDOMWindow* aOwner); + nsPIDOMWindow* aOwner, + JSObject* aScriptOwner); + + static + already_AddRefed + Create(IDBWrapperCache* aOwnerCache) + { + return Create(aOwnerCache->GetScriptContext(), aOwnerCache->GetOwner(), + aOwnerCache->GetScriptOwner()); + } void SetTransaction(IDBTransaction* aTransaction); - virtual void RootResultVal(); - virtual void UnrootResultVal(); - protected: ~IDBOpenDBRequest(); - nsRefPtr mOnblockedListener; - nsRefPtr mOnupgradeneededListener; + // Only touched on the main thread. + NS_DECL_EVENT_HANDLER(blocked); + NS_DECL_EVENT_HANDLER(upgradeneeded); }; END_INDEXEDDB_NAMESPACE diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index ce3a0b5d17f1..7f506a3b6237 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -42,6 +42,7 @@ #include "nsIScriptContext.h" #include "mozilla/storage.h" +#include "nsContentUtils.h" #include "nsDOMClassInfoID.h" #include "nsDOMLists.h" #include "nsEventDispatcher.h" @@ -116,8 +117,9 @@ IDBTransaction::Create(IDBDatabase* aDatabase, nsRefPtr transaction = new IDBTransaction(); - transaction->mScriptContext = aDatabase->ScriptContext(); - transaction->mOwner = aDatabase->Owner(); + transaction->mScriptContext = aDatabase->GetScriptContext(); + transaction->mOwner = aDatabase->GetOwner(); + transaction->mScriptOwner = aDatabase->GetScriptOwner(); transaction->mDatabase = aDatabase; transaction->mMode = aMode; @@ -184,6 +186,8 @@ IDBTransaction::~IDBTransaction() NS_ASSERTION(!mConnection, "Should have called CommitOrRollback!"); NS_ASSERTION(!mCreating, "Should have been cleared already!"); NS_ASSERTION(mFiredCompleteOrAbort, "Should have fired event!"); + + nsContentUtils::ReleaseWrapper(static_cast(this), this); } void @@ -474,27 +478,25 @@ IDBTransaction::ClearCreatedFileInfos() NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction, - nsDOMEventTargetHelper) + IDBWrapperCache) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDatabase, nsIDOMEventTarget) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCompleteListener) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete) + NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort) for (PRUint32 i = 0; i < tmp->mCreatedObjectStores.Length(); i++) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedObjectStores[i]"); cb.NoteXPCOMChild(static_cast( tmp->mCreatedObjectStores[i].get())); } - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, - nsDOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache) // Don't unlink mDatabase! - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCompleteListener) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete) + NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort) tmp->mCreatedObjectStores.Clear(); @@ -504,13 +506,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction) NS_INTERFACE_MAP_ENTRY(nsIIDBTransaction) NS_INTERFACE_MAP_ENTRY(nsIThreadObserver) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBTransaction) -NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) +NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache) -NS_IMPL_ADDREF_INHERITED(IDBTransaction, nsDOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(IDBTransaction, nsDOMEventTargetHelper) +NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache) +NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache) DOMCI_DATA(IDBTransaction, IDBTransaction) +NS_IMPL_EVENT_HANDLER(IDBTransaction, error); +NS_IMPL_EVENT_HANDLER(IDBTransaction, complete); +NS_IMPL_EVENT_HANDLER(IDBTransaction, abort); + NS_IMETHODIMP IDBTransaction::GetDb(nsIIDBDatabase** aDB) { @@ -626,53 +632,6 @@ IDBTransaction::Abort() return NS_OK; } -NS_IMETHODIMP -IDBTransaction::SetOnerror(nsIDOMEventListener* aErrorListener) -{ - return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR), - mOnErrorListener, aErrorListener); -} - -NS_IMETHODIMP -IDBTransaction::GetOnerror(nsIDOMEventListener** aErrorListener) -{ - return GetInnerEventListener(mOnErrorListener, aErrorListener); -} - -NS_IMETHODIMP -IDBTransaction::GetOncomplete(nsIDOMEventListener** aOncomplete) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return GetInnerEventListener(mOnCompleteListener, aOncomplete); -} - -NS_IMETHODIMP -IDBTransaction::SetOncomplete(nsIDOMEventListener* aOncomplete) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return RemoveAddEventListener(NS_LITERAL_STRING(COMPLETE_EVT_STR), - mOnCompleteListener, aOncomplete); -} - -NS_IMETHODIMP -IDBTransaction::GetOnabort(nsIDOMEventListener** aOnabort) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return GetInnerEventListener(mOnAbortListener, aOnabort); -} - -NS_IMETHODIMP -IDBTransaction::SetOnabort(nsIDOMEventListener* aOnabort) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - - return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR), - mOnAbortListener, aOnabort); -} - nsresult IDBTransaction::PreHandleEvent(nsEventChainPreVisitor& aVisitor) { @@ -817,7 +776,7 @@ CommitHelper::Run() } if (mConnection) { - IndexedDatabaseManager::SetCurrentWindow(database->Owner()); + IndexedDatabaseManager::SetCurrentWindow(database->GetOwner()); if (!mAborted && mUpdateFileRefcountFunction && NS_FAILED(mUpdateFileRefcountFunction->UpdateDatabase(mConnection))) { diff --git a/dom/indexedDB/IDBTransaction.h b/dom/indexedDB/IDBTransaction.h index 4d6cdfff7250..f05f8b308887 100644 --- a/dom/indexedDB/IDBTransaction.h +++ b/dom/indexedDB/IDBTransaction.h @@ -41,8 +41,6 @@ #define mozilla_dom_indexeddb_idbtransaction_h__ #include "mozilla/dom/indexedDB/IndexedDatabase.h" -#include "mozilla/dom/indexedDB/IDBDatabase.h" -#include "mozilla/dom/indexedDB/FileInfo.h" #include "mozIStorageConnection.h" #include "mozIStorageStatement.h" @@ -51,14 +49,15 @@ #include "nsIRunnable.h" #include "nsIThreadInternal.h" -#include "nsDOMEventTargetHelper.h" -#include "nsCycleCollectionParticipant.h" - #include "nsAutoPtr.h" #include "nsClassHashtable.h" #include "nsHashKeys.h" #include "nsInterfaceHashtable.h" +#include "mozilla/dom/indexedDB/IDBDatabase.h" +#include "mozilla/dom/indexedDB/IDBWrapperCache.h" +#include "mozilla/dom/indexedDB/FileInfo.h" + class nsIThread; BEGIN_INDEXEDDB_NAMESPACE @@ -78,7 +77,7 @@ public: virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction) = 0; }; -class IDBTransaction : public nsDOMEventTargetHelper, +class IDBTransaction : public IDBWrapperCache, public nsIIDBTransaction, public nsIThreadObserver { @@ -92,8 +91,7 @@ public: NS_DECL_NSIIDBTRANSACTION NS_DECL_NSITHREADOBSERVER - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache) static already_AddRefed Create(IDBDatabase* aDatabase, @@ -180,9 +178,9 @@ private: PRUint32 mCreatedRecursionDepth; // Only touched on the main thread. - nsRefPtr mOnErrorListener; - nsRefPtr mOnCompleteListener; - nsRefPtr mOnAbortListener; + NS_DECL_EVENT_HANDLER(error); + NS_DECL_EVENT_HANDLER(complete); + NS_DECL_EVENT_HANDLER(abort); nsInterfaceHashtable mCachedStatements; diff --git a/dom/indexedDB/IDBWrapperCache.cpp b/dom/indexedDB/IDBWrapperCache.cpp new file mode 100644 index 000000000000..c09482fd7c30 --- /dev/null +++ b/dom/indexedDB/IDBWrapperCache.cpp @@ -0,0 +1,38 @@ +/* -*- 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 "IDBWrapperCache.h" + +USING_INDEXEDDB_NAMESPACE + +NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBWrapperCache, + nsDOMEventTargetWrapperCache) + // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because + // nsDOMEventTargetHelper does it for us. +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache, + nsDOMEventTargetWrapperCache) + tmp->mScriptOwner = nsnull; +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBWrapperCache, + nsDOMEventTargetWrapperCache) + // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because + // nsDOMEventTargetHelper does it for us. + if (tmp->mScriptOwner) { + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner, + "mScriptOwner") + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBWrapperCache) +NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache) + +NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache) +NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache) diff --git a/dom/indexedDB/IDBWrapperCache.h b/dom/indexedDB/IDBWrapperCache.h new file mode 100644 index 000000000000..8d4fdb55b0a5 --- /dev/null +++ b/dom/indexedDB/IDBWrapperCache.h @@ -0,0 +1,74 @@ +/* -*- 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/. */ + +#ifndef mozilla_dom_indexeddb_idbwrappercache_h__ +#define mozilla_dom_indexeddb_idbwrappercache_h__ + +#include "mozilla/dom/indexedDB/IndexedDatabase.h" + +#include "nsDOMEventTargetWrapperCache.h" + +BEGIN_INDEXEDDB_NAMESPACE + +class IDBWrapperCache : public nsDOMEventTargetWrapperCache +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED( + IDBWrapperCache, + nsDOMEventTargetWrapperCache) + + JSObject* GetScriptOwner() const + { + return mScriptOwner; + } + + nsIScriptContext* GetScriptContext() const + { + return mScriptContext; + } + + nsPIDOMWindow* GetOwner() const + { + return mOwner; + } + + JSObject* GetParentObject() + { + if (mScriptOwner) { + return mScriptOwner; + } + + // Do what nsEventTargetSH::PreCreate does. + nsCOMPtr parent; + nsDOMEventTargetWrapperCache::GetParentObject(getter_AddRefs(parent)); + + return parent ? parent->GetGlobalJSObject() : nsnull; + } + + virtual void OnWrapperCreated() + { } + + static IDBWrapperCache* FromSupports(nsISupports* aSupports) + { + return static_cast( + nsDOMEventTargetWrapperCache::FromSupports(aSupports)); + } + +protected: + IDBWrapperCache() + : mScriptOwner(nsnull) + { } + + virtual ~IDBWrapperCache() + { } + + JSObject* mScriptOwner; +}; + +END_INDEXEDDB_NAMESPACE + +#endif // mozilla_dom_indexeddb_idbwrappercache_h__ diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 1f43d3bc73b6..cb9034f720e3 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -505,7 +505,7 @@ IndexedDatabaseManager::AbortCloseDatabasesForWindow(nsPIDOMWindow* aWindow) for (PRUint32 index = 0; index < liveDatabases.Length(); index++) { IDBDatabase*& database = liveDatabases[index]; - if (database->Owner() == aWindow) { + if (database->GetOwner() == aWindow) { if (NS_FAILED(database->Close())) { NS_WARNING("Failed to close database for dying window!"); } @@ -533,7 +533,7 @@ IndexedDatabaseManager::HasOpenTransactions(nsPIDOMWindow* aWindow) for (PRUint32 index = 0; index < liveDatabases.Length(); index++) { IDBDatabase*& database = liveDatabases[index]; - if (database->Owner() == aWindow && + if (database->GetOwner() == aWindow && pool->HasTransactionsForDatabase(database)) { return true; } @@ -1591,32 +1591,32 @@ NS_IMETHODIMP IndexedDatabaseManager::InitWindowless(const jsval& aObj, JSContext* aCx) { NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - + NS_ENSURE_ARG(!JSVAL_IS_PRIMITIVE(aObj)); + // Instantiating this class will register exception providers so even - // in xpcshell we will get typed (dom) exceptions, instead of general exceptions. + // in xpcshell we will get typed (dom) exceptions, instead of general + // exceptions. nsCOMPtr sof(do_GetService(kDOMSOF_CID)); - // Defining IDBKeyrange static functions on the global. - if (JSVAL_IS_PRIMITIVE(aObj)) { - return NS_ERROR_INVALID_ARG; - } - - nsCOMPtr factory = IDBFactory::Create(nsnull); - NS_ASSERTION(factory, "IDBFactory should not be null."); - JSObject* obj = JSVAL_TO_OBJECT(aObj); + + JSObject* global = JS_GetGlobalForObject(aCx, obj); + + nsCOMPtr factory = IDBFactory::Create(aCx, global); + NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE); + jsval mozIndexedDBVal; nsresult rv = nsContentUtils::WrapNative(aCx, obj, factory, &mozIndexedDBVal); NS_ENSURE_SUCCESS(rv, rv); - if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, - nsnull, nsnull, JSPROP_ENUMERATE)) { + if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, nsnull, + nsnull, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } JSObject* keyrangeObj = JS_NewObject(aCx, nsnull, nsnull, nsnull); NS_ENSURE_TRUE(keyrangeObj, NS_ERROR_OUT_OF_MEMORY); - + if (!IDBKeyRange::DefineConstructors(aCx, keyrangeObj)) { return NS_ERROR_FAILURE; } diff --git a/dom/indexedDB/Makefile.in b/dom/indexedDB/Makefile.in index 36b7e0902198..2bf85c2db826 100644 --- a/dom/indexedDB/Makefile.in +++ b/dom/indexedDB/Makefile.in @@ -61,16 +61,17 @@ CPPSRCS = \ IDBCursor.cpp \ IDBDatabase.cpp \ IDBEvents.cpp \ + IDBFactory.cpp \ IDBIndex.cpp \ IDBKeyRange.cpp \ IDBObjectStore.cpp \ IDBRequest.cpp \ IDBTransaction.cpp \ - IDBFactory.cpp \ + IDBWrapperCache.cpp \ IndexedDatabaseManager.cpp \ + Key.cpp \ OpenDatabaseHelper.cpp \ TransactionThreadPool.cpp \ - Key.cpp \ $(NULL) EXPORTS_mozilla/dom/indexedDB = \ @@ -82,6 +83,7 @@ EXPORTS_mozilla/dom/indexedDB = \ IDBObjectStore.h \ IDBRequest.h \ IDBTransaction.h \ + IDBWrapperCache.h \ IndexedDatabase.h \ IndexedDatabaseManager.h \ IDBFactory.h \ diff --git a/dom/indexedDB/OpenDatabaseHelper.cpp b/dom/indexedDB/OpenDatabaseHelper.cpp index ab3e86a3ede3..4a145575478f 100644 --- a/dom/indexedDB/OpenDatabaseHelper.cpp +++ b/dom/indexedDB/OpenDatabaseHelper.cpp @@ -1611,7 +1611,9 @@ OpenDatabaseHelper::DoDatabaseWork() NS_ASSERTION(mOpenDBRequest, "This should never be null!"); - nsPIDOMWindow* window = mOpenDBRequest->Owner(); + // This will be null for non-window contexts. + nsPIDOMWindow* window = mOpenDBRequest->GetOwner(); + AutoEnterWindow autoWindow(window); nsCOMPtr dbDirectory; @@ -2111,8 +2113,7 @@ OpenDatabaseHelper::EnsureSuccessResult() dbInfo->nextIndexId = mLastIndexId + 1; nsRefPtr database = - IDBDatabase::Create(mOpenDBRequest->ScriptContext(), - mOpenDBRequest->Owner(), + IDBDatabase::Create(mOpenDBRequest, dbInfo.forget(), mASCIIOrigin, mFileManager);