Modern IDB: Cursors (still) do not keep their opening request alive.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Feb 2016 01:42:54 +0000 (01:42 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Feb 2016 01:42:54 +0000 (01:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153724

Reviewed by Alex Christensen.

No new tests (All existing tests pass without flakiness).

IDBCursors did not properly keep their JS wrappers alive.
Making them ActiveDOMObjects that keep track of how many requests might be in flight fixes this.
This also makes them actually keep their opening-request live via the opaque-root mechanism.

IDBCursorWithValue also needed to opt in to all of these mechanisms.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/indexeddb/IDBCursor.h:
(WebCore::IDBCursor::hasPendingActivity): The base IDBCursor always has no pending activity,
  to maintain current behavior in LegacyIDB. This weirdness will go away when LegacyIDB does.
* Modules/indexeddb/IDBCursor.idl:
* Modules/indexeddb/IDBCursorWithValue.idl:

Track a count for all outstanding requests to keep the cursor alive as an ActiveDOMObject.
* Modules/indexeddb/client/IDBCursorImpl.cpp:
(WebCore::IDBClient::IDBCursor::IDBCursor):
(WebCore::IDBClient::IDBCursor::update):
(WebCore::IDBClient::IDBCursor::uncheckedIterateCursor):
(WebCore::IDBClient::IDBCursor::deleteFunction):
(WebCore::IDBClient::IDBCursor::activeDOMObjectName):
(WebCore::IDBClient::IDBCursor::canSuspendForDocumentSuspension):
(WebCore::IDBClient::IDBCursor::hasPendingActivity):
(WebCore::IDBClient::IDBCursor::decrementOutstandingRequestCount):
* Modules/indexeddb/client/IDBCursorImpl.h:

Rework the "delete" family of functions on the object store to allow for returning a modern IDBRequest.
A lot of this can go away when LegacyIDB does.
* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::deleteFunction):
(WebCore::IDBClient::IDBObjectStore::doDelete):
(WebCore::IDBClient::IDBObjectStore::modernDelete):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:

* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::setSource): Setup a ScopeGuard to decrement the cursor's request
  count whenever it makes sense to do so.
(WebCore::IDBClient::IDBRequest::dispatchEvent): Clear the ScopeGuard (if it exists) to decrement the count.
(WebCore::IDBClient::IDBRequest::willIterateCursor): Set the ScopeGuard.
(WebCore::IDBClient::IDBRequest::didOpenOrIterateCursor): Clear the ScopeGuard (if it exists) to decrement the count.
* Modules/indexeddb/client/IDBRequestImpl.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::ScopeGuard::ScopeGuard): Deleted.
(WebCore::IDBServer::ScopeGuard::~ScopeGuard): Deleted.
(WebCore::IDBServer::ScopeGuard::enable): Deleted.
(WebCore::IDBServer::ScopeGuard::disable): Deleted.

* bindings/js/JSIDBCursorWithValueCustom.cpp: Added.
(WebCore::JSIDBCursorWithValue::visitAdditionalChildren):

* platform/ScopeGuard.h: Added.
(WebCore::ScopeGuard::ScopeGuard):
(WebCore::ScopeGuard::~ScopeGuard):
(WebCore::ScopeGuard::enable):
(WebCore::ScopeGuard::disable):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195997 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCursor.h
Source/WebCore/Modules/indexeddb/IDBCursor.idl
Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl
Source/WebCore/Modules/indexeddb/client/IDBCursorImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBCursorImpl.h
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h
Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp [new file with mode: 0644]
Source/WebCore/platform/ScopeGuard.h [new file with mode: 0644]

index c48e108..ec47b0f 100644 (file)
@@ -1186,6 +1186,7 @@ set(WebCore_SOURCES
     bindings/js/JSHistoryCustom.cpp
     bindings/js/JSIDBAnyCustom.cpp
     bindings/js/JSIDBCursorCustom.cpp
+    bindings/js/JSIDBCursorWithValueCustom.cpp
     bindings/js/JSIDBDatabaseCustom.cpp
     bindings/js/JSIDBObjectStoreCustom.cpp
     bindings/js/JSImageConstructor.cpp
index c5882fd..5e31905 100644 (file)
@@ -1,3 +1,70 @@
+2016-02-01  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Cursors (still) do not keep their opening request alive.
+        https://bugs.webkit.org/show_bug.cgi?id=153724
+
+        Reviewed by Alex Christensen.
+
+        No new tests (All existing tests pass without flakiness).
+
+        IDBCursors did not properly keep their JS wrappers alive.
+        Making them ActiveDOMObjects that keep track of how many requests might be in flight fixes this.
+        This also makes them actually keep their opening-request live via the opaque-root mechanism.
+        
+        IDBCursorWithValue also needed to opt in to all of these mechanisms.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * Modules/indexeddb/IDBCursor.h:
+        (WebCore::IDBCursor::hasPendingActivity): The base IDBCursor always has no pending activity,
+          to maintain current behavior in LegacyIDB. This weirdness will go away when LegacyIDB does.
+        * Modules/indexeddb/IDBCursor.idl:
+        * Modules/indexeddb/IDBCursorWithValue.idl:
+
+        Track a count for all outstanding requests to keep the cursor alive as an ActiveDOMObject.
+        * Modules/indexeddb/client/IDBCursorImpl.cpp:
+        (WebCore::IDBClient::IDBCursor::IDBCursor):
+        (WebCore::IDBClient::IDBCursor::update):
+        (WebCore::IDBClient::IDBCursor::uncheckedIterateCursor):
+        (WebCore::IDBClient::IDBCursor::deleteFunction):
+        (WebCore::IDBClient::IDBCursor::activeDOMObjectName):
+        (WebCore::IDBClient::IDBCursor::canSuspendForDocumentSuspension):
+        (WebCore::IDBClient::IDBCursor::hasPendingActivity):
+        (WebCore::IDBClient::IDBCursor::decrementOutstandingRequestCount):
+        * Modules/indexeddb/client/IDBCursorImpl.h:
+        
+        Rework the "delete" family of functions on the object store to allow for returning a modern IDBRequest.
+        A lot of this can go away when LegacyIDB does.
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::deleteFunction):
+        (WebCore::IDBClient::IDBObjectStore::doDelete):
+        (WebCore::IDBClient::IDBObjectStore::modernDelete):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+        
+        * Modules/indexeddb/client/IDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBRequest::setSource): Setup a ScopeGuard to decrement the cursor's request
+          count whenever it makes sense to do so.
+        (WebCore::IDBClient::IDBRequest::dispatchEvent): Clear the ScopeGuard (if it exists) to decrement the count.
+        (WebCore::IDBClient::IDBRequest::willIterateCursor): Set the ScopeGuard.
+        (WebCore::IDBClient::IDBRequest::didOpenOrIterateCursor): Clear the ScopeGuard (if it exists) to decrement the count.
+        * Modules/indexeddb/client/IDBRequestImpl.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::ScopeGuard::ScopeGuard): Deleted.
+        (WebCore::IDBServer::ScopeGuard::~ScopeGuard): Deleted.
+        (WebCore::IDBServer::ScopeGuard::enable): Deleted.
+        (WebCore::IDBServer::ScopeGuard::disable): Deleted.
+        
+        * bindings/js/JSIDBCursorWithValueCustom.cpp: Added.
+        (WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
+        
+        * platform/ScopeGuard.h: Added.
+        (WebCore::ScopeGuard::ScopeGuard):
+        (WebCore::ScopeGuard::~ScopeGuard):
+        (WebCore::ScopeGuard::enable):
+        (WebCore::ScopeGuard::disable):
+
 2016-02-01  Sun-woo Nam  <sunny.nam@samsung.com>
 
         Free Colormap when XWindow is destroyed.
index 78d60e9..b502caf 100644 (file)
@@ -76,6 +76,8 @@ public:
 
     virtual bool isModernCursor() const { return false; }
 
+    virtual bool hasPendingActivity() const { return false; }
+
 protected:
     IDBCursor();
 };
index 95180e8..046f905 100644 (file)
@@ -26,6 +26,7 @@
 [
     Conditional=INDEXED_DATABASE,
     EnabledAtRuntime=IndexedDB,
+    ActiveDOMObject,
     SkipVTableValidation,
     JSCustomMarkFunction,
 ] interface IDBCursor {
index 3471a24..852e147 100644 (file)
@@ -26,7 +26,9 @@
 [
     Conditional=INDEXED_DATABASE,
     EnabledAtRuntime=IndexedDB,
+    ActiveDOMObject,
     SkipVTableValidation,
+    JSCustomMarkFunction,
 ] interface IDBCursorWithValue : IDBCursor {
     readonly attribute any value;
 };
index 0263f92..8679a62 100644 (file)
@@ -44,18 +44,22 @@ Ref<IDBCursor> IDBCursor::create(IDBTransaction& transaction, IDBIndex& index, c
     return adoptRef(*new IDBCursor(transaction, index, info));
 }
 
-IDBCursor::IDBCursor(IDBTransaction&, IDBObjectStore& objectStore, const IDBCursorInfo& info)
-    : m_info(info)
+IDBCursor::IDBCursor(IDBTransaction& transaction, IDBObjectStore& objectStore, const IDBCursorInfo& info)
+    : ActiveDOMObject(transaction.scriptExecutionContext())
+    , m_info(info)
     , m_source(IDBAny::create(objectStore).leakRef())
     , m_objectStore(&objectStore)
 {
+    suspendIfNeeded();
 }
 
-IDBCursor::IDBCursor(IDBTransaction&, IDBIndex& index, const IDBCursorInfo& info)
-    : m_info(info)
+IDBCursor::IDBCursor(IDBTransaction& transaction, IDBIndex& index, const IDBCursorInfo& info)
+    : ActiveDOMObject(transaction.scriptExecutionContext())
+    , m_info(info)
     , m_source(IDBAny::create(index).leakRef())
     , m_index(&index)
 {
+    suspendIfNeeded();
 }
 
 IDBCursor::~IDBCursor()
@@ -163,6 +167,8 @@ RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::
 
     ASSERT(request);
     request->setSource(*this);
+    ++m_outstandingRequestCount;
+
     return request;
 }
 
@@ -281,6 +287,8 @@ void IDBCursor::continueFunction(const IDBKeyData& key, ExceptionCodeWithMessage
 
 void IDBCursor::uncheckedIterateCursor(const IDBKeyData& key, unsigned long count)
 {
+    ++m_outstandingRequestCount;
+
     m_request->willIterateCursor(*this);
     transaction().iterateCursor(*this, key, count);
 }
@@ -324,7 +332,15 @@ RefPtr<WebCore::IDBRequest> IDBCursor::deleteFunction(ScriptExecutionContext* co
         return nullptr;
     }
 
-    return effectiveObjectStore().deleteFunction(context, m_deprecatedCurrentPrimaryKey.jsValue(), ec);
+    auto request = effectiveObjectStore().modernDelete(context, m_deprecatedCurrentPrimaryKey.jsValue(), ec);
+    if (ec.code)
+        return nullptr;
+
+    ASSERT(request);
+    request->setSource(*this);
+    ++m_outstandingRequestCount;
+
+    return request;
 }
 
 void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
@@ -359,6 +375,27 @@ void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
     m_gotValue = true;
 }
 
+const char* IDBCursor::activeDOMObjectName() const
+{
+    return "IDBCursor";
+}
+
+bool IDBCursor::canSuspendForDocumentSuspension() const
+{
+    return false;
+}
+
+bool IDBCursor::hasPendingActivity() const
+{
+    return m_outstandingRequestCount;
+}
+
+void IDBCursor::decrementOutstandingRequestCount()
+{
+    ASSERT(m_outstandingRequestCount);
+    --m_outstandingRequestCount;
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 
index 9c72e25..868b1a1 100644 (file)
@@ -42,7 +42,7 @@ class IDBIndex;
 class IDBObjectStore;
 class IDBTransaction;
 
-class IDBCursor : public WebCore::IDBCursorWithValue {
+class IDBCursor : public WebCore::IDBCursorWithValue, public ActiveDOMObject {
 public:
     static Ref<IDBCursor> create(IDBTransaction&, IDBIndex&, const IDBCursorInfo&);
 
@@ -74,11 +74,21 @@ public:
     virtual bool isKeyCursor() const override { return true; }
     virtual bool isModernCursor() const override final { return true; }
 
+    void decrementOutstandingRequestCount();
+
 protected:
     IDBCursor(IDBTransaction&, IDBObjectStore&, const IDBCursorInfo&);
     IDBCursor(IDBTransaction&, IDBIndex&, const IDBCursorInfo&);
 
 private:
+    // ActiveDOMObject.
+    virtual const char* activeDOMObjectName() const override final;
+    virtual bool canSuspendForDocumentSuspension() const override final;
+    virtual bool hasPendingActivity() const override final;
+
+    // Cursors are created with an outstanding iteration request.
+    unsigned m_outstandingRequestCount { 1 };
+
     IDBCursorInfo m_info;
     Ref<IDBAny> m_source;
     IDBObjectStore* m_objectStore { nullptr };
index b29c7fe..85f6725 100644 (file)
@@ -340,9 +340,13 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue
     return adoptRef(request.leakRef());
 }
 
-
 RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
 {
+    return doDelete(context, keyRange, ec);
+}
+
+RefPtr<IDBRequest> IDBObjectStore::doDelete(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
+{
     LOG(IndexedDB, "IDBObjectStore::deleteFunction");
 
     // The IDB spec for several IDBObjectStore methods states that transaction related exceptions should fire before
@@ -381,10 +385,10 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContex
 
 RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
 {
-    return deleteFunction(context, key.jsValue(), ec);
+    return modernDelete(context, key.jsValue(), ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCodeWithMessage& ec)
+RefPtr<IDBRequest> IDBObjectStore::modernDelete(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCodeWithMessage& ec)
 {
     DOMRequestState requestState(context);
     RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
@@ -394,7 +398,7 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContex
         return nullptr;
     }
 
-    return deleteFunction(context, &IDBKeyRange::create(idbKey.get()).get(), ec);
+    return doDelete(context, &IDBKeyRange::create(idbKey.get()).get(), ec);
 }
 
 RefPtr<WebCore::IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
index 2385b8c..8b02de0 100644 (file)
@@ -80,8 +80,7 @@ public:
     virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
 
     RefPtr<IDBRequest> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
-
-    RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, JSC::JSValue key, ExceptionCodeWithMessage&);
+    RefPtr<IDBRequest> modernDelete(ScriptExecutionContext*, JSC::JSValue key, ExceptionCodeWithMessage&);
 
     void markAsDeleted();
     bool isDeleted() const { return m_deleted; }
@@ -104,6 +103,7 @@ private:
 
     RefPtr<IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck, ExceptionCodeWithMessage&);
     RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
+    RefPtr<IDBRequest> doDelete(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec);
 
     IDBObjectStoreInfo m_info;
     IDBObjectStoreInfo m_originalInfo;
index b9d1fb2..b74e17a 100644 (file)
@@ -152,7 +152,13 @@ RefPtr<WebCore::IDBAny> IDBRequest::source() const
 
 void IDBRequest::setSource(IDBCursor& cursor)
 {
+    ASSERT(!m_cursorRequestNotifier);
+
     m_source = IDBAny::create(cursor);
+    m_cursorRequestNotifier = std::make_unique<ScopeGuard>([this]() {
+        ASSERT(m_source->type() == IDBAny::Type::IDBCursor || m_source->type() == IDBAny::Type::IDBCursorWithValue);
+        m_source->modernIDBCursor()->decrementOutstandingRequestCount();
+    });
 }
 
 void IDBRequest::setVersionChangeTransaction(IDBTransaction& transaction)
@@ -283,6 +289,8 @@ bool IDBRequest::dispatchEvent(Event& event)
 
     m_hasPendingActivity = false;
 
+    m_cursorRequestNotifier = nullptr;
+
     bool dontPreventDefault;
     {
         TransactionActivator activator(m_transaction.get());
@@ -364,6 +372,7 @@ void IDBRequest::willIterateCursor(IDBCursor& cursor)
     ASSERT(m_transaction);
     ASSERT(!m_pendingCursor);
     ASSERT(&cursor == resultCursor());
+    ASSERT(!m_cursorRequestNotifier);
 
     m_pendingCursor = &cursor;
     m_hasPendingActivity = true;
@@ -371,6 +380,10 @@ void IDBRequest::willIterateCursor(IDBCursor& cursor)
     m_readyState = IDBRequestReadyState::Pending;
     m_domError = nullptr;
     m_idbError = { };
+
+    m_cursorRequestNotifier = std::make_unique<ScopeGuard>([this]() {
+        m_pendingCursor->decrementOutstandingRequestCount();
+    });
 }
 
 void IDBRequest::didOpenOrIterateCursor(const IDBResultData& resultData)
@@ -384,6 +397,7 @@ void IDBRequest::didOpenOrIterateCursor(const IDBResultData& resultData)
             m_result = IDBAny::create(*m_pendingCursor);
     }
 
+    m_cursorRequestNotifier = nullptr;
     m_pendingCursor = nullptr;
 
     requestCompleted(resultData);
index 1f7ef21..3bf4299 100644 (file)
@@ -32,6 +32,7 @@
 #include "IDBOpenDBRequest.h"
 #include "IDBResourceIdentifier.h"
 #include "IDBTransactionImpl.h"
+#include "ScopeGuard.h"
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
@@ -146,6 +147,8 @@ private:
     IndexedDB::IndexRecordType m_requestedIndexRecordType;
 
     RefPtr<IDBCursor> m_pendingCursor;
+
+    std::unique_ptr<ScopeGuard> m_cursorRequestNotifier;
 };
 
 } // namespace IDBClient
index 8058de4..9c1943b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
 #include "IDBServer.h"
 #include "IDBTransactionInfo.h"
 #include "Logging.h"
+#include "ScopeGuard.h"
 #include "UniqueIDBDatabaseConnection.h"
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
@@ -675,37 +676,6 @@ ExecState& UniqueIDBDatabase::databaseThreadExecState()
     return *globalObject.get()->globalExec();
 }
 
-class ScopeGuard {
-public:
-    ScopeGuard()
-    {
-    }
-
-    ScopeGuard(std::function<void()> function)
-        : m_function(WTFMove(function))
-    {
-    }
-
-    ~ScopeGuard()
-    {
-        if (m_function)
-            m_function();
-    }
-
-    void enable(std::function<void()> function)
-    {
-        m_function = WTFMove(function);
-    }
-
-    void disable()
-    {
-        m_function = nullptr;
-    }
-
-private:
-    std::function<void()> m_function { nullptr };
-};
-
 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const ThreadSafeDataBuffer& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     ASSERT(!isMainThread());
index e92a8bd..2a7d27d 100644 (file)
                513F14540AB634C400094DDF /* IconLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 513F14520AB634C400094DDF /* IconLoader.h */; };
                51405C88190B014400754F94 /* SelectionRectGatherer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51405C86190B014400754F94 /* SelectionRectGatherer.cpp */; };
                51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */ = {isa = PBXBuildFile; fileRef = 51405C87190B014400754F94 /* SelectionRectGatherer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               5141298E1C5FD83A0059E714 /* JSIDBCursorWithValueCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */; };
+               514129901C601ACC0059E714 /* ScopeGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5141298F1C601A890059E714 /* ScopeGuard.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5145B1091BC48E2E00E86219 /* IDBResourceIdentifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */; };
                5145B10A1BC48E2E00E86219 /* IDBResourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5148453E1BB9D07E006A72ED /* IDBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5148453C1BB9D076006A72ED /* IDBError.cpp */; };
                513F14520AB634C400094DDF /* IconLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IconLoader.h; sourceTree = "<group>"; };
                51405C86190B014400754F94 /* SelectionRectGatherer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRectGatherer.cpp; sourceTree = "<group>"; };
                51405C87190B014400754F94 /* SelectionRectGatherer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRectGatherer.h; sourceTree = "<group>"; };
+               5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorWithValueCustom.cpp; sourceTree = "<group>"; };
+               5141298F1C601A890059E714 /* ScopeGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeGuard.h; sourceTree = "<group>"; };
                5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBResourceIdentifier.cpp; sourceTree = "<group>"; };
                5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBResourceIdentifier.h; sourceTree = "<group>"; };
                5148453C1BB9D076006A72ED /* IDBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBError.cpp; sourceTree = "<group>"; };
                                D6F7960C166FFECE0076DD18 /* JSHTMLTemplateElementCustom.cpp */,
                                511EF2CC17F0FDF100E4FA16 /* JSIDBAnyCustom.cpp */,
                                512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */,
+                               5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */,
                                511EF2CD17F0FDF100E4FA16 /* JSIDBDatabaseCustom.cpp */,
                                511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */,
                                A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
                                44C363EF0FAA7BB30097F8CC /* RuntimeApplicationChecksIOS.mm */,
                                5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */,
                                5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
+                               5141298F1C601A890059E714 /* ScopeGuard.h */,
                                BC8AE34C12EA096A00EB3AE6 /* ScrollableArea.cpp */,
                                BC8AE34D12EA096A00EB3AE6 /* ScrollableArea.h */,
                                CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
                                31C0FF4C0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.h in Headers */,
                                31C0FF4E0E4CEFDD007D6FE5 /* DOMWebKitTransitionEventInternal.h in Headers */,
                                85C7F5E70AAFBAFB004014DD /* DOMWheelEvent.h in Headers */,
+                               514129901C601ACC0059E714 /* ScopeGuard.h in Headers */,
                                85989DD10ACC8BBD00A0BC51 /* DOMWheelEventInternal.h in Headers */,
                                1403B99709EB13AF00797C7F /* DOMWindow.h in Headers */,
                                FC9A0F75164094CF003D6B8D /* DOMWindowCSS.h in Headers */,
                                B5A684240FFABEAA00D24689 /* SQLiteFileSystem.cpp in Sources */,
                                1A22464B0CC98DDB00C05240 /* SQLiteStatement.cpp in Sources */,
                                1A22464D0CC98DDB00C05240 /* SQLiteTransaction.cpp in Sources */,
+                               5141298E1C5FD83A0059E714 /* JSIDBCursorWithValueCustom.cpp in Sources */,
                                97BC6A411505F081001B74AC /* SQLResultSet.cpp in Sources */,
                                97BC6A441505F081001B74AC /* SQLResultSetRowList.cpp in Sources */,
                                FE8A674716CDD19E00930BF8 /* SQLStatement.cpp in Sources */,
diff --git a/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp b/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp
new file mode 100644 (file)
index 0000000..a59b877
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSIDBCursorWithValue.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBCursorWithValueImpl.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSIDBCursorWithValue::visitAdditionalChildren(SlotVisitor& visitor)
+{
+    JSIDBCursor::visitAdditionalChildren(visitor);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebCore/platform/ScopeGuard.h b/Source/WebCore/platform/ScopeGuard.h
new file mode 100644 (file)
index 0000000..7def9d4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ScopeGuard_h
+#define ScopeGuard_h
+
+namespace WebCore {
+
+class ScopeGuard {
+public:
+    ScopeGuard()
+    {
+    }
+
+    ScopeGuard(std::function<void()> function)
+        : m_function(WTFMove(function))
+    {
+    }
+
+    ~ScopeGuard()
+    {
+        if (m_function)
+            m_function();
+    }
+
+    void enable(std::function<void()> function)
+    {
+        m_function = WTFMove(function);
+    }
+
+    void disable()
+    {
+        m_function = nullptr;
+    }
+
+private:
+    std::function<void()> m_function { nullptr };
+};
+
+} // namespace WebCore
+
+#endif // ScopeGuard_h