Title: [241196] trunk/Source/WebCore
Revision
241196
Author
[email protected]
Date
2019-02-08 09:05:53 -0800 (Fri, 08 Feb 2019)

Log Message

IndexedDB tests leak documents
https://bugs.webkit.org/show_bug.cgi?id=189435
<rdar://problem/44240043>

Reviewed by Geoffrey Garen.

Remove use of JSC::Strong in IndexedDatabase.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::update):
(WebCore::IDBCursor::continuePrimaryKey):
(WebCore::IDBCursor::continueFunction):
(WebCore::IDBCursor::deleteFunction):
(WebCore::IDBCursor::setGetResult):
* Modules/indexeddb/IDBCursor.h:
(WebCore::IDBCursor::key):
(WebCore::IDBCursor::primaryKey):
(WebCore::IDBCursor::value):
(WebCore::IDBCursor::keyWrapper):
(WebCore::IDBCursor::primaryKeyWrapper):
(WebCore::IDBCursor::valueWrapper):
(WebCore::IDBCursor::key const): Deleted.
(WebCore::IDBCursor::primaryKey const): Deleted.
(WebCore::IDBCursor::value const): Deleted.
* Modules/indexeddb/IDBCursor.idl:
* Modules/indexeddb/IDBCursorWithValue.idl:
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::putForCursorUpdate):
* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::IDBRequest):
(WebCore::IDBRequest::~IDBRequest):
(WebCore::IDBRequest::result const):
(WebCore::IDBRequest::setResult):
(WebCore::IDBRequest::setResultToStructuredClone):
(WebCore::IDBRequest::setResultToUndefined):
(WebCore::IDBRequest::resultCursor):
(WebCore::IDBRequest::willIterateCursor):
(WebCore::IDBRequest::didOpenOrIterateCursor):
* Modules/indexeddb/IDBRequest.h:
(WebCore::IDBRequest::resultWrapper):
* Modules/indexeddb/IDBRequest.idl:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSIDBCursorCustom.cpp:
(WebCore::JSIDBCursor::key const):
(WebCore::JSIDBCursor::primaryKey const):
(WebCore::JSIDBCursor::visitAdditionalChildren):
* bindings/js/JSIDBCursorWithValueCustom.cpp:
(WebCore::JSIDBCursorWithValue::value const):
(WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
* bindings/js/JSIDBRequestCustom.cpp: Added.
(WebCore::JSIDBRequest::result const):
(WebCore::JSIDBRequest::visitAdditionalChildren):
* inspector/agents/InspectorIndexedDBAgent.cpp:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (241195 => 241196)


--- trunk/Source/WebCore/ChangeLog	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/ChangeLog	2019-02-08 17:05:53 UTC (rev 241196)
@@ -1,3 +1,61 @@
+2019-02-08  Sihui Liu  <[email protected]>
+
+        IndexedDB tests leak documents
+        https://bugs.webkit.org/show_bug.cgi?id=189435
+        <rdar://problem/44240043>
+
+        Reviewed by Geoffrey Garen.
+
+        Remove use of JSC::Strong in IndexedDatabase.
+
+        * Modules/indexeddb/IDBCursor.cpp:
+        (WebCore::IDBCursor::update):
+        (WebCore::IDBCursor::continuePrimaryKey):
+        (WebCore::IDBCursor::continueFunction):
+        (WebCore::IDBCursor::deleteFunction):
+        (WebCore::IDBCursor::setGetResult):
+        * Modules/indexeddb/IDBCursor.h:
+        (WebCore::IDBCursor::key):
+        (WebCore::IDBCursor::primaryKey):
+        (WebCore::IDBCursor::value):
+        (WebCore::IDBCursor::keyWrapper):
+        (WebCore::IDBCursor::primaryKeyWrapper):
+        (WebCore::IDBCursor::valueWrapper):
+        (WebCore::IDBCursor::key const): Deleted.
+        (WebCore::IDBCursor::primaryKey const): Deleted.
+        (WebCore::IDBCursor::value const): Deleted.
+        * Modules/indexeddb/IDBCursor.idl:
+        * Modules/indexeddb/IDBCursorWithValue.idl:
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::putForCursorUpdate):
+        * Modules/indexeddb/IDBObjectStore.h:
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::IDBRequest):
+        (WebCore::IDBRequest::~IDBRequest):
+        (WebCore::IDBRequest::result const):
+        (WebCore::IDBRequest::setResult):
+        (WebCore::IDBRequest::setResultToStructuredClone):
+        (WebCore::IDBRequest::setResultToUndefined):
+        (WebCore::IDBRequest::resultCursor):
+        (WebCore::IDBRequest::willIterateCursor):
+        (WebCore::IDBRequest::didOpenOrIterateCursor):
+        * Modules/indexeddb/IDBRequest.h:
+        (WebCore::IDBRequest::resultWrapper):
+        * Modules/indexeddb/IDBRequest.idl:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSIDBCursorCustom.cpp:
+        (WebCore::JSIDBCursor::key const):
+        (WebCore::JSIDBCursor::primaryKey const):
+        (WebCore::JSIDBCursor::visitAdditionalChildren):
+        * bindings/js/JSIDBCursorWithValueCustom.cpp:
+        (WebCore::JSIDBCursorWithValue::value const):
+        (WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
+        * bindings/js/JSIDBRequestCustom.cpp: Added.
+        (WebCore::JSIDBRequest::result const):
+        (WebCore::JSIDBRequest::visitAdditionalChildren):
+        * inspector/agents/InspectorIndexedDBAgent.cpp:
+
 2019-02-08  Zalan Bujtas  <[email protected]>
 
         [LFC] The used containing block width value is optional

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -124,11 +124,11 @@
     if (usesInLineKeys) {
         RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, optionalKeyPath.value());
         IDBKeyData keyPathKeyData(keyPathKey.get());
-        if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData)
+        if (!keyPathKey || keyPathKeyData != m_primaryKeyData)
             return Exception { DataError, "Failed to execute 'update' on 'IDBCursor': The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."_s };
     }
 
-    auto putResult = effectiveObjectStore().putForCursorUpdate(state, value, m_currentPrimaryKey.get());
+    auto putResult = effectiveObjectStore().putForCursorUpdate(state, value, m_primaryKey.copyRef());
     if (putResult.hasException())
         return putResult.releaseException();
 
@@ -197,16 +197,16 @@
     IDBKeyData keyData = { key.get() };
     IDBKeyData primaryKeyData = { primaryKey.get() };
 
-    if (keyData < m_currentKeyData && direction == IndexedDB::CursorDirection::Next)
+    if (keyData < m_keyData && direction == IndexedDB::CursorDirection::Next)
         return Exception { DataError, "Failed to execute 'continuePrimaryKey' on 'IDBCursor': The first parameter is less than this cursor's position and this cursor's direction is \"next\"."_s };
 
-    if (keyData > m_currentKeyData && direction == IndexedDB::CursorDirection::Prev)
+    if (keyData > m_keyData && direction == IndexedDB::CursorDirection::Prev)
         return Exception { DataError, "Failed to execute 'continuePrimaryKey' on 'IDBCursor': The first parameter is greater than this cursor's position and this cursor's direction is \"prev\"."_s };
 
-    if (keyData == m_currentKeyData) {
-        if (primaryKeyData <= m_currentPrimaryKeyData && direction == IndexedDB::CursorDirection::Next)
+    if (keyData == m_keyData) {
+        if (primaryKeyData <= m_primaryKeyData && direction == IndexedDB::CursorDirection::Next)
             return Exception { DataError, "Failed to execute 'continuePrimaryKey' on 'IDBCursor': The key parameters represent a position less-than-or-equal-to this cursor's position and this cursor's direction is \"next\"."_s };
-        if (primaryKeyData >= m_currentPrimaryKeyData && direction == IndexedDB::CursorDirection::Prev)
+        if (primaryKeyData >= m_primaryKeyData && direction == IndexedDB::CursorDirection::Prev)
             return Exception { DataError, "Failed to execute 'continuePrimaryKey' on 'IDBCursor': The key parameters represent a position greater-than-or-equal-to this cursor's position and this cursor's direction is \"prev\"."_s };
     }
 
@@ -247,10 +247,10 @@
         return Exception { DataError, "Failed to execute 'continue' on 'IDBCursor': The parameter is not a valid key."_s };
 
     if (m_info.isDirectionForward()) {
-        if (!key.isNull() && key.compare(m_currentKeyData) <= 0)
+        if (!key.isNull() && key.compare(m_keyData) <= 0)
             return Exception { DataError, "Failed to execute 'continue' on 'IDBCursor': The parameter is less than or equal to this cursor's position."_s };
     } else {
-        if (!key.isNull() && key.compare(m_currentKeyData) >= 0)
+        if (!key.isNull() && key.compare(m_keyData) >= 0)
             return Exception { DataError, "Failed to execute 'continue' on 'IDBCursor': The parameter is greater than or equal to this cursor's position."_s };
     }
 
@@ -299,7 +299,7 @@
     if (!isKeyCursorWithValue())
         return Exception { InvalidStateError, "Failed to execute 'delete' on 'IDBCursor': The cursor is a key cursor."_s };
 
-    auto result = effectiveObjectStore().deleteFunction(state, m_currentPrimaryKey.get());
+    auto result = effectiveObjectStore().deleteFunction(state, IDBKeyRange::create(m_primaryKey.copyRef()).ptr());
     if (result.hasException())
         return result.releaseException();
 
@@ -309,43 +309,33 @@
     return WTFMove(request);
 }
 
-void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
+void IDBCursor::setGetResult(IDBRequest&, const IDBGetResult& getResult)
 {
     LOG(IndexedDB, "IDBCursor::setGetResult - current key %s", getResult.keyData().loggingString().substring(0, 100).utf8().data());
     ASSERT(&effectiveObjectStore().transaction().database().originThread() == &Thread::current());
 
-    auto* context = request.scriptExecutionContext();
-    if (!context)
-        return;
+    m_keyWrapper = { };
+    m_primaryKeyWrapper = { };
+    m_valueWrapper = { };
 
-    auto* exec = context->execState();
-    if (!exec)
-        return;
-
     if (!getResult.isDefined()) {
-        m_currentKey = { };
-        m_currentKeyData = { };
-        m_currentPrimaryKey = { };
-        m_currentPrimaryKeyData = { };
-        m_currentValue = { };
+        m_keyData = { };
+        m_key = nullptr;
+        m_primaryKeyData = { };
+        m_primaryKey = nullptr;
+        m_value = { };
 
         m_gotValue = false;
         return;
     }
 
-    auto& vm = context->vm();
+    m_keyData = getResult.keyData();
+    m_key = m_keyData.maybeCreateIDBKey();
+    m_primaryKeyData = getResult.primaryKeyData();
+    m_primaryKey = m_primaryKeyData.maybeCreateIDBKey();
 
-    // FIXME: This conversion should be done lazily, when script needs the JSValues, so that global object
-    // of the IDBCursor wrapper can be used, rather than the lexicalGlobalObject.
-    m_currentKey = { vm, toJS(*exec, *exec->lexicalGlobalObject(), getResult.keyData().maybeCreateIDBKey().get()) };
-    m_currentKeyData = getResult.keyData();
-    m_currentPrimaryKey = { vm, toJS(*exec, *exec->lexicalGlobalObject(), getResult.primaryKeyData().maybeCreateIDBKey().get()) };
-    m_currentPrimaryKeyData = getResult.primaryKeyData();
-
     if (isKeyCursorWithValue())
-        m_currentValue = { vm, deserializeIDBValueToJSValue(*exec, getResult.value()) };
-    else
-        m_currentValue = { };
+        m_value = getResult.value();
 
     m_gotValue = true;
 }

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h	2019-02-08 17:05:53 UTC (rev 241196)
@@ -30,6 +30,8 @@
 #include "ExceptionOr.h"
 #include "IDBCursorDirection.h"
 #include "IDBCursorInfo.h"
+#include "IDBValue.h"
+#include "JSValueInWrappedObject.h"
 #include <_javascript_Core/Strong.h>
 #include <wtf/Variant.h>
 #include <wtf/WeakPtr.h>
@@ -52,10 +54,14 @@
 
     const Source& source() const;
     IDBCursorDirection direction() const;
-    JSC::JSValue key() const;
-    JSC::JSValue primaryKey() const;
-    JSC::JSValue value() const;
 
+    IDBKey* key() { return m_key.get(); };
+    IDBKey* primaryKey() { return m_primaryKey.get(); };
+    IDBValue value() { return m_value; };
+    JSValueInWrappedObject& keyWrapper() { return m_keyWrapper; }
+    JSValueInWrappedObject& primaryKeyWrapper() { return m_primaryKeyWrapper; }
+    JSValueInWrappedObject& valueWrapper() { return m_valueWrapper; }
+
     ExceptionOr<Ref<IDBRequest>> update(JSC::ExecState&, JSC::JSValue);
     ExceptionOr<void> advance(unsigned);
     ExceptionOr<void> continueFunction(JSC::ExecState&, JSC::JSValue key);
@@ -92,14 +98,15 @@
 
     bool m_gotValue { false };
 
-    IDBKeyData m_currentKeyData;
-    IDBKeyData m_currentPrimaryKeyData;
+    RefPtr<IDBKey> m_key;
+    RefPtr<IDBKey> m_primaryKey;
+    IDBKeyData m_keyData;
+    IDBKeyData m_primaryKeyData;
+    IDBValue m_value;
 
-    // FIXME: The following uses of JSC::Strong are incorrect and can lead to storage leaks
-    // due to reference cycles; we should use JSValueInWrappedObject instead.
-    JSC::Strong<JSC::Unknown> m_currentKey;
-    JSC::Strong<JSC::Unknown> m_currentPrimaryKey;
-    JSC::Strong<JSC::Unknown> m_currentValue;
+    JSValueInWrappedObject m_keyWrapper;
+    JSValueInWrappedObject m_primaryKeyWrapper;
+    JSValueInWrappedObject m_valueWrapper;
 };
 
 
@@ -113,21 +120,6 @@
     return m_info.cursorDirection();
 }
 
-inline JSC::JSValue IDBCursor::key() const
-{
-    return m_currentKey.get();
-}
-
-inline JSC::JSValue IDBCursor::primaryKey() const
-{
-    return m_currentPrimaryKey.get();
-}
-
-inline JSC::JSValue IDBCursor::value() const
-{
-    return m_currentValue.get();
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.idl (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.idl	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.idl	2019-02-08 17:05:53 UTC (rev 241196)
@@ -31,8 +31,8 @@
 ] interface IDBCursor {
     readonly attribute (IDBObjectStore or IDBIndex) source;
     readonly attribute IDBCursorDirection direction;
-    readonly attribute any key;
-    readonly attribute any primaryKey;
+    [CustomGetter] readonly attribute any key;
+    [CustomGetter] readonly attribute any primaryKey;
 
     [CallWith=ExecState, MayThrowException] IDBRequest update(any value);
     [MayThrowException] void advance([EnforceRange] unsigned long count);

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl	2019-02-08 17:05:53 UTC (rev 241196)
@@ -28,5 +28,5 @@
     SkipVTableValidation,
     JSCustomMarkFunction,
 ] interface IDBCursorWithValue : IDBCursor {
-    readonly attribute any value;
+    [CustomGetter] readonly attribute any value;
 };

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -285,9 +285,9 @@
     return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::Perform);
 }
 
-ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putForCursorUpdate(ExecState& state, JSValue value, JSValue key)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putForCursorUpdate(ExecState& state, JSValue value, RefPtr<IDBKey> key)
 {
-    return putOrAdd(state, value, scriptValueToIDBKey(state, key), IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor, InlineKeyCheck::DoNotPerform);
+    return putOrAdd(state, value, WTFMove(key), IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor, InlineKeyCheck::DoNotPerform);
 }
 
 ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putOrAdd(ExecState& state, JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck)

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h	2019-02-08 17:05:53 UTC (rev 241196)
@@ -96,7 +96,7 @@
     ExceptionOr<Ref<IDBRequest>> getAllKeys(JSC::ExecState&, RefPtr<IDBKeyRange>, Optional<uint32_t> count);
     ExceptionOr<Ref<IDBRequest>> getAllKeys(JSC::ExecState&, JSC::JSValue key, Optional<uint32_t> count);
 
-    ExceptionOr<Ref<IDBRequest>> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>);
 
     void markAsDeleted();
     bool isDeleted() const { return m_deleted; }

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -85,6 +85,7 @@
     , m_resourceIdentifier(connectionProxy)
     , m_connectionProxy(connectionProxy)
 {
+    m_result = NullResultType::Empty;
     suspendIfNeeded();
 }
 
@@ -95,6 +96,7 @@
     , m_source(&objectStore)
     , m_connectionProxy(transaction.database().connectionProxy())
 {
+    m_result = NullResultType::Empty;
     suspendIfNeeded();
 }
 
@@ -111,6 +113,7 @@
         [this] (const auto& value) { this->m_source = IDBRequest::Source { value }; }
     );
 
+    m_result = NullResultType::Empty;
     cursor.setRequest(*this);
 }
 
@@ -121,6 +124,7 @@
     , m_source(&index)
     , m_connectionProxy(transaction.database().connectionProxy())
 {
+    m_result = NullResultType::Empty;
     suspendIfNeeded();
 }
 
@@ -132,6 +136,7 @@
     , m_requestedObjectStoreRecordType(type)
     , m_connectionProxy(transaction.database().connectionProxy())
 {
+    m_result = NullResultType::Empty;
     suspendIfNeeded();
 }
 
@@ -138,6 +143,7 @@
 IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBIndex& index, IndexedDB::IndexRecordType requestedRecordType, IDBTransaction& transaction)
     : IDBRequest(context, index, transaction)
 {
+    m_result = NullResultType::Empty;
     m_requestedIndexRecordType = requestedRecordType;
 }
 
@@ -145,20 +151,18 @@
 {
     ASSERT(&originThread() == &Thread::current());
 
-    if (m_result) {
-        WTF::switchOn(m_result.value(),
-            [] (RefPtr<IDBCursor>& cursor) { cursor->clearRequest(); },
-            [] (const auto&) { }
-        );
-    }
+    WTF::switchOn(m_result,
+        [] (RefPtr<IDBCursor>& cursor) { cursor->clearRequest(); },
+        [] (const auto&) { }
+    );
 }
 
-ExceptionOr<Optional<IDBRequest::Result>> IDBRequest::result() const
+ExceptionOr<IDBRequest::Result> IDBRequest::result() const
 {
     if (!isDone())
         return Exception { InvalidStateError, "Failed to read the 'result' property from 'IDBRequest': The request has not finished."_s };
 
-    return Optional<IDBRequest::Result> { m_result };
+    return IDBRequest::Result { m_result };
 }
 
 ExceptionOr<DOMException*> IDBRequest::error() const
@@ -358,11 +362,10 @@
     if (!state)
         return;
 
-    // FIXME: This conversion should be done lazily, when script needs the JSValues, so that global object
-    // of the IDBRequest wrapper can be used, rather than the lexicalGlobalObject.
     VM& vm = context->vm();
     JSLockHolder lock(vm);
-    m_result = Result { JSC::Strong<JSC::Unknown> { vm, toJS<IDLIDBKeyData>(*state, *jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), keyData) } };
+    m_result = keyData;
+    m_resultWrapper = { };
 }
 
 void IDBRequest::setResult(const Vector<IDBKeyData>& keyDatas)
@@ -377,11 +380,10 @@
     if (!state)
         return;
 
-    // FIXME: This conversion should be done lazily, when script needs the JSValues, so that global object
-    // of the IDBRequest wrapper can be used, rather than the lexicalGlobalObject.
     VM& vm = context->vm();
     JSLockHolder lock(vm);
-    m_result = Result { JSC::Strong<JSC::Unknown> { vm, toJS<IDLSequence<IDLIDBKeyData>>(*state, *jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), keyDatas) } };
+    m_result = keyDatas;
+    m_resultWrapper = { };
 }
 
 void IDBRequest::setResult(const Vector<IDBValue>& values)
@@ -396,11 +398,10 @@
     if (!state)
         return;
 
-    // FIXME: This conversion should be done lazily, when script needs the JSValues, so that global object
-    // of the IDBRequest wrapper can be used, rather than the lexicalGlobalObject.
     VM& vm = context->vm();
     JSLockHolder lock(vm);
-    m_result = Result { JSC::Strong<JSC::Unknown> { vm, toJS<IDLSequence<IDLIDBValue>>(*state, *jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), values) } };
+    m_result = values;
+    m_resultWrapper = { };
 }
 
 void IDBRequest::setResult(uint64_t number)
@@ -411,7 +412,8 @@
     if (!context)
         return;
 
-    m_result = Result { JSC::Strong<JSC::Unknown> { context->vm(), toJS<IDLUnrestrictedDouble>(number) } };
+    m_result = number;
+    m_resultWrapper = { };
 }
 
 void IDBRequest::setResultToStructuredClone(const IDBValue& value)
@@ -428,11 +430,10 @@
     if (!state)
         return;
 
-    // FIXME: This conversion should be done lazily, when script needs the JSValues, so that global object
-    // of the IDBRequest wrapper can be used, rather than the lexicalGlobalObject.
     VM& vm = context->vm();
     JSLockHolder lock(vm);
-    m_result = Result { JSC::Strong<JSC::Unknown> { vm, toJS<IDLIDBValue>(*state, *jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), value) } };
+    m_result = value;
+    m_resultWrapper = { };
 }
 
 void IDBRequest::setResultToUndefined()
@@ -439,11 +440,8 @@
 {
     ASSERT(&originThread() == &Thread::current());
 
-    auto* context = scriptExecutionContext();
-    if (!context)
-        return;
-
-    m_result = Result { JSC::Strong<JSC::Unknown> { context->vm(), JSC::jsUndefined() } };
+    m_result = NullResultType::Undefined;
+    m_resultWrapper = { };
 }
 
 IDBCursor* IDBRequest::resultCursor()
@@ -450,10 +448,7 @@
 {
     ASSERT(&originThread() == &Thread::current());
 
-    if (!m_result)
-        return nullptr;
-
-    return WTF::switchOn(m_result.value(),
+    return WTF::switchOn(m_result,
         [] (const RefPtr<IDBCursor>& cursor) -> IDBCursor* { return cursor.get(); },
         [] (const auto&) -> IDBCursor* { return nullptr; }
     );
@@ -470,7 +465,8 @@
 
     m_pendingCursor = &cursor;
     m_hasPendingActivity = true;
-    m_result = WTF::nullopt;
+    m_result = NullResultType::Empty;
+    m_resultWrapper = { };
     m_readyState = ReadyState::Pending;
     m_domError = nullptr;
     m_idbError = IDBError { };
@@ -481,12 +477,13 @@
     ASSERT(&originThread() == &Thread::current());
     ASSERT(m_pendingCursor);
 
-    m_result = WTF::nullopt;
+    m_result = NullResultType::Empty;
+    m_resultWrapper = { };
 
     if (resultData.type() == IDBResultType::IterateCursorSuccess || resultData.type() == IDBResultType::OpenCursorSuccess) {
         m_pendingCursor->setGetResult(*this, resultData.getResult());
         if (resultData.getResult().isDefined())
-            m_result = Result { m_pendingCursor };
+            m_result = m_pendingCursor;
     }
 
     m_pendingCursor = nullptr;
@@ -529,7 +526,8 @@
 {
     ASSERT(&originThread() == &Thread::current());
 
-    m_result = Result { RefPtr<IDBDatabase> { WTFMove(database) } };
+    m_result = RefPtr<IDBDatabase> { WTFMove(database) };
+    m_resultWrapper = { };
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h	2019-02-08 17:05:53 UTC (rev 241196)
@@ -31,8 +31,11 @@
 #include "ExceptionOr.h"
 #include "IDBActiveDOMObject.h"
 #include "IDBError.h"
+#include "IDBKeyData.h"
 #include "IDBResourceIdentifier.h"
+#include "IDBValue.h"
 #include "IndexedDB.h"
+#include "JSValueInWrappedObject.h"
 #include <_javascript_Core/Strong.h>
 #include <wtf/Function.h>
 #include <wtf/Scope.h>
@@ -45,11 +48,9 @@
 class IDBCursor;
 class IDBDatabase;
 class IDBIndex;
-class IDBKeyData;
 class IDBObjectStore;
 class IDBResultData;
 class IDBTransaction;
-class IDBValue;
 class ThreadSafeDataBuffer;
 
 namespace IDBClient {
@@ -59,6 +60,11 @@
 
 class IDBRequest : public EventTargetWithInlineData, public IDBActiveDOMObject, public RefCounted<IDBRequest>, public CanMakeWeakPtr<IDBRequest> {
 public:
+    enum class NullResultType {
+        Empty,
+        Undefined
+    };
+
     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBObjectStore&, IDBTransaction&);
     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBCursor&, IDBTransaction&);
     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBIndex&, IDBTransaction&);
@@ -69,10 +75,9 @@
 
     virtual ~IDBRequest();
 
-    // FIXME: The following use of JSC::Strong is incorrect and can lead to storage leaks
-    // due to reference cycles; we should use JSValueInWrappedObject instead.
-    using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, JSC::Strong<JSC::Unknown>>;
-    ExceptionOr<Optional<Result>> result() const;
+    using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBValue, Vector<IDBValue>, uint64_t, NullResultType>;
+    ExceptionOr<Result> result() const;
+    JSValueInWrappedObject& resultWrapper() { return m_resultWrapper; }
 
     using Source = Variant<RefPtr<IDBObjectStore>, RefPtr<IDBIndex>, RefPtr<IDBCursor>>;
     const Optional<Source>& source() const { return m_source; }
@@ -165,7 +170,8 @@
     IDBError m_idbError;
     IDBResourceIdentifier m_resourceIdentifier;
 
-    Optional<Result> m_result;
+    JSValueInWrappedObject m_resultWrapper;
+    Result m_result;
     Optional<Source> m_source;
 
     bool m_hasPendingActivity { true };

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.idl (241195 => 241196)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.idl	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.idl	2019-02-08 17:05:53 UTC (rev 241196)
@@ -31,9 +31,10 @@
     ActiveDOMObject,
     Conditional=INDEXED_DATABASE,
     GenerateIsReachable=Impl,
+    JSCustomMarkFunction,
     SkipVTableValidation,
 ] interface IDBRequest : EventTarget {
-    readonly attribute (IDBCursor or IDBDatabase or any)? result;
+    [CustomGetter] readonly attribute (IDBCursor or IDBDatabase or any) result;
     readonly attribute DOMException? error;
     readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
     readonly attribute IDBTransaction transaction;

Modified: trunk/Source/WebCore/Sources.txt (241195 => 241196)


--- trunk/Source/WebCore/Sources.txt	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/Sources.txt	2019-02-08 17:05:53 UTC (rev 241196)
@@ -489,6 +489,7 @@
 bindings/js/JSIDBCursorWithValueCustom.cpp
 bindings/js/JSIDBIndexCustom.cpp
 bindings/js/JSIDBObjectStoreCustom.cpp
+bindings/js/JSIDBRequestCustom.cpp
 bindings/js/JSIDBTransactionCustom.cpp
 bindings/js/JSImageDataCustom.cpp
 bindings/js/JSIntersectionObserverEntryCustom.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (241195 => 241196)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-02-08 17:05:53 UTC (rev 241196)
@@ -4047,6 +4047,7 @@
 		C9D851F01B39DC780085062E /* MediaSessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = C9D851EE1B39DC780085062E /* MediaSessionMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C9F87CFE1B28F40E00979B83 /* MediaSessionEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = C9F87CFD1B28E5F600979B83 /* MediaSessionEvents.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		CA6C1530220B98CC0055CBFC /* JSValueInWrappedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 931AE3B81FB80EAE00F5EFB2 /* JSValueInWrappedObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */; };
 		CB38FD521CCF939400592A3F /* JSPerformanceEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = CB38FD4E1CCF937E00592A3F /* JSPerformanceEntry.h */; };
 		CB38FD5B1CD2325B00592A3F /* JSPerformanceResourceTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = CB38FD591CD2314500592A3F /* JSPerformanceResourceTiming.h */; };
@@ -8116,7 +8117,6 @@
 		5123AF1C18918AE40031CDC9 /* IDBGetResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBGetResult.h; sourceTree = "<group>"; };
 		512BDB481C456FAB006494DF /* SQLiteIDBBackingStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBBackingStore.cpp; sourceTree = "<group>"; };
 		512BDB491C456FAB006494DF /* SQLiteIDBBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBBackingStore.h; sourceTree = "<group>"; };
-		512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorCustom.cpp; sourceTree = "<group>"; };
 		512DD8E20D91E2B4000F89EE /* SharedBufferCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBufferCF.cpp; sourceTree = "<group>"; };
 		512DD8EA0D91E6AF000F89EE /* LegacyWebArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyWebArchive.cpp; sourceTree = "<group>"; };
 		512DD8EB0D91E6AF000F89EE /* LegacyWebArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyWebArchive.h; sourceTree = "<group>"; };
@@ -8134,7 +8134,6 @@
 		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>"; };
 		514129961C6976150059E714 /* IDBRequestCompletionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBRequestCompletionEvent.cpp; sourceTree = "<group>"; };
 		514129971C6976150059E714 /* IDBRequestCompletionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBRequestCompletionEvent.h; sourceTree = "<group>"; };
 		5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBIndexCustom.cpp; sourceTree = "<group>"; };
@@ -13538,6 +13537,9 @@
 		CA1635DC2072E76900E7D2CE /* ReferrerPolicy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReferrerPolicy.cpp; sourceTree = "<group>"; };
 		CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; };
 		CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
+		CA6C152F220B4A550055CBFC /* JSIDBRequestCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBRequestCustom.cpp; sourceTree = "<group>"; };
+		CA6C1537220D1EB30055CBFC /* JSIDBCursorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorCustom.cpp; sourceTree = "<group>"; };
+		CA6C1538220D1EB30055CBFC /* JSIDBCursorWithValueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorWithValueCustom.cpp; sourceTree = "<group>"; };
 		CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSAspectRatioValue.cpp; sourceTree = "<group>"; };
 		CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSAspectRatioValue.h; sourceTree = "<group>"; };
 		CB38FD4A1CCCF2DD00592A3F /* PerformanceEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceEntry.cpp; sourceTree = "<group>"; };
@@ -20848,8 +20850,6 @@
 				BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */,
 				BC51580A0C03D404008BB0EE /* JSHTMLDocumentCustom.cpp */,
 				D6F7960C166FFECE0076DD18 /* JSHTMLTemplateElementCustom.cpp */,
-				512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */,
-				5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */,
 				5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */,
 				511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */,
 				51E269321DD3BC43006B6A58 /* JSIDBTransactionCustom.cpp */,
@@ -20984,6 +20984,9 @@
 				831C46C31F9EE5E000EBD450 /* JSExtendableMessageEventCustom.cpp */,
 				4131F3B11F9552810059995A /* JSFetchEventCustom.cpp */,
 				BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */,
+				CA6C1537220D1EB30055CBFC /* JSIDBCursorCustom.cpp */,
+				CA6C1538220D1EB30055CBFC /* JSIDBCursorWithValueCustom.cpp */,
+				CA6C152F220B4A550055CBFC /* JSIDBRequestCustom.cpp */,
 				410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */,
 				A1677E242144532800A08C34 /* JSPaymentMethodChangeEventCustom.cpp */,
 				A10D6E942144C99800FDD14D /* JSPaymentResponseCustom.cpp */,
@@ -30508,6 +30511,7 @@
 				7C73FB0D191EF5A8007DE061 /* JSUserMessageHandlersNamespace.h in Headers */,
 				572B402C21769020000AD43E /* JSUserVerificationRequirement.h in Headers */,
 				15C77093100D3CA8005BA267 /* JSValidityState.h in Headers */,
+				CA6C1530220B98CC0055CBFC /* JSValueInWrappedObject.h in Headers */,
 				BE8EF04B171C9014009B48C3 /* JSVideoTrack.h in Headers */,
 				BE8EF04D171C9014009B48C3 /* JSVideoTrackList.h in Headers */,
 				46E791491F97E01A00199739 /* JSVisibilityState.h in Headers */,

Modified: trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp (241195 => 241196)


--- trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "IDBBindingUtilities.h"
 #include "JSDOMBinding.h"
 #include "JSIDBCursorWithValue.h"
 
@@ -35,11 +36,27 @@
 namespace WebCore {
 using namespace JSC;
 
+JSC::JSValue JSIDBCursor::key(JSC::ExecState& state) const
+{
+    return cachedPropertyValue(state, *this, wrapped().keyWrapper(), [&] {
+        return toJS(state, *state.lexicalGlobalObject(), wrapped().key());
+    });
+}
+
+JSC::JSValue JSIDBCursor::primaryKey(JSC::ExecState& state) const
+{
+    return cachedPropertyValue(state, *this, wrapped().primaryKeyWrapper(), [&] {
+        return toJS(state, *state.lexicalGlobalObject(), wrapped().primaryKey());
+    });
+}
+
 void JSIDBCursor::visitAdditionalChildren(SlotVisitor& visitor)
 {
     auto& cursor = wrapped();
     if (auto* request = cursor.request())
         visitor.addOpaqueRoot(request);
+    cursor.keyWrapper().visit(visitor);
+    cursor.primaryKeyWrapper().visit(visitor);
 }
 
 JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<IDBCursor>&& cursor)

Modified: trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp (241195 => 241196)


--- trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "IDBBindingUtilities.h"
 #include "IDBCursorWithValue.h"
 #include <_javascript_Core/HeapInlines.h>
 
@@ -34,9 +35,17 @@
 namespace WebCore {
 using namespace JSC;
 
+JSC::JSValue JSIDBCursorWithValue::value(JSC::ExecState& state) const
+{
+    return cachedPropertyValue(state, *this, wrapped().valueWrapper(), [&] {
+        return deserializeIDBValueToJSValue(state, wrapped().value());
+    });
+}
+
 void JSIDBCursorWithValue::visitAdditionalChildren(SlotVisitor& visitor)
 {
     JSIDBCursor::visitAdditionalChildren(visitor);
+    wrapped().valueWrapper().visit(visitor);
 }
 
 } // namespace WebCore

Added: trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp (0 => 241196)


--- trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp	                        (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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 "JSIDBRequest.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBBindingUtilities.h"
+#include "JSDOMConvertInterface.h"
+#include "JSIDBCursor.h"
+#include "JSIDBDatabase.h"
+
+namespace WebCore {
+using namespace JSC;
+
+JSC::JSValue JSIDBRequest::result(JSC::ExecState& state) const
+{
+    return cachedPropertyValue(state, *this, wrapped().resultWrapper(), [&] {
+        auto result = wrapped().result();
+        if (UNLIKELY(result.hasException())) {
+            auto throwScope = DECLARE_THROW_SCOPE(state.vm());
+            propagateException(state, throwScope, result.releaseException());
+            return jsNull();
+        }
+
+        IDBRequest::Result resultValue = result.releaseReturnValue();
+        return WTF::switchOn(resultValue, [&state] (RefPtr<IDBCursor>& cursor) {
+            auto throwScope = DECLARE_THROW_SCOPE(state.vm());
+            return toJS<IDLInterface<IDBCursor>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), throwScope, cursor.get());
+        }, [&state] (RefPtr<IDBDatabase>& database) {
+            auto throwScope = DECLARE_THROW_SCOPE(state.vm());
+            return toJS<IDLInterface<IDBDatabase>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), throwScope, database.get());
+        }, [&state] (IDBKeyData keyData) {
+            return toJS<IDLIDBKeyData>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), keyData);
+        }, [&state] (Vector<IDBKeyData> keyDatas) {
+            return toJS<IDLSequence<IDLIDBKeyData>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), keyDatas);
+        }, [&state] (IDBValue value) {
+            return toJS<IDLIDBValue>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), value);
+        }, [&state] (Vector<IDBValue> values) {
+            return toJS<IDLSequence<IDLIDBValue>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), values);
+        }, [] (uint64_t number) {
+            return toJS<IDLUnsignedLongLong>(number);
+        }, [] (IDBRequest::NullResultType other) {
+            if (other == IDBRequest::NullResultType::Empty)
+                return JSC::jsNull();
+            return JSC::jsUndefined();
+        });
+    });
+}
+
+void JSIDBRequest::visitAdditionalChildren(SlotVisitor& visitor)
+{
+    auto& request = wrapped();
+    request.resultWrapper().visit(visitor);
+}
+
+}
+#endif // ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp (241195 => 241196)


--- trunk/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp	2019-02-08 14:46:36 UTC (rev 241195)
+++ trunk/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp	2019-02-08 17:05:53 UTC (rev 241196)
@@ -137,12 +137,12 @@
         }
 
         auto resultValue = result.releaseReturnValue();
-        if (!resultValue || !WTF::holds_alternative<RefPtr<IDBDatabase>>(resultValue.value())) {
+        if (!WTF::holds_alternative<RefPtr<IDBDatabase>>(resultValue)) {
             m_executableWithDatabase->requestCallback().sendFailure("Unexpected result type.");
             return;
         }
 
-        auto databaseResult = WTF::get<RefPtr<IDBDatabase>>(resultValue.value());
+        auto databaseResult = WTF::get<RefPtr<IDBDatabase>>(resultValue);
         m_executableWithDatabase->execute(*databaseResult);
         databaseResult->close();
     }
@@ -363,7 +363,7 @@
         return this == &other;
     }
 
-    void handleEvent(ScriptExecutionContext&, Event& event) override
+    void handleEvent(ScriptExecutionContext& context, Event& event) override
     {
         if (event.type() != eventNames().successEvent) {
             m_requestCallback->sendFailure("Unexpected event type.");
@@ -379,12 +379,12 @@
         }
         
         auto resultValue = result.releaseReturnValue();
-        if (!resultValue || !WTF::holds_alternative<RefPtr<IDBCursor>>(resultValue.value())) {
+        if (!WTF::holds_alternative<RefPtr<IDBCursor>>(resultValue)) {
             end(false);
             return;
         }
 
-        auto cursor = WTF::get<RefPtr<IDBCursor>>(resultValue.value());
+        auto cursor = WTF::get<RefPtr<IDBCursor>>(resultValue);
 
         if (m_skipCount) {
             if (cursor->advance(m_skipCount).hasException())
@@ -404,10 +404,14 @@
             return;
         }
 
+        auto* state = context.execState();
+        auto key =  toJS(*state, *state->lexicalGlobalObject(), cursor->key());
+        auto primaryKey = toJS(*state, *state->lexicalGlobalObject(), cursor->primaryKey());
+        auto value = deserializeIDBValueToJSValue(*state, cursor->value());
         auto dataEntry = DataEntry::create()
-            .setKey(m_injectedScript.wrapObject(cursor->key(), String(), true))
-            .setPrimaryKey(m_injectedScript.wrapObject(cursor->primaryKey(), String(), true))
-            .setValue(m_injectedScript.wrapObject(cursor->value(), String(), true))
+            .setKey(m_injectedScript.wrapObject(key, String(), true))
+            .setPrimaryKey(m_injectedScript.wrapObject(primaryKey, String(), true))
+            .setValue(m_injectedScript.wrapObject(value, String(), true))
             .release();
         m_result->addItem(WTFMove(dataEntry));
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to