Replace all uses of ExceptionCodeWithMessage with WebCore::Exception
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Oct 2016 02:13:28 +0000 (02:13 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Oct 2016 02:13:28 +0000 (02:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163178

Reviewed by Sam Weinig.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::stringToDirection): Return an Optional instead of
using an ExceptionCode out argument, since this function just needs to
indicate failure, not actually throw an exception.
(WebCore::IDBCursor::update): Return ExceptionOr instead of using an
ExceptionCodeWithMessage out argument.
(WebCore::IDBCursor::advance): Ditto.
(WebCore::IDBCursor::continueFunction): Ditto.
(WebCore::IDBCursor::deleteFunction): Ditto.
* Modules/indexeddb/IDBCursor.h: Updated for above changes.

* Modules/indexeddb/IDBCursor.idl: Sorted extended attributes alphabetically.
Use MayThrowException instead of MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::createObjectStore): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBDatabase::transaction): Ditto.
(WebCore::IDBDatabase::deleteObjectStore): Ditto.
* Modules/indexeddb/IDBDatabase.h: Updated for above changes.

* Modules/indexeddb/IDBDatabase.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBFactory.cpp:
(WebCore::IDBFactory::open): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBFactory::openInternal): Ditto.
(WebCore::IDBFactory::deleteDatabase): Ditto.
(WebCore::IDBFactory::cmp): Ditto.
* Modules/indexeddb/IDBFactory.h: Updated for above changes.

* Modules/indexeddb/IDBFactory.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBIndex.cpp:
(WebCore::IDBIndex::openCursor): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBIndex::count): Ditto.
(WebCore::IDBIndex::doCount): Ditto.
(WebCore::IDBIndex::openKeyCursor): Ditto.
(WebCore::IDBIndex::get): Ditto.
(WebCore::IDBIndex::doGet): Ditto.
(WebCore::IDBIndex::getKey): Ditto.
(WebCore::IDBIndex::doGetKey): Ditto.
* Modules/indexeddb/IDBIndex.h: Updated for above changes.

* Modules/indexeddb/IDBIndex.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBKeyRange.cpp:
(WebCore::IDBKeyRange::only): Return ExceptionOr instead of
using an ExceptionCode out argument.
(WebCore::IDBKeyRange::lowerBound): Ditto.
(WebCore::IDBKeyRange::upperBound): Ditto.
(WebCore::IDBKeyRange::bound): Ditto.
* Modules/indexeddb/IDBKeyRange.h: Updated for above changes.
* Modules/indexeddb/IDBKeyRange.idl: Use MayThrowException instead of
MayThrowLegacyException.

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::openCursor): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBObjectStore::get): Ditto.
(WebCore::IDBObjectStore::add): Ditto.
(WebCore::IDBObjectStore::put): Ditto.
(WebCore::IDBObjectStore::putForCursorUpdate): Ditto.
(WebCore::IDBObjectStore::putOrAdd): Ditto.
(WebCore::IDBObjectStore::deleteFunction): Ditto.
(WebCore::IDBObjectStore::doDelete): Ditto.
(WebCore::IDBObjectStore::clear): Ditto.
(WebCore::IDBObjectStore::createIndex): Ditto.
(WebCore::IDBObjectStore::index): Ditto.
(WebCore::IDBObjectStore::deleteIndex): Ditto.
(WebCore::IDBObjectStore::count): Ditto.
(WebCore::IDBObjectStore::doCount): Ditto.
* Modules/indexeddb/IDBObjectStore.h: Updated for above changes.

* Modules/indexeddb/IDBObjectStore.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::errorCode): Deleted. Was dead code.
(WebCore::IDBRequest::error): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
* Modules/indexeddb/IDBRequest.h: Updated for above changes.

* Modules/indexeddb/IDBRequest.idl: Use GetterMayThrowException instead of
GetterMayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::stringToMode): Return an Optional instead of
using an ExceptionCode out argument, since this function just needs to
indicate failure, not actually throw an exception.
(WebCore::IDBTransaction::db): Tweaked code a bit.
(WebCore::IDBTransaction::error): Return a pointer instead of a RefPtr.
(WebCore::IDBTransaction::objectStore): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBTransaction::abortDueToFailedRequest): Call internalAbort.
(WebCore::IDBTransaction::abort): Return ExceptionOr instead of
using an ExceptionCodeWithMessage out argument.
(WebCore::IDBTransaction::internalAbort): Added a version that asserts
instead of throwing an exception for internal use.
(WebCore::IDBTransaction::stop): Call internalAbort.
* Modules/indexeddb/IDBTransaction.h: Updated for above changes.

* Modules/indexeddb/IDBTransaction.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::openDatabase): Updated to return
a Ref instead of a RefPtr, since the function can never return null.
(WebCore::IDBClient::IDBConnectionProxy::deleteDatabase): Ditto.
* Modules/indexeddb/client/IDBConnectionProxy.h: Updated for above changes.

* Modules/mediastream/MediaEndpointPeerConnection.cpp:
(WebCore::MediaEndpointPeerConnection::setLocalDescriptionTask): Updated
exception handling to use ExceptionOr instead of ExceptionCodeWithMessage.
(WebCore::MediaEndpointPeerConnection::setRemoteDescriptionTask): Ditto.
* Modules/mediastream/MediaEndpointSessionDescription.cpp:
(WebCore::MediaEndpointSessionDescription::create): Ditto.
* Modules/mediastream/MediaEndpointSessionDescription.h: Updated for above change.

* bindings/js/JSDOMBinding.cpp:
(WebCore::createDOMException): Added overload for Exception.
(WebCore::throwDOMException): Deleted overload for ExceptionCodeWithMessage.
Updated code to call the new createDOMException function.
(WebCore::setDOMExceptionSlow): Ditto.
(WebCore::setDOMException): Ditto.

* bindings/js/JSDOMBinding.h: Added overload of createDOMException that takes
an Exception. Deleted functions dealing with ExceptionCodeWithMessage. Fixed
interface of toJSNumber and toJSNullableNumber and implemented toJSNumber.

* bindings/js/JSDOMPromise.cpp:
(WebCore::DeferredPromise::reject): Added overload that takes an Exception.
* bindings/js/JSDOMPromise.h: Updated for above change.

* bindings/js/JSHistoryCustom.cpp:
(WebCore::JSHistory::pushState): Use propagateException to deal with
ExceptionOr instead of ExceptionCodeWithMessage.
(WebCore::JSHistory::replaceState): Ditto.

* bindings/js/JSIDBDatabaseCustom.cpp:
(WebCore::JSIDBDatabase::createObjectStore): Use toJS and
to deal with ExceptionOr rather than setDOMException to deal
with ExceptionCodeWithMessage.

* bindings/js/JSIDBRequestCustom.cpp:
(WebCore::JSIDBRequest::result): Use propagateException and
Exception rather than setDOMException and ExceptionCodeWithMessage.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation): Removed support for GetterMayThrowLegacyExceptionWithMessage,
SetterMayThrowLegacyExceptionWithMessage, and MayThrowLegacyExceptionWithMessage.
(GenerateReturnParameters): Ditto.
(GenerateImplementationFunctionCall): Ditto.
(GenerateConstructorDefinition): Ditto.

* bindings/scripts/IDLAttributes.txt: Removed GetterMayThrowLegacyExceptionWithMessage,
SetterMayThrowLegacyExceptionWithMessage, and MayThrowLegacyExceptionWithMessage.

* bindings/scripts/test/JS/JSTestObj.cpp: Regenerated.
* bindings/scripts/test/TestObj.idl: Removed tests cases for now-removed attributes.

* dom/CustomElementRegistry.idl: Use MayThrowException instead of
MayThrowLegacyExceptionWithMessage.

* dom/ExceptionCode.h: Removed ExceptionCodeWithMessage. Also updated to use pragma
once, removed include of WTFString.h and switched to using instead of typedef.

* history/HistoryItem.h: Return a pointer instead of a RefPtr from stateObject
to cut down a little on unnecessary reference count churn.

* inspector/InspectorIndexedDBAgent.cpp: Updated all the code that uses IDB
classes to use the new versions rather than the old ExceptionCodeWithMessage versions.

* page/DOMWindow.cpp:
(WebCore::DOMWindow::history): Pass a reference instead of a pointer.

* page/History.cpp:
(WebCore::History::History): Take a reference instead of a pointer.
(WebCore::History::length): Tweaked to use a local variable.
(WebCore::History::state): Return a pointer instead of a PassRefPtr.
(WebCore::History::stateInternal): Ditto. Also use early return consistently.
(WebCore::History::isSameAsCurrentState): Updated for above change.
(WebCore::History::stateObjectAdded): Return ExceptionOr rather than taking an
ExceptionCodeWithMessage out argument.

* page/History.h: Use pragma once. Removed some unneeded includes. Marked class final.
Updated for changes above.

* page/History.idl: Use MayThrowException instead of MayThrowLegacyException.

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

49 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCursor.cpp
Source/WebCore/Modules/indexeddb/IDBCursor.h
Source/WebCore/Modules/indexeddb/IDBCursor.idl
Source/WebCore/Modules/indexeddb/IDBDatabase.cpp
Source/WebCore/Modules/indexeddb/IDBDatabase.h
Source/WebCore/Modules/indexeddb/IDBDatabase.idl
Source/WebCore/Modules/indexeddb/IDBFactory.cpp
Source/WebCore/Modules/indexeddb/IDBFactory.h
Source/WebCore/Modules/indexeddb/IDBFactory.idl
Source/WebCore/Modules/indexeddb/IDBIndex.cpp
Source/WebCore/Modules/indexeddb/IDBIndex.h
Source/WebCore/Modules/indexeddb/IDBIndex.idl
Source/WebCore/Modules/indexeddb/IDBKeyRange.cpp
Source/WebCore/Modules/indexeddb/IDBKeyRange.h
Source/WebCore/Modules/indexeddb/IDBKeyRange.idl
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStore.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.idl
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.h
Source/WebCore/Modules/indexeddb/IDBRequest.idl
Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
Source/WebCore/Modules/indexeddb/IDBTransaction.h
Source/WebCore/Modules/indexeddb/IDBTransaction.idl
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h
Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp
Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.cpp
Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.h
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/js/JSDOMPromise.cpp
Source/WebCore/bindings/js/JSDOMPromise.h
Source/WebCore/bindings/js/JSHistoryCustom.cpp
Source/WebCore/bindings/js/JSIDBDatabaseCustom.cpp
Source/WebCore/bindings/js/JSIDBRequestCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/dom/CustomElementRegistry.idl
Source/WebCore/dom/ExceptionCode.h
Source/WebCore/history/HistoryItem.h
Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/History.cpp
Source/WebCore/page/History.h
Source/WebCore/page/History.idl

index 47526d7..53435af 100644 (file)
@@ -1,3 +1,204 @@
+2016-10-09  Darin Adler  <darin@apple.com>
+
+        Replace all uses of ExceptionCodeWithMessage with WebCore::Exception
+        https://bugs.webkit.org/show_bug.cgi?id=163178
+
+        Reviewed by Sam Weinig.
+
+        * Modules/indexeddb/IDBCursor.cpp:
+        (WebCore::IDBCursor::stringToDirection): Return an Optional instead of
+        using an ExceptionCode out argument, since this function just needs to
+        indicate failure, not actually throw an exception.
+        (WebCore::IDBCursor::update): Return ExceptionOr instead of using an
+        ExceptionCodeWithMessage out argument.
+        (WebCore::IDBCursor::advance): Ditto.
+        (WebCore::IDBCursor::continueFunction): Ditto.
+        (WebCore::IDBCursor::deleteFunction): Ditto.
+        * Modules/indexeddb/IDBCursor.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBCursor.idl: Sorted extended attributes alphabetically.
+        Use MayThrowException instead of MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::createObjectStore): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBDatabase::transaction): Ditto.
+        (WebCore::IDBDatabase::deleteObjectStore): Ditto.
+        * Modules/indexeddb/IDBDatabase.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBDatabase.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBFactory.cpp:
+        (WebCore::IDBFactory::open): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBFactory::openInternal): Ditto.
+        (WebCore::IDBFactory::deleteDatabase): Ditto.
+        (WebCore::IDBFactory::cmp): Ditto.
+        * Modules/indexeddb/IDBFactory.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBFactory.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBIndex.cpp:
+        (WebCore::IDBIndex::openCursor): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBIndex::count): Ditto.
+        (WebCore::IDBIndex::doCount): Ditto.
+        (WebCore::IDBIndex::openKeyCursor): Ditto.
+        (WebCore::IDBIndex::get): Ditto.
+        (WebCore::IDBIndex::doGet): Ditto.
+        (WebCore::IDBIndex::getKey): Ditto.
+        (WebCore::IDBIndex::doGetKey): Ditto.
+        * Modules/indexeddb/IDBIndex.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBIndex.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBKeyRange.cpp:
+        (WebCore::IDBKeyRange::only): Return ExceptionOr instead of
+        using an ExceptionCode out argument.
+        (WebCore::IDBKeyRange::lowerBound): Ditto.
+        (WebCore::IDBKeyRange::upperBound): Ditto.
+        (WebCore::IDBKeyRange::bound): Ditto.
+        * Modules/indexeddb/IDBKeyRange.h: Updated for above changes.
+        * Modules/indexeddb/IDBKeyRange.idl: Use MayThrowException instead of
+        MayThrowLegacyException.
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::openCursor): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBObjectStore::get): Ditto.
+        (WebCore::IDBObjectStore::add): Ditto.
+        (WebCore::IDBObjectStore::put): Ditto.
+        (WebCore::IDBObjectStore::putForCursorUpdate): Ditto.
+        (WebCore::IDBObjectStore::putOrAdd): Ditto.
+        (WebCore::IDBObjectStore::deleteFunction): Ditto.
+        (WebCore::IDBObjectStore::doDelete): Ditto.
+        (WebCore::IDBObjectStore::clear): Ditto.
+        (WebCore::IDBObjectStore::createIndex): Ditto.
+        (WebCore::IDBObjectStore::index): Ditto.
+        (WebCore::IDBObjectStore::deleteIndex): Ditto.
+        (WebCore::IDBObjectStore::count): Ditto.
+        (WebCore::IDBObjectStore::doCount): Ditto.
+        * Modules/indexeddb/IDBObjectStore.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBObjectStore.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::errorCode): Deleted. Was dead code.
+        (WebCore::IDBRequest::error): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        * Modules/indexeddb/IDBRequest.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBRequest.idl: Use GetterMayThrowException instead of
+        GetterMayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::stringToMode): Return an Optional instead of
+        using an ExceptionCode out argument, since this function just needs to
+        indicate failure, not actually throw an exception.
+        (WebCore::IDBTransaction::db): Tweaked code a bit.
+        (WebCore::IDBTransaction::error): Return a pointer instead of a RefPtr.
+        (WebCore::IDBTransaction::objectStore): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBTransaction::abortDueToFailedRequest): Call internalAbort.
+        (WebCore::IDBTransaction::abort): Return ExceptionOr instead of
+        using an ExceptionCodeWithMessage out argument.
+        (WebCore::IDBTransaction::internalAbort): Added a version that asserts
+        instead of throwing an exception for internal use.
+        (WebCore::IDBTransaction::stop): Call internalAbort.
+        * Modules/indexeddb/IDBTransaction.h: Updated for above changes.
+
+        * Modules/indexeddb/IDBTransaction.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::openDatabase): Updated to return
+        a Ref instead of a RefPtr, since the function can never return null.
+        (WebCore::IDBClient::IDBConnectionProxy::deleteDatabase): Ditto.
+        * Modules/indexeddb/client/IDBConnectionProxy.h: Updated for above changes.
+
+        * Modules/mediastream/MediaEndpointPeerConnection.cpp:
+        (WebCore::MediaEndpointPeerConnection::setLocalDescriptionTask): Updated
+        exception handling to use ExceptionOr instead of ExceptionCodeWithMessage.
+        (WebCore::MediaEndpointPeerConnection::setRemoteDescriptionTask): Ditto.
+        * Modules/mediastream/MediaEndpointSessionDescription.cpp:
+        (WebCore::MediaEndpointSessionDescription::create): Ditto.
+        * Modules/mediastream/MediaEndpointSessionDescription.h: Updated for above change.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::createDOMException): Added overload for Exception.
+        (WebCore::throwDOMException): Deleted overload for ExceptionCodeWithMessage.
+        Updated code to call the new createDOMException function.
+        (WebCore::setDOMExceptionSlow): Ditto.
+        (WebCore::setDOMException): Ditto.
+
+        * bindings/js/JSDOMBinding.h: Added overload of createDOMException that takes
+        an Exception. Deleted functions dealing with ExceptionCodeWithMessage. Fixed
+        interface of toJSNumber and toJSNullableNumber and implemented toJSNumber.
+
+        * bindings/js/JSDOMPromise.cpp:
+        (WebCore::DeferredPromise::reject): Added overload that takes an Exception.
+        * bindings/js/JSDOMPromise.h: Updated for above change.
+
+        * bindings/js/JSHistoryCustom.cpp:
+        (WebCore::JSHistory::pushState): Use propagateException to deal with
+        ExceptionOr instead of ExceptionCodeWithMessage.
+        (WebCore::JSHistory::replaceState): Ditto.
+
+        * bindings/js/JSIDBDatabaseCustom.cpp:
+        (WebCore::JSIDBDatabase::createObjectStore): Use toJS and
+        to deal with ExceptionOr rather than setDOMException to deal
+        with ExceptionCodeWithMessage.
+
+        * bindings/js/JSIDBRequestCustom.cpp:
+        (WebCore::JSIDBRequest::result): Use propagateException and
+        Exception rather than setDOMException and ExceptionCodeWithMessage.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation): Removed support for GetterMayThrowLegacyExceptionWithMessage,
+        SetterMayThrowLegacyExceptionWithMessage, and MayThrowLegacyExceptionWithMessage.
+        (GenerateReturnParameters): Ditto.
+        (GenerateImplementationFunctionCall): Ditto.
+        (GenerateConstructorDefinition): Ditto.
+
+        * bindings/scripts/IDLAttributes.txt: Removed GetterMayThrowLegacyExceptionWithMessage,
+        SetterMayThrowLegacyExceptionWithMessage, and MayThrowLegacyExceptionWithMessage.
+
+        * bindings/scripts/test/JS/JSTestObj.cpp: Regenerated.
+        * bindings/scripts/test/TestObj.idl: Removed tests cases for now-removed attributes.
+
+        * dom/CustomElementRegistry.idl: Use MayThrowException instead of
+        MayThrowLegacyExceptionWithMessage.
+
+        * dom/ExceptionCode.h: Removed ExceptionCodeWithMessage. Also updated to use pragma
+        once, removed include of WTFString.h and switched to using instead of typedef.
+
+        * history/HistoryItem.h: Return a pointer instead of a RefPtr from stateObject
+        to cut down a little on unnecessary reference count churn.
+
+        * inspector/InspectorIndexedDBAgent.cpp: Updated all the code that uses IDB
+        classes to use the new versions rather than the old ExceptionCodeWithMessage versions.
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::history): Pass a reference instead of a pointer.
+
+        * page/History.cpp:
+        (WebCore::History::History): Take a reference instead of a pointer.
+        (WebCore::History::length): Tweaked to use a local variable.
+        (WebCore::History::state): Return a pointer instead of a PassRefPtr.
+        (WebCore::History::stateInternal): Ditto. Also use early return consistently.
+        (WebCore::History::isSameAsCurrentState): Updated for above change.
+        (WebCore::History::stateObjectAdded): Return ExceptionOr rather than taking an
+        ExceptionCodeWithMessage out argument.
+
+        * page/History.h: Use pragma once. Removed some unneeded includes. Marked class final.
+        Updated for changes above.
+
+        * page/History.idl: Use MayThrowException instead of MayThrowLegacyException.
+
 2016-10-07  Ryosuke Niwa  <rniwa@webkit.org>
 
         REGRESSION(r165103): labels list doesn't get invalidated when other lists are invalidated at document level
index c3517d0..9e80594 100644 (file)
@@ -71,7 +71,7 @@ const AtomicString& IDBCursor::directionPrevUnique()
     return prevunique;
 }
 
-IndexedDB::CursorDirection IDBCursor::stringToDirection(const String& directionString, ExceptionCode& ec)
+Optional<IndexedDB::CursorDirection> IDBCursor::stringToDirection(const String& directionString)
 {
     if (directionString == directionNext())
         return IndexedDB::CursorDirection::Next;
@@ -82,8 +82,7 @@ IndexedDB::CursorDirection IDBCursor::stringToDirection(const String& directionS
     if (directionString == directionPrevUnique())
         return IndexedDB::CursorDirection::PrevNoDuplicate;
 
-    ec = TypeError;
-    return IndexedDB::CursorDirection::Next;
+    return Nullopt;
 }
 
 const AtomicString& IDBCursor::directionToString(IndexedDB::CursorDirection direction)
@@ -169,162 +168,116 @@ const String& IDBCursor::direction() const
     return directionToString(m_info.cursorDirection());
 }
 
-RefPtr<WebCore::IDBRequest> IDBCursor::update(ExecState& exec, JSValue value, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBCursor::update(ExecState& state, JSValue value)
 {
     LOG(IndexedDB, "IDBCursor::update");
     ASSERT(currentThread() == effectiveObjectStore().transaction().database().originThreadID());
 
-    if (sourcesDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor's source or effective object store has been deleted.");
-        return nullptr;
-    }
+    if (sourcesDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor's source or effective object store has been deleted.") };
 
-    if (!transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished.") };
 
-    if (transaction().isReadOnly()) {
-        ec.code = IDBDatabaseException::ReadOnlyError;
-        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction.");
-        return nullptr;
-    }
+    if (transaction().isReadOnly())
+        return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction.") };
 
-    if (!m_gotValue) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
-        return nullptr;
-    }
+    if (!m_gotValue)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is being iterated or has iterated past its end.") };
 
-    if (!isKeyCursorWithValue()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor.");
-        return nullptr;
-    }
+    if (!isKeyCursorWithValue())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor.") };
 
     auto& objectStore = effectiveObjectStore();
     auto& keyPath = objectStore.info().keyPath();
     const bool usesInLineKeys = !keyPath.isNull();
     if (usesInLineKeys) {
-        RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath);
+        RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, keyPath);
         IDBKeyData keyPathKeyData(keyPathKey.get());
-        if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData) {
-            ec.code = IDBDatabaseException::DataError;
-            ec.message = ASCIILiteral("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.");
-            return nullptr;
-        }
+        if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData)
+            return Exception { IDBDatabaseException::DataError, ASCIILiteral("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.") };
     }
 
-    auto request = effectiveObjectStore().putForCursorUpdate(exec, value, m_currentPrimaryKey.get(), ec);
-    if (ec.code)
-        return nullptr;
+    auto putResult = effectiveObjectStore().putForCursorUpdate(state, value, m_currentPrimaryKey.get());
+    if (putResult.hasException())
+        return putResult.releaseException();
 
-    ASSERT(request);
+    auto request = putResult.releaseReturnValue();
     request->setSource(*this);
     ++m_outstandingRequestCount;
 
-    return request;
+    return WTFMove(request);
 }
 
-void IDBCursor::advance(unsigned count, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBCursor::advance(unsigned count)
 {
     LOG(IndexedDB, "IDBCursor::advance");
     ASSERT(currentThread() == effectiveObjectStore().transaction().database().originThreadID());
 
-    if (!m_request) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        return;
-    }
-    
-    if (!count) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': A count argument with value 0 (zero) was supplied, must be greater than 0.");
-        return;
-    }
+    if (!m_request)
+        return Exception { IDBDatabaseException::InvalidStateError };
 
-    if (sourcesDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor's source or effective object store has been deleted.");
-        return;
-    }
+    if (!count)
+        return Exception { TypeError, ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': A count argument with value 0 (zero) was supplied, must be greater than 0.") };
 
-    if (!transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The transaction is inactive or finished.");
-        return;
-    }
+    if (sourcesDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor's source or effective object store has been deleted.") };
 
-    if (!m_gotValue) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
-        return;
-    }
+    if (!transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The transaction is inactive or finished.") };
+
+    if (!m_gotValue)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor is being iterated or has iterated past its end.") };
 
     m_gotValue = false;
 
     uncheckedIterateCursor(IDBKeyData(), count);
+
+    return { };
 }
 
-void IDBCursor::continueFunction(ExecState& execState, JSValue keyValue, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBCursor::continueFunction(ExecState& execState, JSValue keyValue)
 {
     RefPtr<IDBKey> key;
     if (!keyValue.isUndefined())
         key = scriptValueToIDBKey(execState, keyValue);
 
-    continueFunction(key.get(), ec);
+    return continueFunction(key.get());
 }
 
-void IDBCursor::continueFunction(const IDBKeyData& key, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBCursor::continueFunction(const IDBKeyData& key)
 {
     LOG(IndexedDB, "IDBCursor::continueFunction (to key %s)", key.loggingString().utf8().data());
     ASSERT(currentThread() == effectiveObjectStore().transaction().database().originThreadID());
 
-    if (!m_request) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        return;
-    }
+    if (!m_request)
+        return Exception { IDBDatabaseException::InvalidStateError };
 
-    if (sourcesDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The cursor's source or effective object store has been deleted.");
-        return;
-    }
+    if (sourcesDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The cursor's source or effective object store has been deleted.") };
 
-    if (!transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The transaction is inactive or finished.");
-        return;
-    }
+    if (!transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The transaction is inactive or finished.") };
 
-    if (!m_gotValue) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
-        return;
-    }
+    if (!m_gotValue)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.") };
 
-    if (!key.isNull() && !key.isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is not a valid key.");
-        return;
-    }
+    if (!key.isNull() && !key.isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is not a valid key.") };
 
     if (m_info.isDirectionForward()) {
-        if (!key.isNull() && key.compare(m_currentKeyData) <= 0) {
-            ec.code = IDBDatabaseException::DataError;
-            ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is less than or equal to this cursor's position.");
-            return;
-        }
-    } else if (!key.isNull() && key.compare(m_currentKeyData) >= 0) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is greater than or equal to this cursor's position.");
-        return;
+        if (!key.isNull() && key.compare(m_currentKeyData) <= 0)
+            return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is less than or equal to this cursor's position.") };
+    } else {
+        if (!key.isNull() && key.compare(m_currentKeyData) >= 0)
+            return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'continue' on 'IDBCursor': The parameter is greater than or equal to this cursor's position.") };
     }
 
     m_gotValue = false;
 
     uncheckedIterateCursor(key, 0);
+
+    return { };
 }
 
 void IDBCursor::uncheckedIterateCursor(const IDBKeyData& key, unsigned count)
@@ -337,50 +290,35 @@ void IDBCursor::uncheckedIterateCursor(const IDBKeyData& key, unsigned count)
     transaction().iterateCursor(*this, key, count);
 }
 
-RefPtr<WebCore::IDBRequest> IDBCursor::deleteFunction(ExecState& execState, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<WebCore::IDBRequest>> IDBCursor::deleteFunction(ExecState& state)
 {
     LOG(IndexedDB, "IDBCursor::deleteFunction");
     ASSERT(currentThread() == effectiveObjectStore().transaction().database().originThreadID());
 
-    if (sourcesDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor's source or effective object store has been deleted.");
-        return nullptr;
-    }
+    if (sourcesDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor's source or effective object store has been deleted.") };
 
-    if (!transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The transaction is inactive or finished.") };
 
-    if (transaction().isReadOnly()) {
-        ec.code = IDBDatabaseException::ReadOnlyError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The record may not be deleted inside a read-only transaction.");
-        return nullptr;
-    }
+    if (transaction().isReadOnly())
+        return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The record may not be deleted inside a read-only transaction.") };
 
-    if (!m_gotValue) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
-        return nullptr;
-    }
+    if (!m_gotValue)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is being iterated or has iterated past its end.") };
 
-    if (!isKeyCursorWithValue()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is a key cursor.");
-        return nullptr;
-    }
+    if (!isKeyCursorWithValue())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'delete' on 'IDBCursor': The cursor is a key cursor.") };
 
-    auto request = effectiveObjectStore().deleteFunction(execState, m_currentPrimaryKey.get(), ec);
-    if (ec.code)
-        return nullptr;
+    auto result = effectiveObjectStore().deleteFunction(state, m_currentPrimaryKey.get());
+    if (result.hasException())
+        return result.releaseException();
 
-    ASSERT(request);
+    auto request = result.releaseReturnValue();
     request->setSource(*this);
     ++m_outstandingRequestCount;
 
-    return request;
+    return WTFMove(request);
 }
 
 void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
index b3f0bd2..94b0f79 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "ActiveDOMObject.h"
 #include "DOMWrapperWorld.h"
+#include "ExceptionOr.h"
 #include "IDBCursorInfo.h"
 #include <heap/Strong.h>
 
@@ -39,8 +40,6 @@ class IDBIndex;
 class IDBObjectStore;
 class IDBTransaction;
 
-struct ExceptionCodeWithMessage;
-
 class IDBCursor : public ScriptWrappable, public RefCounted<IDBCursor>, public ActiveDOMObject {
 public:
     static Ref<IDBCursor> create(IDBTransaction&, IDBIndex&, const IDBCursorInfo&);
@@ -50,7 +49,7 @@ public:
     static const AtomicString& directionPrev();
     static const AtomicString& directionPrevUnique();
 
-    static IndexedDB::CursorDirection stringToDirection(const String& modeString, ExceptionCode&);
+    static Optional<IndexedDB::CursorDirection> stringToDirection(const String& modeString);
     static const AtomicString& directionToString(IndexedDB::CursorDirection mode);
     
     virtual ~IDBCursor();
@@ -62,12 +61,12 @@ public:
     IDBObjectStore* objectStore() const { return m_objectStore.get(); }
     IDBIndex* index() const { return m_index.get(); }
 
-    RefPtr<IDBRequest> update(JSC::ExecState&, JSC::JSValue, ExceptionCodeWithMessage&);
-    void advance(unsigned, ExceptionCodeWithMessage&);
-    void continueFunction(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> deleteFunction(JSC::ExecState&, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> update(JSC::ExecState&, JSC::JSValue);
+    ExceptionOr<void> advance(unsigned);
+    ExceptionOr<void> continueFunction(JSC::ExecState&, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> deleteFunction(JSC::ExecState&);
 
-    void continueFunction(const IDBKeyData&, ExceptionCodeWithMessage&);
+    ExceptionOr<void> continueFunction(const IDBKeyData&);
 
     const IDBCursorInfo& info() const { return m_info; }
 
index 00e7e6e..0d66547 100644 (file)
  */
 
 [
+    ActiveDOMObject,
     Conditional=INDEXED_DATABASE,
     CustomToJSObject,
     EnabledAtRuntime=IndexedDB,
-    ActiveDOMObject,
-    SkipVTableValidation,
     JSCustomMarkFunction,
+    SkipVTableValidation,
 ] interface IDBCursor {
     [CustomGetter] readonly attribute any source;
     readonly attribute DOMString direction;
     readonly attribute any key;
     readonly attribute any primaryKey;
 
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest update(any value);
-    [MayThrowLegacyExceptionWithMessage] void advance([EnforceRange] unsigned long count);
-    [CallWith=ScriptState, ImplementedAs=continueFunction, MayThrowLegacyExceptionWithMessage] void continue(optional any key);
-    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowLegacyExceptionWithMessage] IDBRequest delete();
+    [CallWith=ScriptState, MayThrowException] IDBRequest update(any value);
+    [MayThrowException] void advance([EnforceRange] unsigned long count);
+    [CallWith=ScriptState, ImplementedAs=continueFunction, MayThrowException] void continue(optional any key);
+    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowException] IDBRequest delete();
 };
index e48ac32..4304cf3 100644 (file)
@@ -106,145 +106,107 @@ RefPtr<DOMStringList> IDBDatabase::objectStoreNames() const
     return objectStoreNames;
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String&, const Dictionary&, ExceptionCodeWithMessage&)
+ExceptionOr<Ref<IDBObjectStore>> IDBDatabase::createObjectStore(const String&, const Dictionary&)
 {
     ASSERT_NOT_REACHED();
-    return nullptr;
+    return Exception { IDBDatabaseException::InvalidStateError };
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBObjectStore>> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
 {
     LOG(IndexedDB, "IDBDatabase::createObjectStore - (%s %s)", m_info.name().utf8().data(), name.utf8().data());
 
     ASSERT(currentThread() == originThreadID());
     ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->isVersionChange());
 
-    if (!m_versionChangeTransaction) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.");
-        return nullptr;
-    }
+    if (!m_versionChangeTransaction)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction.") };
 
-    if (!m_versionChangeTransaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        return nullptr;
-    }
+    if (!m_versionChangeTransaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError };
 
-    if (m_info.hasObjectStore(name)) {
-        ec.code = IDBDatabaseException::ConstraintError;
-        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists.");
-        return nullptr;
-    }
+    if (m_info.hasObjectStore(name))
+        return Exception { IDBDatabaseException::ConstraintError, ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists.") };
 
-    if (!keyPath.isNull() && !keyPath.isValid()) {
-        ec.code = IDBDatabaseException::SyntaxError;
-        ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path.");
-        return nullptr;
-    }
+    if (!keyPath.isNull() && !keyPath.isValid())
+        return Exception { IDBDatabaseException::SyntaxError, ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path.") };
 
-    if (autoIncrement && !keyPath.isNull()) {
-        if ((keyPath.type() == IDBKeyPath::Type::String && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::Type::Array) {
-            ec.code = IDBDatabaseException::InvalidAccessError;
-            ec.message = ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.");
-            return nullptr;
-        }
-    }
+    if (autoIncrement && ((keyPath.type() == IDBKeyPath::Type::String && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::Type::Array))
+        return Exception { IDBDatabaseException::InvalidAccessError, ASCIILiteral("Failed to execute 'createObjectStore' on 'IDBDatabase': The autoIncrement option was set but the keyPath option was empty or an array.") };
 
     // Install the new ObjectStore into the connection's metadata.
-    IDBObjectStoreInfo info = m_info.createNewObjectStore(name, keyPath, autoIncrement);
+    auto info = m_info.createNewObjectStore(name, keyPath, autoIncrement);
 
     // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side.
-    Ref<IDBObjectStore> objectStore = m_versionChangeTransaction->createObjectStore(info);
-    return adoptRef(&objectStore.leakRef());
+    return m_versionChangeTransaction->createObjectStore(info);
 }
 
-RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(const Vector<String>& objectStores, const String& modeString, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBTransaction>> IDBDatabase::transaction(const Vector<String>& objectStores, const String& modeString)
 {
     LOG(IndexedDB, "IDBDatabase::transaction");
 
     ASSERT(currentThread() == originThreadID());
 
-    if (m_closePending) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing.");
-        return nullptr;
-    }
+    if (m_closePending)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing.") };
 
-    if (objectStores.isEmpty()) {
-        ec.code = IDBDatabaseException::InvalidAccessError;
-        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The storeNames parameter was empty.");
-        return nullptr;
-    }
+    if (objectStores.isEmpty())
+        return Exception { IDBDatabaseException::InvalidAccessError, ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The storeNames parameter was empty.") };
 
-    IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, ec.code);
-    if (ec.code) {
-        ec.message = makeString(ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': The mode provided ('"), modeString, ASCIILiteral("') is not one of 'readonly' or 'readwrite'."));
-        return nullptr;
-    }
+    auto mode = IDBTransaction::stringToMode(modeString);
+    if (!mode)
+        return Exception { TypeError, "Failed to execute 'transaction' on 'IDBDatabase': The mode provided ('" + modeString + "') is not one of 'readonly' or 'readwrite'." };
 
-    if (mode != IndexedDB::TransactionMode::ReadOnly && mode != IndexedDB::TransactionMode::ReadWrite) {
-        ec.code = TypeError;
-        return nullptr;
-    }
+    if (mode.value() != IndexedDB::TransactionMode::ReadOnly && mode.value() != IndexedDB::TransactionMode::ReadWrite)
+        return Exception { TypeError };
 
-    if (m_versionChangeTransaction && !m_versionChangeTransaction->isFinishedOrFinishing()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.");
-        return nullptr;
-    }
+    if (m_versionChangeTransaction && !m_versionChangeTransaction->isFinishedOrFinishing())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.") };
 
     for (auto& objectStoreName : objectStores) {
         if (m_info.hasObjectStore(objectStoreName))
             continue;
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.");
-        return nullptr;
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.") };
     }
 
-    auto info = IDBTransactionInfo::clientTransaction(m_connectionProxy.get(), objectStores, mode);
+    auto info = IDBTransactionInfo::clientTransaction(m_connectionProxy.get(), objectStores, mode.value());
     auto transaction = IDBTransaction::create(*this, info);
 
     LOG(IndexedDB, "IDBDatabase::transaction - Added active transaction %s", info.identifier().loggingString().utf8().data());
 
-    m_activeTransactions.set(info.identifier(), &transaction.get());
+    m_activeTransactions.set(info.identifier(), transaction.ptr());
 
-    return adoptRef(&transaction.leakRef());
+    return WTFMove(transaction);
 }
 
-RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(const String& objectStore, const String& mode, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBTransaction>> IDBDatabase::transaction(const String& objectStore, const String& mode)
 {
     ASSERT(currentThread() == originThreadID());
 
     Vector<String> objectStores(1);
     objectStores[0] = objectStore;
-    return transaction(objectStores, mode, ec);
+    return transaction(objectStores, mode);
 }
 
-void IDBDatabase::deleteObjectStore(const String& objectStoreName, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBDatabase::deleteObjectStore(const String& objectStoreName)
 {
     LOG(IndexedDB, "IDBDatabase::deleteObjectStore");
 
     ASSERT(currentThread() == originThreadID());
 
-    if (!m_versionChangeTransaction) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.");
-        return;
-    }
+    if (!m_versionChangeTransaction)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The database is not running a version change transaction.") };
 
-    if (!m_versionChangeTransaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        return;
-    }
+    if (!m_versionChangeTransaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError };
 
-    if (!m_info.hasObjectStore(objectStoreName)) {
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The specified object store was not found.");
-        return;
-    }
+    if (!m_info.hasObjectStore(objectStoreName))
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'deleteObjectStore' on 'IDBDatabase': The specified object store was not found.") };
 
     m_info.deleteObjectStore(objectStoreName);
     m_versionChangeTransaction->deleteObjectStore(objectStoreName);
+
+    return { };
 }
 
 void IDBDatabase::close()
index e285fd6..2065e4c 100644 (file)
@@ -55,11 +55,11 @@ public:
     uint64_t version() const;
     RefPtr<DOMStringList> objectStoreNames() const;
 
-    RefPtr<IDBObjectStore> createObjectStore(const String& name, const Dictionary&, ExceptionCodeWithMessage&);
-    RefPtr<IDBObjectStore> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, ExceptionCodeWithMessage&);
-    RefPtr<IDBTransaction> transaction(const Vector<String>&, const String& mode, ExceptionCodeWithMessage&);
-    RefPtr<IDBTransaction> transaction(const String&, const String& mode, ExceptionCodeWithMessage&);
-    void deleteObjectStore(const String& name, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBObjectStore>> createObjectStore(const String& name, const Dictionary&);
+    ExceptionOr<Ref<IDBObjectStore>> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement);
+    ExceptionOr<Ref<IDBTransaction>> transaction(const Vector<String>&, const String& mode);
+    ExceptionOr<Ref<IDBTransaction>> transaction(const String&, const String& mode);
+    ExceptionOr<void> deleteObjectStore(const String& name);
     void close();
 
     // EventTarget
index 9cf1621..5a9a393 100644 (file)
     readonly attribute unsigned long long version;
     readonly attribute DOMStringList objectStoreNames;
 
-    [Custom, MayThrowLegacyExceptionWithMessage] IDBObjectStore createObjectStore(DOMString name, optional Dictionary options);
-    [MayThrowLegacyExceptionWithMessage] void deleteObjectStore(DOMString name);
-    [MayThrowLegacyExceptionWithMessage] IDBTransaction transaction(DOMString storeName, optional DOMString mode = "readonly");
-    [MayThrowLegacyExceptionWithMessage] IDBTransaction transaction(sequence<DOMString> storeNames, optional DOMString mode = "readonly");
+    [Custom, MayThrowException] IDBObjectStore createObjectStore(DOMString name, optional Dictionary options);
+    [MayThrowException] void deleteObjectStore(DOMString name);
+    [MayThrowException] IDBTransaction transaction(DOMString storeName, optional DOMString mode = "readonly");
+    [MayThrowException] IDBTransaction transaction(sequence<DOMString> storeNames, optional DOMString mode = "readonly");
     // FIXME: This is not part of the spec, but is needed for compatibility.
     // See https://github.com/w3c/IndexedDB/issues/85
-    [MayThrowLegacyExceptionWithMessage] IDBTransaction transaction(DOMStringList storeNames, optional DOMString mode = "readonly");
+    [MayThrowException] IDBTransaction transaction(DOMStringList storeNames, optional DOMString mode = "readonly");
     void close();
 
     attribute EventHandler onabort;
index 9db846f..1c440b8 100644 (file)
@@ -76,82 +76,59 @@ IDBFactory::~IDBFactory()
 {
 }
 
-RefPtr<IDBOpenDBRequest> IDBFactory::open(ScriptExecutionContext& context, const String& name, Optional<uint64_t> version, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::open(ScriptExecutionContext& context, const String& name, Optional<uint64_t> version)
 {
     LOG(IndexedDB, "IDBFactory::open");
     
-    if (version && !version.value()) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("IDBFactory.open() called with a version of 0");
-        return nullptr;
-    }
+    if (version && !version.value())
+        return Exception { TypeError, ASCIILiteral("IDBFactory.open() called with a version of 0") };
 
-    return openInternal(context, name, version.valueOr(0), ec);
+    return openInternal(context, name, version.valueOr(0));
 }
 
-RefPtr<IDBOpenDBRequest> IDBFactory::openInternal(ScriptExecutionContext& context, const String& name, unsigned long long version, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::openInternal(ScriptExecutionContext& context, const String& name, unsigned long long version)
 {
-    if (name.isNull()) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("IDBFactory.open() called without a database name");
-        return nullptr;
-    }
+    if (name.isNull())
+        return Exception { TypeError, ASCIILiteral("IDBFactory.open() called without a database name") };
 
-    if (shouldThrowSecurityException(context)) {
-        ec.code = SECURITY_ERR;
-        ec.message = ASCIILiteral("IDBFactory.open() called in an invalid security context");
-        return nullptr;
-    }
+    if (shouldThrowSecurityException(context))
+        return Exception { SECURITY_ERR, ASCIILiteral("IDBFactory.open() called in an invalid security context") };
 
     ASSERT(context.securityOrigin());
     ASSERT(context.topOrigin());
     IDBDatabaseIdentifier databaseIdentifier(name, *context.securityOrigin(), *context.topOrigin());
-    if (!databaseIdentifier.isValid()) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("IDBFactory.open() called with an invalid security origin");
-        return nullptr;
-    }
+    if (!databaseIdentifier.isValid())
+        return Exception { TypeError, ASCIILiteral("IDBFactory.open() called with an invalid security origin") };
 
     return m_connectionProxy->openDatabase(context, databaseIdentifier, version);
 }
 
-RefPtr<IDBOpenDBRequest> IDBFactory::deleteDatabase(ScriptExecutionContext& context, const String& name, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::deleteDatabase(ScriptExecutionContext& context, const String& name)
 {
     LOG(IndexedDB, "IDBFactory::deleteDatabase - %s", name.utf8().data());
 
-    if (name.isNull()) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("IDBFactory.deleteDatabase() called without a database name");
-    }
-    
-    if (shouldThrowSecurityException(context)) {
-        ec.code = SECURITY_ERR;
-        ec.message = ASCIILiteral("IDBFactory.deleteDatabase() called in an invalid security context");
-        return nullptr;
-    }
+    if (name.isNull())
+        return Exception { TypeError, ASCIILiteral("IDBFactory.deleteDatabase() called without a database name") };
+
+    if (shouldThrowSecurityException(context))
+        return Exception { SECURITY_ERR, ASCIILiteral("IDBFactory.deleteDatabase() called in an invalid security context") };
 
     ASSERT(context.securityOrigin());
     ASSERT(context.topOrigin());
     IDBDatabaseIdentifier databaseIdentifier(name, *context.securityOrigin(), *context.topOrigin());
-    if (!databaseIdentifier.isValid()) {
-        ec.code = TypeError;
-        ec.message = ASCIILiteral("IDBFactory.deleteDatabase() called with an invalid security origin");
-        return nullptr;
-    }
+    if (!databaseIdentifier.isValid())
+        return Exception { TypeError, ASCIILiteral("IDBFactory.deleteDatabase() called with an invalid security origin") };
 
     return m_connectionProxy->deleteDatabase(context, databaseIdentifier);
 }
 
-short IDBFactory::cmp(ExecState& execState, JSValue firstValue, JSValue secondValue, ExceptionCodeWithMessage& ec)
+ExceptionOr<short> IDBFactory::cmp(ExecState& execState, JSValue firstValue, JSValue secondValue)
 {
-    Ref<IDBKey> first = scriptValueToIDBKey(execState, firstValue);
-    Ref<IDBKey> second = scriptValueToIDBKey(execState, secondValue);
+    auto first = scriptValueToIDBKey(execState, firstValue);
+    auto second = scriptValueToIDBKey(execState, secondValue);
 
-    if (!first->isValid() || !second->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key.");
-        return 0;
-    }
+    if (!first->isValid() || !second->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key.") };
 
     return first->compare(second.get());
 }
index d6c0a68..43b9369 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "ExceptionOr.h"
 #include <functional>
 #include <wtf/Forward.h>
 #include <wtf/Ref.h>
@@ -44,8 +45,6 @@ class IDBOpenDBRequest;
 class ScriptExecutionContext;
 class SecurityOrigin;
 
-struct ExceptionCodeWithMessage;
-
 namespace IDBClient {
 class IDBConnectionProxy;
 }
@@ -57,17 +56,17 @@ public:
     static Ref<IDBFactory> create(IDBClient::IDBConnectionProxy&);
     ~IDBFactory();
 
-    RefPtr<IDBOpenDBRequest> open(ScriptExecutionContext&, const String& name, Optional<uint64_t> version, ExceptionCodeWithMessage&);
-    RefPtr<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext&, const String& name, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBOpenDBRequest>> open(ScriptExecutionContext&, const String& name, Optional<uint64_t> version);
+    ExceptionOr<Ref<IDBOpenDBRequest>> deleteDatabase(ScriptExecutionContext&, const String& name);
 
-    short cmp(JSC::ExecState&, JSC::JSValue first, JSC::JSValue second, ExceptionCodeWithMessage&);
+    ExceptionOr<short> cmp(JSC::ExecState&, JSC::JSValue first, JSC::JSValue second);
 
     WEBCORE_EXPORT void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)>);
 
 private:
     explicit IDBFactory(IDBClient::IDBConnectionProxy&);
 
-    RefPtr<IDBOpenDBRequest> openInternal(ScriptExecutionContext&, const String& name, unsigned long long version, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBOpenDBRequest>> openInternal(ScriptExecutionContext&, const String& name, unsigned long long version);
 
     Ref<IDBClient::IDBConnectionProxy> m_connectionProxy;
 };
index 3c605a2..e262540 100644 (file)
@@ -28,8 +28,7 @@
     EnabledAtRuntime=IndexedDB,
     SkipVTableValidation,
 ] interface IDBFactory {
-    [CallWith=ScriptExecutionContext, MayThrowLegacyExceptionWithMessage] IDBOpenDBRequest open(DOMString name, [EnforceRange] optional unsigned long long version);
-    [CallWith=ScriptExecutionContext, MayThrowLegacyExceptionWithMessage] IDBOpenDBRequest deleteDatabase(DOMString name);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] short cmp(any first, any second);
+    [CallWith=ScriptExecutionContext, MayThrowException] IDBOpenDBRequest open(DOMString name, [EnforceRange] optional unsigned long long version);
+    [CallWith=ScriptExecutionContext, MayThrowException] IDBOpenDBRequest deleteDatabase(DOMString name);
+    [CallWith=ScriptState, MayThrowException] short cmp(any first, any second);
 };
-
index 40532e9..0430af4 100644 (file)
@@ -102,28 +102,20 @@ bool IDBIndex::multiEntry() const
     return m_info.multiEntry();
 }
 
-RefPtr<IDBRequest> IDBIndex::openCursor(ExecState& execState, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::openCursor(ExecState& execState, IDBKeyRange* range, const String& directionString)
 {
     LOG(IndexedDB, "IDBIndex::openCursor");
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    if (m_deleted || m_objectStore.isDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The index or its object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted || m_objectStore.isDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The index or its object store has been deleted.") };
 
-    if (!m_objectStore.transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_objectStore.transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.") };
 
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
-    if (ec.code) {
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.");
-        return nullptr;
-    }
+    auto direction = IDBCursor::stringToDirection(directionString);
+    if (!direction)
+        return Exception { TypeError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.") };
 
     IDBKeyRangeData rangeData = range;
     if (rangeData.lowerKey.isNull())
@@ -131,196 +123,152 @@ RefPtr<IDBRequest> IDBIndex::openCursor(ExecState& execState, IDBKeyRange* range
     if (rangeData.upperKey.isNull())
         rangeData.upperKey = IDBKeyData::maximum();
 
-    auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), rangeData, direction, IndexedDB::CursorType::KeyAndValue);
+    auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), rangeData, direction.value(), IndexedDB::CursorType::KeyAndValue);
     return m_objectStore.transaction().requestOpenCursor(execState, *this, info);
 }
 
-RefPtr<IDBRequest> IDBIndex::openCursor(ExecState& execState, JSValue key, const String& direction, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::openCursor(ExecState& execState, JSValue key, const String& direction)
 {
     LOG(IndexedDB, "IDBIndex::openCursor");
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(execState, key, ec.code);
-    if (ec.code) {
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The parameter is not a valid key.");
-        return nullptr;
-    }
+    auto keyRange = IDBKeyRange::only(execState, key);
+    if (keyRange.hasException())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The parameter is not a valid key.") };
 
-    return openCursor(execState, keyRange.get(), direction, ec);
+    return openCursor(execState, keyRange.releaseReturnValue().ptr(), direction);
 }
 
-RefPtr<IDBRequest> IDBIndex::count(ExecState& execState, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::count(ExecState& execState, IDBKeyRange* range)
 {
     LOG(IndexedDB, "IDBIndex::count");
 
-    return doCount(execState, range ? IDBKeyRangeData(range) : IDBKeyRangeData::allKeys(), ec);
+    return doCount(execState, range ? IDBKeyRangeData(range) : IDBKeyRangeData::allKeys());
 }
 
-RefPtr<IDBRequest> IDBIndex::count(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::count(ExecState& execState, JSValue key)
 {
     LOG(IndexedDB, "IDBIndex::count");
 
-    Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The parameter is not a valid key.");
-        return nullptr;
-    }
+    auto idbKey = scriptValueToIDBKey(execState, key);
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The parameter is not a valid key.") };
 
-    return doCount(execState, IDBKeyRangeData(idbKey.ptr()), ec);
+    return doCount(execState, IDBKeyRangeData(idbKey.ptr()));
 }
 
-RefPtr<IDBRequest> IDBIndex::doCount(ExecState& execState, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::doCount(ExecState& execState, const IDBKeyRangeData& range)
 {
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    if (m_deleted || m_objectStore.isDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted || m_objectStore.isDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted.") };
 
-    if (!range.isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!range.isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     auto& transaction = m_objectStore.transaction();
-    if (!transaction.isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!transaction.isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.") };
 
     return transaction.requestCount(execState, *this, range);
 }
 
-RefPtr<IDBRequest> IDBIndex::openKeyCursor(ExecState& execState, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::openKeyCursor(ExecState& execState, IDBKeyRange* range, const String& directionString)
 {
     LOG(IndexedDB, "IDBIndex::openKeyCursor");
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    if (m_deleted || m_objectStore.isDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The index or its object store has been deleted.");
-        return nullptr;
-    }
-
-    if (!m_objectStore.transaction().isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.");
-        return nullptr;
-    }
-
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
-    if (ec.code) {
-        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.");
-        return nullptr;
-    }
-
-    auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly);
+    if (m_deleted || m_objectStore.isDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The index or its object store has been deleted.") };
+
+    if (!m_objectStore.transaction().isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.") };
+
+    auto direction = IDBCursor::stringToDirection(directionString);
+    if (!direction)
+        return Exception { TypeError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The direction provided ('invalid-direction') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.") };
+
+    auto info = IDBCursorInfo::indexCursor(m_objectStore.transaction(), m_objectStore.info().identifier(), m_info.identifier(), range, direction.value(), IndexedDB::CursorType::KeyOnly);
     return m_objectStore.transaction().requestOpenCursor(execState, *this, info);
 }
 
-RefPtr<IDBRequest> IDBIndex::openKeyCursor(ExecState& execState, JSValue key, const String& direction, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::openKeyCursor(ExecState& execState, JSValue key, const String& direction)
 {
     LOG(IndexedDB, "IDBIndex::openKeyCursor");
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(execState, key, ec.code);
-    if (ec.code) {
-        ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The parameter is not a valid key.");
-        return nullptr;
-    }
-    return openKeyCursor(execState, keyRange.get(), direction, ec);
+
+    auto keyRange = IDBKeyRange::only(execState, key);
+    if (keyRange.hasException())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The parameter is not a valid key.") };
+    return openKeyCursor(execState, keyRange.releaseReturnValue().ptr(), direction);
 }
 
-RefPtr<IDBRequest> IDBIndex::get(ExecState& execState, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::get(ExecState& execState, IDBKeyRange* range)
 {
     LOG(IndexedDB, "IDBIndex::get");
 
-    return doGet(execState, IDBKeyRangeData(range), ec);
+    return doGet(execState, IDBKeyRangeData(range));
 }
 
-RefPtr<IDBRequest> IDBIndex::get(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::get(ExecState& execState, JSValue key)
 {
     LOG(IndexedDB, "IDBIndex::get");
 
-    Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The parameter is not a valid key.");
-        return nullptr;
-    }
+    auto idbKey = scriptValueToIDBKey(execState, key);
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The parameter is not a valid key.") };
 
-    return doGet(execState, IDBKeyRangeData(idbKey.ptr()), ec);
+    return doGet(execState, IDBKeyRangeData(idbKey.ptr()));
 }
 
-RefPtr<IDBRequest> IDBIndex::doGet(ExecState& execState, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::doGet(ExecState& execState, const IDBKeyRangeData& range)
 {
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    if (m_deleted || m_objectStore.isDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The index or its object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted || m_objectStore.isDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The index or its object store has been deleted.") };
 
-    if (range.isNull) {
-        ec.code = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (range.isNull)
+        return Exception { IDBDatabaseException::DataError };
 
     auto& transaction = m_objectStore.transaction();
-    if (!transaction.isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!transaction.isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.") };
 
     return transaction.requestGetValue(execState, *this, range);
 }
 
-RefPtr<IDBRequest> IDBIndex::getKey(ExecState& execState, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::getKey(ExecState& execState, IDBKeyRange* range)
 {
     LOG(IndexedDB, "IDBIndex::getKey");
 
-    return doGetKey(execState, IDBKeyRangeData(range), ec);
+    return doGetKey(execState, IDBKeyRangeData(range));
 }
 
-RefPtr<IDBRequest> IDBIndex::getKey(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::getKey(ExecState& execState, JSValue key)
 {
     LOG(IndexedDB, "IDBIndex::getKey");
 
-    Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The parameter is not a valid key.");
-        return nullptr;
-    }
+    auto idbKey = scriptValueToIDBKey(execState, key);
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The parameter is not a valid key.") };
 
-    return doGetKey(execState, IDBKeyRangeData(idbKey.ptr()), ec);
+    return doGetKey(execState, IDBKeyRangeData(idbKey.ptr()));
 }
 
-RefPtr<IDBRequest> IDBIndex::doGetKey(ExecState& execState, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBIndex::doGetKey(ExecState& execState, const IDBKeyRangeData& range)
 {
     ASSERT(currentThread() == m_objectStore.transaction().database().originThreadID());
 
-    if (m_deleted || m_objectStore.isDeleted()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The index or its object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted || m_objectStore.isDeleted())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The index or its object store has been deleted.") };
 
-    if (range.isNull) {
-        ec.code = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (range.isNull)
+        return Exception { IDBDatabaseException::DataError };
 
     auto& transaction = m_objectStore.transaction();
-    if (!transaction.isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!transaction.isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.") };
 
     return transaction.requestGetKey(execState, *this, range);
 }
index 6424197..dae695b 100644 (file)
@@ -53,19 +53,19 @@ public:
     bool unique() const;
     bool multiEntry() const;
 
-    RefPtr<IDBRequest> openCursor(JSC::ExecState&, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> openCursor(JSC::ExecState&, JSC::JSValue key, const String& direction, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, IDBKeyRange*, const String& direction);
+    ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, JSC::JSValue key, const String& direction);
 
-    RefPtr<IDBRequest> count(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> count(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, JSC::JSValue key);
 
-    RefPtr<IDBRequest> openKeyCursor(JSC::ExecState&, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> openKeyCursor(JSC::ExecState&, JSC::JSValue key, const String& direction, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> openKeyCursor(JSC::ExecState&, IDBKeyRange*, const String& direction);
+    ExceptionOr<Ref<IDBRequest>> openKeyCursor(JSC::ExecState&, JSC::JSValue key, const String& direction);
 
-    RefPtr<IDBRequest> get(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> get(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> getKey(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> getKey(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> getKey(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> getKey(JSC::ExecState&, JSC::JSValue key);
 
     const IDBIndexInfo& info() const { return m_info; }
 
@@ -78,9 +78,9 @@ public:
     void* objectStoreAsOpaqueRoot() { return &m_objectStore; }
 
 private:
-    RefPtr<IDBRequest> doCount(JSC::ExecState&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> doGet(JSC::ExecState&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> doGetKey(JSC::ExecState&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> doCount(JSC::ExecState&, const IDBKeyRangeData&);
+    ExceptionOr<Ref<IDBRequest>> doGet(JSC::ExecState&, const IDBKeyRangeData&);
+    ExceptionOr<Ref<IDBRequest>> doGetKey(JSC::ExecState&, const IDBKeyRangeData&);
 
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
index 6ffd6d0..8b73bc8 100644 (file)
@@ -26,9 +26,9 @@
 [
     Conditional=INDEXED_DATABASE,
     EnabledAtRuntime=IndexedDB,
-    SkipVTableValidation,
-    JSCustomMarkFunction,
     GenerateIsReachable=Impl,
+    JSCustomMarkFunction,
+    SkipVTableValidation,
 ] interface IDBIndex {
     readonly attribute DOMString name;
     readonly attribute IDBObjectStore objectStore;
     readonly attribute boolean multiEntry;
     readonly attribute boolean unique;
 
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openCursor(any key, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBRequest openCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBRequest openCursor(any key, optional DOMString direction = "next");
 
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openKeyCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openKeyCursor(any key, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBRequest openKeyCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBRequest openKeyCursor(any key, optional DOMString direction = "next");
 
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest get(IDBKeyRange? key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest get(any key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest getKey(IDBKeyRange? key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest getKey(any key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest count(optional IDBKeyRange? range = null);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest count(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest get(IDBKeyRange? key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest get(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest getKey(IDBKeyRange? key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest getKey(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest count(optional IDBKeyRange? range = null);
+    [CallWith=ScriptState, MayThrowException] IDBRequest count(any key);
 };
 
index 4060187..2a5979a 100644 (file)
@@ -62,60 +62,48 @@ IDBKeyRange::~IDBKeyRange()
 {
 }
 
-RefPtr<IDBKeyRange> IDBKeyRange::only(RefPtr<IDBKey>&& key, ExceptionCode& ec)
+ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::only(RefPtr<IDBKey>&& key)
 {
-    if (!key || !key->isValid()) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!key || !key->isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     return create(WTFMove(key));
 }
 
-RefPtr<IDBKeyRange> IDBKeyRange::only(ExecState& state, JSValue keyValue, ExceptionCode& ec)
+ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::only(ExecState& state, JSValue keyValue)
 {
-    return only(scriptValueToIDBKey(state, keyValue), ec);
+    return only(scriptValueToIDBKey(state, keyValue));
 }
 
-RefPtr<IDBKeyRange> IDBKeyRange::lowerBound(ExecState& state, JSValue boundValue, bool open, ExceptionCode& ec)
+ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::lowerBound(ExecState& state, JSValue boundValue, bool open)
 {
     auto bound = scriptValueToIDBKey(state, boundValue);
-    if (!bound->isValid()) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!bound->isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     return create(WTFMove(bound), nullptr, open, true);
 }
 
-RefPtr<IDBKeyRange> IDBKeyRange::upperBound(ExecState& state, JSValue boundValue, bool open, ExceptionCode& ec)
+ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::upperBound(ExecState& state, JSValue boundValue, bool open)
 {
     auto bound = scriptValueToIDBKey(state, boundValue);
-    if (!bound->isValid()) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!bound->isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     return create(nullptr, WTFMove(bound), true, open);
 }
 
-RefPtr<IDBKeyRange> IDBKeyRange::bound(ExecState& state, JSValue lowerValue, JSValue upperValue, bool lowerOpen, bool upperOpen, ExceptionCode& ec)
+ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::bound(ExecState& state, JSValue lowerValue, JSValue upperValue, bool lowerOpen, bool upperOpen)
 {
     auto lower = scriptValueToIDBKey(state, lowerValue);
     auto upper = scriptValueToIDBKey(state, upperValue);
 
-    if (!lower->isValid() || !upper->isValid()) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
-    if (upper->isLessThan(lower.get())) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
-    if (upper->isEqual(lower.get()) && (lowerOpen || upperOpen)) {
-        ec = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!lower->isValid() || !upper->isValid())
+        return Exception { IDBDatabaseException::DataError };
+    if (upper->isLessThan(lower.get()))
+        return Exception { IDBDatabaseException::DataError };
+    if (upper->isEqual(lower.get()) && (lowerOpen || upperOpen))
+        return Exception { IDBDatabaseException::DataError };
 
     return create(WTFMove(lower), WTFMove(upper), lowerOpen, upperOpen);
 }
index f357436..10242de 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "ExceptionOr.h"
 #include "ScriptWrappable.h"
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
@@ -54,13 +55,13 @@ public:
     bool lowerOpen() const { return m_isLowerOpen; }
     bool upperOpen() const { return m_isUpperOpen; }
 
-    static RefPtr<IDBKeyRange> only(RefPtr<IDBKey>&& value, ExceptionCode&);
-    static RefPtr<IDBKeyRange> only(JSC::ExecState&, JSC::JSValue key, ExceptionCode&);
+    static ExceptionOr<Ref<IDBKeyRange>> only(RefPtr<IDBKey>&& value);
+    static ExceptionOr<Ref<IDBKeyRange>> only(JSC::ExecState&, JSC::JSValue key);
 
-    static RefPtr<IDBKeyRange> lowerBound(JSC::ExecState&, JSC::JSValue bound, bool open, ExceptionCode&);
-    static RefPtr<IDBKeyRange> upperBound(JSC::ExecState&, JSC::JSValue bound, bool open, ExceptionCode&);
+    static ExceptionOr<Ref<IDBKeyRange>> lowerBound(JSC::ExecState&, JSC::JSValue bound, bool open);
+    static ExceptionOr<Ref<IDBKeyRange>> upperBound(JSC::ExecState&, JSC::JSValue bound, bool open);
 
-    static RefPtr<IDBKeyRange> bound(JSC::ExecState&, JSC::JSValue lower, JSC::JSValue upper, bool lowerOpen, bool upperOpen, ExceptionCode&);
+    static ExceptionOr<Ref<IDBKeyRange>> bound(JSC::ExecState&, JSC::JSValue lower, JSC::JSValue upper, bool lowerOpen, bool upperOpen);
 
     WEBCORE_EXPORT bool isOnlyKey() const;
 
index 4ac4591..5b6fa57 100644 (file)
@@ -33,8 +33,8 @@
     readonly attribute boolean lowerOpen;
     readonly attribute boolean upperOpen;
 
-    [CallWith=ScriptState, MayThrowLegacyException] static IDBKeyRange only(any value);
-    [CallWith=ScriptState, MayThrowLegacyException] static IDBKeyRange lowerBound(any lower, optional boolean open = false);
-    [CallWith=ScriptState, MayThrowLegacyException] static IDBKeyRange upperBound(any upper, optional boolean open = false);
-    [CallWith=ScriptState, MayThrowLegacyException] static IDBKeyRange bound(any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
+    [CallWith=ScriptState, MayThrowException] static IDBKeyRange only(any value);
+    [CallWith=ScriptState, MayThrowException] static IDBKeyRange lowerBound(any lower, optional boolean open = false);
+    [CallWith=ScriptState, MayThrowException] static IDBKeyRange upperBound(any upper, optional boolean open = false);
+    [CallWith=ScriptState, MayThrowException] static IDBKeyRange bound(any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
 };
index b007d41..94cd707 100644 (file)
@@ -125,116 +125,92 @@ bool IDBObjectStore::autoIncrement() const
     return m_info.autoIncrement();
 }
 
-RefPtr<IDBRequest> IDBObjectStore::openCursor(ExecState& execState, IDBKeyRange* range, const String& directionString, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::openCursor(ExecState& execState, IDBKeyRange* range, const String& directionString)
 {
     LOG(IndexedDB, "IDBObjectStore::openCursor");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec.code);
-    if (ec.code)
-        return nullptr;
+    auto direction = IDBCursor::stringToDirection(directionString);
+    if (!direction)
+        return Exception { TypeError };
 
-    auto info = IDBCursorInfo::objectStoreCursor(m_transaction.get(), m_info.identifier(), range, direction);
+    auto info = IDBCursorInfo::objectStoreCursor(m_transaction.get(), m_info.identifier(), range, direction.value());
     return m_transaction->requestOpenCursor(execState, *this, info);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::openCursor(ExecState& execState, JSValue key, const String& direction, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::openCursor(ExecState& execState, JSValue key, const String& direction)
 {
-    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(execState, key, ec.code);
-    if (ec.code) {
-        ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The parameter is not a valid key.");
-        return 0;
-    }
+    auto onlyResult = IDBKeyRange::only(execState, key);
+    if (onlyResult.hasException())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openCursor' on 'IDBObjectStore': The parameter is not a valid key.") };
 
-    return openCursor(execState, keyRange.get(), direction, ec);
+    return openCursor(execState, onlyResult.releaseReturnValue().ptr(), direction);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::get(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::get(ExecState& execState, JSValue key)
 {
     LOG(IndexedDB, "IDBObjectStore::get");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The object store has been deleted.") };
 
-    Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The parameter is not a valid key.");
-        return nullptr;
-    }
+    auto idbKey = scriptValueToIDBKey(execState, key);
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The parameter is not a valid key.") };
 
     return m_transaction->requestGetRecord(execState, *this, { idbKey.ptr() });
 }
 
-RefPtr<IDBRequest> IDBObjectStore::get(ExecState& execState, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::get(ExecState& execState, IDBKeyRange* keyRange)
 {
     LOG(IndexedDB, "IDBObjectStore::get");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError };
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'get' on 'IDBObjectStore': The object store has been deleted.") };
 
     IDBKeyRangeData keyRangeData(keyRange);
-    if (!keyRangeData.isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!keyRangeData.isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     return m_transaction->requestGetRecord(execState, *this, { keyRangeData });
 }
 
-RefPtr<IDBRequest> IDBObjectStore::add(ExecState& execState, JSValue value, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::add(ExecState& execState, JSValue value, JSValue key)
 {
     RefPtr<IDBKey> idbKey;
     if (!key.isUndefined())
         idbKey = scriptValueToIDBKey(execState, key);
-    return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, InlineKeyCheck::Perform, ec);
+    return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, InlineKeyCheck::Perform);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::put(ExecState& execState, JSValue value, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::put(ExecState& execState, JSValue value, JSValue key)
 {
     RefPtr<IDBKey> idbKey;
     if (!key.isUndefined())
         idbKey = scriptValueToIDBKey(execState, key);
-    return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::Perform, ec);
+    return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, InlineKeyCheck::Perform);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::putForCursorUpdate(ExecState& state, JSValue value, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putForCursorUpdate(ExecState& state, JSValue value, JSValue key)
 {
-    return putOrAdd(state, value, scriptValueToIDBKey(state, key), IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor, InlineKeyCheck::DoNotPerform, ec);
+    return putOrAdd(state, value, scriptValueToIDBKey(state, key), IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor, InlineKeyCheck::DoNotPerform);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::putOrAdd(ExecState& state, JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putOrAdd(ExecState& state, JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck)
 {
     VM& vm = state.vm();
     auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -243,43 +219,29 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(ExecState& state, JSValue value, Ref
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
     auto context = scriptExecutionContextFromExecState(&state);
-    if (!context) {
-        ec.code = IDBDatabaseException::UnknownError;
-        ec.message = ASCIILiteral("Unable to store record in object store because it does not have a valid script execution context");
-        return nullptr;
-    }
+    if (!context)
+        return Exception { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store because it does not have a valid script execution context") };
 
     // The IDB spec for several IDBObjectStore methods states that transaction related exceptions should fire before
     // the exception for an object store being deleted.
     // However, a handful of W3C IDB tests expect the deleted exception even though the transaction inactive exception also applies.
     // Additionally, Chrome and Edge agree with the test, as does Legacy IDB in WebKit.
     // Until this is sorted out, we'll agree with the test and the majority share browsers.
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to store record in an IDBObjectStore: The object store has been deleted.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is inactive or finished.") };
 
-    if (m_transaction->isReadOnly()) {
-        ec.code = IDBDatabaseException::ReadOnlyError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only.");
-        return nullptr;
-    }
+    if (m_transaction->isReadOnly())
+        return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only.") };
 
     RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
     if (UNLIKELY(scope.exception())) {
         // Clear the DOM exception from the serializer so we can give a more targeted exception.
         scope.clearException();
 
-        ec.code = IDBDatabaseException::DataCloneError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: An object could not be cloned.");
-        return nullptr;
+        return Exception { IDBDatabaseException::DataCloneError, ASCIILiteral("Failed to store record in an IDBObjectStore: An object could not be cloned.") };
     }
 
     bool privateBrowsingEnabled = false;
@@ -290,65 +252,45 @@ RefPtr<IDBRequest> IDBObjectStore::putOrAdd(ExecState& state, JSValue value, Ref
 
     if (serializedValue->hasBlobURLs() && privateBrowsingEnabled) {
         // https://bugs.webkit.org/show_bug.cgi?id=156347 - Support Blobs in private browsing.
-        ec.code = IDBDatabaseException::DataCloneError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: BlobURLs are not yet supported.");
-        return nullptr;
+        return Exception { IDBDatabaseException::DataCloneError, ASCIILiteral("Failed to store record in an IDBObjectStore: BlobURLs are not yet supported.") };
     }
 
-    if (key && !key->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The parameter is not a valid key.");
-        return nullptr;
-    }
+    if (key && !key->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to store record in an IDBObjectStore: The parameter is not a valid key.") };
 
     bool usesInlineKeys = !m_info.keyPath().isNull();
     bool usesKeyGenerator = autoIncrement();
     if (usesInlineKeys && inlineKeyCheck == InlineKeyCheck::Perform) {
-        if (key) {
-            ec.code = IDBDatabaseException::DataError;
-            ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The object store uses in-line keys and the key parameter was provided.");
-            return nullptr;
-        }
+        if (key)
+            return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to store record in an IDBObjectStore: The object store uses in-line keys and the key parameter was provided.") };
 
         RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath());
-        if (keyPathKey && !keyPathKey->isValid()) {
-            ec.code = IDBDatabaseException::DataError;
-            ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: Evaluating the object store's key path yielded a value that is not a valid key.");
-            return nullptr;
-        }
+        if (keyPathKey && !keyPathKey->isValid())
+            return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to store record in an IDBObjectStore: Evaluating the object store's key path yielded a value that is not a valid key.") };
 
         if (!keyPathKey) {
-            if (usesKeyGenerator) {
-                if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) {
-                    ec.code = IDBDatabaseException::DataError;
-                    return nullptr;
-                }
-            } else {
-                ec.code = IDBDatabaseException::DataError;
-                ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.");
-                return nullptr;
-            }
+            if (!usesKeyGenerator)
+                return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.") };
+            if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath()))
+                return Exception { IDBDatabaseException::DataError };
         }
 
         if (keyPathKey) {
             ASSERT(!key);
             key = keyPathKey;
         }
-    } else if (!usesKeyGenerator && !key) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.");
-        return nullptr;
-    }
+    } else if (!usesKeyGenerator && !key)
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.") };
 
     return m_transaction->requestPutOrAdd(state, *this, key.get(), *serializedValue, overwriteMode);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::deleteFunction(ExecState& execState, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::deleteFunction(ExecState& execState, IDBKeyRange* keyRange)
 {
-    return doDelete(execState, keyRange, ec);
+    return doDelete(execState, keyRange);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::doDelete(ExecState& execState, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::doDelete(ExecState& execState, IDBKeyRange* keyRange)
 {
     LOG(IndexedDB, "IDBObjectStore::deleteFunction");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
@@ -358,47 +300,31 @@ RefPtr<IDBRequest> IDBObjectStore::doDelete(ExecState& execState, IDBKeyRange* k
     // However, a handful of W3C IDB tests expect the deleted exception even though the transaction inactive exception also applies.
     // Additionally, Chrome and Edge agree with the test, as does Legacy IDB in WebKit.
     // Until this is sorted out, we'll agree with the test and the majority share browsers.
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    if (m_transaction->isReadOnly()) {
-        ec.code = IDBDatabaseException::ReadOnlyError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only.");
-        return nullptr;
-    }
+    if (m_transaction->isReadOnly())
+        return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only.") };
 
     IDBKeyRangeData keyRangeData(keyRange);
-    if (!keyRangeData.isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.");
-        return nullptr;
-    }
+    if (!keyRangeData.isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.") };
 
     return m_transaction->requestDeleteRecord(execState, *this, keyRangeData);
 }
 
-RefPtr<IDBRequest> IDBObjectStore::deleteFunction(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::deleteFunction(ExecState& execState, JSValue key)
 {
     Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key.");
-        return nullptr;
-    }
-
-    return doDelete(execState, &IDBKeyRange::create(WTFMove(idbKey)).get(), ec);
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key.") };
+    return doDelete(execState, IDBKeyRange::create(WTFMove(idbKey)).ptr());
 }
 
-RefPtr<IDBRequest> IDBObjectStore::clear(ExecState& execState, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::clear(ExecState& execState)
 {
     LOG(IndexedDB, "IDBObjectStore::clear");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
@@ -408,72 +334,43 @@ RefPtr<IDBRequest> IDBObjectStore::clear(ExecState& execState, ExceptionCodeWith
     // However, a handful of W3C IDB tests expect the deleted exception even though the transaction inactive exception also applies.
     // Additionally, Chrome and Edge agree with the test, as does Legacy IDB in WebKit.
     // Until this is sorted out, we'll agree with the test and the majority share browsers.
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    if (m_transaction->isReadOnly()) {
-        ec.code = IDBDatabaseException::ReadOnlyError;
-        ec.message = ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is read-only.");
-        return nullptr;
-    }
+    if (m_transaction->isReadOnly())
+        return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to execute 'clear' on 'IDBObjectStore': The transaction is read-only.") };
 
-    Ref<IDBRequest> request = m_transaction->requestClearObjectStore(execState, *this);
-    return adoptRef(request.leakRef());
+    return m_transaction->requestClearObjectStore(execState, *this);
 }
 
-RefPtr<IDBIndex> IDBObjectStore::createIndex(ExecState&, const String& name, const IDBKeyPath& keyPath, const IndexParameters& parameters, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBIndex>> IDBObjectStore::createIndex(ExecState&, const String& name, const IDBKeyPath& keyPath, const IndexParameters& parameters)
 {
     LOG(IndexedDB, "IDBObjectStore::createIndex %s", name.utf8().data());
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isVersionChange()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The database is not running a version change transaction.");
-        return nullptr;
-    }
+    if (!m_transaction->isVersionChange())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The database is not running a version change transaction.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError };
 
-    if (!keyPath.isValid()) {
-        ec.code = IDBDatabaseException::SyntaxError;
-        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument contains an invalid key path.");
-        return nullptr;
-    }
+    if (!keyPath.isValid())
+        return Exception { IDBDatabaseException::SyntaxError, ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument contains an invalid key path.") };
 
-    if (name.isNull()) {
-        ec.code = TypeError;
-        return nullptr;
-    }
+    if (name.isNull())
+        return Exception { TypeError };
 
-    if (m_info.hasIndex(name)) {
-        ec.code = IDBDatabaseException::ConstraintError;
-        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': An index with the specified name already exists.");
-        return nullptr;
-    }
+    if (m_info.hasIndex(name))
+        return Exception { IDBDatabaseException::ConstraintError, ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': An index with the specified name already exists.") };
 
-    if (keyPath.type() == IDBKeyPath::Type::Array && parameters.multiEntry) {
-        ec.code = IDBDatabaseException::InvalidAccessError;
-        ec.message = ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument was an array and the multiEntry option is true.");
-        return nullptr;
-    }
+    if (keyPath.type() == IDBKeyPath::Type::Array && parameters.multiEntry)
+        return Exception { IDBDatabaseException::InvalidAccessError, ASCIILiteral("Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument was an array and the multiEntry option is true.") };
 
     // Install the new Index into the ObjectStore's info.
     IDBIndexInfo info = m_info.createNewIndex(name, keyPath, parameters.unique, parameters.multiEntry);
@@ -481,81 +378,63 @@ RefPtr<IDBIndex> IDBObjectStore::createIndex(ExecState&, const String& name, con
 
     // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side.
     auto index = m_transaction->createIndex(*this, info);
-    RefPtr<IDBIndex> refIndex = index.get();
+
+    Ref<IDBIndex> referencedIndex { *index };
 
     Locker<Lock> locker(m_referencedIndexLock);
     m_referencedIndexes.set(name, WTFMove(index));
 
-    return refIndex;
+    return WTFMove(referencedIndex);
 }
 
-RefPtr<IDBIndex> IDBObjectStore::index(const String& indexName, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBIndex>> IDBObjectStore::index(const String& indexName)
 {
     LOG(IndexedDB, "IDBObjectStore::index");
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
     if (!scriptExecutionContext())
-        return nullptr;
+        return Exception { IDBDatabaseException::InvalidStateError }; // FIXME: Is this code tested? Is iteven reachable?
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (m_transaction->isFinishedOrFinishing()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The transaction is finished.");
-        return nullptr;
-    }
+    if (m_transaction->isFinishedOrFinishing())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The transaction is finished.") };
 
     Locker<Lock> locker(m_referencedIndexLock);
     auto iterator = m_referencedIndexes.find(indexName);
     if (iterator != m_referencedIndexes.end())
-        return iterator->value.get();
+        return Ref<IDBIndex> { *iterator->value };
 
     auto* info = m_info.infoForExistingIndex(indexName);
-    if (!info) {
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The specified index was not found.");
-        return nullptr;
-    }
+    if (!info)
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'index' on 'IDBObjectStore': The specified index was not found.") };
 
     auto index = std::make_unique<IDBIndex>(*scriptExecutionContext(), *info, *this);
-    RefPtr<IDBIndex> refIndex = index.get();
+
+    Ref<IDBIndex> referencedIndex { *index };
+
     m_referencedIndexes.set(indexName, WTFMove(index));
 
-    return refIndex;
+    return WTFMove(referencedIndex);
 }
 
-void IDBObjectStore::deleteIndex(const String& name, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBObjectStore::deleteIndex(const String& name)
 {
     LOG(IndexedDB, "IDBObjectStore::deleteIndex %s", name.utf8().data());
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The object store has been deleted.");
-        return;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isVersionChange()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The database is not running a version change transaction.");
-        return;
-    }
+    if (!m_transaction->isVersionChange())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The database is not running a version change transaction.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError,  ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    if (!m_info.hasIndex(name)) {
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The specified index was not found.");
-        return;
-    }
+    if (!m_info.hasIndex(name))
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'deleteIndex' on 'IDBObjectStore': The specified index was not found.") };
 
     auto* info = m_info.infoForExistingIndex(name);
     ASSERT(info);
@@ -573,30 +452,29 @@ void IDBObjectStore::deleteIndex(const String& name, ExceptionCodeWithMessage& e
     }
 
     m_transaction->deleteIndex(m_info.identifier(), name);
+
+    return { };
 }
 
-RefPtr<IDBRequest> IDBObjectStore::count(ExecState& execState, JSValue key, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::count(ExecState& execState, JSValue key)
 {
     LOG(IndexedDB, "IDBObjectStore::count");
 
     Ref<IDBKey> idbKey = scriptValueToIDBKey(execState, key);
-    if (!idbKey->isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The parameter is not a valid key.");
-        return nullptr;
-    }
+    if (!idbKey->isValid())
+        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The parameter is not a valid key.") };
 
-    return doCount(execState, IDBKeyRangeData(idbKey.ptr()), ec);
+    return doCount(execState, IDBKeyRangeData(idbKey.ptr()));
 }
 
-RefPtr<IDBRequest> IDBObjectStore::count(ExecState& execState, IDBKeyRange* range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::count(ExecState& execState, IDBKeyRange* range)
 {
     LOG(IndexedDB, "IDBObjectStore::count");
 
-    return doCount(execState, range ? IDBKeyRangeData(range) : IDBKeyRangeData::allKeys(), ec);
+    return doCount(execState, range ? IDBKeyRangeData(range) : IDBKeyRangeData::allKeys());
 }
 
-RefPtr<IDBRequest> IDBObjectStore::doCount(ExecState& execState, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBRequest>> IDBObjectStore::doCount(ExecState& execState, const IDBKeyRangeData& range)
 {
     ASSERT(currentThread() == m_transaction->database().originThreadID());
 
@@ -605,22 +483,14 @@ RefPtr<IDBRequest> IDBObjectStore::doCount(ExecState& execState, const IDBKeyRan
     // However, a handful of W3C IDB tests expect the deleted exception even though the transaction inactive exception also applies.
     // Additionally, Chrome and Edge agree with the test, as does Legacy IDB in WebKit.
     // Until this is sorted out, we'll agree with the test and the majority share browsers.
-    if (m_deleted) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The object store has been deleted.");
-        return nullptr;
-    }
+    if (m_deleted)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The object store has been deleted.") };
 
-    if (!m_transaction->isActive()) {
-        ec.code = IDBDatabaseException::TransactionInactiveError;
-        ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The transaction is inactive or finished.");
-        return nullptr;
-    }
+    if (!m_transaction->isActive())
+        return Exception { IDBDatabaseException::TransactionInactiveError, ASCIILiteral("Failed to execute 'count' on 'IDBObjectStore': The transaction is inactive or finished.") };
 
-    if (!range.isValid()) {
-        ec.code = IDBDatabaseException::DataError;
-        return nullptr;
-    }
+    if (!range.isValid())
+        return Exception { IDBDatabaseException::DataError };
 
     return m_transaction->requestCount(execState, *this, range);
 }
index 3ecb901..5750b98 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(INDEXED_DATABASE)
 
 #include "ActiveDOMObject.h"
+#include "ExceptionOr.h"
 #include "IDBObjectStoreInfo.h"
 #include <wtf/HashSet.h>
 
@@ -46,7 +47,6 @@ class IDBKeyRange;
 class IDBRequest;
 class IDBTransaction;
 
-struct ExceptionCodeWithMessage;
 struct IDBKeyRangeData;
 
 namespace IndexedDB {
@@ -70,22 +70,22 @@ public:
         bool multiEntry;
     };
 
-    RefPtr<IDBRequest> openCursor(JSC::ExecState&, IDBKeyRange*, const String& direction, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> openCursor(JSC::ExecState&, JSC::JSValue key, const String& direction, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> get(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> get(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> deleteFunction(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> deleteFunction(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> clear(JSC::ExecState&, ExceptionCodeWithMessage&);
-    RefPtr<IDBIndex> createIndex(JSC::ExecState&, const String& name, const IDBKeyPath&, const IndexParameters&, ExceptionCodeWithMessage&);
-    RefPtr<IDBIndex> index(const String& name, ExceptionCodeWithMessage&);
-    void deleteIndex(const String& name, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> count(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> count(JSC::ExecState&, JSC::JSValue key, ExceptionCodeWithMessage&);
-
-    RefPtr<IDBRequest> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, IDBKeyRange*, const String& direction);
+    ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, JSC::JSValue key, const String& direction);
+    ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> deleteFunction(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> deleteFunction(JSC::ExecState&, JSC::JSValue key);
+    ExceptionOr<Ref<IDBRequest>> clear(JSC::ExecState&);
+    ExceptionOr<Ref<IDBIndex>> createIndex(JSC::ExecState&, const String& name, const IDBKeyPath&, const IndexParameters&);
+    ExceptionOr<Ref<IDBIndex>> index(const String& name);
+    ExceptionOr<void> deleteIndex(const String& name);
+    ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, IDBKeyRange*);
+    ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, JSC::JSValue key);
+
+    ExceptionOr<Ref<IDBRequest>> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
 
     void markAsDeleted();
     bool isDeleted() const { return m_deleted; }
@@ -100,9 +100,9 @@ private:
     IDBObjectStore(ScriptExecutionContext&, const IDBObjectStoreInfo&, IDBTransaction&);
 
     enum class InlineKeyCheck { Perform, DoNotPerform };
-    RefPtr<IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> doCount(JSC::ExecState&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
-    RefPtr<IDBRequest> doDelete(JSC::ExecState&, IDBKeyRange*, ExceptionCodeWithMessage&);
+    ExceptionOr<Ref<IDBRequest>> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck);
+    ExceptionOr<Ref<IDBRequest>> doCount(JSC::ExecState&, const IDBKeyRangeData&);
+    ExceptionOr<Ref<IDBRequest>> doDelete(JSC::ExecState&, IDBKeyRange*);
 
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
index 1559d31..2f5532d 100644 (file)
     readonly attribute IDBTransaction transaction;
     readonly attribute boolean autoIncrement;
 
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest put(any value, optional any key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest add(any value, optional any key);
-    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowLegacyExceptionWithMessage] IDBRequest delete(IDBKeyRange? keyRange);
-    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowLegacyExceptionWithMessage] IDBRequest delete(any key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest get(IDBKeyRange? key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest get(any key);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest clear();
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest openCursor(any key, optional DOMString direction = "next");
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBIndex createIndex(DOMString name, sequence<DOMString> keyPath, optional IDBIndexParameters options);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBIndex createIndex(DOMString name, DOMString keyPath, optional IDBIndexParameters options);
-    [MayThrowLegacyExceptionWithMessage] IDBIndex index(DOMString name);
-    [MayThrowLegacyExceptionWithMessage] void deleteIndex(DOMString name);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest count(optional IDBKeyRange? range = null);
-    [CallWith=ScriptState, MayThrowLegacyExceptionWithMessage] IDBRequest count(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest put(any value, optional any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest add(any value, optional any key);
+    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowException] IDBRequest delete(IDBKeyRange? keyRange);
+    [CallWith=ScriptState, ImplementedAs=deleteFunction, MayThrowException] IDBRequest delete(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest get(IDBKeyRange? key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest get(any key);
+    [CallWith=ScriptState, MayThrowException] IDBRequest clear();
+    [CallWith=ScriptState, MayThrowException] IDBRequest openCursor(optional IDBKeyRange? range = null, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBRequest openCursor(any key, optional DOMString direction = "next");
+    [CallWith=ScriptState, MayThrowException] IDBIndex createIndex(DOMString name, sequence<DOMString> keyPath, optional IDBIndexParameters options);
+    [CallWith=ScriptState, MayThrowException] IDBIndex createIndex(DOMString name, DOMString keyPath, optional IDBIndexParameters options);
+    [MayThrowException] IDBIndex index(DOMString name);
+    [MayThrowException] void deleteIndex(DOMString name);
+    [CallWith=ScriptState, MayThrowException] IDBRequest count(optional IDBKeyRange? range = null);
+    [CallWith=ScriptState, MayThrowException] IDBRequest count(any key);
 };
 
 dictionary IDBIndexParameters {
index 0691b6f..1300f68 100644 (file)
@@ -126,23 +126,14 @@ IDBRequest::~IDBRequest()
         m_cursorResult->clearRequest();
 }
 
-unsigned short IDBRequest::errorCode(ExceptionCode&) const
+ExceptionOr<DOMError*> IDBRequest::error() const
 {
     ASSERT(currentThread() == originThreadID());
 
-    return 0;
-}
-
-RefPtr<DOMError> IDBRequest::error(ExceptionCodeWithMessage& ec) const
-{
-    ASSERT(currentThread() == originThreadID());
-
-    if (m_isDone)
-        return m_domError;
+    if (!m_isDone)
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to read the 'error' property from 'IDBRequest': The request has not finished.") };
 
-    ec.code = IDBDatabaseException::InvalidStateError;
-    ec.message = ASCIILiteral("Failed to read the 'error' property from 'IDBRequest': The request has not finished.");
-    return nullptr;
+    return m_domError.get();
 }
 
 void IDBRequest::setSource(IDBCursor& cursor)
index 520464e..650c8d0 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(INDEXED_DATABASE)
 
 #include "EventTarget.h"
+#include "ExceptionOr.h"
 #include "IDBActiveDOMObject.h"
 #include "IDBError.h"
 #include "IDBResourceIdentifier.h"
@@ -66,8 +67,7 @@ public:
     IDBCursor* cursorResult() const { return m_cursorResult.get(); }
     IDBDatabase* databaseResult() const { return m_databaseResult.get(); }
     JSC::JSValue scriptResult() const { return m_scriptResult.get(); }
-    unsigned short errorCode(ExceptionCode&) const;
-    RefPtr<DOMError> error(ExceptionCodeWithMessage&) const;
+    ExceptionOr<DOMError*> error() const;
     IDBObjectStore* objectStoreSource() const { return m_objectStoreSource.get(); }
     IDBIndex* indexSource() const { return m_indexSource.get(); }
     IDBCursor* cursorSource() const { return m_cursorSource.get(); }
index 398e165..cdf45b0 100644 (file)
@@ -35,7 +35,7 @@
     SkipVTableValidation,
 ] interface IDBRequest : EventTarget {
     [CustomGetter] readonly attribute any result;
-    [GetterMayThrowLegacyExceptionWithMessage] readonly attribute DOMError error;
+    [GetterMayThrowException] readonly attribute DOMError? error;
     [CustomGetter] readonly attribute any source;
     readonly attribute IDBTransaction transaction;
     readonly attribute DOMString readyState;
index f9e8bfa..77c5499 100644 (file)
@@ -88,16 +88,14 @@ const AtomicString& IDBTransaction::modeReadWriteLegacy()
     return readwrite;
 }
 
-IndexedDB::TransactionMode IDBTransaction::stringToMode(const String& modeString, ExceptionCode& ec)
+Optional<IndexedDB::TransactionMode> IDBTransaction::stringToMode(const String& modeString)
 {
-    if (modeString.isNull()
-        || modeString == IDBTransaction::modeReadOnly())
+    if (modeString.isNull() || modeString == IDBTransaction::modeReadOnly())
         return IndexedDB::TransactionMode::ReadOnly;
     if (modeString == IDBTransaction::modeReadWrite())
         return IndexedDB::TransactionMode::ReadWrite;
 
-    ec = TypeError;
-    return IndexedDB::TransactionMode::ReadOnly;
+    return Nullopt;
 }
 
 const AtomicString& IDBTransaction::modeToString(IndexedDB::TransactionMode mode)
@@ -186,35 +184,32 @@ const String& IDBTransaction::mode() const
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-WebCore::IDBDatabase* IDBTransaction::db()
+IDBDatabase* IDBTransaction::db()
 {
     ASSERT(currentThread() == m_database->originThreadID());
-    return &m_database.get();
+    return m_database.ptr();
 }
 
-RefPtr<DOMError> IDBTransaction::error() const
+DOMError* IDBTransaction::error() const
 {
     ASSERT(currentThread() == m_database->originThreadID());
-    return m_domError;
+    return m_domError.get();
 }
 
-RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& objectStoreName, ExceptionCodeWithMessage& ec)
+ExceptionOr<Ref<IDBObjectStore>> IDBTransaction::objectStore(const String& objectStoreName)
 {
     LOG(IndexedDB, "IDBTransaction::objectStore");
     ASSERT(currentThread() == m_database->originThreadID());
 
     if (!scriptExecutionContext())
-        return nullptr;
+        return Exception { IDBDatabaseException::InvalidStateError };
 
-    if (isFinishedOrFinishing()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The transaction finished.");
-        return nullptr;
-    }
+    if (isFinishedOrFinishing())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The transaction finished.") };
 
     auto iterator = m_referencedObjectStores.find(objectStoreName);
     if (iterator != m_referencedObjectStores.end())
-        return iterator->value;
+        return Ref<IDBObjectStore> { *iterator->value };
 
     bool found = false;
     for (auto& objectStore : m_info.objectStores()) {
@@ -225,23 +220,17 @@ RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& object
     }
 
     auto* info = m_database->info().infoForExistingObjectStore(objectStoreName);
-    if (!info) {
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.");
-        return nullptr;
-    }
+    if (!info)
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.") };
 
     // Version change transactions are scoped to every object store in the database.
-    if (!info || (!found && !isVersionChange())) {
-        ec.code = IDBDatabaseException::NotFoundError;
-        ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.");
-        return nullptr;
-    }
+    if (!info || (!found && !isVersionChange()))
+        return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.") };
 
     auto objectStore = IDBObjectStore::create(*scriptExecutionContext(), *info, *this);
-    m_referencedObjectStores.set(objectStoreName, &objectStore.get());
+    m_referencedObjectStores.set(objectStoreName, objectStore.ptr());
 
-    return adoptRef(&objectStore.leakRef());
+    return WTFMove(objectStore);
 }
 
 
@@ -254,8 +243,7 @@ void IDBTransaction::abortDueToFailedRequest(DOMError& error)
         return;
 
     m_domError = &error;
-    ExceptionCodeWithMessage ec;
-    abort(ec);
+    internalAbort();
 }
 
 void IDBTransaction::transitionedToFinishing(IndexedDB::TransactionState state)
@@ -268,16 +256,24 @@ void IDBTransaction::transitionedToFinishing(IndexedDB::TransactionState state)
     m_referencedObjectStores.clear();
 }
 
-void IDBTransaction::abort(ExceptionCodeWithMessage& ec)
+ExceptionOr<void> IDBTransaction::abort()
 {
     LOG(IndexedDB, "IDBTransaction::abort");
     ASSERT(currentThread() == m_database->originThreadID());
 
-    if (isFinishedOrFinishing()) {
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.");
-        return;
-    }
+    if (isFinishedOrFinishing())
+        return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished.") };
+
+    internalAbort();
+
+    return { };
+}
+
+void IDBTransaction::internalAbort()
+{
+    LOG(IndexedDB, "IDBTransaction::internalAbort");
+    ASSERT(currentThread() == m_database->originThreadID());
+    ASSERT(!isFinishedOrFinishing());
 
     m_database->willAbortTransaction(*this);
 
@@ -290,8 +286,7 @@ void IDBTransaction::abort(ExceptionCodeWithMessage& ec)
     
     m_abortQueue.swap(m_transactionOperationQueue);
 
-    auto operation = IDBClient::createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServerAndCancelRequests);
-    scheduleOperation(WTFMove(operation));
+    scheduleOperation(IDBClient::createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServerAndCancelRequests));
 }
 
 void IDBTransaction::abortOnServerAndCancelRequests(IDBClient::TransactionOperation& operation)
@@ -348,8 +343,7 @@ void IDBTransaction::stop()
     if (isFinishedOrFinishing())
         return;
 
-    ExceptionCodeWithMessage ec;
-    abort(ec);
+    internalAbort();
 }
 
 bool IDBTransaction::isActive() const
index 0487ac0..ae7eb25 100644 (file)
@@ -69,7 +69,7 @@ public:
     static const AtomicString& modeReadOnlyLegacy();
     static const AtomicString& modeReadWriteLegacy();
 
-    static IndexedDB::TransactionMode stringToMode(const String&, ExceptionCode&);
+    static Optional<IndexedDB::TransactionMode> stringToMode(const String&);
     static const AtomicString& modeToString(IndexedDB::TransactionMode);
 
     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
@@ -80,9 +80,9 @@ public:
     // IDBTransaction IDL
     const String& mode() const;
     IDBDatabase* db();
-    RefPtr<DOMError> error() const;
-    RefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCodeWithMessage&);
-    void abort(ExceptionCodeWithMessage&);
+    DOMError* error() const;
+    ExceptionOr<Ref<IDBObjectStore>> objectStore(const String& name);
+    ExceptionOr<void> abort();
 
     EventTargetInterface eventTargetInterface() const final { return IDBTransactionEventTargetInterfaceType; }
     ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
@@ -152,6 +152,7 @@ private:
 
     void commit();
 
+    void internalAbort();
     void notifyDidAbort(const IDBError&);
     void finishAbortOrCommit();
 
index 57a2c70..8ebae82 100644 (file)
@@ -25,8 +25,8 @@
  */
 
 [
-    Conditional=INDEXED_DATABASE,
     ActiveDOMObject,
+    Conditional=INDEXED_DATABASE,
     EnabledAtRuntime=IndexedDB,
     SkipVTableValidation,
 ] interface IDBTransaction : EventTarget {
@@ -34,8 +34,8 @@
     readonly attribute IDBDatabase db;
     readonly attribute DOMError error;
 
-    [MayThrowLegacyExceptionWithMessage] IDBObjectStore objectStore (DOMString name);
-    [MayThrowLegacyExceptionWithMessage] void abort ();
+    [MayThrowException] IDBObjectStore objectStore(DOMString name);
+    [MayThrowException] void abort();
 
     attribute EventHandler onabort;
     attribute EventHandler oncomplete;
index ee1db06..37d22b2 100644 (file)
@@ -59,7 +59,7 @@ void IDBConnectionProxy::deref()
     m_connectionToServer.deref();
 }
 
-RefPtr<IDBOpenDBRequest> IDBConnectionProxy::openDatabase(ScriptExecutionContext& context, const IDBDatabaseIdentifier& databaseIdentifier, uint64_t version)
+Ref<IDBOpenDBRequest> IDBConnectionProxy::openDatabase(ScriptExecutionContext& context, const IDBDatabaseIdentifier& databaseIdentifier, uint64_t version)
 {
     RefPtr<IDBOpenDBRequest> request;
     {
@@ -72,10 +72,10 @@ RefPtr<IDBOpenDBRequest> IDBConnectionProxy::openDatabase(ScriptExecutionContext
 
     callConnectionOnMainThread(&IDBConnectionToServer::openDatabase, IDBRequestData(*this, *request));
 
-    return request;
+    return request.releaseNonNull();
 }
 
-RefPtr<IDBOpenDBRequest> IDBConnectionProxy::deleteDatabase(ScriptExecutionContext& context, const IDBDatabaseIdentifier& databaseIdentifier)
+Ref<IDBOpenDBRequest> IDBConnectionProxy::deleteDatabase(ScriptExecutionContext& context, const IDBDatabaseIdentifier& databaseIdentifier)
 {
     RefPtr<IDBOpenDBRequest> request;
     {
@@ -88,7 +88,7 @@ RefPtr<IDBOpenDBRequest> IDBConnectionProxy::deleteDatabase(ScriptExecutionConte
 
     callConnectionOnMainThread(&IDBConnectionToServer::deleteDatabase, IDBRequestData(*this, *request));
 
-    return request;
+    return request.releaseNonNull();
 }
 
 void IDBConnectionProxy::didOpenDatabase(const IDBResultData& resultData)
index 4cac4f4..15aa0e2 100644 (file)
@@ -60,10 +60,10 @@ class IDBConnectionProxy {
 public:
     IDBConnectionProxy(IDBConnectionToServer&);
 
-    RefPtr<IDBOpenDBRequest> openDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&, uint64_t version);
+    Ref<IDBOpenDBRequest> openDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&, uint64_t version);
     void didOpenDatabase(const IDBResultData&);
 
-    RefPtr<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&);
+    Ref<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&);
     void didDeleteDatabase(const IDBResultData&);
 
     void createObjectStore(TransactionOperation&, const IDBObjectStoreInfo&);
index 41011e5..4444a3a 100644 (file)
@@ -322,12 +322,12 @@ void MediaEndpointPeerConnection::setLocalDescriptionTask(RefPtr<RTCSessionDescr
     if (m_client->internalSignalingState() == SignalingState::Closed)
         return;
 
-    ExceptionCodeWithMessage exception;
-    auto newDescription = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor, exception);
-    if (exception.code) {
-        promise.reject(exception.code, exception.message);
+    auto result = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor);
+    if (result.hasException()) {
+        promise.reject(result.releaseException());
         return;
     }
+    auto newDescription = result.releaseReturnValue();
 
     if (!localDescriptionTypeValidForState(newDescription->type())) {
         promise.reject(INVALID_STATE_ERR, "Description type incompatible with current signaling state");
@@ -389,12 +389,12 @@ void MediaEndpointPeerConnection::setLocalDescriptionTask(RefPtr<RTCSessionDescr
     // Update state and local descriptions according to setLocal/RemoteDescription processing model
     switch (newDescription->type()) {
     case RTCSessionDescription::SdpType::Offer:
-        m_pendingLocalDescription = newDescription;
+        m_pendingLocalDescription = WTFMove(newDescription);
         newSignalingState = SignalingState::HaveLocalOffer;
         break;
 
     case RTCSessionDescription::SdpType::Answer:
-        m_currentLocalDescription = newDescription;
+        m_currentLocalDescription = WTFMove(newDescription);
         m_currentRemoteDescription = m_pendingRemoteDescription;
         m_pendingLocalDescription = nullptr;
         m_pendingRemoteDescription = nullptr;
@@ -407,7 +407,7 @@ void MediaEndpointPeerConnection::setLocalDescriptionTask(RefPtr<RTCSessionDescr
         break;
 
     case RTCSessionDescription::SdpType::Pranswer:
-        m_pendingLocalDescription = newDescription;
+        m_pendingLocalDescription = WTFMove(newDescription);
         newSignalingState = SignalingState::HaveLocalPrAnswer;
         break;
     }
@@ -453,12 +453,12 @@ void MediaEndpointPeerConnection::setRemoteDescriptionTask(RefPtr<RTCSessionDesc
     if (m_client->internalSignalingState() == SignalingState::Closed)
         return;
 
-    ExceptionCodeWithMessage exception;
-    auto newDescription = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor, exception);
-    if (exception.code) {
-        promise.reject(exception.code, exception.message);
+    auto result = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor);
+    if (result.hasException()) {
+        promise.reject(result.releaseException());
         return;
     }
+    auto newDescription = result.releaseReturnValue();
 
     if (!remoteDescriptionTypeValidForState(newDescription->type())) {
         promise.reject(INVALID_STATE_ERR, "Description type incompatible with current signaling state");
@@ -564,12 +564,12 @@ void MediaEndpointPeerConnection::setRemoteDescriptionTask(RefPtr<RTCSessionDesc
     // Update state and local descriptions according to setLocal/RemoteDescription processing model
     switch (newDescription->type()) {
     case RTCSessionDescription::SdpType::Offer:
-        m_pendingRemoteDescription = newDescription;
+        m_pendingRemoteDescription = WTFMove(newDescription);
         newSignalingState = SignalingState::HaveRemoteOffer;
         break;
 
     case RTCSessionDescription::SdpType::Answer:
-        m_currentRemoteDescription = newDescription;
+        m_currentRemoteDescription = WTFMove(newDescription);
         m_currentLocalDescription = m_pendingLocalDescription;
         m_pendingRemoteDescription = nullptr;
         m_pendingLocalDescription = nullptr;
@@ -582,7 +582,7 @@ void MediaEndpointPeerConnection::setRemoteDescriptionTask(RefPtr<RTCSessionDesc
         break;
 
     case RTCSessionDescription::SdpType::Pranswer:
-        m_pendingRemoteDescription = newDescription;
+        m_pendingRemoteDescription = WTFMove(newDescription);
         newSignalingState = SignalingState::HaveRemotePrAnswer;
         break;
     }
index 7095d7e..354fcd6 100644 (file)
@@ -55,23 +55,17 @@ Ref<MediaEndpointSessionDescription> MediaEndpointSessionDescription::create(RTC
     return adoptRef(*new MediaEndpointSessionDescription(type, WTFMove(configuration), nullptr));
 }
 
-RefPtr<MediaEndpointSessionDescription> MediaEndpointSessionDescription::create(RefPtr<RTCSessionDescription>&& rtcDescription, const SDPProcessor& sdpProcessor, ExceptionCodeWithMessage& exception)
+ExceptionOr<Ref<MediaEndpointSessionDescription>> MediaEndpointSessionDescription::create(RefPtr<RTCSessionDescription>&& rtcDescription, const SDPProcessor& sdpProcessor)
 {
     RefPtr<MediaEndpointSessionConfiguration> configuration;
-    SDPProcessor::Result result = sdpProcessor.parse(rtcDescription->sdp(), configuration);
+    auto result = sdpProcessor.parse(rtcDescription->sdp(), configuration);
     if (result != SDPProcessor::Result::Success) {
-        if (result == SDPProcessor::Result::ParseError) {
-            exception.code = INVALID_ACCESS_ERR;
-            exception.message = ASCIILiteral("SDP content is invalid");
-            return nullptr;
-        }
+        if (result == SDPProcessor::Result::ParseError)
+            return Exception { INVALID_ACCESS_ERR, ASCIILiteral("SDP content is invalid") };
         LOG_ERROR("SDPProcessor internal error");
-        exception.code = ABORT_ERR;
-        exception.message = ASCIILiteral("Internal error");
-        return nullptr;
+        return Exception { ABORT_ERR, ASCIILiteral("Internal error") };
     }
-
-    return adoptRef(new MediaEndpointSessionDescription(rtcDescription->type(), WTFMove(configuration), WTFMove(rtcDescription)));
+    return adoptRef(*new MediaEndpointSessionDescription(rtcDescription->type(), WTFMove(configuration), WTFMove(rtcDescription)));
 }
 
 RefPtr<RTCSessionDescription> MediaEndpointSessionDescription::toRTCSessionDescription(const SDPProcessor& sdpProcessor) const
index ecaa2bb..60316ce 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef MediaEndpointSessionDescription_h
-#define MediaEndpointSessionDescription_h
+#pragma once
 
 #if ENABLE(WEB_RTC)
 
+#include "ExceptionOr.h"
 #include "RTCSessionDescription.h"
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
@@ -46,8 +46,8 @@ class DOMError;
 class MediaEndpointSessionDescription : public RefCounted<MediaEndpointSessionDescription> {
 public:
     static Ref<MediaEndpointSessionDescription> create(RTCSessionDescription::SdpType, RefPtr<MediaEndpointSessionConfiguration>&&);
-    static RefPtr<MediaEndpointSessionDescription> create(RefPtr<RTCSessionDescription>&&, const SDPProcessor&, ExceptionCodeWithMessage&);
-    virtual ~MediaEndpointSessionDescription() { }
+    static ExceptionOr<Ref<MediaEndpointSessionDescription>> create(RefPtr<RTCSessionDescription>&&, const SDPProcessor&);
+    virtual ~MediaEndpointSessionDescription() { } // FIXME: Why is this virtual? There are no other virtual functions in this class.
 
     RefPtr<RTCSessionDescription> toRTCSessionDescription(const SDPProcessor&) const;
 
@@ -73,5 +73,3 @@ private:
 } // namespace WebCore
 
 #endif // ENABLE(WEB_RTC)
-
-#endif // MediaEndpointSessionDescription_h
index 6896b9b..a9e2b21 100644 (file)
@@ -335,22 +335,21 @@ JSValue createDOMException(ExecState* exec, ExceptionCode ec, const String& mess
     return createDOMException(exec, ec, &message);
 }
 
-ALWAYS_INLINE static void throwDOMException(ExecState* exec, ThrowScope& throwScope, ExceptionCode ec)
+JSValue createDOMException(ExecState& state, Exception&& exception)
 {
-    ASSERT(ec && !throwScope.exception());
-    throwException(exec, throwScope, createDOMException(exec, ec));
+    return createDOMException(&state, exception.code(), exception.releaseMessage());
 }
 
-ALWAYS_INLINE static void throwDOMException(ExecState* exec, ThrowScope& throwScope, const ExceptionCodeWithMessage& ec)
+ALWAYS_INLINE static void throwDOMException(ExecState* exec, ThrowScope& throwScope, ExceptionCode ec)
 {
-    ASSERT(ec.code && !throwScope.exception());
-    throwException(exec, throwScope, createDOMException(exec, ec.code, ec.message));
+    ASSERT(ec && !throwScope.exception());
+    throwException(exec, throwScope, createDOMException(exec, ec));
 }
 
 void propagateExceptionSlowPath(JSC::ExecState& state, JSC::ThrowScope& throwScope, Exception&& exception)
 {
     ASSERT(!throwScope.exception());
-    throwException(&state, throwScope, createDOMException(&state, exception.code(), exception.releaseMessage()));
+    throwException(&state, throwScope, createDOMException(state, WTFMove(exception)));
 }
 
 void propagateException(JSC::ExecState& state, Exception&& exception)
@@ -365,11 +364,6 @@ void setDOMExceptionSlow(ExecState* exec, ThrowScope& throwScope, ExceptionCode
     throwDOMException(exec, throwScope, ec);
 }
 
-void setDOMExceptionSlow(ExecState* exec, ThrowScope& throwScope, const ExceptionCodeWithMessage& ec)
-{
-    throwDOMException(exec, throwScope, ec);
-}
-
 void setDOMException(ExecState* exec, ExceptionCode ec)
 {
     VM& vm = exec->vm();
@@ -381,17 +375,6 @@ void setDOMException(ExecState* exec, ExceptionCode ec)
     throwDOMException(exec, scope, ec);
 }
 
-void setDOMException(ExecState* exec, const ExceptionCodeWithMessage& ec)
-{
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (!ec.code || scope.exception())
-        return;
-
-    throwDOMException(exec, scope, ec);
-}
-
 bool hasIteratorMethod(JSC::ExecState& state, JSC::JSValue value)
 {
     auto& vm = state.vm();
index a12f1de..2408b68 100644 (file)
@@ -181,22 +181,20 @@ WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::JSValue exception, Cac
 WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::Exception*, CachedScript* = nullptr, ExceptionDetails* = nullptr);
 void reportCurrentException(JSC::ExecState*);
 
+JSC::JSValue createDOMException(JSC::ExecState&, Exception&&);
 JSC::JSValue createDOMException(JSC::ExecState*, ExceptionCode, const String&);
 
 // Convert a DOM implementation exception into a JavaScript exception in the execution state.
 void propagateException(JSC::ExecState&, JSC::ThrowScope&, Exception&&);
 void setDOMException(JSC::ExecState*, JSC::ThrowScope&, ExceptionCode);
-void setDOMException(JSC::ExecState*, JSC::ThrowScope&, const ExceptionCodeWithMessage&);
 
 // Slower versions of the above for use when the caller doesn't have a ThrowScope.
 void propagateException(JSC::ExecState&, Exception&&);
 WEBCORE_EXPORT void setDOMException(JSC::ExecState*, ExceptionCode);
-void setDOMException(JSC::ExecState*, const ExceptionCodeWithMessage&);
 
 // Implementation details of the above.
-WEBCORE_EXPORT void setDOMExceptionSlow(JSC::ExecState*, JSC::ThrowScope&, ExceptionCode);
-void setDOMExceptionSlow(JSC::ExecState*, JSC::ThrowScope&, const ExceptionCodeWithMessage&);
 void propagateExceptionSlowPath(JSC::ExecState&, JSC::ThrowScope&, Exception&&);
+WEBCORE_EXPORT void setDOMExceptionSlow(JSC::ExecState*, JSC::ThrowScope&, ExceptionCode);
 
 JSC::JSValue jsString(JSC::ExecState*, const URL&); // empty if the URL is null
 
@@ -364,8 +362,8 @@ JSC::JSValue toJSDate(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<double>&&);
 JSC::JSValue toJSNullableDate(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<Optional<double>>&&);
 JSC::JSValue toJSNullableString(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<String>&&);
 template<typename T> JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<T>&& value);
-template<typename T> JSC::JSValue toJSNumber(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<T>&& value);
-template<typename T> JSC::JSValue toJSNullableNumber(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<T>&& value);
+template<typename T> JSC::JSValue toJSNumber(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<T>&& value);
+template<typename T> JSC::JSValue toJSNullableNumber(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<T>&& value);
 JSC::JSValue toJSString(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<String>&&);
 
 // Inline functions and template definitions.
@@ -903,13 +901,6 @@ ALWAYS_INLINE void setDOMException(JSC::ExecState* exec, JSC::ThrowScope& throwS
     setDOMExceptionSlow(exec, throwScope, ec);
 }
 
-ALWAYS_INLINE void setDOMException(JSC::ExecState* exec, JSC::ThrowScope& throwScope, const ExceptionCodeWithMessage& exception)
-{
-    if (LIKELY(!exception.code || throwScope.exception()))
-        return;
-    setDOMExceptionSlow(exec, throwScope, exception);
-}
-
 inline void propagateException(JSC::ExecState& state, JSC::ThrowScope& throwScope, ExceptionOr<void>&& value)
 {
     if (UNLIKELY(value.hasException()))
@@ -934,4 +925,13 @@ template<typename T> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState& state,
     return toJSNewlyCreated(&state, &globalObject, value.releaseReturnValue());
 }
 
+template<typename T> inline JSC::JSValue toJSNumber(JSC::ExecState& state, JSC::ThrowScope& throwScope, ExceptionOr<T>&& value)
+{
+    if (UNLIKELY(value.hasException())) {
+        propagateException(state, throwScope, value.releaseException());
+        return { };
+    }
+    return JSC::jsNumber(value.releaseReturnValue());
+}
+
 } // namespace WebCore
index c4624d4..292e73f 100644 (file)
@@ -89,6 +89,18 @@ void DeferredPromise::callFunction(ExecState& exec, JSValue function, JSValue re
     clear();
 }
 
+void DeferredPromise::reject(Exception&& exception)
+{
+    if (isSuspended())
+        return;
+
+    ASSERT(m_deferred);
+    ASSERT(m_globalObject);
+    auto& state = *m_globalObject->globalExec();
+    JSC::JSLockHolder locker(&state);
+    reject(state, createDOMException(state, WTFMove(exception)));
+}
+
 void DeferredPromise::reject(ExceptionCode ec, const String& message)
 {
     if (isSuspended())
index f587cb3..241271f 100644 (file)
@@ -125,6 +125,7 @@ public:
 
     template<class ResolveResultType> void resolveWithNewlyCreated(Ref<ResolveResultType>&&);
 
+    void reject(Exception&&);
     void reject(ExceptionCode, const String& = { });
 
     JSC::JSValue promise() const;
index 0a4ab61..bdcb5f0 100644 (file)
@@ -75,9 +75,7 @@ JSValue JSHistory::pushState(ExecState& state)
         RETURN_IF_EXCEPTION(scope, JSValue());
     }
 
-    ExceptionCodeWithMessage ec;
-    wrapped().stateObjectAdded(WTFMove(historyState), title, url, History::StateObjectType::Push, ec);
-    setDOMException(&state, ec);
+    propagateException(state, scope, wrapped().stateObjectAdded(WTFMove(historyState), title, url, History::StateObjectType::Push));
 
     m_state.clear();
 
@@ -106,9 +104,7 @@ JSValue JSHistory::replaceState(ExecState& state)
         RETURN_IF_EXCEPTION(scope, JSValue());
     }
 
-    ExceptionCodeWithMessage ec;
-    wrapped().stateObjectAdded(WTFMove(historyState), title, url, History::StateObjectType::Replace, ec);
-    setDOMException(&state, ec);
+    propagateException(state, scope, wrapped().stateObjectAdded(WTFMove(historyState), title, url, History::StateObjectType::Replace));
 
     m_state.clear();
 
index df5e7a7..9f85396 100644 (file)
@@ -76,10 +76,7 @@ JSValue JSIDBDatabase::createObjectStore(ExecState& state)
         RETURN_IF_EXCEPTION(scope, JSValue());
     }
 
-    ExceptionCodeWithMessage ec;
-    JSValue result = toJS(&state, globalObject(), wrapped().createObjectStore(name, keyPath, autoIncrement, ec));
-    setDOMException(&state, ec);
-    return result;
+    return toJS(state, *globalObject(), scope, wrapped().createObjectStore(name, keyPath, autoIncrement));
 }
 
 }
index b249247..24a22c3 100644 (file)
@@ -42,13 +42,9 @@ JSValue JSIDBRequest::result(ExecState& state) const
     auto& request = wrapped();
 
     if (!request.isDone()) {
-        ExceptionCodeWithMessage ec;
-        ec.code = IDBDatabaseException::InvalidStateError;
-        ec.message = ASCIILiteral("Failed to read the 'result' property from 'IDBRequest': The request has not finished.");
-        setDOMException(&state, ec);
-        return jsUndefined();
+        propagateException(state, Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to read the 'result' property from 'IDBRequest': The request has not finished.") });
+        return { };
     }
-
     if (auto* cursor = request.cursorResult())
         return toJS(&state, globalObject(), *cursor);
     if (auto* database = request.databaseResult())
index 3f78e20..8244dce 100644 (file)
@@ -2896,8 +2896,7 @@ sub GenerateImplementation
             my $type = $attribute->signature->type;
             my $getFunctionName = GetAttributeGetterName($interface, $className, $attribute);
             my $implGetterFunctionName = $codeGenerator->WK_lcfirst($attribute->signature->extendedAttributes->{ImplementedAs} || $name);
-            my $getterMayThrowLegacyExceptionWithMessage = $attribute->signature->extendedAttributes->{GetterMayThrowLegacyExceptionWithMessage};
-            my $getterMayThrowLegacyException = $attribute->signature->extendedAttributes->{GetterMayThrowLegacyException} || $getterMayThrowLegacyExceptionWithMessage;
+            my $getterMayThrowLegacyException = $attribute->signature->extendedAttributes->{GetterMayThrowLegacyException};
 
             $implIncludes{"ExceptionCode.h"} = 1 if $getterMayThrowLegacyException;
 
@@ -2938,11 +2937,7 @@ sub GenerateImplementation
             my @arguments = ();
             if ($getterMayThrowLegacyException && !HasCustomGetter($attribute->signature->extendedAttributes)) {
                 push(@arguments, "ec");
-                if ($getterMayThrowLegacyExceptionWithMessage) {
-                    push(@implContent, "    ExceptionCodeWithMessage ec;\n");
-                } else {
-                    push(@implContent, "    ExceptionCode ec = 0;\n");
-                }
+                push(@implContent, "    ExceptionCode ec = 0;\n");
             }
 
             # Global constructors can be disabled at runtime.
@@ -2983,7 +2978,7 @@ sub GenerateImplementation
 
                 my $nativeType = GetNativeType($interface, $type);
                 my $memoizedType = GetNativeTypeForMemoization($interface, $type);
-                my $exceptionCode = $getterMayThrowLegacyExceptionWithMessage ? "ec.code" : ($getterMayThrowLegacyException ? "ec" : "0");
+                my $exceptionCode = $getterMayThrowLegacyException ? "ec" : "0";
                 push(@implContent, "    static NeverDestroyed<const AtomicString> bindingName(\"$interfaceName.$name\", AtomicString::ConstructFromLiteral);\n");
                 push(@implContent, "    if (cursor.isCapturing()) {\n");
                 push(@implContent, "        $memoizedType memoizedResult = thisObject->wrapped().$implGetterFunctionName(" . join(", ", @arguments) . ");\n");
@@ -3032,7 +3027,7 @@ sub GenerateImplementation
                     AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{Conditional});
                     push(@implContent, "    return JS" . $constructorType . "::getConstructor(state->vm(), thisObject->globalObject());\n");
                 }
-            } elsif (!$attribute->signature->extendedAttributes->{GetterMayThrowLegacyException} && !$attribute->signature->extendedAttributes->{GetterMayThrowLegacyExceptionWithMessage}) {
+            } elsif (!$attribute->signature->extendedAttributes->{GetterMayThrowLegacyException}) {
                 my $cacheIndex = 0;
                 if ($attribute->signature->extendedAttributes->{CachedAttribute}) {
                     $cacheIndex = $currentCachedAttribute;
@@ -3199,8 +3194,7 @@ sub GenerateImplementation
             my $type = $attribute->signature->type;
             my $putFunctionName = GetAttributeSetterName($interface, $className, $attribute);
             my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name);
-            my $setterMayThrowLegacyExceptionWithMessage = $attribute->signature->extendedAttributes->{SetterMayThrowLegacyExceptionWithMessage};
-            my $setterMayThrowLegacyException = $attribute->signature->extendedAttributes->{SetterMayThrowLegacyException} || $setterMayThrowLegacyExceptionWithMessage;
+            my $setterMayThrowLegacyException = $attribute->signature->extendedAttributes->{SetterMayThrowLegacyException};
 
             $implIncludes{"ExceptionCode.h"} = 1 if $setterMayThrowLegacyException;
 
@@ -3293,11 +3287,8 @@ sub GenerateImplementation
                         push(@implContent, "    auto& impl = castedThis->wrapped();\n");
                     }
                 }
-                if ($setterMayThrowLegacyExceptionWithMessage) {
-                    push(@implContent, "    ExceptionCodeWithMessage ec;\n");
-                } elsif ($setterMayThrowLegacyException) {
-                    push(@implContent, "    ExceptionCode ec = 0;\n");
-                }
+
+                push(@implContent, "    ExceptionCode ec = 0;\n") if $setterMayThrowLegacyException;
 
                 my $shouldPassByReference = ShouldPassWrapperByReference($attribute->signature, $interface);
 
@@ -3348,10 +3339,7 @@ sub GenerateImplementation
                         push(@implContent, "    setDOMException(state, throwScope, ec);\n") if $setterMayThrowLegacyException;
                     }
                     if ($svgPropertyType) {
-                        if ($setterMayThrowLegacyExceptionWithMessage) {
-                            push(@implContent, "    if (LIKELY(!ec.code))\n");
-                            push(@implContent, "        impl.commitChange();\n");
-                        } elsif ($setterMayThrowLegacyException) {
+                        if ($setterMayThrowLegacyException) {
                             push(@implContent, "    if (LIKELY(!ec))\n");
                             push(@implContent, "        impl.commitChange();\n");
                         } else {
@@ -3449,10 +3437,7 @@ sub GenerateImplementation
             my $isCustom = HasCustomMethod($function->signature->extendedAttributes);
             my $isOverloaded = $function->{overloads} && @{$function->{overloads}} > 1;
 
-            die "MayThrowLegacyException and MayThrowLegacyExceptionWithMessage are mutually exclusive" if $function->signature->extendedAttributes->{MayThrowLegacyException} && $function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage};
-
-            my $mayThrowLegacyExceptionWithMessage = $function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage};
-            my $mayThrowLegacyException = $function->signature->extendedAttributes->{MayThrowLegacyException} || $mayThrowLegacyExceptionWithMessage;
+            my $mayThrowLegacyException = $function->signature->extendedAttributes->{MayThrowLegacyException};
 
             next if $isCustom && $isOverloaded && $function->{overloadIndex} > 1;
 
@@ -3517,11 +3502,7 @@ END
                 } else {
                     GenerateArgumentsCountCheck(\@implContent, $function, $interface);
 
-                    if ($mayThrowLegacyExceptionWithMessage) {
-                        push(@implContent, "    ExceptionCodeWithMessage ec;\n");
-                    } elsif ($mayThrowLegacyException) {
-                        push(@implContent, "    ExceptionCode ec = 0;\n");
-                    }
+                    push(@implContent, "    ExceptionCode ec = 0;\n") if $mayThrowLegacyException;
 
                     my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $interface, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
                     GenerateImplementationFunctionCall($function, $functionString, "    ", $svgPropertyType, $interface);
@@ -3563,11 +3544,7 @@ END
 
                     GenerateArgumentsCountCheck(\@implContent, $function, $interface);
 
-                    if ($mayThrowLegacyExceptionWithMessage) {
-                        push(@implContent, "    ExceptionCodeWithMessage ec;\n");
-                    } elsif ($mayThrowLegacyException) {
-                        push(@implContent, "    ExceptionCode ec = 0;\n");
-                    }
+                    push(@implContent, "    ExceptionCode ec = 0;\n") if $mayThrowLegacyException;
 
                     if ($function->signature->extendedAttributes->{CheckSecurityForNode}) {
                         push(@implContent, "    if (!shouldAllowAccessToNode(state, impl." . $function->signature->name . "(" . ($mayThrowLegacyException ? "ec" : "") .")))\n");
@@ -4229,7 +4206,7 @@ sub GenerateReturnParameters
 
     my @arguments;
     push(@arguments, "WTFMove(promise)") if IsReturningPromise($function);
-    push(@arguments, "ec") if $function->signature->extendedAttributes->{MayThrowLegacyException} || $function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage};
+    push(@arguments, "ec") if $function->signature->extendedAttributes->{MayThrowLegacyException};
     return @arguments;
 }
 
@@ -4516,8 +4493,7 @@ sub GenerateImplementationFunctionCall()
     my ($function, $functionString, $indent, $svgPropertyType, $interface) = @_;
 
     my $nondeterministic = $function->signature->extendedAttributes->{Nondeterministic};
-    my $mayThrowLegacyExceptionWithMessage = $function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage};
-    my $mayThrowLegacyException = $function->signature->extendedAttributes->{MayThrowLegacyException} || $mayThrowLegacyExceptionWithMessage;
+    my $mayThrowLegacyException = $function->signature->extendedAttributes->{MayThrowLegacyException};
 
     if ($function->signature->type eq "void" || IsReturningPromise($function)) {
         if ($nondeterministic) {
@@ -4538,10 +4514,7 @@ sub GenerateImplementationFunctionCall()
         }
 
         if ($svgPropertyType and !$function->isStatic) {
-            if ($mayThrowLegacyExceptionWithMessage) {
-                push(@implContent, $indent . "if (LIKELY(!ec.code))\n");
-                push(@implContent, $indent . "    impl.commitChange();\n");
-            } elsif ($mayThrowLegacyException) {
+            if ($mayThrowLegacyException) {
                 push(@implContent, $indent . "if (LIKELY(!ec))\n");
                 push(@implContent, $indent . "    impl.commitChange();\n");
             } else {
@@ -4566,7 +4539,7 @@ sub GenerateImplementationFunctionCall()
             push(@implContent, $indent . "static NeverDestroyed<const AtomicString> bindingName(\"$bindingName\", AtomicString::ConstructFromLiteral);\n");
             push(@implContent, $indent . "if (cursor.isCapturing()) {\n");
             push(@implContent, $indent . "    $nativeType memoizedResult = $functionString;\n");
-            my $exceptionCode = $mayThrowLegacyExceptionWithMessage ? "ec.code" : ($mayThrowLegacyException ? "ec" : "0");
+            my $exceptionCode = $mayThrowLegacyException ? "ec" : "0";
             push(@implContent, $indent . "    cursor.appendInput<MemoizedDOMResult<$memoizedType>>(bindingName.get().string(), memoizedResult, $exceptionCode);\n");
             push(@implContent, $indent . "    result = " . NativeToJSValue($function->signature, 1, $interface, "memoizedResult", $thisObject) . ";\n");
             push(@implContent, $indent . "} else if (cursor.isReplaying()) {\n");
@@ -4575,8 +4548,7 @@ sub GenerateImplementationFunctionCall()
             # FIXME: the generated code should report an error if an input cannot be fetched or converted.
             push(@implContent, $indent . "    if (input && input->convertTo<$memoizedType>(memoizedResult)) {\n");
             push(@implContent, $indent . "        result = " . NativeToJSValue($function->signature, 1, $interface, "memoizedResult", $thisObject) . ";\n");
-            push(@implContent, $indent . "        ec.code = input->exceptionCode();\n") if $mayThrowLegacyExceptionWithMessage;
-            push(@implContent, $indent . "        ec = input->exceptionCode();\n") if $mayThrowLegacyException && !$mayThrowLegacyExceptionWithMessage;
+            push(@implContent, $indent . "        ec = input->exceptionCode();\n") if $mayThrowLegacyException;
             push(@implContent, $indent . "    } else\n");
             push(@implContent, $indent . "        result = " . NativeToJSValue($function->signature, 1, $interface, $functionString, $thisObject) . ";\n");
             push(@implContent, $indent . "} else\n");
@@ -5506,13 +5478,9 @@ END
 
             GenerateArgumentsCountCheck($outputArray, $function, $interface);
 
-            if ($function->signature->extendedAttributes->{MayThrowLegacyException} || $function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage} || $interface->extendedAttributes->{ConstructorMayThrowLegacyException}) {
+            if ($function->signature->extendedAttributes->{MayThrowLegacyException} || $interface->extendedAttributes->{ConstructorMayThrowLegacyException}) {
                 $implIncludes{"ExceptionCode.h"} = 1;
-                if ($function->signature->extendedAttributes->{MayThrowLegacyExceptionWithMessage}) {
-                    push(@$outputArray, "    ExceptionCodeWithMessage ec;\n");
-                } else {
-                    push(@$outputArray, "    ExceptionCode ec = 0;\n");
-                }
+                push(@$outputArray, "    ExceptionCode ec = 0;\n");
             }
 
             # FIXME: For now, we do not support SVG constructors.
index 6d26c55..52afbf3 100644 (file)
@@ -70,7 +70,6 @@ ForwardDeclareInHeader
 GenerateIsReachable=|Impl|ImplWebGLRenderingContext|ImplDocument|ImplElementRoot|ImplFrame|ImplOwnerNodeRoot|ImplScriptExecutionContext
 GetterMayThrowException
 GetterMayThrowLegacyException
-GetterMayThrowLegacyExceptionWithMessage
 Immutable
 ImplementedAs=*
 ImplementationLacksVTable
@@ -98,7 +97,6 @@ LenientThis
 MasqueradesAsUndefined
 MayThrowException
 MayThrowLegacyException
-MayThrowLegacyExceptionWithMessage
 NamedConstructor=*
 NewImpurePropertyFiresWatchpoints
 NewObject
@@ -118,7 +116,6 @@ RequiresExistingAtomicString
 SetterCallWith=ScriptExecutionContext|ScriptState|ScriptArguments|CallStack|ActiveWindow|FirstWindow
 SetterMayThrowException
 SetterMayThrowLegacyException
-SetterMayThrowLegacyExceptionWithMessage
 SkipVTableValidation
 SuppressToJSObject
 TreatNullAs=EmptyString
index 9f35ea8..7f6b9b8 100644 (file)
@@ -866,7 +866,6 @@ JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithException(
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionReturningLong(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionReturningObject(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithLegacyException(JSC::ExecState*);
-JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionWithMessage(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionCustomMethod(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionCustomMethodWithArgs(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionPrivateMethod(JSC::ExecState*);
@@ -1061,14 +1060,10 @@ JSC::EncodedJSValue jsTestObjAttributeWithGetterException(JSC::ExecState*, JSC::
 bool setJSTestObjAttributeWithGetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjAttributeWithGetterLegacyException(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjAttributeWithGetterLegacyException(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
-JSC::EncodedJSValue jsTestObjAttrWithGetterExceptionWithMessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
-bool setJSTestObjAttrWithGetterExceptionWithMessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjAttributeWithSetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjAttributeWithSetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjAttributeWithSetterLegacyException(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjAttributeWithSetterLegacyException(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
-JSC::EncodedJSValue jsTestObjAttrWithSetterExceptionWithMessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
-bool setJSTestObjAttrWithSetterExceptionWithMessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjStringAttrWithGetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjStringAttrWithGetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjStringAttrWithSetterException(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
@@ -1378,10 +1373,8 @@ static const HashTableValue JSTestObjPrototypeTableValues[] =
     { "typedArrayAttr", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjTypedArrayAttr), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjTypedArrayAttr) } },
     { "attributeWithGetterException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttributeWithGetterException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttributeWithGetterException) } },
     { "attributeWithGetterLegacyException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttributeWithGetterLegacyException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttributeWithGetterLegacyException) } },
-    { "attrWithGetterExceptionWithMessage", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttrWithGetterExceptionWithMessage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttrWithGetterExceptionWithMessage) } },
     { "attributeWithSetterException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttributeWithSetterException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttributeWithSetterException) } },
     { "attributeWithSetterLegacyException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttributeWithSetterLegacyException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttributeWithSetterLegacyException) } },
-    { "attrWithSetterExceptionWithMessage", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttrWithSetterExceptionWithMessage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttrWithSetterExceptionWithMessage) } },
     { "stringAttrWithGetterException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjStringAttrWithGetterException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjStringAttrWithGetterException) } },
     { "stringAttrWithSetterException", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjStringAttrWithSetterException), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjStringAttrWithSetterException) } },
     { "customAttr", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCustomAttr), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjCustomAttr) } },
@@ -1478,7 +1471,6 @@ static const HashTableValue JSTestObjPrototypeTableValues[] =
     { "methodWithExceptionReturningLong", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithExceptionReturningLong), (intptr_t) (0) } },
     { "methodWithExceptionReturningObject", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithExceptionReturningObject), (intptr_t) (0) } },
     { "methodWithLegacyException", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithLegacyException), (intptr_t) (0) } },
-    { "methodWithExceptionWithMessage", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithExceptionWithMessage), (intptr_t) (0) } },
     { "customMethod", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionCustomMethod), (intptr_t) (0) } },
     { "customMethodWithArgs", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionCustomMethodWithArgs), (intptr_t) (3) } },
 #if ENABLE(Condition3)
@@ -2391,24 +2383,6 @@ static inline JSValue jsTestObjAttributeWithGetterLegacyExceptionGetter(ExecStat
     return result;
 }
 
-static inline JSValue jsTestObjAttrWithGetterExceptionWithMessageGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
-
-EncodedJSValue jsTestObjAttrWithGetterExceptionWithMessage(ExecState* state, EncodedJSValue thisValue, PropertyName)
-{
-    return BindingCaller<JSTestObj>::attribute<jsTestObjAttrWithGetterExceptionWithMessageGetter>(state, thisValue, "attrWithGetterExceptionWithMessage");
-}
-
-static inline JSValue jsTestObjAttrWithGetterExceptionWithMessageGetter(ExecState* state, JSTestObj* thisObject, ThrowScope& throwScope)
-{
-    UNUSED_PARAM(throwScope);
-    UNUSED_PARAM(state);
-    ExceptionCodeWithMessage ec;
-    auto& impl = thisObject->wrapped();
-    JSValue result = jsNumber(impl.attrWithGetterExceptionWithMessage(ec));
-    setDOMException(state, throwScope, ec);
-    return result;
-}
-
 static inline JSValue jsTestObjAttributeWithSetterExceptionGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
 
 EncodedJSValue jsTestObjAttributeWithSetterException(ExecState* state, EncodedJSValue thisValue, PropertyName)
@@ -2441,22 +2415,6 @@ static inline JSValue jsTestObjAttributeWithSetterLegacyExceptionGetter(ExecStat
     return result;
 }
 
-static inline JSValue jsTestObjAttrWithSetterExceptionWithMessageGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
-
-EncodedJSValue jsTestObjAttrWithSetterExceptionWithMessage(ExecState* state, EncodedJSValue thisValue, PropertyName)
-{
-    return BindingCaller<JSTestObj>::attribute<jsTestObjAttrWithSetterExceptionWithMessageGetter>(state, thisValue, "attrWithSetterExceptionWithMessage");
-}
-
-static inline JSValue jsTestObjAttrWithSetterExceptionWithMessageGetter(ExecState* state, JSTestObj* thisObject, ThrowScope& throwScope)
-{
-    UNUSED_PARAM(throwScope);
-    UNUSED_PARAM(state);
-    auto& impl = thisObject->wrapped();
-    JSValue result = jsNumber(impl.attrWithSetterExceptionWithMessage());
-    return result;
-}
-
 static inline JSValue jsTestObjStringAttrWithGetterExceptionGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
 
 EncodedJSValue jsTestObjStringAttrWithGetterException(ExecState* state, EncodedJSValue thisValue, PropertyName)
@@ -3920,24 +3878,6 @@ bool setJSTestObjAttributeWithGetterLegacyException(ExecState* state, EncodedJSV
 }
 
 
-bool setJSTestObjAttrWithGetterExceptionWithMessage(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
-{
-    VM& vm = state->vm();
-    auto throwScope = DECLARE_THROW_SCOPE(vm);
-    UNUSED_PARAM(throwScope);
-    JSValue value = JSValue::decode(encodedValue);
-    UNUSED_PARAM(thisValue);
-    JSTestObj* castedThis = jsDynamicCast<JSTestObj*>(JSValue::decode(thisValue));
-    if (UNLIKELY(!castedThis))
-        return throwSetterTypeError(*state, throwScope, "TestObject", "attrWithGetterExceptionWithMessage");
-    auto& impl = castedThis->wrapped();
-    auto nativeValue = convert<int32_t>(*state, value, NormalConversion);
-    RETURN_IF_EXCEPTION(throwScope, false);
-    impl.setAttrWithGetterExceptionWithMessage(WTFMove(nativeValue));
-    return true;
-}
-
-
 bool setJSTestObjAttributeWithSetterException(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
 {
     VM& vm = state->vm();
@@ -3976,26 +3916,6 @@ bool setJSTestObjAttributeWithSetterLegacyException(ExecState* state, EncodedJSV
 }
 
 
-bool setJSTestObjAttrWithSetterExceptionWithMessage(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
-{
-    VM& vm = state->vm();
-    auto throwScope = DECLARE_THROW_SCOPE(vm);
-    UNUSED_PARAM(throwScope);
-    JSValue value = JSValue::decode(encodedValue);
-    UNUSED_PARAM(thisValue);
-    JSTestObj* castedThis = jsDynamicCast<JSTestObj*>(JSValue::decode(thisValue));
-    if (UNLIKELY(!castedThis))
-        return throwSetterTypeError(*state, throwScope, "TestObject", "attrWithSetterExceptionWithMessage");
-    auto& impl = castedThis->wrapped();
-    ExceptionCodeWithMessage ec;
-    auto nativeValue = convert<int32_t>(*state, value, NormalConversion);
-    RETURN_IF_EXCEPTION(throwScope, false);
-    impl.setAttrWithSetterExceptionWithMessage(WTFMove(nativeValue), ec);
-    setDOMException(state, throwScope, ec);
-    return true;
-}
-
-
 bool setJSTestObjStringAttrWithGetterException(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
 {
     VM& vm = state->vm();
@@ -5281,23 +5201,6 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithLegacyException
     return JSValue::encode(jsUndefined());
 }
 
-EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionWithMessage(ExecState* state)
-{
-    VM& vm = state->vm();
-    auto throwScope = DECLARE_THROW_SCOPE(vm);
-    UNUSED_PARAM(throwScope);
-    JSValue thisValue = state->thisValue();
-    auto castedThis = jsDynamicCast<JSTestObj*>(thisValue);
-    if (UNLIKELY(!castedThis))
-        return throwThisTypeError(*state, throwScope, "TestObject", "methodWithExceptionWithMessage");
-    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
-    auto& impl = castedThis->wrapped();
-    ExceptionCodeWithMessage ec;
-    impl.methodWithExceptionWithMessage(ec);
-    setDOMException(state, throwScope, ec);
-    return JSValue::encode(jsUndefined());
-}
-
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionCustomMethod(ExecState* state)
 {
     VM& vm = state->vm();
index f445523..677c3b4 100644 (file)
@@ -153,13 +153,10 @@ enum TestConfidence { "high", "kinda-low" };
     [MayThrowException] long methodWithExceptionReturningLong();
     [MayThrowException] TestObj methodWithExceptionReturningObject();
     [MayThrowLegacyException] void methodWithLegacyException();
-    [MayThrowLegacyExceptionWithMessage] void methodWithExceptionWithMessage();
     [GetterMayThrowException] attribute long attributeWithGetterException;
     [GetterMayThrowLegacyException] attribute long attributeWithGetterLegacyException;
-    [GetterMayThrowLegacyExceptionWithMessage] attribute long attrWithGetterExceptionWithMessage;
     [SetterMayThrowException] attribute long attributeWithSetterException;
     [SetterMayThrowLegacyException] attribute long attributeWithSetterLegacyException;
-    [SetterMayThrowLegacyExceptionWithMessage] attribute long attrWithSetterExceptionWithMessage;
     [GetterMayThrowLegacyException] attribute DOMString stringAttrWithGetterException;
     [SetterMayThrowLegacyException] attribute DOMString stringAttrWithSetterException;
 
index 4e5f988..31dbaca 100644 (file)
 [
     Conditional=CUSTOM_ELEMENTS,
     EnabledAtRuntime=CustomElements,
+    ImplementationLacksVTable,
     JSGenerateToNativeObject,
-    ImplementationLacksVTable
 ] interface CustomElementRegistry {
-
     [CEReactions, Custom] void define(DOMString name, Function constructor);
     any get(DOMString name);
-    [MayThrowLegacyExceptionWithMessage, Custom] Promise whenDefined(DOMString name);
-
+    [Custom, MayThrowException] Promise whenDefined(DOMString name);
 };
index f624f23..5354c86 100644 (file)
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef ExceptionCode_h
-#define ExceptionCode_h
-
-#include <wtf/text/WTFString.h>
+#pragma once
 
 namespace WebCore {
 
@@ -27,8 +24,7 @@ namespace WebCore {
 // In our DOM implementation we use int instead, and use different
 // numerical ranges for different types of DOM exception, so that
 // an exception of any type can be expressed with a single integer.
-typedef int ExceptionCode;
-
+using ExceptionCode = int;
 
 // Some of these are considered historical since they have been
 // changed or removed from the specifications.
@@ -82,11 +78,4 @@ enum {
     RangeError = 106,
 };
 
-struct ExceptionCodeWithMessage {
-    ExceptionCode code { 0 };
-    String message;
-};
-
 } // namespace WebCore
-
-#endif // ExceptionCode_h
index ea13cf1..8bfb4fc 100644 (file)
@@ -125,7 +125,7 @@ public:
     WEBCORE_EXPORT void setIsTargetItem(bool);
     
     WEBCORE_EXPORT void setStateObject(RefPtr<SerializedScriptValue>&&);
-    RefPtr<SerializedScriptValue> stateObject() const { return m_stateObject; }
+    SerializedScriptValue* stateObject() const { return m_stateObject.get(); }
 
     void setItemSequenceNumber(long long number) { m_itemSequenceNumber = number; }
     long long itemSequenceNumber() const { return m_itemSequenceNumber; }
index e39fda8..c5c8013 100644 (file)
@@ -106,19 +106,17 @@ private:
 
 class OpenDatabaseCallback final : public EventListener {
 public:
-    static Ref<OpenDatabaseCallback> create(ExecutableWithDatabase* executableWithDatabase)
+    static Ref<OpenDatabaseCallback> create(ExecutableWithDatabase& executableWithDatabase)
     {
         return adoptRef(*new OpenDatabaseCallback(executableWithDatabase));
     }
 
-    virtual ~OpenDatabaseCallback() { }
-
-    bool operator==(const EventListener& other) const override
+    bool operator==(const EventListener& other) const final
     {
         return this == &other;
     }
 
-    void handleEvent(ScriptExecutionContext*, Event* event) override
+    void handleEvent(ScriptExecutionContext*, Event* event) final
     {
         if (event->type() != eventNames().successEvent) {
             m_executableWithDatabase->requestCallback().sendFailure("Unexpected event type.");
@@ -141,10 +139,10 @@ public:
     }
 
 private:
-    OpenDatabaseCallback(ExecutableWithDatabase* executableWithDatabase)
+    OpenDatabaseCallback(ExecutableWithDatabase& executableWithDatabase)
         : EventListener(EventListener::CPPEventListenerType)
         , m_executableWithDatabase(executableWithDatabase) { }
-    RefPtr<ExecutableWithDatabase> m_executableWithDatabase;
+    Ref<ExecutableWithDatabase> m_executableWithDatabase;
 };
 
 void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, const String& databaseName)
@@ -154,15 +152,13 @@ void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, cons
         return;
     }
 
-    ExceptionCodeWithMessage ec;
-    RefPtr<IDBOpenDBRequest> idbOpenDBRequest = idbFactory->open(*context(), databaseName, Nullopt, ec);
-    if (ec.code) {
+    auto result = idbFactory->open(*context(), databaseName, Nullopt);
+    if (result.hasException()) {
         requestCallback().sendFailure("Could not open database.");
         return;
     }
 
-    Ref<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this);
-    idbOpenDBRequest->addEventListener(eventNames().successEvent, WTFMove(callback), false);
+    result.releaseReturnValue()->addEventListener(eventNames().successEvent, OpenDatabaseCallback::create(*this), false);
 }
 
 
@@ -203,29 +199,26 @@ static RefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath)
 
 static RefPtr<IDBTransaction> transactionForDatabase(IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly())
 {
-    ExceptionCodeWithMessage ec;
-    RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(objectStoreName, mode, ec);
-    if (ec.code)
+    auto result = idbDatabase->transaction(objectStoreName, mode);
+    if (result.hasException())
         return nullptr;
-    return idbTransaction;
+    return result.releaseReturnValue();
 }
 
 static RefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName)
 {
-    ExceptionCodeWithMessage ec;
-    RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectStoreName, ec);
-    if (ec.code)
+    auto result = idbTransaction->objectStore(objectStoreName);
+    if (result.hasException())
         return nullptr;
-    return idbObjectStore;
+    return result.releaseReturnValue();
 }
 
 static RefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName)
 {
-    ExceptionCodeWithMessage ec;
-    RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, ec);
-    if (ec.code)
+    auto index = idbObjectStore->index(indexName);
+    if (index.hasException())
         return nullptr;
-    return idbIndex;
+    return index.releaseReturnValue();
 }
 
 class DatabaseLoader final : public ExecutableWithDatabase {
@@ -253,7 +246,7 @@ public:
             auto indexes = Inspector::Protocol::Array<Inspector::Protocol::IndexedDB::ObjectStoreIndex>::create();
     
             for (auto& indexInfo : objectStoreInfo->indexMap().values()) {
-                Ref<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
+                auto objectStoreIndex = ObjectStoreIndex::create()
                     .setName(indexInfo.name())
                     .setKeyPath(keyPathFromIDBKeyPath(indexInfo.keyPath()))
                     .setUnique(indexInfo.unique())
@@ -262,7 +255,7 @@ public:
                 indexes->addItem(WTFMove(objectStoreIndex));
             }
     
-            Ref<ObjectStore> objectStore = ObjectStore::create()
+            auto objectStore = ObjectStore::create()
                 .setName(objectStoreInfo->name())
                 .setKeyPath(keyPathFromIDBKeyPath(objectStoreInfo->keyPath()))
                 .setAutoIncrement(objectStoreInfo->autoIncrement())
@@ -271,7 +264,7 @@ public:
             objectStores->addItem(WTFMove(objectStore));
         }
     
-        Ref<DatabaseWithObjectStores> result = DatabaseWithObjectStores::create()
+        auto result = DatabaseWithObjectStores::create()
             .setName(databaseInfo.name())
             .setVersion(databaseInfo.version())
             .setObjectStores(WTFMove(objectStores))
@@ -403,9 +396,7 @@ public:
         auto& cursor = *cursorResult;
 
         if (m_skipCount) {
-            ExceptionCodeWithMessage ec;
-            cursor.advance(m_skipCount, ec);
-            if (ec.code)
+            if (cursor.advance(m_skipCount).hasException())
                 m_requestCallback->sendFailure("Could not advance cursor.");
             m_skipCount = 0;
             return;
@@ -417,18 +408,16 @@ public:
         }
 
         // Continue cursor before making injected script calls, otherwise transaction might be finished.
-        ExceptionCodeWithMessage ec;
-        cursor.continueFunction(nullptr, ec);
-        if (ec.code) {
+        if (cursor.continueFunction(nullptr).hasException()) {
             m_requestCallback->sendFailure("Could not continue cursor.");
             return;
         }
 
-        JSC::ExecState* state = context ? context->execState() : nullptr;
+        auto* state = context ? context->execState() : nullptr;
         if (!state)
             return;
 
-        RefPtr<DataEntry> dataEntry = DataEntry::create()
+        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))
@@ -474,39 +463,47 @@ public:
         if (!requestCallback().isActive())
             return;
 
-        RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(&database, m_objectStoreName);
+        auto idbTransaction = transactionForDatabase(&database, m_objectStoreName);
         if (!idbTransaction) {
             m_requestCallback->sendFailure("Could not get transaction");
             return;
         }
 
-        RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
+        auto idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
         if (!idbObjectStore) {
             m_requestCallback->sendFailure("Could not get object store");
             return;
         }
 
         TransactionActivator activator(idbTransaction.get());
-        ExceptionCodeWithMessage ec;
         RefPtr<IDBRequest> idbRequest;
-        JSC::ExecState* exec = context() ? context()->execState() : nullptr;
+        auto* exec = context() ? context()->execState() : nullptr;
         if (!m_indexName.isEmpty()) {
-            RefPtr<IDBIndex> idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName);
+            auto idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName);
             if (!idbIndex) {
                 m_requestCallback->sendFailure("Could not get index");
                 return;
             }
 
-            idbRequest = exec ? idbIndex->openCursor(*exec, m_idbKeyRange.get(), IDBCursor::directionNext(), ec) : nullptr;
-        } else
-            idbRequest = exec ? idbObjectStore->openCursor(*exec, m_idbKeyRange.get(), IDBCursor::directionNext(), ec) : nullptr;
+            if (exec) {
+                auto result = idbIndex->openCursor(*exec, m_idbKeyRange.get(), IDBCursor::directionNext());
+                if (!result.hasException())
+                    idbRequest = result.releaseReturnValue();
+            }
+        } else {
+            if (exec) {
+                auto result = idbObjectStore->openCursor(*exec, m_idbKeyRange.get(), IDBCursor::directionNext());
+                if (!result.hasException())
+                    idbRequest = result.releaseReturnValue();
+            }
+        }
 
         if (!idbRequest) {
             m_requestCallback->sendFailure("Could not open cursor to populate database data");
             return;
         }
 
-        Ref<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback.copyRef(), m_skipCount, m_pageSize);
+        auto openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback.copyRef(), m_skipCount, m_pageSize);
         idbRequest->addEventListener(eventNames().successEvent, WTFMove(openCursorCallback), false);
     }
 
@@ -709,26 +706,28 @@ public:
         if (!requestCallback().isActive())
             return;
 
-        RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(&database, m_objectStoreName, IDBTransaction::modeReadWrite());
+        auto idbTransaction = transactionForDatabase(&database, m_objectStoreName, IDBTransaction::modeReadWrite());
         if (!idbTransaction) {
             m_requestCallback->sendFailure("Could not get transaction");
             return;
         }
 
-        RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
+        auto idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
         if (!idbObjectStore) {
             m_requestCallback->sendFailure("Could not get object store");
             return;
         }
 
         TransactionActivator activator(idbTransaction.get());
-        ExceptionCodeWithMessage ec;
-        JSC::ExecState* exec = context() ? context()->execState() : nullptr;
-        RefPtr<IDBRequest> idbRequest = exec ? idbObjectStore->clear(*exec, ec) : nullptr;
-        ASSERT(!ec.code);
-        if (ec.code) {
-            m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), ec.code));
-            return;
+        RefPtr<IDBRequest> idbRequest;
+        if (auto* exec = context() ? context()->execState() : nullptr) {
+            auto result = idbObjectStore->clear(*exec);
+            ASSERT(!result.hasException());
+            if (result.hasException()) {
+                m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), result.releaseException().code()));
+                return;
+            }
+            idbRequest = result.releaseReturnValue();
         }
 
         idbTransaction->addEventListener(eventNames().completeEvent, ClearObjectStoreListener::create(m_requestCallback.copyRef()), false);
index cdae5ff..9db7faf 100644 (file)
@@ -657,7 +657,7 @@ History* DOMWindow::history() const
     if (!isCurrentlyDisplayedInFrame())
         return nullptr;
     if (!m_history)
-        m_history = History::create(m_frame);
+        m_history = History::create(*m_frame);
     return m_history.get();
 }
 
index 6859d7e..1d4542b 100644 (file)
 #include "Page.h"
 #include "ScriptController.h"
 #include "SecurityOrigin.h"
-#include "SerializedScriptValue.h"
 #include <wtf/CheckedArithmetic.h>
 #include <wtf/MainThread.h>
 
 namespace WebCore {
 
-History::History(Frame* frame)
-    : DOMWindowProperty(frame)
-    , m_lastStateObjectRequested(nullptr)
+History::History(Frame& frame)
+    : DOMWindowProperty(&frame)
 {
 }
 
@@ -54,26 +52,26 @@ unsigned History::length() const
 {
     if (!m_frame)
         return 0;
-    if (!m_frame->page())
+    auto* page = m_frame->page();
+    if (!page)
         return 0;
-    return m_frame->page()->backForward().count();
+    return page->backForward().count();
 }
 
-PassRefPtr<SerializedScriptValue> History::state()
+SerializedScriptValue* History::state()
 {
     m_lastStateObjectRequested = stateInternal();
-    return m_lastStateObjectRequested;
+    return m_lastStateObjectRequested.get();
 }
 
-PassRefPtr<SerializedScriptValue> History::stateInternal() const
+SerializedScriptValue* History::stateInternal() const
 {
     if (!m_frame)
-        return 0;
-
-    if (HistoryItem* historyItem = m_frame->loader().history().currentItem())
-        return historyItem->stateObject();
-
-    return 0;
+        return nullptr;
+    auto* historyItem = m_frame->loader().history().currentItem();
+    if (!historyItem)
+        return nullptr;
+    return historyItem->stateObject();
 }
 
 bool History::stateChanged() const
@@ -83,7 +81,7 @@ bool History::stateChanged() const
 
 bool History::isSameAsCurrentState(SerializedScriptValue* state) const
 {
-    return state == stateInternal().get();
+    return state == stateInternal();
 }
 
 void History::back()
@@ -136,29 +134,24 @@ URL History::urlForState(const String& urlString)
     return URL(baseURL, urlString);
 }
 
-void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCodeWithMessage& ec)
+ExceptionOr<void> History::stateObjectAdded(RefPtr<SerializedScriptValue>&& data, const String& title, const String& urlString, StateObjectType stateObjectType)
 {
-    // Each unique main-frame document is only allowed to send 64mb of state object payload to the UI client/process.
+    // Each unique main-frame document is only allowed to send 64MB of state object payload to the UI client/process.
     static uint32_t totalStateObjectPayloadLimit = 0x4000000;
     static double stateObjectTimeSpan = 30.0;
     static unsigned perStateObjectTimeSpanLimit = 100;
 
     if (!m_frame || !m_frame->page())
-        return;
+        return { };
 
     URL fullURL = urlForState(urlString);
-    if (!fullURL.isValid() || !m_frame->document()->securityOrigin()->canRequest(fullURL)) {
-        ec.code = SECURITY_ERR;
-        return;
-    }
+    if (!fullURL.isValid() || !m_frame->document()->securityOrigin()->canRequest(fullURL))
+        return Exception { SECURITY_ERR };
 
     if (fullURL.hasUsername() || fullURL.hasPassword()) {
-        ec.code = SECURITY_ERR;
         if (stateObjectType == StateObjectType::Replace)
-            ec.message = makeString("Attempt to use history.replaceState() to change session history URL to ", fullURL.string(), " is insecure; Username/passwords aren't allowed in state object URLs");
-        else
-            ec.message = makeString("Attempt to use history.pushState() to add URL ", fullURL.string(), " to session history is insecure; Username/passwords aren't allowed in state object URLs");
-        return;
+            return Exception { SECURITY_ERR, "Attempt to use history.replaceState() to change session history URL to " + fullURL.string() + " is insecure; Username/passwords aren't allowed in state object URLs" };
+        return Exception { SECURITY_ERR, "Attempt to use history.pushState() to add URL " + fullURL.string() + " to session history is insecure; Username/passwords aren't allowed in state object URLs" };
     }
 
     Document* mainDocument = m_frame->page()->mainFrame().document();
@@ -169,7 +162,7 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
     }
 
     if (!mainHistory)
-        return;
+        return { };
 
     double currentTimestamp = currentTime();
     if (currentTimestamp - mainHistory->m_currentStateObjectTimeSpanStart > stateObjectTimeSpan) {
@@ -178,12 +171,9 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
     }
     
     if (mainHistory->m_currentStateObjectTimeSpanObjectsAdded >= perStateObjectTimeSpanLimit) {
-        ec.code = SECURITY_ERR;
         if (stateObjectType == StateObjectType::Replace)
-            ec.message = String::format("Attempt to use history.replaceState() more than %u times per %f seconds", perStateObjectTimeSpanLimit, stateObjectTimeSpan);
-        else
-            ec.message = String::format("Attempt to use history.pushState() more than %u times per %f seconds", perStateObjectTimeSpanLimit, stateObjectTimeSpan);
-        return;
+            return Exception { SECURITY_ERR, String::format("Attempt to use history.replaceState() more than %u times per %f seconds", perStateObjectTimeSpanLimit, stateObjectTimeSpan) };
+        return Exception { SECURITY_ERR, String::format("Attempt to use history.pushState() more than %u times per %f seconds", perStateObjectTimeSpanLimit, stateObjectTimeSpan) };
     }
 
     Checked<unsigned> titleSize = title.length();
@@ -203,12 +193,9 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
     newTotalUsage += payloadSize;
 
     if (newTotalUsage > totalStateObjectPayloadLimit) {
-        ec.code = QUOTA_EXCEEDED_ERR;
         if (stateObjectType == StateObjectType::Replace)
-            ec.message = ASCIILiteral("Attempt to store more data than allowed using history.replaceState()");
-        else
-            ec.message = ASCIILiteral("Attempt to store more data than allowed using history.pushState()");
-        return;
+            return Exception { QUOTA_EXCEEDED_ERR, ASCIILiteral("Attempt to store more data than allowed using history.replaceState()") };
+        return Exception { QUOTA_EXCEEDED_ERR, ASCIILiteral("Attempt to store more data than allowed using history.pushState()") };
     }
 
     m_mostRecentStateObjectUsage = payloadSize.unsafeGet();
@@ -226,6 +213,8 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
         m_frame->loader().history().replaceState(data, title, fullURL.string());
         m_frame->loader().client().dispatchDidReplaceStateWithinPage();
     }
+
+    return { };
 }
 
 } // namespace WebCore
index b3f9d1f..e722a08 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef History_h
-#define History_h
+#pragma once
 
 #include "DOMWindowProperty.h"
+#include "ExceptionOr.h"
 #include "ScriptWrappable.h"
 #include "SerializedScriptValue.h"
-#include "URL.h"
-#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
 
 namespace WebCore {
 
 class Document;
 class Frame;
-struct ExceptionCodeWithMessage;
-typedef int ExceptionCode;
+class URL;
 
-class History : public ScriptWrappable, public RefCounted<History>, public DOMWindowProperty {
+class History final : public ScriptWrappable, public RefCounted<History>, public DOMWindowProperty {
 public:
-    static Ref<History> create(Frame* frame) { return adoptRef(*new History(frame)); }
+    static Ref<History> create(Frame& frame) { return adoptRef(*new History(frame)); }
 
     unsigned length() const;
-    PassRefPtr<SerializedScriptValue> state();
+    SerializedScriptValue* state();
     void back();
     void forward();
     void go(int);
@@ -58,18 +53,15 @@ public:
     bool stateChanged() const;
     bool isSameAsCurrentState(SerializedScriptValue*) const;
 
-    enum class StateObjectType {
-        Push,
-        Replace
-    };
-    void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, StateObjectType, ExceptionCodeWithMessage&);
+    enum class StateObjectType { Push, Replace };
+    ExceptionOr<void> stateObjectAdded(RefPtr<SerializedScriptValue>&&, const String& title, const String& url, StateObjectType);
 
 private:
-    explicit History(Frame*);
+    explicit History(Frame&);
 
     URL urlForState(const String& url);
 
-    PassRefPtr<SerializedScriptValue> stateInternal() const;
+    SerializedScriptValue* stateInternal() const;
 
     RefPtr<SerializedScriptValue> m_lastStateObjectRequested;
 
@@ -84,5 +76,3 @@ private:
 };
 
 } // namespace WebCore
-
-#endif // History_h
index e26f0cd..8d9a669 100644 (file)
@@ -33,6 +33,6 @@
     [CallWith=Document, ForwardDeclareInHeader] void forward();
     [CallWith=Document, ForwardDeclareInHeader] void go(optional long distance = 0);
 
-    [Custom, MayThrowLegacyException] void pushState(any data, DOMString title, optional USVString? url = null);
-    [Custom, MayThrowLegacyException] void replaceState(any data, DOMString title, optional USVString? url = null);
+    [Custom, MayThrowException] void pushState(any data, DOMString title, optional USVString? url = null);
+    [Custom, MayThrowException] void replaceState(any data, DOMString title, optional USVString? url = null);
 };