WebKit Bugzilla
Attachment 361483 Details for
Bug 189435
: IndexedDB tests leak documents
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189435-20190207183153.patch (text/plain), 43.69 KB, created by
Sihui Liu
on 2019-02-07 18:31:54 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Sihui Liu
Created:
2019-02-07 18:31:54 PST
Size:
43.69 KB
patch
obsolete
>Subversion Revision: 241176 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8f02883d97ca1f73a1c03a4625d2c7854993c36a..17e10ddd2fd9eb54af471e25c4c181951cec8534 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,61 @@ >+2019-02-07 Sihui Liu <sihui_liu@apple.com> >+ >+ IndexedDB tests leak documents >+ https://bugs.webkit.org/show_bug.cgi?id=189435 >+ <rdar://problem/44240043> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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-07 Sihui Liu <sihui_liu@apple.com> > > REGRESSION(r239887): Crash under IDBConnectionToClient::didDeleteDatabase(WebCore::IDBResultData const&) >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >index 9b59cffce546669e8fce3f4642fe1a1bb740c93a..253a3b158bf5041af1aeb865011ecfbcf206f3cc 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp >@@ -124,11 +124,11 @@ ExceptionOr<Ref<IDBRequest>> IDBCursor::update(ExecState& state, JSValue value) > 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 @@ ExceptionOr<void> IDBCursor::continuePrimaryKey(ExecState& state, JSValue keyVal > 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 @@ ExceptionOr<void> IDBCursor::continueFunction(const IDBKeyData& key) > 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 @@ ExceptionOr<Ref<WebCore::IDBRequest>> IDBCursor::deleteFunction(ExecState& state > 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 @@ ExceptionOr<Ref<WebCore::IDBRequest>> IDBCursor::deleteFunction(ExecState& state > 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; >- >- auto* exec = context->execState(); >- if (!exec) >- return; >+ m_keyWrapper = { }; >+ m_primaryKeyWrapper = { }; >+ m_valueWrapper = { }; > > 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(); >- >- // 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(); >+ m_keyData = getResult.keyData(); >+ m_key = m_keyData.maybeCreateIDBKey(); >+ m_primaryKeyData = getResult.primaryKeyData(); >+ m_primaryKey = m_primaryKeyData.maybeCreateIDBKey(); > > if (isKeyCursorWithValue()) >- m_currentValue = { vm, deserializeIDBValueToJSValue(*exec, getResult.value()) }; >- else >- m_currentValue = { }; >+ m_value = getResult.value(); > > m_gotValue = true; > } >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.h b/Source/WebCore/Modules/indexeddb/IDBCursor.h >index 9ba27f370361b1df3502b4cc6c572d5d75015bbc..03e6b1eb24fe414df7a7af602055a3c44e753a93 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursor.h >+++ b/Source/WebCore/Modules/indexeddb/IDBCursor.h >@@ -30,6 +30,8 @@ > #include "ExceptionOr.h" > #include "IDBCursorDirection.h" > #include "IDBCursorInfo.h" >+#include "IDBValue.h" >+#include "JSValueInWrappedObject.h" > #include <JavaScriptCore/Strong.h> > #include <wtf/Variant.h> > #include <wtf/WeakPtr.h> >@@ -52,9 +54,13 @@ public: > > 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); >@@ -92,14 +98,15 @@ private: > > 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 @@ inline IDBCursorDirection IDBCursor::direction() const > 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) >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.idl b/Source/WebCore/Modules/indexeddb/IDBCursor.idl >index fccb30fee0f8930dacffc2058217a8ab858ea244..06e3a503d27ced94d943536ca4f3eca1241e1d47 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursor.idl >+++ b/Source/WebCore/Modules/indexeddb/IDBCursor.idl >@@ -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); >diff --git a/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl b/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl >index 5b047d51b16b651a07a8662fbda77035c4fcadbf..ba52c4c057654ff908b1ea837a7a2dc8746b2f12 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl >+++ b/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.idl >@@ -28,5 +28,5 @@ > SkipVTableValidation, > JSCustomMarkFunction, > ] interface IDBCursorWithValue : IDBCursor { >- readonly attribute any value; >+ [CustomGetter] readonly attribute any value; > }; >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >index b96cfd01250afedca6f303f0f0374c1de7ebe03d..c175dee115975e48a9c9db78e6a2de98b6df43d6 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >@@ -285,9 +285,9 @@ ExceptionOr<Ref<IDBRequest>> IDBObjectStore::put(ExecState& execState, JSValue v > 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) >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >index cfc7df720cca69748fdc65512b9f26252f6d6f19..ddf768f55772a829c3e08d454e4e5a044bffd6f7 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >@@ -96,7 +96,7 @@ public: > 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; } >diff --git a/Source/WebCore/Modules/indexeddb/IDBRequest.cpp b/Source/WebCore/Modules/indexeddb/IDBRequest.cpp >index 67178727f80d24412469f837478be1546564f665..cec7c9a4f898628eff168bc7fa54b0799c18c013 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBRequest.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBRequest.cpp >@@ -85,6 +85,7 @@ IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBClient::IDBConnection > , m_resourceIdentifier(connectionProxy) > , m_connectionProxy(connectionProxy) > { >+ m_result = NullResultType::Empty; > suspendIfNeeded(); > } > >@@ -95,6 +96,7 @@ IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBObjectStore& objectSt > , m_source(&objectStore) > , m_connectionProxy(transaction.database().connectionProxy()) > { >+ m_result = NullResultType::Empty; > suspendIfNeeded(); > } > >@@ -111,6 +113,7 @@ IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBCursor& cursor, IDBTr > [this] (const auto& value) { this->m_source = IDBRequest::Source { value }; } > ); > >+ m_result = NullResultType::Empty; > cursor.setRequest(*this); > } > >@@ -121,6 +124,7 @@ IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBIndex& index, IDBTran > , m_source(&index) > , m_connectionProxy(transaction.database().connectionProxy()) > { >+ m_result = NullResultType::Empty; > suspendIfNeeded(); > } > >@@ -132,12 +136,14 @@ IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBObjectStore& objectSt > , m_requestedObjectStoreRecordType(type) > , m_connectionProxy(transaction.database().connectionProxy()) > { >+ m_result = NullResultType::Empty; > suspendIfNeeded(); > } > > 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 @@ IDBRequest::~IDBRequest() > { > 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 @@ void IDBRequest::setResult(const IDBKeyData& keyData) > 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 @@ void IDBRequest::setResult(const Vector<IDBKeyData>& keyDatas) > 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 @@ void IDBRequest::setResult(const Vector<IDBValue>& values) > 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 @@ void IDBRequest::setResult(uint64_t number) > 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,32 +430,25 @@ void IDBRequest::setResultToStructuredClone(const IDBValue& value) > 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() > { > 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() > { > 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 @@ void IDBRequest::willIterateCursor(IDBCursor& cursor) > > 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 @@ void IDBRequest::didOpenOrIterateCursor(const IDBResultData& resultData) > 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 @@ void IDBRequest::setResult(Ref<IDBDatabase>&& database) > { > ASSERT(&originThread() == &Thread::current()); > >- m_result = Result { RefPtr<IDBDatabase> { WTFMove(database) } }; >+ m_result = RefPtr<IDBDatabase> { WTFMove(database) }; >+ m_resultWrapper = { }; > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBRequest.h b/Source/WebCore/Modules/indexeddb/IDBRequest.h >index a3433a5926993fe8f7920d263ebaddbdaaf5f6b3..613512b67f756cc1d708e0bdebcb26cef744f630 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBRequest.h >+++ b/Source/WebCore/Modules/indexeddb/IDBRequest.h >@@ -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 <JavaScriptCore/Strong.h> > #include <wtf/Function.h> > #include <wtf/Scope.h> >@@ -45,11 +48,9 @@ class Event; > 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 IDBConnectionToServer; > > 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 @@ public: > > 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 @@ private: > IDBError m_idbError; > IDBResourceIdentifier m_resourceIdentifier; > >- Optional<Result> m_result; >+ JSValueInWrappedObject m_resultWrapper; >+ Result m_result; > Optional<Source> m_source; > > bool m_hasPendingActivity { true }; >diff --git a/Source/WebCore/Modules/indexeddb/IDBRequest.idl b/Source/WebCore/Modules/indexeddb/IDBRequest.idl >index 7751e205282b8e8a58895155f4b54e0aaabb04ad..85bbde9168b50cec42fd14c3dd65b9d9fef22483 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBRequest.idl >+++ b/Source/WebCore/Modules/indexeddb/IDBRequest.idl >@@ -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; >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 7df1e56aa2d1f8c6c50359f52e882d9d9b09e078..7aeccf700fe3be564caf02ea8c41d9a30cd38dd8 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -489,6 +489,7 @@ bindings/js/JSIDBCursorCustom.cpp > 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 >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index aa3b41d8da8f40dfe3ed3fea640853ffede5c367..0d08e3a7b6cb73be4fb78a77c265c18c08cda94c 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -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>"; }; >@@ -20845,8 +20847,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 */, >@@ -20981,6 +20981,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 */, >@@ -30504,6 +30507,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 */, >diff --git a/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp b/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp >index bafe2fe0bf427af9c14a217945b6b23bd06c9b93..96165ecd347ee498cb2e2834872145e8e16cf279 100644 >--- a/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp >+++ b/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp >@@ -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) >diff --git a/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp b/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp >index 8c323b6010f56e24007eddf7ee23d0025c46c54b..f43501cf94b411f8ed96cdb8d76c6f058d515707 100644 >--- a/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp >+++ b/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp >@@ -28,15 +28,24 @@ > > #if ENABLE(INDEXED_DATABASE) > >+#include "IDBBindingUtilities.h" > #include "IDBCursorWithValue.h" > #include <JavaScriptCore/HeapInlines.h> > > 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 >diff --git a/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp b/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..2e710a1609ad5d0d5353888cc0a9c575df2108a5 >--- /dev/null >+++ b/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp >@@ -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) >diff --git a/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp b/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp >index 6d5881ea0e664cbbce2a85f8d9de093fb43ccac0..e4443dbafef041aa15d441dee551dc47599acdc7 100644 >--- a/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp >+++ b/Source/WebCore/inspector/agents/InspectorIndexedDBAgent.cpp >@@ -137,12 +137,12 @@ public: > } > > 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 @@ public: > 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 @@ public: > } > > 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 @@ public: > 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)); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189435
:
361349
|
361403
| 361483