<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191635] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191635">191635</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2015-10-27 13:39:40 -0700 (Tue, 27 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modern IDB: Support IDBObjectStore.put/get support.
https://bugs.webkit.org/show_bug.cgi?id=150468

Reviewed by Alex Christensen.

Source/WebCore:

Tests: storage/indexeddb/modern/basic-put.html
       storage/indexeddb/modern/keypath-basic.html

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

* Modules/indexeddb/IDBKeyData.cpp:
(WebCore::IDBKeyData::deletedValue):
(WebCore::IDBKeyData::operator&lt;):
(WebCore::IDBKeyData::operator==):
* Modules/indexeddb/IDBKeyData.h:
(WebCore::IDBKeyData::isValid):
(WebCore::IDBKeyData::operator!=):
(WebCore::IDBKeyData::hash):
(WebCore::IDBKeyData::isDeletedValue):
(WebCore::IDBKeyDataHash::hash):
(WebCore::IDBKeyDataHash::equal):
(WebCore::IDBKeyDataHashTraits::constructDeletedValue):
(WebCore::IDBKeyDataHashTraits::isDeletedValue):
(WebCore::IDBKeyDataHashTraits::emptyValue):
(WebCore::IDBKeyDataHashTraits::isEmptyValue):

* Modules/indexeddb/IndexedDB.h:

* Modules/indexeddb/client/IDBAnyImpl.cpp:
(WebCore::IDBClient::IDBAny::IDBAny):
(WebCore::IDBClient::IDBAny::modernIDBObjectStore):
* Modules/indexeddb/client/IDBAnyImpl.h:
(WebCore::IDBClient::IDBAny::create):

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::createObjectStore):
(WebCore::IDBClient::IDBConnectionToServer::didCreateObjectStore):
(WebCore::IDBClient::IDBConnectionToServer::putOrAdd):
(WebCore::IDBClient::IDBConnectionToServer::didPutOrAdd):
(WebCore::IDBClient::IDBConnectionToServer::getRecord):
(WebCore::IDBClient::IDBConnectionToServer::didGetRecord):
(WebCore::IDBClient::IDBConnectionToServer::saveOperation):
(WebCore::IDBClient::IDBConnectionToServer::completeOperation):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::autoIncrement):
(WebCore::IDBClient::IDBObjectStore::put):
(WebCore::IDBClient::IDBObjectStore::get):
(WebCore::IDBClient::IDBObjectStore::putOrAdd):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:
(WebCore::IDBClient::IDBObjectStore::info):

* Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:
(WebCore::IDBClient::IDBOpenDBRequest::IDBOpenDBRequest): Deleted.

* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::create):
(WebCore::IDBClient::IDBRequest::IDBRequest):
(WebCore::IDBClient::IDBRequest::sourceObjectStoreIdentifier):
(WebCore::IDBClient::IDBRequest::hasPendingActivity):
(WebCore::IDBClient::IDBRequest::dispatchEvent):
(WebCore::IDBClient::IDBRequest::setResult):
(WebCore::IDBClient::IDBRequest::setResultToStructuredClone):
(WebCore::IDBClient::IDBRequest::requestCompleted):
(WebCore::IDBClient::IDBRequest::onError):
(WebCore::IDBClient::IDBRequest::onSuccess):
* Modules/indexeddb/client/IDBRequestImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::IDBTransaction):
(WebCore::IDBClient::IDBTransaction::hasPendingActivity):
(WebCore::IDBClient::IDBTransaction::isActive):
(WebCore::IDBClient::IDBTransaction::operationTimerFired):
(WebCore::IDBClient::IDBTransaction::commit):
(WebCore::IDBClient::IDBTransaction::didAbort):
(WebCore::IDBClient::IDBTransaction::createObjectStoreOnServer):
(WebCore::IDBClient::IDBTransaction::requestGetRecord):
(WebCore::IDBClient::IDBTransaction::getRecordOnServer):
(WebCore::IDBClient::IDBTransaction::didGetRecordOnServer):
(WebCore::IDBClient::IDBTransaction::requestPutOrAdd):
(WebCore::IDBClient::IDBTransaction::putOrAddOnServer):
(WebCore::IDBClient::IDBTransaction::didPutOrAddOnServer):
(WebCore::IDBClient::IDBTransaction::activate):
(WebCore::IDBClient::IDBTransaction::deactivate):
* Modules/indexeddb/client/IDBTransactionImpl.h:
(WebCore::IDBClient::IDBTransaction::isReadOnly):
(WebCore::IDBClient::TransactionActivator::TransactionActivator):
(WebCore::IDBClient::TransactionActivator::~TransactionActivator):

* Modules/indexeddb/client/TransactionOperation.cpp:
(WebCore::IDBClient::TransactionOperation::TransactionOperation):
* Modules/indexeddb/client/TransactionOperation.h:
(WebCore::IDBClient::TransactionOperation::objectStoreIdentifier):
(WebCore::IDBClient::TransactionOperation::transaction):
(WebCore::IDBClient::createTransactionOperation):

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/IDBConnectionToClient.cpp:
(WebCore::IDBServer::IDBConnectionToClient::didPutOrAdd):
(WebCore::IDBServer::IDBConnectionToClient::didGetRecord):
* Modules/indexeddb/server/IDBConnectionToClient.h:
* Modules/indexeddb/server/IDBConnectionToClientDelegate.h:

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::putOrAdd):
(WebCore::IDBServer::IDBServer::getRecord):
* Modules/indexeddb/server/IDBServer.h:

* Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
(WebCore::IDBServer::MemoryBackingStoreTransaction::recordValueChanged):
(WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
* Modules/indexeddb/server/MemoryBackingStoreTransaction.h:

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::keyExistsInObjectStore):
(WebCore::IDBServer::MemoryIDBBackingStore::deleteRecord):
(WebCore::IDBServer::MemoryIDBBackingStore::putRecord):
(WebCore::IDBServer::MemoryIDBBackingStore::getRecord):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/MemoryObjectStore.cpp:
(WebCore::IDBServer::MemoryObjectStore::containsRecord):
(WebCore::IDBServer::MemoryObjectStore::deleteRecord):
(WebCore::IDBServer::MemoryObjectStore::putRecord):
(WebCore::IDBServer::MemoryObjectStore::valueForKey):
* Modules/indexeddb/server/MemoryObjectStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::storeCallback):
(WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformPutOrAdd):
(WebCore::IDBServer::UniqueIDBDatabase::getRecord):
(WebCore::IDBServer::UniqueIDBDatabase::performGetRecord):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformGetRecord):
(WebCore::IDBServer::UniqueIDBDatabase::performKeyDataCallback):
(WebCore::IDBServer::UniqueIDBDatabase::performValueDataCallback):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::isReadOnly):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:

* Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
(WebCore::IDBDatabaseInfo::infoForExistingObjectStore):
* Modules/indexeddb/shared/IDBDatabaseInfo.h:

* Modules/indexeddb/shared/IDBError.cpp:
(WebCore::idbErrorName):
(WebCore::idbErrorDescription):
* Modules/indexeddb/shared/IDBError.h:

* Modules/indexeddb/shared/IDBRequestData.cpp:
(WebCore::IDBRequestData::IDBRequestData):
(WebCore::IDBRequestData::serverConnectionIdentifier):
(WebCore::IDBRequestData::objectStoreIdentifier):
* Modules/indexeddb/shared/IDBRequestData.h:

* Modules/indexeddb/shared/IDBResultData.cpp:
(WebCore::IDBResultData::IDBResultData):
(WebCore::IDBResultData::putOrAddSuccess):
(WebCore::IDBResultData::getRecordSuccess):
* Modules/indexeddb/shared/IDBResultData.h:
(WebCore::IDBResultData::resultKey):
(WebCore::IDBResultData::resultData):

* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::didPutOrAdd):
(WebCore::InProcessIDBServer::didGetRecord):
(WebCore::InProcessIDBServer::putOrAdd):
(WebCore::InProcessIDBServer::getRecord):
* Modules/indexeddb/shared/InProcessIDBServer.h:

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::idbKeyToJSValue):
(WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
(WebCore::canInjectIDBKeyIntoScriptValue):
(WebCore::deserializeIDBValueData):
(WebCore::scriptValueToIDBKey):
(WebCore::idbKeyDataToScriptValue):
* bindings/js/IDBBindingUtilities.h:

* platform/CrossThreadCopier.cpp:
(WebCore::ThreadSafeDataBuffer&gt;::copy):
* platform/CrossThreadCopier.h:

* platform/ThreadSafeDataBuffer.h: Added.
(WebCore::ThreadSafeDataBufferImpl::ThreadSafeDataBufferImpl):
(WebCore::ThreadSafeDataBuffer::adoptVector):
(WebCore::ThreadSafeDataBuffer::copyVector):
(WebCore::ThreadSafeDataBuffer::ThreadSafeDataBuffer):
(WebCore::ThreadSafeDataBuffer::data):

LayoutTests:

* platform/mac-wk1/TestExpectations: Re-enable a test that can now be made reliable.

* storage/indexeddb/modern/basic-put-expected.txt: Added.
* storage/indexeddb/modern/basic-put.html: Added.
* storage/indexeddb/modern/createobjectstore-basic-expected.txt:
* storage/indexeddb/modern/createobjectstore-basic.html:
* storage/indexeddb/modern/keypath-basic-expected.txt: Added.
* storage/indexeddb/modern/keypath-basic.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk1TestExpectations">trunk/LayoutTests/platform/mac-wk1/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmoderncreateobjectstorebasicexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmoderncreateobjectstorebasichtml">trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic.html</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBKeyDatacpp">trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBKeyDatah">trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIndexedDBh">trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBAnyImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBAnyImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServercpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerh">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerDelegateh">trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBOpenDBRequestImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBRequestImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBRequestImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientTransactionOperationh">trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientcpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClienth">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientDelegateh">trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServerh">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactionh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryObjectStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseTransactionh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfocpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfoh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBErrorcpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBErrorh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatacpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatah">trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBResultDatacpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBResultDatah">trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServerh">trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiesh">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h</a></li>
<li><a href="#trunkSourceWebCoreplatformCrossThreadCopiercpp">trunk/Source/WebCore/platform/CrossThreadCopier.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformCrossThreadCopierh">trunk/Source/WebCore/platform/CrossThreadCopier.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernbasicputexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/basic-put-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernbasicputhtml">trunk/LayoutTests/storage/indexeddb/modern/basic-put.html</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernkeypathbasicexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/keypath-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernkeypathbasichtml">trunk/LayoutTests/storage/indexeddb/modern/keypath-basic.html</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientTransactionOperationcpp">trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformThreadSafeDataBufferh">trunk/Source/WebCore/platform/ThreadSafeDataBuffer.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/LayoutTests/ChangeLog        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2015-10-27  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Support IDBObjectStore.put/get support.
+        https://bugs.webkit.org/show_bug.cgi?id=150468
+
+        Reviewed by Alex Christensen.
+
+        * platform/mac-wk1/TestExpectations: Re-enable a test that can now be made reliable.
+        
+        * storage/indexeddb/modern/basic-put-expected.txt: Added.
+        * storage/indexeddb/modern/basic-put.html: Added.
+        * storage/indexeddb/modern/createobjectstore-basic-expected.txt:
+        * storage/indexeddb/modern/createobjectstore-basic.html:
+        * storage/indexeddb/modern/keypath-basic-expected.txt: Added.
+        * storage/indexeddb/modern/keypath-basic.html: Added.
+
</ins><span class="cx"> 2015-10-27  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking newly imported W3C html/semantics/forms tests as flaky on Windows
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk1TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk1/TestExpectations        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -73,9 +73,6 @@
</span><span class="cx"> # But Modern IndexedDB is.
</span><span class="cx"> storage/indexeddb/modern [ Pass ]
</span><span class="cx"> 
</span><del>-# Flakey, skipped until https://bugs.webkit.org/show_bug.cgi?id=150468 lets us implement a proper fix
-storage/indexeddb/modern/createobjectstore-basic.html
-
</del><span class="cx"> # Fails with WebKit1 only.
</span><span class="cx"> editing/secure-input/reset-state-on-navigation.html [ Failure ]
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernbasicputexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/basic-put-expected.txt (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/basic-put-expected.txt                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/basic-put-expected.txt        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+ALERT: Upgrade needed: Old version - 0 New version - 1
+ALERT: [object IDBTransaction] - versionchange
+ALERT: [object IDBDatabase]
+ALERT: put succeeded - key was 'foo'
+ALERT: get succeeded - value was 'bar'
+ALERT: version change transaction completed
+ALERT: Done
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernbasicputhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/basic-put.html (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/basic-put.html                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/basic-put.html        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+&lt;script&gt;
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+var request = window.indexedDB.open(&quot;NewDatabasePutTestDatabase&quot;);
+
+function done()
+{
+    alert(&quot;Done&quot;);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+request.onupgradeneeded = function(event) {
+    alert(&quot;Upgrade needed: Old version - &quot; + event.oldVersion + &quot; New version - &quot; + event.newVersion);
+    
+    var tx = request.transaction;
+    var db = event.target.result;
+
+    alert(tx + &quot; - &quot; + tx.mode);
+    alert(db);
+
+    var os = db.createObjectStore(&quot;TestObjectStore&quot;);
+    var putRequest = os.put(&quot;bar&quot;, &quot;foo&quot;);
+    
+    putRequest.onsuccess = function(event) {
+        alert(&quot;put succeeded - key was '&quot; + putRequest.result + &quot;'&quot;);
+        
+        var getRequest = os.get(&quot;foo&quot;);
+        getRequest.onsuccess = function(event) {
+            alert(&quot;get succeeded - value was '&quot; + getRequest.result + &quot;'&quot;);
+        }
+
+        getRequest.onerror = function(event) {
+            alert(&quot;get unexpectedly failed - &quot; + event);
+            done();
+        }
+    }
+
+    putRequest.onerror = function(event) {
+        alert(&quot;put unexpectedly failed - &quot; + event);
+        done();
+    }
+    
+    tx.onabort = function(event) {
+        alert(&quot;version change transaction unexpected abort&quot;);
+        done();
+    }
+
+    tx.oncomplete = function(event) {
+        alert(&quot;version change transaction completed&quot;);
+        done();
+    }
+
+    tx.onerror = function(event) {
+        alert(&quot;version change transaction unexpected error - &quot; + event);
+        done();
+    }
+}
+
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmoderncreateobjectstorebasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic-expected.txt (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic-expected.txt        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic-expected.txt        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> ALERT: Initial upgrade needed: Old version - 0 New version - 1
</span><span class="cx"> ALERT: Object store names:
</span><span class="cx"> ALERT: FirstAbortedObjectStore
</span><ins>+ALERT: Put succeeded
</ins><span class="cx"> ALERT: Initial upgrade versionchange transaction aborted
</span><span class="cx"> ALERT: Object store names:
</span><span class="cx"> ALERT: Second upgrade needed: Old version - 0 New version - 1
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmoderncreateobjectstorebasichtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic.html (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic.html        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/LayoutTests/storage/indexeddb/modern/createobjectstore-basic.html        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,13 +30,18 @@
</span><span class="cx">     var versionTransaction = createRequest.transaction;
</span><span class="cx">     var database = event.target.result;
</span><span class="cx">     var objectStore = database.createObjectStore(&quot;FirstAbortedObjectStore&quot;);
</span><ins>+    var request = objectStore.put(&quot;foo&quot;, &quot;bar&quot;);
</ins><span class="cx"> 
</span><del>-    var f = function() {
</del><ins>+    request.onsuccess = function(event) {
+        alert(&quot;Put succeeded&quot;);
</ins><span class="cx">         versionTransaction.abort();
</span><del>-    };
-
</del><ins>+    }
+    request.onerror = function(event) {
+        alert(&quot;Put failed - &quot; + event);
+        done();
+    }
+    
</ins><span class="cx">     dumpObjectStores(database);    
</span><del>-    setTimeout(f, 0);
</del><span class="cx">     
</span><span class="cx">     versionTransaction.onabort = function(event) {
</span><span class="cx">         alert(&quot;Initial upgrade versionchange transaction aborted&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernkeypathbasicexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/keypath-basic-expected.txt (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/keypath-basic-expected.txt                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/keypath-basic-expected.txt        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: object put SUCCESS - foo1
+ALERT: array put SUCCESS - foo2
+ALERT: Second object put SUCCESS - baz1
+ALERT: Second array put SUCCESS - baz2
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Done
+This test creates some object stores with keypaths.
+It then puts some values in them.
+It makes sure the keys used are as expected.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernkeypathbasichtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/keypath-basic.html (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/keypath-basic.html                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/keypath-basic.html        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+This test creates some object stores with keypaths.&lt;br&gt;
+It then puts some values in them.&lt;br&gt;
+It makes sure the keys used are as expected.&lt;br&gt;
+&lt;script&gt;
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert(&quot;Done&quot;);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open(&quot;KeypathBasicTestDatabase&quot;, 1);
+
+createRequest.onupgradeneeded = function(event) {
+    alert(&quot;Initial upgrade needed: Old version - &quot; + event.oldVersion + &quot; New version - &quot; + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    var database = event.target.result;    
+    var objectStore1 = database.createObjectStore(&quot;OS1&quot;, { keyPath: &quot;foo&quot; });
+    var objectStore2 = database.createObjectStore(&quot;OS2&quot;, { keyPath: &quot;foo.bar&quot; });
+
+    var object = new Object;
+    object.stuff = &quot;bar1&quot;;
+    object.foo = &quot;foo1&quot;;
+        
+    var request1 = objectStore1.put(object);
+    request1.onsuccess = function(event) {
+        alert(&quot;object put SUCCESS - &quot; + request1.result);
+    }
+
+    var array = { foo: &quot;foo2&quot;, stuff: &quot;bar2&quot; };
+
+    var request2 = objectStore1.put(array);
+    request2.onsuccess = function(event) {
+        alert(&quot;array put SUCCESS - &quot; + request2.result);
+    }
+    
+    object.foo = new Object;
+    object.foo.bar = &quot;baz1&quot;;
+    var request3 = objectStore2.put(object);
+    request3.onsuccess = function(event) {
+        alert(&quot;Second object put SUCCESS - &quot; + request3.result);
+    }
+
+    array.foo = { bar: &quot;baz2&quot; };
+
+    var request4 = objectStore2.put(array);
+    request4.onsuccess = function(event) {
+        alert(&quot;Second array put SUCCESS - &quot; + request4.result);
+    }
+
+    versionTransaction.onabort = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction unexpected aborted&quot;);
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction complete&quot;);
+        done();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction unexpected error&quot; + event);
+        done();
+    }
+}
+
+&lt;/script&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -876,6 +876,7 @@
</span><span class="cx">     Modules/indexeddb/client/IDBRequestImpl.cpp
</span><span class="cx">     Modules/indexeddb/client/IDBTransactionImpl.cpp
</span><span class="cx">     Modules/indexeddb/client/IDBVersionChangeEventImpl.cpp
</span><ins>+    Modules/indexeddb/client/TransactionOperation.cpp
</ins><span class="cx"> 
</span><span class="cx">     Modules/indexeddb/legacy/IDBCursorBackend.cpp
</span><span class="cx">     Modules/indexeddb/legacy/IDBCursorBackendOperations.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/ChangeLog        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -1,3 +1,204 @@
</span><ins>+2015-10-27  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Support IDBObjectStore.put/get support.
+        https://bugs.webkit.org/show_bug.cgi?id=150468
+
+        Reviewed by Alex Christensen.
+
+        Tests: storage/indexeddb/modern/basic-put.html
+               storage/indexeddb/modern/keypath-basic.html
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * Modules/indexeddb/IDBKeyData.cpp:
+        (WebCore::IDBKeyData::deletedValue):
+        (WebCore::IDBKeyData::operator&lt;):
+        (WebCore::IDBKeyData::operator==):
+        * Modules/indexeddb/IDBKeyData.h:
+        (WebCore::IDBKeyData::isValid):
+        (WebCore::IDBKeyData::operator!=):
+        (WebCore::IDBKeyData::hash):
+        (WebCore::IDBKeyData::isDeletedValue):
+        (WebCore::IDBKeyDataHash::hash):
+        (WebCore::IDBKeyDataHash::equal):
+        (WebCore::IDBKeyDataHashTraits::constructDeletedValue):
+        (WebCore::IDBKeyDataHashTraits::isDeletedValue):
+        (WebCore::IDBKeyDataHashTraits::emptyValue):
+        (WebCore::IDBKeyDataHashTraits::isEmptyValue):
+
+        * Modules/indexeddb/IndexedDB.h:
+
+        * Modules/indexeddb/client/IDBAnyImpl.cpp:
+        (WebCore::IDBClient::IDBAny::IDBAny):
+        (WebCore::IDBClient::IDBAny::modernIDBObjectStore):
+        * Modules/indexeddb/client/IDBAnyImpl.h:
+        (WebCore::IDBClient::IDBAny::create):
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::createObjectStore):
+        (WebCore::IDBClient::IDBConnectionToServer::didCreateObjectStore):
+        (WebCore::IDBClient::IDBConnectionToServer::putOrAdd):
+        (WebCore::IDBClient::IDBConnectionToServer::didPutOrAdd):
+        (WebCore::IDBClient::IDBConnectionToServer::getRecord):
+        (WebCore::IDBClient::IDBConnectionToServer::didGetRecord):
+        (WebCore::IDBClient::IDBConnectionToServer::saveOperation):
+        (WebCore::IDBClient::IDBConnectionToServer::completeOperation):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::autoIncrement):
+        (WebCore::IDBClient::IDBObjectStore::put):
+        (WebCore::IDBClient::IDBObjectStore::get):
+        (WebCore::IDBClient::IDBObjectStore::putOrAdd):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+        (WebCore::IDBClient::IDBObjectStore::info):
+
+        * Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBOpenDBRequest::IDBOpenDBRequest): Deleted.
+
+        * Modules/indexeddb/client/IDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBRequest::create):
+        (WebCore::IDBClient::IDBRequest::IDBRequest):
+        (WebCore::IDBClient::IDBRequest::sourceObjectStoreIdentifier):
+        (WebCore::IDBClient::IDBRequest::hasPendingActivity):
+        (WebCore::IDBClient::IDBRequest::dispatchEvent):
+        (WebCore::IDBClient::IDBRequest::setResult):
+        (WebCore::IDBClient::IDBRequest::setResultToStructuredClone):
+        (WebCore::IDBClient::IDBRequest::requestCompleted):
+        (WebCore::IDBClient::IDBRequest::onError):
+        (WebCore::IDBClient::IDBRequest::onSuccess):
+        * Modules/indexeddb/client/IDBRequestImpl.h:
+
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::IDBTransaction):
+        (WebCore::IDBClient::IDBTransaction::hasPendingActivity):
+        (WebCore::IDBClient::IDBTransaction::isActive):
+        (WebCore::IDBClient::IDBTransaction::operationTimerFired):
+        (WebCore::IDBClient::IDBTransaction::commit):
+        (WebCore::IDBClient::IDBTransaction::didAbort):
+        (WebCore::IDBClient::IDBTransaction::createObjectStoreOnServer):
+        (WebCore::IDBClient::IDBTransaction::requestGetRecord):
+        (WebCore::IDBClient::IDBTransaction::getRecordOnServer):
+        (WebCore::IDBClient::IDBTransaction::didGetRecordOnServer):
+        (WebCore::IDBClient::IDBTransaction::requestPutOrAdd):
+        (WebCore::IDBClient::IDBTransaction::putOrAddOnServer):
+        (WebCore::IDBClient::IDBTransaction::didPutOrAddOnServer):
+        (WebCore::IDBClient::IDBTransaction::activate):
+        (WebCore::IDBClient::IDBTransaction::deactivate):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+        (WebCore::IDBClient::IDBTransaction::isReadOnly):
+        (WebCore::IDBClient::TransactionActivator::TransactionActivator):
+        (WebCore::IDBClient::TransactionActivator::~TransactionActivator):
+
+        * Modules/indexeddb/client/TransactionOperation.cpp: 
+        (WebCore::IDBClient::TransactionOperation::TransactionOperation):
+        * Modules/indexeddb/client/TransactionOperation.h:
+        (WebCore::IDBClient::TransactionOperation::objectStoreIdentifier):
+        (WebCore::IDBClient::TransactionOperation::transaction):
+        (WebCore::IDBClient::createTransactionOperation):
+
+        * Modules/indexeddb/server/IDBBackingStore.h:
+        
+        * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+        (WebCore::IDBServer::IDBConnectionToClient::didPutOrAdd):
+        (WebCore::IDBServer::IDBConnectionToClient::didGetRecord):
+        * Modules/indexeddb/server/IDBConnectionToClient.h:
+        * Modules/indexeddb/server/IDBConnectionToClientDelegate.h:
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::putOrAdd):
+        (WebCore::IDBServer::IDBServer::getRecord):
+        * Modules/indexeddb/server/IDBServer.h:
+
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::recordValueChanged):
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.h:
+
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::keyExistsInObjectStore):
+        (WebCore::IDBServer::MemoryIDBBackingStore::deleteRecord):
+        (WebCore::IDBServer::MemoryIDBBackingStore::putRecord):
+        (WebCore::IDBServer::MemoryIDBBackingStore::getRecord):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+
+        * Modules/indexeddb/server/MemoryObjectStore.cpp:
+        (WebCore::IDBServer::MemoryObjectStore::containsRecord):
+        (WebCore::IDBServer::MemoryObjectStore::deleteRecord):
+        (WebCore::IDBServer::MemoryObjectStore::putRecord):
+        (WebCore::IDBServer::MemoryObjectStore::valueForKey):
+        * Modules/indexeddb/server/MemoryObjectStore.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::storeCallback):
+        (WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformPutOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabase::getRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::performGetRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformGetRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::performKeyDataCallback):
+        (WebCore::IDBServer::UniqueIDBDatabase::performValueDataCallback):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::isReadOnly):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
+
+        * Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
+        (WebCore::IDBDatabaseInfo::infoForExistingObjectStore):
+        * Modules/indexeddb/shared/IDBDatabaseInfo.h:
+
+        * Modules/indexeddb/shared/IDBError.cpp:
+        (WebCore::idbErrorName):
+        (WebCore::idbErrorDescription):
+        * Modules/indexeddb/shared/IDBError.h:
+
+        * Modules/indexeddb/shared/IDBRequestData.cpp:
+        (WebCore::IDBRequestData::IDBRequestData):
+        (WebCore::IDBRequestData::serverConnectionIdentifier):
+        (WebCore::IDBRequestData::objectStoreIdentifier):
+        * Modules/indexeddb/shared/IDBRequestData.h:
+
+        * Modules/indexeddb/shared/IDBResultData.cpp:
+        (WebCore::IDBResultData::IDBResultData):
+        (WebCore::IDBResultData::putOrAddSuccess):
+        (WebCore::IDBResultData::getRecordSuccess):
+        * Modules/indexeddb/shared/IDBResultData.h:
+        (WebCore::IDBResultData::resultKey):
+        (WebCore::IDBResultData::resultData):
+
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::didPutOrAdd):
+        (WebCore::InProcessIDBServer::didGetRecord):
+        (WebCore::InProcessIDBServer::putOrAdd):
+        (WebCore::InProcessIDBServer::getRecord):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::idbKeyToJSValue):
+        (WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
+        (WebCore::canInjectIDBKeyIntoScriptValue):
+        (WebCore::deserializeIDBValueData):
+        (WebCore::scriptValueToIDBKey):
+        (WebCore::idbKeyDataToScriptValue):
+        * bindings/js/IDBBindingUtilities.h:
+
+        * platform/CrossThreadCopier.cpp:
+        (WebCore::ThreadSafeDataBuffer&gt;::copy):
+        * platform/CrossThreadCopier.h:
+
+        * platform/ThreadSafeDataBuffer.h: Added.
+        (WebCore::ThreadSafeDataBufferImpl::ThreadSafeDataBufferImpl):
+        (WebCore::ThreadSafeDataBuffer::adoptVector):
+        (WebCore::ThreadSafeDataBuffer::copyVector):
+        (WebCore::ThreadSafeDataBuffer::ThreadSafeDataBuffer):
+        (WebCore::ThreadSafeDataBuffer::data):
+
</ins><span class="cx"> 2015-10-27  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WKView being inside WKWebView leads to weird API issues
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBKeyDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -319,6 +319,45 @@
</span><span class="cx">     m_isNull = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBKeyData IDBKeyData::deletedValue()
+{
+    IDBKeyData result;
+    result.m_isNull = false;
+    result.m_isDeletedValue = true;
+    return WTF::move(result);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool IDBKeyData::operator&lt;(const IDBKeyData&amp; rhs) const
+{
+    return compare(rhs) &lt; 0;
+}
+
+bool IDBKeyData::operator==(const IDBKeyData&amp; other) const
+{
+    if (m_type != other.m_type || m_isNull != other.m_isNull || m_isDeletedValue != other.m_isDeletedValue)
+        return false;
+    switch (m_type) {
+    case KeyType::Invalid:
+    case KeyType::Max:
+    case KeyType::Min:
+        return true;
+    case KeyType::Number:
+    case KeyType::Date:
+        return m_numberValue == other.m_numberValue;
+    case KeyType::String:
+        return m_stringValue == other.m_stringValue;
+    case KeyType::Array:
+        if (m_arrayValue.size() != other.m_arrayValue.size())
+            return false;
+        for (size_t i = 0; i &lt; m_arrayValue.size(); ++i) {
+            if (m_arrayValue[0] != other.m_arrayValue[0])
+                return false;
+        }
+        return true;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WebCore
+
</ins><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBKeyDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBKeyData.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBKey.h&quot;
</span><ins>+#include &lt;wtf/text/StringHash.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -87,16 +88,89 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool isNull() const { return m_isNull; }
</span><ins>+    bool isValid() const { return m_type != KeyType::Invalid; }
</ins><span class="cx">     KeyType type() const { return m_type; }
</span><span class="cx"> 
</span><ins>+    bool operator&lt;(const IDBKeyData&amp;) const;
+    bool operator==(const IDBKeyData&amp; other) const;
+    bool operator!=(const IDBKeyData&amp; other) const
+    {
+        return !(*this == other);
+    }
+
+    unsigned hash() const
+    {
+        Vector&lt;unsigned&gt; hashCodes;
+        hashCodes.append(static_cast&lt;unsigned&gt;(m_type));
+        hashCodes.append(m_isNull ? 1 : 0);
+        hashCodes.append(m_isDeletedValue ? 1 : 0);
+        switch (m_type) {
+        case KeyType::Invalid:
+        case KeyType::Max:
+        case KeyType::Min:
+            break;
+        case KeyType::Number:
+        case KeyType::Date:
+            hashCodes.append(StringHasher::hashMemory&lt;sizeof(double)&gt;(&amp;m_numberValue));
+            break;
+        case KeyType::String:
+            hashCodes.append(StringHash::hash(m_stringValue));
+            break;
+        case KeyType::Array:
+            for (auto&amp; key : m_arrayValue)
+                hashCodes.append(key.hash());
+            break;
+        }
+
+        unsigned targetSize = WTF::roundUpToPowerOfTwo(hashCodes.size());
+        hashCodes.resize(targetSize);
+
+        return StringHasher::hashMemory(hashCodes.data(), hashCodes.size() * sizeof(unsigned));
+    }
+
+    static IDBKeyData deletedValue();
+    bool isDeletedValue() const { return m_isDeletedValue; }
+
</ins><span class="cx"> private:
</span><span class="cx">     KeyType m_type;
</span><span class="cx">     Vector&lt;IDBKeyData&gt; m_arrayValue;
</span><span class="cx">     String m_stringValue;
</span><span class="cx">     double m_numberValue { 0 };
</span><span class="cx">     bool m_isNull { false };
</span><ins>+    bool m_isDeletedValue { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct IDBKeyDataHash {
+    static unsigned hash(const IDBKeyData&amp; a) { return a.hash(); }
+    static bool equal(const IDBKeyData&amp; a, const IDBKeyData&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+struct IDBKeyDataHashTraits : public WTF::CustomHashTraits&lt;IDBKeyData&gt; {
+    static const bool emptyValueIsZero = false;
+    static const bool hasIsEmptyValueFunction = true;
+
+    static void constructDeletedValue(IDBKeyData&amp; key)
+    {
+        key = IDBKeyData::deletedValue();
+    }
+
+    static bool isDeletedValue(const IDBKeyData&amp; key)
+    {
+        return key.isDeletedValue();
+    }
+
+    static IDBKeyData emptyValue()
+    {
+        return IDBKeyData();
+    }
+
+    static bool isEmptyValue(const IDBKeyData&amp; key)
+    {
+        return key.isNull();
+    }
+};
+
</ins><span class="cx"> template&lt;class Encoder&gt;
</span><span class="cx"> void IDBKeyData::encode(Encoder&amp; encoder) const
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIndexedDBh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -41,7 +41,8 @@
</span><span class="cx"> 
</span><span class="cx"> enum class TransactionState {
</span><span class="cx">     Unstarted,
</span><del>-    Running,
</del><ins>+    Active,
+    Inactive,
</ins><span class="cx">     Committing,
</span><span class="cx">     Aborting,
</span><span class="cx">     Finished,
</span><span class="lines">@@ -71,7 +72,12 @@
</span><span class="cx">     String,
</span><span class="cx">     Array,
</span><span class="cx"> };
</span><del>-    
</del><ins>+
+enum class ObjectStoreOverwriteMode {
+    Overwrite,
+    NoOverwrite,
+};
+
</ins><span class="cx"> // In order of the least to the highest precedent in terms of sort order.
</span><span class="cx"> enum KeyType {
</span><span class="cx">     Max = -1,
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBAnyImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -42,6 +42,18 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBAny::IDBAny(Ref&lt;IDBObjectStore&gt;&amp;&amp; objectStore)
+    : m_type(IDBAny::Type::IDBObjectStore)
+    , m_objectStore(adoptRef(&amp;objectStore.leakRef()))
+{
+}
+
+IDBAny::IDBAny(const Deprecated::ScriptValue&amp; value)
+    : m_type(IDBAny::Type::ScriptValue)
+    , m_scriptValue(value)
+{
+}
+
</ins><span class="cx"> IDBAny::~IDBAny()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -82,6 +94,12 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBObjectStore* IDBAny::modernIDBObjectStore()
+{
+    ASSERT(m_type == IDBAny::Type::IDBObjectStore);
+    return m_objectStore.get();
+}
+
</ins><span class="cx"> RefPtr&lt;WebCore::IDBTransaction&gt; IDBAny::idbTransaction()
</span><span class="cx"> {
</span><span class="cx">     return nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBAnyImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBAny.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseImpl.h&quot;
</span><ins>+#include &quot;IDBObjectStoreImpl.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="lines">@@ -41,6 +42,16 @@
</span><span class="cx">         return adoptRef(new IDBAny(WTF::move(database)));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static RefPtr&lt;IDBAny&gt; create(Ref&lt;IDBObjectStore&gt;&amp;&amp; objectStore)
+    {
+        return adoptRef(new IDBAny(WTF::move(objectStore)));
+    }
+
+    static RefPtr&lt;IDBAny&gt; create(const Deprecated::ScriptValue&amp; value)
+    {
+        return adoptRef(new IDBAny(value));
+    }
+
</ins><span class="cx">     virtual ~IDBAny();
</span><span class="cx"> 
</span><span class="cx">     virtual Type type() const override final { return m_type; }
</span><span class="lines">@@ -57,11 +68,17 @@
</span><span class="cx">     virtual const String&amp; string() override final;
</span><span class="cx">     virtual const IDBKeyPath&amp; keyPath() override final;
</span><span class="cx"> 
</span><ins>+    IDBObjectStore* modernIDBObjectStore();
+
</ins><span class="cx"> private:
</span><del>-    IDBAny(Ref&lt;IDBDatabase&gt;&amp;&amp;);
</del><ins>+    explicit IDBAny(Ref&lt;IDBDatabase&gt;&amp;&amp;);
+    explicit IDBAny(Ref&lt;IDBObjectStore&gt;&amp;&amp;);
+    explicit IDBAny(const Deprecated::ScriptValue&amp;);
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     IDBAny::Type m_type { IDBAny::Type::Undefined };
</span><span class="cx">     RefPtr&lt;IDBDatabase&gt; m_database;
</span><ins>+    RefPtr&lt;IDBObjectStore&gt; m_objectStore;
</ins><span class="cx"> 
</span><span class="cx">     const IDBKeyPath m_idbKeyPath;
</span><span class="cx">     const Deprecated::ScriptValue m_scriptValue;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -98,8 +98,7 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBConnectionToServer::createObjectStore&quot;);
</span><span class="cx"> 
</span><del>-    ASSERT(!m_activeOperations.contains(operation.identifier()));
-    m_activeOperations.set(operation.identifier(), &amp;operation);
</del><ins>+    saveOperation(operation);
</ins><span class="cx"> 
</span><span class="cx">     m_delegate-&gt;createObjectStore(IDBRequestData(operation), info);
</span><span class="cx"> }
</span><span class="lines">@@ -107,13 +106,39 @@
</span><span class="cx"> void IDBConnectionToServer::didCreateObjectStore(const IDBResultData&amp; resultData)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBConnectionToServer::didCreateObjectStore&quot;);
</span><ins>+    completeOperation(resultData);
+}
</ins><span class="cx"> 
</span><del>-    auto operation = m_activeOperations.take(resultData.requestIdentifier());
-    ASSERT(operation);
</del><ins>+void IDBConnectionToServer::putOrAdd(TransactionOperation&amp; operation, RefPtr&lt;IDBKey&gt;&amp; key, RefPtr&lt;SerializedScriptValue&gt;&amp; value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    LOG(IndexedDB, &quot;IDBConnectionToServer::putOrAdd&quot;);
</ins><span class="cx"> 
</span><del>-    operation-&gt;completed(resultData);
</del><ins>+    saveOperation(operation);
+    m_delegate-&gt;putOrAdd(IDBRequestData(operation), key.get(), *value, overwriteMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBConnectionToServer::didPutOrAdd(const IDBResultData&amp; resultData)
+{
+    LOG(IndexedDB, &quot;IDBConnectionToServer::didPutOrAdd&quot;);
+    completeOperation(resultData);
+}
+
+void IDBConnectionToServer::getRecord(TransactionOperation&amp; operation, RefPtr&lt;IDBKey&gt;&amp; key)
+{
+    LOG(IndexedDB, &quot;IDBConnectionToServer::getRecord&quot;);
+
+    ASSERT(key);
+
+    saveOperation(operation);
+    m_delegate-&gt;getRecord(IDBRequestData(operation), key.get());
+}
+
+void IDBConnectionToServer::didGetRecord(const IDBResultData&amp; resultData)
+{
+    LOG(IndexedDB, &quot;IDBConnectionToServer::didGetRecord&quot;);
+    completeOperation(resultData);
+}
+
</ins><span class="cx"> void IDBConnectionToServer::commitTransaction(IDBTransaction&amp; transaction)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBConnectionToServer::commitTransaction&quot;);
</span><span class="lines">@@ -185,6 +210,20 @@
</span><span class="cx">     m_databaseConnectionMap.remove(database.databaseConnectionIdentifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBConnectionToServer::saveOperation(TransactionOperation&amp; operation)
+{
+    ASSERT(!m_activeOperations.contains(operation.identifier()));
+    m_activeOperations.set(operation.identifier(), &amp;operation);
+}
+
+void IDBConnectionToServer::completeOperation(const IDBResultData&amp; resultData)
+{
+    auto operation = m_activeOperations.take(resultData.requestIdentifier());
+    ASSERT(operation);
+
+    operation-&gt;completed(resultData);
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> class IDBDatabase;
</span><span class="cx"> class IDBOpenDBRequest;
</span><span class="cx"> class IDBTransaction;
</span><ins>+class TransactionOperation;
</ins><span class="cx"> 
</span><span class="cx"> class IDBConnectionToServer : public RefCounted&lt;IDBConnectionToServer&gt; {
</span><span class="cx"> public:
</span><span class="lines">@@ -63,6 +64,12 @@
</span><span class="cx">     void createObjectStore(TransactionOperation&amp;, const IDBObjectStoreInfo&amp;);
</span><span class="cx">     void didCreateObjectStore(const IDBResultData&amp;);
</span><span class="cx"> 
</span><ins>+    void putOrAdd(TransactionOperation&amp;, RefPtr&lt;IDBKey&gt;&amp;, RefPtr&lt;SerializedScriptValue&gt;&amp;, const IndexedDB::ObjectStoreOverwriteMode);
+    void didPutOrAdd(const IDBResultData&amp;);
+
+    void getRecord(TransactionOperation&amp;, RefPtr&lt;IDBKey&gt;&amp;);
+    void didGetRecord(const IDBResultData&amp;);
+
</ins><span class="cx">     void commitTransaction(IDBTransaction&amp;);
</span><span class="cx">     void didCommitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -77,7 +84,10 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     IDBConnectionToServer(IDBConnectionToServerDelegate&amp;);
</span><del>-    
</del><ins>+
+    void saveOperation(TransactionOperation&amp;);
+    void completeOperation(const IDBResultData&amp;);
+
</ins><span class="cx">     Ref&lt;IDBConnectionToServerDelegate&gt; m_delegate;
</span><span class="cx"> 
</span><span class="cx">     HashMap&lt;IDBResourceIdentifier, RefPtr&lt;IDBClient::IDBOpenDBRequest&gt;&gt; m_openDBRequestMap;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerDelegateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,10 +30,16 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class IDBKey;
</ins><span class="cx"> class IDBObjectStoreInfo;
</span><span class="cx"> class IDBRequestData;
</span><span class="cx"> class IDBResourceIdentifier;
</span><ins>+class SerializedScriptValue;
</ins><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class ObjectStoreOverwriteMode;
+}
+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class IDBConnectionToServerDelegate {
</span><span class="lines">@@ -46,6 +52,9 @@
</span><span class="cx">     virtual void abortTransaction(IDBResourceIdentifier&amp;) = 0;
</span><span class="cx">     virtual void commitTransaction(IDBResourceIdentifier&amp;) = 0;
</span><span class="cx">     virtual void createObjectStore(const IDBRequestData&amp;, const IDBObjectStoreInfo&amp;) = 0;
</span><ins>+    virtual void putOrAdd(const IDBRequestData&amp;, IDBKey*, SerializedScriptValue&amp;, const IndexedDB::ObjectStoreOverwriteMode) = 0;
+    virtual void getRecord(const IDBRequestData&amp;, IDBKey*) = 0;
+
</ins><span class="cx">     virtual void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) = 0;
</span><span class="cx"> 
</span><span class="cx">     virtual void ref() = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -28,7 +28,15 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;DOMRequestState.h&quot;
+#include &quot;IDBBindingUtilities.h&quot;
+#include &quot;IDBError.h&quot;
+#include &quot;IDBKey.h&quot;
+#include &quot;IDBRequestImpl.h&quot;
</ins><span class="cx"> #include &quot;IDBTransactionImpl.h&quot;
</span><ins>+#include &quot;IndexedDB.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;SerializedScriptValue.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="lines">@@ -80,7 +88,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool IDBObjectStore::autoIncrement() const
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    return m_info.autoIncrement();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::add(JSC::ExecState&amp;, Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</span><span class="lines">@@ -88,9 +96,9 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::put(JSC::ExecState&amp;, Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::put(JSC::ExecState&amp; state, Deprecated::ScriptValue&amp; value, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::openCursor(ScriptExecutionContext*, ExceptionCode&amp;)
</span><span class="lines">@@ -118,9 +126,34 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::get(ScriptExecutionContext*, const Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::get(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBObjectStore::get&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    if (!m_transaction-&gt;isActive()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
+    if (m_deleted) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    DOMRequestState requestState(context);
+    RefPtr&lt;IDBKey&gt; idbKey = scriptValueToIDBKey(&amp;requestState, key);
+    if (!idbKey || idbKey-&gt;type() == KeyType::Invalid) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    Ref&lt;IDBRequest&gt; request = m_transaction-&gt;requestGetRecord(*context, *this, *idbKey);
+    return adoptRef(request.leakRef());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;)
</span><span class="lines">@@ -133,11 +166,94 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::put(JSC::ExecState&amp;, Deprecated::ScriptValue&amp;, const Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::put(JSC::ExecState&amp; execState, Deprecated::ScriptValue&amp; value, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    auto idbKey = scriptValueToIDBKey(execState, key);
+    return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::putOrAdd(JSC::ExecState&amp; state, Deprecated::ScriptValue&amp; value, RefPtr&lt;IDBKey&gt; key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode&amp; ec)
+{
+    LOG(IndexedDB, &quot;IDBObjectStore::putOrAdd&quot;);
+
+    if (m_transaction-&gt;isReadOnly()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::ReadOnlyError);
+        return nullptr;
+    }
+
+    if (!m_transaction-&gt;isActive()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
+    if (m_deleted) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    RefPtr&lt;SerializedScriptValue&gt; serializedValue = SerializedScriptValue::create(&amp;state, value.jsValue(), nullptr, nullptr);
+    if (state.hadException()) {
+        ec = DATA_CLONE_ERR;
+        return nullptr;
+    }
+
+    if (serializedValue-&gt;hasBlobURLs()) {
+        // FIXME: Add Blob/File/FileList support
+        ec = DATA_CLONE_ERR;
+        return nullptr;
+    }
+
+    if (key &amp;&amp; key-&gt;type() == KeyType::Invalid) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    bool usesInlineKeys = !m_info.keyPath().isNull();
+    bool usesKeyGenerator = autoIncrement();
+    if (usesInlineKeys) {
+        if (key) {
+            ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+            return nullptr;
+        }
+
+        RefPtr&lt;IDBKey&gt; keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath());
+        if (keyPathKey &amp;&amp; !keyPathKey-&gt;isValid()) {
+            ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+            return nullptr;
+        }
+
+        if (!keyPathKey) {
+            if (usesKeyGenerator) {
+                if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) {
+                    ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+                    return nullptr;
+                }
+            } else {
+                ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+                return nullptr;
+            }
+        }
+
+        if (keyPathKey) {
+            ASSERT(!key);
+            key = keyPathKey;
+        }
+    } else if (!usesKeyGenerator &amp;&amp; !key) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    auto context = scriptExecutionContextFromExecState(&amp;state);
+    if (!context) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::Unknown);
+        return nullptr;
+    }
+
+    Ref&lt;IDBRequest&gt; request = m_transaction-&gt;requestPutOrAdd(*context, *this, key.get(), *serializedValue, overwriteMode);
+    return adoptRef(request.leakRef());
+}
+
+
</ins><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBObjectStore::deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,8 +30,12 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBObjectStore.h&quot;
</span><span class="cx"> #include &quot;IDBObjectStoreInfo.h&quot;
</span><ins>+#include &quot;IndexedDB.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+
+class IDBKey;
+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class IDBTransaction;
</span><span class="lines">@@ -72,11 +76,17 @@
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBRequest&gt; count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;) override final;
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBRequest&gt; count(ScriptExecutionContext*, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp;) override final;
</span><span class="cx"> 
</span><ins>+    const IDBObjectStoreInfo&amp; info() const { return m_info; }
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBObjectStore(const IDBObjectStoreInfo&amp;, IDBTransaction&amp;);
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;WebCore::IDBRequest&gt; putOrAdd(JSC::ExecState&amp;, Deprecated::ScriptValue&amp;, RefPtr&lt;IDBKey&gt;, IndexedDB::ObjectStoreOverwriteMode, ExceptionCode&amp;);
+
</ins><span class="cx">     IDBObjectStoreInfo m_info;
</span><span class="cx">     Ref&lt;IDBTransaction&gt; m_transaction;
</span><ins>+
+    bool m_deleted { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBOpenDBRequestImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBOpenDBRequestImpl.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -55,7 +55,6 @@
</span><span class="cx">     , m_databaseIdentifier(databaseIdentifier)
</span><span class="cx">     , m_version(version)
</span><span class="cx"> {
</span><del>-    suspendIfNeeded();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBOpenDBRequest::~IDBOpenDBRequest()
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBRequestImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -29,19 +29,41 @@
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;EventQueue.h&quot;
</span><ins>+#include &quot;IDBBindingUtilities.h&quot;
+#include &quot;IDBEventDispatcher.h&quot;
+#include &quot;IDBKeyData.h&quot;
+#include &quot;IDBResultData.h&quot;
+#include &quot;Logging.h&quot;
</ins><span class="cx"> #include &quot;ScriptExecutionContext.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><ins>+Ref&lt;IDBRequest&gt; IDBRequest::create(ScriptExecutionContext&amp; context, IDBObjectStore&amp; objectStore, IDBTransaction&amp; transaction)
+{
+    return adoptRef(*new IDBRequest(context, objectStore, transaction));
+}
+
</ins><span class="cx"> IDBRequest::IDBRequest(IDBConnectionToServer&amp; connection, ScriptExecutionContext* context)
</span><span class="cx">     : IDBOpenDBRequest(context)
</span><span class="cx">     , m_connection(connection)
</span><span class="cx">     , m_resourceIdentifier(connection)
</span><span class="cx"> {
</span><ins>+    suspendIfNeeded();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBRequest::IDBRequest(ScriptExecutionContext&amp; context, IDBObjectStore&amp; objectStore, IDBTransaction&amp; transaction)
+    : IDBOpenDBRequest(&amp;context)
+    , m_transaction(&amp;transaction)
+    , m_connection(transaction.serverConnection())
+    , m_resourceIdentifier(transaction.serverConnection())
+    , m_source(adoptRef(*IDBAny::create(objectStore).leakRef()))
+{
+    suspendIfNeeded();
+}
+
</ins><span class="cx"> IDBRequest::~IDBRequest()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -77,6 +99,18 @@
</span><span class="cx">     return readyState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint64_t IDBRequest::sourceObjectStoreIdentifier() const
+{
+    if (!m_source)
+        return 0;
+    if (m_source-&gt;type() != IDBAny::Type::IDBObjectStore)
+        return 0;
+    if (!m_source-&gt;modernIDBObjectStore())
+        return 0;
+
+    return m_source-&gt;modernIDBObjectStore()-&gt;info().identifier();
+}
+
</ins><span class="cx"> EventTargetInterface IDBRequest::eventTargetInterface() const
</span><span class="cx"> {
</span><span class="cx">     return IDBRequestEventTargetInterfaceType;
</span><span class="lines">@@ -92,6 +126,11 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool IDBRequest::hasPendingActivity() const
+{
+    return m_hasPendingActivity;
+}
+
</ins><span class="cx"> void IDBRequest::enqueueEvent(Ref&lt;Event&gt;&amp;&amp; event)
</span><span class="cx"> {
</span><span class="cx">     if (!scriptExecutionContext())
</span><span class="lines">@@ -101,6 +140,82 @@
</span><span class="cx">     scriptExecutionContext()-&gt;eventQueue().enqueueEvent(&amp;event.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool IDBRequest::dispatchEvent(PassRefPtr&lt;Event&gt; prpEvent)
+{
+    LOG(IndexedDB, &quot;IDBRequest::dispatchEvent - %s&quot;, prpEvent-&gt;type().characters8());
+
+    RefPtr&lt;Event&gt; event = prpEvent;
+
+    if (event-&gt;type() != eventNames().blockedEvent)
+        m_readyState = IDBRequestReadyState::Done;
+
+    Vector&lt;RefPtr&lt;EventTarget&gt;&gt; targets;
+    targets.append(this);
+
+    if (m_transaction) {
+        targets.append(m_transaction);
+        targets.append(m_transaction-&gt;db());
+    }
+
+    bool dontPreventDefault;
+    {
+        TransactionActivator activator(m_transaction.get());
+        dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets);
+    }
+
+    m_hasPendingActivity = false;
+
+    return dontPreventDefault;
+}
+
+void IDBRequest::setResult(const IDBKeyData* keyData)
+{
+    if (!keyData) {
+        m_result = nullptr;
+        return;
+    }
+
+    Deprecated::ScriptValue value = idbKeyDataToScriptValue(scriptExecutionContext(), *keyData);
+    m_result = IDBAny::create(WTF::move(value));
+}
+
+void IDBRequest::setResultToStructuredClone(const ThreadSafeDataBuffer&amp; valueData)
+{
+    LOG(IndexedDB, &quot;IDBRequest::setResultToStructuredClone&quot;);
+
+    auto context = scriptExecutionContext();
+    if (!context)
+        return;
+
+    Deprecated::ScriptValue value = deserializeIDBValueData(*context, valueData);
+    m_result = IDBAny::create(WTF::move(value));
+}
+
+void IDBRequest::requestCompleted(const IDBResultData&amp; resultData)
+{
+    m_idbError = resultData.error();
+    if (!m_idbError.isNull())
+        onError();
+    else
+        onSuccess();
+}
+
+void IDBRequest::onError()
+{
+    LOG(IndexedDB, &quot;IDBRequest::onError&quot;);
+
+    ASSERT(!m_idbError.isNull());
+    m_domError = DOMError::create(m_idbError.name());
+    enqueueEvent(Event::create(eventNames().errorEvent, true, true));
+}
+
+void IDBRequest::onSuccess()
+{
+    LOG(IndexedDB, &quot;IDBRequest::onSuccess&quot;);
+
+    enqueueEvent(Event::create(eventNames().successEvent, false, false));
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBRequestImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -37,14 +37,19 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Event;
</span><ins>+class IDBKeyData;
</ins><span class="cx"> class IDBResultData;
</span><ins>+class ThreadSafeDataBuffer;
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class IDBConnectionToServer;
</span><span class="cx"> 
</span><span class="cx"> class IDBRequest : public WebCore::IDBOpenDBRequest, public RefCounted&lt;IDBRequest&gt; {
</span><span class="cx"> public:
</span><ins>+    static Ref&lt;IDBRequest&gt; create(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBTransaction&amp;);
+
</ins><span class="cx">     const IDBResourceIdentifier&amp; resourceIdentifier() const { return m_resourceIdentifier; }
</span><span class="cx"> 
</span><span class="cx">     virtual ~IDBRequest() override;
</span><span class="lines">@@ -56,6 +61,8 @@
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBTransaction&gt; transaction() const override;
</span><span class="cx">     virtual const String&amp; readyState() const override;
</span><span class="cx"> 
</span><ins>+    uint64_t sourceObjectStoreIdentifier() const;
+
</ins><span class="cx">     // EventTarget
</span><span class="cx">     virtual EventTargetInterface eventTargetInterface() const override;
</span><span class="cx">     virtual ScriptExecutionContext* scriptExecutionContext() const override final { return ActiveDOMObject::scriptExecutionContext(); }
</span><span class="lines">@@ -64,15 +71,23 @@
</span><span class="cx">     using RefCounted&lt;IDBRequest&gt;::deref;
</span><span class="cx"> 
</span><span class="cx">     void enqueueEvent(Ref&lt;Event&gt;&amp;&amp;);
</span><ins>+    virtual bool dispatchEvent(PassRefPtr&lt;Event&gt;) override final;
</ins><span class="cx"> 
</span><span class="cx">     IDBConnectionToServer&amp; connection() { return m_connection; }
</span><span class="cx"> 
</span><ins>+    void requestCompleted(const IDBResultData&amp;);
+
+    void setResult(const IDBKeyData*);
+    void setResultToStructuredClone(const ThreadSafeDataBuffer&amp;);
+
</ins><span class="cx"> protected:
</span><span class="cx">     IDBRequest(IDBConnectionToServer&amp;, ScriptExecutionContext*);
</span><ins>+    IDBRequest(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBTransaction&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // ActiveDOMObject.
</span><span class="cx">     virtual const char* activeDOMObjectName() const override final;
</span><span class="cx">     virtual bool canSuspendForPageCache() const override final;
</span><ins>+    virtual bool hasPendingActivity() const override final;
</ins><span class="cx">     
</span><span class="cx">     // EventTarget.
</span><span class="cx">     virtual void refEventTarget() override final { RefCounted&lt;IDBRequest&gt;::ref(); }
</span><span class="lines">@@ -82,10 +97,16 @@
</span><span class="cx">     RefPtr&lt;IDBAny&gt; m_result;
</span><span class="cx">     RefPtr&lt;IDBTransaction&gt; m_transaction;
</span><span class="cx">     RefPtr&lt;DOMError&gt; m_domError;
</span><ins>+    IDBError m_idbError;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    void onError();
+    void onSuccess();
+
</ins><span class="cx">     IDBConnectionToServer&amp; m_connection;
</span><span class="cx">     IDBResourceIdentifier m_resourceIdentifier;
</span><ins>+    RefPtr&lt;IDBAny&gt; m_source;
+    bool m_hasPendingActivity { true };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;IDBError.h&quot;
</span><span class="cx"> #include &quot;IDBEventDispatcher.h&quot;
</span><span class="cx"> #include &quot;IDBObjectStore.h&quot;
</span><ins>+#include &quot;IDBRequestImpl.h&quot;
</ins><span class="cx"> #include &quot;IDBResultData.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;ScriptExecutionContext.h&quot;
</span><span class="lines">@@ -61,7 +62,7 @@
</span><span class="cx">         m_originalDatabaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(m_database-&gt;info());
</span><span class="cx"> 
</span><span class="cx">     suspendIfNeeded();
</span><del>-    m_state = IndexedDB::TransactionState::Running;
</del><ins>+    m_state = IndexedDB::TransactionState::Inactive;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBTransaction::~IDBTransaction()
</span><span class="lines">@@ -130,12 +131,15 @@
</span><span class="cx"> 
</span><span class="cx"> bool IDBTransaction::hasPendingActivity() const
</span><span class="cx"> {
</span><ins>+    if (m_state == IndexedDB::TransactionState::Inactive)
+        return !m_transactionOperationQueue.isEmpty() || !m_transactionOperationMap.isEmpty();
+
</ins><span class="cx">     return m_state != IndexedDB::TransactionState::Finished;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool IDBTransaction::isActive() const
</span><span class="cx"> {
</span><del>-    return m_state == IndexedDB::TransactionState::Running;
</del><ins>+    return m_state == IndexedDB::TransactionState::Active;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool IDBTransaction::isFinishedOrFinishing() const
</span><span class="lines">@@ -181,7 +185,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (isActive())
</del><ins>+    if (!isFinishedOrFinishing())
</ins><span class="cx">         commit();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -189,10 +193,8 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::commit&quot;);
</span><span class="cx"> 
</span><del>-    if (m_state != IndexedDB::TransactionState::Running) {
-        m_state = IndexedDB::TransactionState::Finished;
</del><ins>+    if (isFinishedOrFinishing())
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     m_state = IndexedDB::TransactionState::Committing;
</span><span class="cx"> 
</span><span class="lines">@@ -211,7 +213,8 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::didAbort&quot;);
</span><span class="cx"> 
</span><del>-    ASSERT(m_state == IndexedDB::TransactionState::Aborting || m_state == IndexedDB::TransactionState::Running);
</del><ins>+    if (m_state == IndexedDB::TransactionState::Finished)
+        return;
</ins><span class="cx"> 
</span><span class="cx">     m_database-&gt;didAbortTransaction(*this);
</span><span class="cx"> 
</span><span class="lines">@@ -294,7 +297,7 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::createObjectStoreOnServer&quot;);
</span><span class="cx"> 
</span><del>-    ASSERT(isActive());
</del><ins>+    ASSERT(!isFinishedOrFinishing());
</ins><span class="cx">     ASSERT(isVersionChange());
</span><span class="cx"> 
</span><span class="cx">     m_database-&gt;serverConnection().createObjectStore(operation, info);
</span><span class="lines">@@ -309,6 +312,84 @@
</span><span class="cx">     scheduleOperationTimer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;IDBRequest&gt; IDBTransaction::requestGetRecord(ScriptExecutionContext&amp; context, IDBObjectStore&amp; objectStore, IDBKey&amp; key)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestPutOrAdd&quot;);
+    ASSERT(isActive());
+    ASSERT(key.isValid());
+
+    Ref&lt;IDBRequest&gt; request = IDBRequest::create(context, objectStore, *this);
+
+    auto operation = createTransactionOperation(*this, request.get(), &amp;IDBTransaction::didGetRecordOnServer, &amp;IDBTransaction::getRecordOnServer, &amp;key);
+    scheduleOperation(WTF::move(operation));
+
+    return WTF::move(request);
+}
+
+void IDBTransaction::getRecordOnServer(TransactionOperation&amp; operation, RefPtr&lt;IDBKey&gt; key)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::getRecordOnServer&quot;);
+
+    ASSERT(!isFinishedOrFinishing());
+
+    serverConnection().getRecord(operation, key);
+}
+
+void IDBTransaction::didGetRecordOnServer(IDBRequest&amp; request, const IDBResultData&amp; resultData)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::didGetRecordOnServer&quot;);
+
+    request.setResultToStructuredClone(resultData.resultData());
+    request.requestCompleted(resultData);
+}
+
+Ref&lt;IDBRequest&gt; IDBTransaction::requestPutOrAdd(ScriptExecutionContext&amp; context, IDBObjectStore&amp; objectStore, IDBKey* key, SerializedScriptValue&amp; value, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestPutOrAdd&quot;);
+    ASSERT(isActive());
+    ASSERT(!isReadOnly());
+    ASSERT(objectStore.info().autoIncrement() || key);
+
+    Ref&lt;IDBRequest&gt; request = IDBRequest::create(context, objectStore, *this);
+
+    auto operation = createTransactionOperation(*this, request.get(), &amp;IDBTransaction::didPutOrAddOnServer, &amp;IDBTransaction::putOrAddOnServer, key, &amp;value, overwriteMode);
+    scheduleOperation(WTF::move(operation));
+
+    return WTF::move(request);
+}
+
+void IDBTransaction::putOrAddOnServer(TransactionOperation&amp; operation, RefPtr&lt;IDBKey&gt; key, RefPtr&lt;SerializedScriptValue&gt; value, const IndexedDB::ObjectStoreOverwriteMode&amp; overwriteMode)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::putOrAddOnServer&quot;);
+
+    ASSERT(!isFinishedOrFinishing());
+    ASSERT(!isReadOnly());
+
+    serverConnection().putOrAdd(operation, key, value, overwriteMode);
+}
+
+void IDBTransaction::didPutOrAddOnServer(IDBRequest&amp; request, const IDBResultData&amp; resultData)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::didPutOrAddOnServer&quot;);
+
+    request.setResult(resultData.resultKey());
+    request.requestCompleted(resultData);
+}
+
+void IDBTransaction::activate()
+{
+    ASSERT(m_state == IndexedDB::TransactionState::Unstarted || m_state == IndexedDB::TransactionState::Inactive);
+    m_state = IndexedDB::TransactionState::Active;
+}
+
+void IDBTransaction::deactivate()
+{
+    if (m_state == IndexedDB::TransactionState::Unstarted || m_state == IndexedDB::TransactionState::Active)
+        m_state = IndexedDB::TransactionState::Inactive;
+
+    scheduleOperationTimer();
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -81,12 +81,19 @@
</span><span class="cx">     void didCommit(const IDBError&amp;);
</span><span class="cx"> 
</span><span class="cx">     bool isVersionChange() const { return m_info.mode() == IndexedDB::TransactionMode::VersionChange; }
</span><ins>+    bool isReadOnly() const { return m_info.mode() == IndexedDB::TransactionMode::ReadOnly; }
</ins><span class="cx">     bool isActive() const;
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;IDBObjectStore&gt; createObjectStore(const IDBObjectStoreInfo&amp;);
</span><span class="cx"> 
</span><ins>+    Ref&lt;IDBRequest&gt; requestPutOrAdd(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBKey*, SerializedScriptValue&amp;, IndexedDB::ObjectStoreOverwriteMode);
+    Ref&lt;IDBRequest&gt; requestGetRecord(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBKey&amp;);
+
</ins><span class="cx">     IDBConnectionToServer&amp; serverConnection();
</span><span class="cx"> 
</span><ins>+    void activate();
+    void deactivate();
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBTransaction(IDBDatabase&amp;, const IDBTransactionInfo&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -108,6 +115,12 @@
</span><span class="cx">     void createObjectStoreOnServer(TransactionOperation&amp;, const IDBObjectStoreInfo&amp;);
</span><span class="cx">     void didCreateObjectStoreOnServer(const IDBResultData&amp;);
</span><span class="cx"> 
</span><ins>+    void putOrAddOnServer(TransactionOperation&amp;, RefPtr&lt;IDBKey&gt;, RefPtr&lt;SerializedScriptValue&gt;, const IndexedDB::ObjectStoreOverwriteMode&amp;);
+    void didPutOrAddOnServer(IDBRequest&amp;, const IDBResultData&amp;);
+
+    void getRecordOnServer(TransactionOperation&amp;, RefPtr&lt;IDBKey&gt;);
+    void didGetRecordOnServer(IDBRequest&amp;, const IDBResultData&amp;);
+
</ins><span class="cx">     Ref&lt;IDBDatabase&gt; m_database;
</span><span class="cx">     IDBTransactionInfo m_info;
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_originalDatabaseInfo;
</span><span class="lines">@@ -122,6 +135,26 @@
</span><span class="cx">     HashMap&lt;IDBResourceIdentifier, RefPtr&lt;TransactionOperation&gt;&gt; m_transactionOperationMap;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class TransactionActivator {
+    WTF_MAKE_NONCOPYABLE(TransactionActivator);
+public:
+    TransactionActivator(IDBTransaction* transaction)
+        : m_transaction(transaction)
+    {
+        if (m_transaction)
+            m_transaction-&gt;activate();
+    }
+
+    ~TransactionActivator()
+    {
+        if (m_transaction)
+            m_transaction-&gt;deactivate();
+    }
+
+private:
+    IDBTransaction* m_transaction;
+};
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientTransactionOperationcppfromrev191634trunkSourceWebCoreModulesindexeddbclientIDBConnectionToServerDelegateh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp (from rev 191634, trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h) (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TransactionOperation.h&quot;
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+namespace IDBClient {
+
+TransactionOperation::TransactionOperation(IDBTransaction&amp; transaction, IDBRequest&amp; request)
+    : TransactionOperation(transaction)
+{
+    m_objectStoreIdentifier = request.sourceObjectStoreIdentifier();
+}
+
+} // namespace IDBClient
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientTransactionOperationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;IDBRequestImpl.h&quot;
</ins><span class="cx"> #include &quot;IDBResourceIdentifier.h&quot;
</span><span class="cx"> #include &quot;IDBTransactionImpl.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -51,6 +52,8 @@
</span><span class="cx"> 
</span><span class="cx">     const IDBResourceIdentifier&amp; identifier() const { return m_identifier; }
</span><span class="cx">     IDBResourceIdentifier transactionIdentifier() const { return m_transaction-&gt;info().identifier(); }
</span><ins>+    uint64_t objectStoreIdentifier() const { return m_objectStoreIdentifier; }
+    IDBTransaction&amp; transaction() { return m_transaction.get(); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     TransactionOperation(IDBTransaction&amp; transaction)
</span><span class="lines">@@ -59,8 +62,11 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    TransactionOperation(IDBTransaction&amp;, IDBRequest&amp;);
+
</ins><span class="cx">     Ref&lt;IDBTransaction&gt; m_transaction;
</span><span class="cx">     IDBResourceIdentifier m_identifier;
</span><ins>+    uint64_t m_objectStoreIdentifier { 0 };
</ins><span class="cx">     std::function&lt;void ()&gt; m_performFunction;
</span><span class="cx">     std::function&lt;void (const IDBResultData&amp;)&gt; m_completeFunction;
</span><span class="cx"> };
</span><span class="lines">@@ -81,6 +87,22 @@
</span><span class="cx">             (&amp;m_transaction.get()-&gt;*completeMethod)(resultData);
</span><span class="cx">         };
</span><span class="cx">     }
</span><ins>+
+    TransactionOperationImpl(IDBTransaction&amp; transaction, IDBRequest&amp; request, void (IDBTransaction::*completeMethod)(IDBRequest&amp;, const IDBResultData&amp;), void (IDBTransaction::*performMethod)(TransactionOperation&amp;, Arguments...), Arguments&amp;&amp;... arguments)
+        : TransactionOperation(transaction, request)
+    {
+        relaxAdoptionRequirement();
+
+        RefPtr&lt;TransactionOperation&gt; self(this);
+        m_performFunction = [self, this, performMethod, arguments...] {
+            (&amp;m_transaction.get()-&gt;*performMethod)(*this, arguments...);
+        };
+
+        RefPtr&lt;IDBRequest&gt; refRequest(&amp;request);
+        m_completeFunction = [self, this, refRequest, completeMethod](const IDBResultData&amp; resultData) {
+            (&amp;m_transaction.get()-&gt;*completeMethod)(*refRequest, resultData);
+        };
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename MP1, typename P1&gt;
</span><span class="lines">@@ -94,6 +116,32 @@
</span><span class="cx">     return adoptRef(operation);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename MP1, typename P1&gt;
+RefPtr&lt;TransactionOperation&gt; createTransactionOperation(
+    IDBTransaction&amp; transaction,
+    IDBRequest&amp; request,
+    void (IDBTransaction::*complete)(IDBRequest&amp;, const IDBResultData&amp;),
+    void (IDBTransaction::*perform)(TransactionOperation&amp;, MP1),
+    const P1&amp; parameter1)
+{
+    auto operation = new TransactionOperationImpl&lt;MP1&gt;(transaction, request, complete, perform, parameter1);
+    return adoptRef(operation);
+}
+
+template&lt;typename MP1, typename MP2, typename MP3, typename P1, typename P2, typename P3&gt;
+RefPtr&lt;TransactionOperation&gt; createTransactionOperation(
+    IDBTransaction&amp; transaction,
+    IDBRequest&amp; request,
+    void (IDBTransaction::*complete)(IDBRequest&amp;, const IDBResultData&amp;),
+    void (IDBTransaction::*perform)(TransactionOperation&amp;, MP1, MP2, MP3),
+    const P1&amp; parameter1,
+    const P2&amp; parameter2,
+    const P3&amp; parameter3)
+{
+    auto operation = new TransactionOperationImpl&lt;MP1, MP2, MP3&gt;(transaction, request, complete, perform, parameter1, parameter2, parameter3);
+    return adoptRef(operation);
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -33,9 +33,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class IDBKeyData;
</ins><span class="cx"> class IDBObjectStoreInfo;
</span><span class="cx"> class IDBResourceIdentifier;
</span><span class="cx"> class IDBTransactionInfo;
</span><ins>+class ThreadSafeDataBuffer;
</ins><span class="cx"> 
</span><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="lines">@@ -50,6 +52,10 @@
</span><span class="cx">     virtual IDBError commitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier) = 0;
</span><span class="cx"> 
</span><span class="cx">     virtual IDBError createObjectStore(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBObjectStoreInfo&amp;) = 0;
</span><ins>+    virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, bool&amp; keyExists) = 0;
+    virtual IDBError deleteRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;) = 0;
+    virtual IDBError putRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value) = 0;
+    virtual IDBError getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, ThreadSafeDataBuffer&amp; outValue) = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -68,6 +68,16 @@
</span><span class="cx">     m_delegate-&gt;didCreateObjectStore(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBConnectionToClient::didPutOrAdd(const IDBResultData&amp; result)
+{
+    m_delegate-&gt;didPutOrAdd(result);
+}
+
+void IDBConnectionToClient::didGetRecord(const IDBResultData&amp; result)
+{
+    m_delegate-&gt;didGetRecord(result);
+}
+
</ins><span class="cx"> void IDBConnectionToClient::didCommitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp; error)
</span><span class="cx"> {
</span><span class="cx">     m_delegate-&gt;didCommitTransaction(transactionIdentifier, error);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx">     void didAbortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;);
</span><span class="cx">     void didCommitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;);
</span><span class="cx">     void didCreateObjectStore(const IDBResultData&amp;);
</span><ins>+    void didPutOrAdd(const IDBResultData&amp;);
+    void didGetRecord(const IDBResultData&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void fireVersionChangeEvent(UniqueIDBDatabaseConnection&amp;, uint64_t requestedVersion);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBConnectionToClientDelegateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx">     virtual void didAbortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;) = 0;
</span><span class="cx">     virtual void didCommitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;) = 0;
</span><span class="cx">     virtual void didCreateObjectStore(const IDBResultData&amp;) = 0;
</span><ins>+    virtual void didPutOrAdd(const IDBResultData&amp;) = 0;
+    virtual void didGetRecord(const IDBResultData&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual void fireVersionChangeEvent(UniqueIDBDatabaseConnection&amp;, uint64_t requestedVersion) = 0;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -168,6 +168,28 @@
</span><span class="cx">     transaction-&gt;createObjectStore(requestData, info);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBServer::putOrAdd(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    LOG(IndexedDB, &quot;IDBServer::putOrAdd&quot;);
+
+    auto transaction = m_transactions.get(requestData.transactionIdentifier());
+    if (!transaction)
+        return;
+
+    transaction-&gt;putOrAdd(requestData, keyData, valueData, overwriteMode);
+}
+
+void IDBServer::getRecord(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData)
+{
+    LOG(IndexedDB, &quot;IDBServer::getRecord&quot;);
+
+    auto transaction = m_transactions.get(requestData.transactionIdentifier());
+    if (!transaction)
+        return;
+
+    transaction-&gt;getRecord(requestData, keyData);
+}
+
</ins><span class="cx"> void IDBServer::commitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBServer::commitTransaction&quot;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -60,6 +60,8 @@
</span><span class="cx">     void abortTransaction(const IDBResourceIdentifier&amp;);
</span><span class="cx">     void commitTransaction(const IDBResourceIdentifier&amp;);
</span><span class="cx">     void createObjectStore(const IDBRequestData&amp;, const IDBObjectStoreInfo&amp;);
</span><ins>+    void putOrAdd(const IDBRequestData&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode);
+    void getRecord(const IDBRequestData&amp;, const IDBKeyData&amp;);
</ins><span class="cx">     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier);
</span><span class="cx"> 
</span><span class="cx">     void postDatabaseTask(std::unique_ptr&lt;CrossThreadTask&gt;&amp;&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;MemoryIDBBackingStore.h&quot;
</span><span class="cx"> #include &quot;MemoryObjectStore.h&quot;
</span><ins>+#include &lt;wtf/TemporaryChange.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBServer {
</span><span class="lines">@@ -67,15 +68,51 @@
</span><span class="cx">     objectStore.writeTransactionStarted(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MemoryBackingStoreTransaction::recordValueChanged(MemoryObjectStore&amp; objectStore, const IDBKeyData&amp; key)
+{
+    ASSERT(m_objectStores.contains(&amp;objectStore));
+
+    if (m_isAborting)
+        return;
+
+    auto originalAddResult = m_originalValues.add(&amp;objectStore, nullptr);
+    if (originalAddResult.isNewEntry)
+        originalAddResult.iterator-&gt;value = std::make_unique&lt;KeyValueMap&gt;();
+
+    auto* map = originalAddResult.iterator-&gt;value.get();
+
+    auto addResult = map-&gt;add(key, ThreadSafeDataBuffer());
+    if (!addResult.isNewEntry)
+        return;
+
+    addResult.iterator-&gt;value = objectStore.valueForKey(key);
+}
+
</ins><span class="cx"> void MemoryBackingStoreTransaction::abort()
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;MemoryBackingStoreTransaction::abort()&quot;);
</span><span class="cx"> 
</span><ins>+    TemporaryChange&lt;bool&gt; change(m_isAborting, true);
+
</ins><span class="cx">     if (m_originalDatabaseInfo) {
</span><span class="cx">         ASSERT(m_info.mode() == IndexedDB::TransactionMode::VersionChange);
</span><span class="cx">         m_backingStore.setDatabaseInfo(*m_originalDatabaseInfo);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    for (auto objectStore : m_objectStores) {
+        auto keyValueMap = m_originalValues.get(objectStore);
+        if (!keyValueMap)
+            continue;
+
+        for (auto entry : *keyValueMap) {
+            objectStore-&gt;deleteRecord(entry.key);
+            objectStore-&gt;setKeyValue(entry.key, entry.value);
+        }
+
+        m_originalValues.remove(objectStore);
+    }
+
+
</ins><span class="cx">     finish();
</span><span class="cx"> 
</span><span class="cx">     for (auto objectStore : m_versionChangeAddedObjectStores)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryBackingStoreTransactionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -29,7 +29,10 @@
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBDatabaseInfo.h&quot;
</span><ins>+#include &quot;IDBKeyData.h&quot;
</ins><span class="cx"> #include &quot;IDBTransactionInfo.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -38,6 +41,8 @@
</span><span class="cx"> class MemoryIDBBackingStore;
</span><span class="cx"> class MemoryObjectStore;
</span><span class="cx"> 
</span><ins>+typedef HashMap&lt;IDBKeyData, ThreadSafeDataBuffer, IDBKeyDataHash, IDBKeyDataHashTraits&gt; KeyValueMap;
+
</ins><span class="cx"> class MemoryBackingStoreTransaction {
</span><span class="cx">     friend std::unique_ptr&lt;MemoryBackingStoreTransaction&gt; std::make_unique&lt;MemoryBackingStoreTransaction&gt;(WebCore::IDBServer::MemoryIDBBackingStore&amp;, const WebCore::IDBTransactionInfo&amp;);
</span><span class="cx"> public:
</span><span class="lines">@@ -51,6 +56,7 @@
</span><span class="cx">     const IDBDatabaseInfo&amp; originalDatabaseInfo() const;
</span><span class="cx"> 
</span><span class="cx">     void addNewObjectStore(MemoryObjectStore&amp;);
</span><ins>+    void recordValueChanged(MemoryObjectStore&amp;, const IDBKeyData&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void abort();
</span><span class="cx">     void commit();
</span><span class="lines">@@ -66,10 +72,13 @@
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_originalDatabaseInfo;
</span><span class="cx"> 
</span><span class="cx">     bool m_inProgress { true };
</span><ins>+    bool m_isAborting { false };
</ins><span class="cx"> 
</span><span class="cx">     HashSet&lt;MemoryObjectStore*&gt; m_objectStores;
</span><span class="cx">     HashSet&lt;MemoryObjectStore*&gt; m_versionChangeAddedObjectStores;
</span><span class="cx"> 
</span><ins>+    HashMap&lt;MemoryObjectStore*, std::unique_ptr&lt;KeyValueMap&gt;&gt; m_originalValues;
+
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -136,6 +136,69 @@
</span><span class="cx">     m_objectStores.remove(objectStore.info().identifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+IDBError MemoryIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&amp;, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData, bool&amp; keyExists)
+{
+    LOG(IndexedDB, &quot;MemoryIDBBackingStore::keyExistsInObjectStore&quot;);
+
+    ASSERT(objectStoreIdentifier);
+
+    MemoryObjectStore* objectStore = m_objectStores.get(objectStoreIdentifier);
+    RELEASE_ASSERT(objectStore);
+
+    keyExists = objectStore-&gt;containsRecord(keyData);
+    return IDBError();
+}
+
+IDBError MemoryIDBBackingStore::deleteRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData)
+{
+    LOG(IndexedDB, &quot;MemoryIDBBackingStore::deleteRecord&quot;);
+
+    ASSERT(objectStoreIdentifier);
+
+    MemoryObjectStore* objectStore = m_objectStores.get(objectStoreIdentifier);
+    RELEASE_ASSERT(objectStore);
+    RELEASE_ASSERT(m_transactions.contains(transactionIdentifier));
+
+    objectStore-&gt;deleteRecord(keyData);
+    return IDBError();
+}
+
+IDBError MemoryIDBBackingStore::putRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; value)
+{
+    LOG(IndexedDB, &quot;MemoryIDBBackingStore::putRecord&quot;);
+
+    ASSERT(objectStoreIdentifier);
+
+    auto transaction = m_transactions.get(transactionIdentifier);
+    if (!transaction)
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store transaction found to get record&quot;));
+
+    MemoryObjectStore* objectStore = m_objectStores.get(objectStoreIdentifier);
+    if (!objectStore)
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store object store found to put record&quot;));
+
+    objectStore-&gt;putRecord(*transaction, keyData, value);
+    return IDBError();
+}
+
+IDBError MemoryIDBBackingStore::getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData, ThreadSafeDataBuffer&amp; outValue)
+{
+    LOG(IndexedDB, &quot;MemoryIDBBackingStore::getRecord&quot;);
+
+    ASSERT(objectStoreIdentifier);
+
+    if (!m_transactions.contains(transactionIdentifier))
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store transaction found to get record&quot;));
+
+    MemoryObjectStore* objectStore = m_objectStores.get(objectStoreIdentifier);
+    if (!objectStore)
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store object store found&quot;));
+
+    outValue = objectStore-&gt;valueForKey(keyData);
+    return IDBError();
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -53,6 +53,10 @@
</span><span class="cx">     virtual IDBError abortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier) override final;
</span><span class="cx">     virtual IDBError commitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier) override final;
</span><span class="cx">     virtual IDBError createObjectStore(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBObjectStoreInfo&amp;) override final;
</span><ins>+    virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, bool&amp; keyExists) override final;
+    virtual IDBError deleteRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;) override final;
+    virtual IDBError putRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value) override final;
+    virtual IDBError getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, ThreadSafeDataBuffer&amp; outValue) override final;
</ins><span class="cx"> 
</span><span class="cx">     void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryObjectStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><ins>+#include &quot;MemoryBackingStoreTransaction.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBServer {
</span><span class="lines">@@ -64,6 +65,61 @@
</span><span class="cx">     m_writeTransaction = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MemoryObjectStore::containsRecord(const IDBKeyData&amp; key)
+{
+    if (!m_keyValueStore)
+        return false;
+
+    return m_keyValueStore-&gt;contains(key);
+}
+
+void MemoryObjectStore::deleteRecord(const IDBKeyData&amp; key)
+{
+    LOG(IndexedDB, &quot;MemoryObjectStore::deleteRecord&quot;);
+
+    ASSERT(m_writeTransaction);
+    m_writeTransaction-&gt;recordValueChanged(*this, key);
+
+    if (!m_keyValueStore)
+        return;
+
+    m_keyValueStore-&gt;remove(key);
+    if (m_orderedKeys)
+        m_orderedKeys-&gt;erase(key);
+}
+
+void MemoryObjectStore::putRecord(MemoryBackingStoreTransaction&amp; transaction, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; value)
+{
+    LOG(IndexedDB, &quot;MemoryObjectStore::putRecord&quot;);
+
+    ASSERT(m_writeTransaction);
+    ASSERT_UNUSED(transaction, m_writeTransaction == &amp;transaction);
+
+    m_writeTransaction-&gt;recordValueChanged(*this, keyData);
+
+    setKeyValue(keyData, value);
+}
+
+void MemoryObjectStore::setKeyValue(const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; value)
+{
+    if (!m_keyValueStore)
+        m_keyValueStore = std::make_unique&lt;KeyValueMap&gt;();
+
+    auto result = m_keyValueStore-&gt;set(keyData, value);
+    if (result.isNewEntry &amp;&amp; m_orderedKeys)
+        m_orderedKeys-&gt;insert(keyData);
+}
+
+ThreadSafeDataBuffer MemoryObjectStore::valueForKey(const IDBKeyData&amp; keyData) const
+{
+    LOG(IndexedDB, &quot;MemoryObjectStore::valueForKey&quot;);
+
+    if (!m_keyValueStore)
+        return ThreadSafeDataBuffer();
+
+    return m_keyValueStore-&gt;get(keyData);
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -28,13 +28,22 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;IDBKeyData.h&quot;
</ins><span class="cx"> #include &quot;IDBObjectStoreInfo.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
+#include &lt;set&gt;
+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+
+class IDBKeyData;
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class MemoryBackingStoreTransaction;
</span><span class="cx"> 
</span><ins>+typedef HashMap&lt;IDBKeyData, ThreadSafeDataBuffer, IDBKeyDataHash, IDBKeyDataHashTraits&gt; KeyValueMap;
+
</ins><span class="cx"> class MemoryObjectStore {
</span><span class="cx">     friend std::unique_ptr&lt;MemoryObjectStore&gt; std::make_unique&lt;MemoryObjectStore&gt;(const WebCore::IDBObjectStoreInfo&amp;);
</span><span class="cx"> public:
</span><span class="lines">@@ -45,6 +54,14 @@
</span><span class="cx">     void writeTransactionStarted(MemoryBackingStoreTransaction&amp;);
</span><span class="cx">     void writeTransactionFinished(MemoryBackingStoreTransaction&amp;);
</span><span class="cx"> 
</span><ins>+    bool containsRecord(const IDBKeyData&amp;);
+    void deleteRecord(const IDBKeyData&amp;);
+    void putRecord(MemoryBackingStoreTransaction&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value);
+
+    void setKeyValue(const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value);
+
+    ThreadSafeDataBuffer valueForKey(const IDBKeyData&amp;) const;
+
</ins><span class="cx">     const IDBObjectStoreInfo&amp; info() const { return m_info; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -53,6 +70,9 @@
</span><span class="cx">     IDBObjectStoreInfo m_info;
</span><span class="cx"> 
</span><span class="cx">     MemoryBackingStoreTransaction* m_writeTransaction { nullptr };
</span><ins>+
+    std::unique_ptr&lt;KeyValueMap&gt; m_keyValueStore;
+    std::unique_ptr&lt;std::set&lt;IDBKeyData&gt;&gt; m_orderedKeys;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -139,6 +139,20 @@
</span><span class="cx">     return identifier;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint64_t UniqueIDBDatabase::storeCallback(KeyDataCallback callback)
+{
+    uint64_t identifier = generateUniqueCallbackIdentifier();
+    m_keyDataCallbacks.set(identifier, callback);
+    return identifier;
+}
+
+uint64_t UniqueIDBDatabase::storeCallback(ValueDataCallback callback)
+{
+    uint64_t identifier = generateUniqueCallbackIdentifier();
+    m_valueDataCallbacks.set(identifier, callback);
+    return identifier;
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::startVersionChangeTransaction()
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::startVersionChangeTransaction&quot;);
</span><span class="lines">@@ -251,6 +265,108 @@
</span><span class="cx">     performErrorCallback(callbackIdentifier, error);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UniqueIDBDatabase::putOrAdd(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::putOrAdd&quot;);
+
+    uint64_t callbackID = storeCallback(callback);
+    m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, valueData, overwriteMode));
+}
+
+void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    ASSERT(!isMainThread());
+    LOG(IndexedDB, &quot;(db) UniqueIDBDatabase::performPutOrAdd&quot;);
+
+    ASSERT(m_backingStore);
+    ASSERT(objectStoreIdentifier);
+
+    IDBKeyData usedKey;
+    IDBError error;
+
+    auto objectStoreInfo = m_databaseInfo-&gt;infoForExistingObjectStore(objectStoreIdentifier);
+    if (!objectStoreInfo) {
+        error = IDBError(IDBExceptionCode::InvalidStateError, ASCIILiteral(&quot;Object store cannot be found in the backing store&quot;));
+        m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
+        return;
+    }
+
+    if (objectStoreInfo-&gt;autoIncrement() &amp;&amp; !keyData.isValid()) {
+        // FIXME: This is where generated key support goes
+        error = IDBError(IDBExceptionCode::Unknown, ASCIILiteral(&quot;Key generators not supported yet&quot;));
+        m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
+        return;
+    }
+
+    usedKey = keyData;
+
+    if (overwriteMode == IndexedDB::ObjectStoreOverwriteMode::NoOverwrite) {
+        bool keyExists;
+        error = m_backingStore-&gt;keyExistsInObjectStore(transactionIdentifier, objectStoreIdentifier, usedKey, keyExists);
+        if (error.isNull() &amp;&amp; keyExists)
+            error = IDBError(IDBExceptionCode::ConstraintError, ASCIILiteral(&quot;Key already exists in the object store&quot;));
+
+        if (!error.isNull()) {
+            m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
+            return;
+        }
+    }
+
+    // 3.4.1 Object Store Storage Operation
+    // ...If a record already exists in store ...
+    // then remove the record from store using the steps for deleting records from an object store...
+    // This is important because formally deleting it from from the object store also removes it from the appropriate indexes.
+    error = m_backingStore-&gt;deleteRecord(transactionIdentifier, objectStoreIdentifier, usedKey);
+    if (!error.isNull()) {
+        m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
+        return;
+    }
+
+    error = m_backingStore-&gt;putRecord(transactionIdentifier, objectStoreIdentifier, usedKey, valueData);
+
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
+}
+
+void UniqueIDBDatabase::didPerformPutOrAdd(uint64_t callbackIdentifier, const IDBError&amp; error, const IDBKeyData&amp; resultKey)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::didPerformPutOrAdd&quot;);
+
+    performKeyDataCallback(callbackIdentifier, error, resultKey);
+}
+
+void UniqueIDBDatabase::getRecord(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData, ValueDataCallback callback)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::getRecord&quot;);
+
+    uint64_t callbackID = storeCallback(callback);
+    m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData));
+}
+
+void UniqueIDBDatabase::performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp; keyData)
+{
+    ASSERT(!isMainThread());
+    LOG(IndexedDB, &quot;(db) UniqueIDBDatabase::performGetRecord&quot;);
+
+    ASSERT(m_backingStore);
+    ASSERT(objectStoreIdentifier);
+
+    ThreadSafeDataBuffer valueData;
+    IDBError error = m_backingStore-&gt;getRecord(transactionIdentifier, objectStoreIdentifier, keyData, valueData);
+
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformGetRecord, callbackIdentifier, error, valueData));
+}
+
+void UniqueIDBDatabase::didPerformGetRecord(uint64_t callbackIdentifier, const IDBError&amp; error, const ThreadSafeDataBuffer&amp; resultData)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::didPerformGetRecord&quot;);
+
+    performValueDataCallback(callbackIdentifier, error, resultData);
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction&amp; transaction, ErrorCallback callback)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="lines">@@ -380,6 +496,20 @@
</span><span class="cx">     callback(error);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UniqueIDBDatabase::performKeyDataCallback(uint64_t callbackIdentifier, const IDBError&amp; error, const IDBKeyData&amp; resultKey)
+{
+    auto callback = m_keyDataCallbacks.take(callbackIdentifier);
+    ASSERT(callback);
+    callback(error, resultKey);
+}
+
+void UniqueIDBDatabase::performValueDataCallback(uint64_t callbackIdentifier, const IDBError&amp; error, const ThreadSafeDataBuffer&amp; resultData)
+{
+    auto callback = m_valueDataCallbacks.take(callbackIdentifier);
+    ASSERT(callback);
+    callback(error, resultData);
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;IDBDatabaseIdentifier.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseInfo.h&quot;
</span><span class="cx"> #include &quot;IDBServerOperation.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
</ins><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="cx"> #include &quot;UniqueIDBDatabaseConnection.h&quot;
</span><span class="cx"> #include &quot;UniqueIDBDatabaseTransaction.h&quot;
</span><span class="lines">@@ -52,6 +53,8 @@
</span><span class="cx"> class IDBServer;
</span><span class="cx"> 
</span><span class="cx"> typedef std::function&lt;void(const IDBError&amp;)&gt; ErrorCallback;
</span><ins>+typedef std::function&lt;void(const IDBError&amp;, const IDBKeyData&amp;)&gt; KeyDataCallback;
+typedef std::function&lt;void(const IDBError&amp;, const ThreadSafeDataBuffer&amp;)&gt; ValueDataCallback;
</ins><span class="cx"> 
</span><span class="cx"> class UniqueIDBDatabase : public ThreadSafeRefCounted&lt;UniqueIDBDatabase&gt; {
</span><span class="cx"> public:
</span><span class="lines">@@ -66,6 +69,8 @@
</span><span class="cx">     IDBServer&amp; server() { return m_server; }
</span><span class="cx"> 
</span><span class="cx">     void createObjectStore(UniqueIDBDatabaseTransaction&amp;, const IDBObjectStoreInfo&amp;, ErrorCallback);
</span><ins>+    void putOrAdd(const IDBRequestData&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback);
+    void getRecord(const IDBRequestData&amp;, const IDBKeyData&amp;, ValueDataCallback);
</ins><span class="cx">     void commitTransaction(UniqueIDBDatabaseTransaction&amp;, ErrorCallback);
</span><span class="cx">     void abortTransaction(UniqueIDBDatabaseTransaction&amp;, ErrorCallback);
</span><span class="cx">     void transactionDestroyed(UniqueIDBDatabaseTransaction&amp;);
</span><span class="lines">@@ -81,22 +86,30 @@
</span><span class="cx">     void startVersionChangeTransaction();
</span><span class="cx">     void notifyConnectionsOfVersionChange();
</span><span class="cx"> 
</span><del>-    uint64_t storeCallback(ErrorCallback);
-    
</del><span class="cx">     // Database thread operations
</span><span class="cx">     void openBackingStore(const IDBDatabaseIdentifier&amp;);
</span><span class="cx">     void performCommitTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier);
</span><span class="cx">     void performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier);
</span><span class="cx">     void beginTransactionInBackingStore(const IDBTransactionInfo&amp;);
</span><span class="cx">     void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, const IDBObjectStoreInfo&amp;);
</span><ins>+    void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode);
+    void performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // Main thread callbacks
</span><span class="cx">     void didOpenBackingStore(const IDBDatabaseInfo&amp;);
</span><span class="cx">     void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&amp;, const IDBObjectStoreInfo&amp;);
</span><ins>+    void didPerformPutOrAdd(uint64_t callbackIdentifier, const IDBError&amp;, const IDBKeyData&amp;);
+    void didPerformGetRecord(uint64_t callbackIdentifier, const IDBError&amp;, const ThreadSafeDataBuffer&amp;);
</ins><span class="cx">     void didPerformCommitTransaction(uint64_t callbackIdentifier, const IDBError&amp;);
</span><span class="cx">     void didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError&amp;, const IDBResourceIdentifier&amp; transactionIdentifier);
</span><span class="cx"> 
</span><ins>+    uint64_t storeCallback(ErrorCallback);
+    uint64_t storeCallback(KeyDataCallback);
+    uint64_t storeCallback(ValueDataCallback);
+
</ins><span class="cx">     void performErrorCallback(uint64_t callbackIdentifier, const IDBError&amp;);
</span><ins>+    void performKeyDataCallback(uint64_t callbackIdentifier, const IDBError&amp;, const IDBKeyData&amp;);
+    void performValueDataCallback(uint64_t callbackIdentifier, const IDBError&amp;, const ThreadSafeDataBuffer&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void invokeTransactionScheduler();
</span><span class="cx">     void transactionSchedulingTimerFired();
</span><span class="lines">@@ -117,6 +130,8 @@
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_databaseInfo;
</span><span class="cx"> 
</span><span class="cx">     HashMap&lt;uint64_t, ErrorCallback&gt; m_errorCallbacks;
</span><ins>+    HashMap&lt;uint64_t, KeyDataCallback&gt; m_keyDataCallbacks;
+    HashMap&lt;uint64_t, ValueDataCallback&gt; m_valueDataCallbacks;
</ins><span class="cx"> 
</span><span class="cx">     Timer m_transactionSchedulingTimer;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -80,6 +80,11 @@
</span><span class="cx">     return m_transactionInfo.mode() == IndexedDB::TransactionMode::VersionChange;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool UniqueIDBDatabaseTransaction::isReadOnly() const
+{
+    return m_transactionInfo.mode() == IndexedDB::TransactionMode::ReadOnly;
+}   
+
</ins><span class="cx"> void UniqueIDBDatabaseTransaction::commit()
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;UniqueIDBDatabaseTransaction::commit&quot;);
</span><span class="lines">@@ -108,6 +113,41 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UniqueIDBDatabaseTransaction::putOrAdd(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    LOG(IndexedDB, &quot;UniqueIDBDatabaseTransaction::putOrAdd&quot;);
+
+    ASSERT(!isReadOnly());
+    ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
+
+    RefPtr&lt;UniqueIDBDatabaseTransaction&gt; self(this);
+    m_databaseConnection-&gt;database().putOrAdd(requestData, keyData, valueData, overwriteMode, [this, self, requestData](const IDBError&amp; error, const IDBKeyData&amp; key) {
+        LOG(IndexedDB, &quot;UniqueIDBDatabaseTransaction::putOrAdd (callback)&quot;);
+
+        if (error.isNull())
+            m_databaseConnection-&gt;connectionToClient().didPutOrAdd(IDBResultData::putOrAddSuccess(requestData.requestIdentifier(), key));
+        else
+            m_databaseConnection-&gt;connectionToClient().didPutOrAdd(IDBResultData::error(requestData.requestIdentifier(), error));
+    });
+}
+
+void UniqueIDBDatabaseTransaction::getRecord(const IDBRequestData&amp; requestData, const IDBKeyData&amp; keyData)
+{
+    LOG(IndexedDB, &quot;UniqueIDBDatabaseTransaction::getRecord&quot;);
+
+    ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
+
+    RefPtr&lt;UniqueIDBDatabaseTransaction&gt; self(this);
+    m_databaseConnection-&gt;database().getRecord(requestData, keyData, [this, self, requestData](const IDBError&amp; error, const ThreadSafeDataBuffer&amp; valueData) {
+        LOG(IndexedDB, &quot;UniqueIDBDatabaseTransaction::getRecord (callback)&quot;);
+
+        if (error.isNull())
+            m_databaseConnection-&gt;connectionToClient().didGetRecord(IDBResultData::getRecordSuccess(requestData.requestIdentifier(), valueData));
+        else
+            m_databaseConnection-&gt;connectionToClient().didGetRecord(IDBResultData::error(requestData.requestIdentifier(), error));
+    });
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseTransactionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -36,8 +36,10 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class IDBDatabaseInfo;
</span><ins>+class IDBKeyData;
</ins><span class="cx"> class IDBObjectStoreInfo;
</span><span class="cx"> class IDBRequestData;
</span><ins>+class ThreadSafeDataBuffer;
</ins><span class="cx"> 
</span><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="lines">@@ -52,6 +54,7 @@
</span><span class="cx">     UniqueIDBDatabaseConnection&amp; databaseConnection() { return m_databaseConnection.get(); }
</span><span class="cx">     const IDBTransactionInfo&amp; info() const { return m_transactionInfo; }
</span><span class="cx">     bool isVersionChange() const;
</span><ins>+    bool isReadOnly() const;
</ins><span class="cx"> 
</span><span class="cx">     IDBDatabaseInfo* originalDatabaseInfo() const;
</span><span class="cx"> 
</span><span class="lines">@@ -59,6 +62,8 @@
</span><span class="cx">     void commit();
</span><span class="cx"> 
</span><span class="cx">     void createObjectStore(const IDBRequestData&amp;, const IDBObjectStoreInfo&amp;);
</span><ins>+    void putOrAdd(const IDBRequestData&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode);
+    void getRecord(const IDBRequestData&amp;, const IDBKeyData&amp;);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     UniqueIDBDatabaseTransaction(UniqueIDBDatabaseConnection&amp;, IDBTransactionInfo&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -77,6 +77,15 @@
</span><span class="cx">     m_objectStoreMap.set(info.identifier(), info);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(uint64_t objectStoreIdentifier) const
+{
+    auto iterator = m_objectStoreMap.find(objectStoreIdentifier);
+    if (iterator == m_objectStoreMap.end())
+        return nullptr;
+
+    return &amp;iterator-&gt;value;
+}
+
</ins><span class="cx"> Vector&lt;String&gt; IDBDatabaseInfo::objectStoreNames() const
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;String&gt; names;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx">     bool hasObjectStore(const String&amp; name) const;
</span><span class="cx">     IDBObjectStoreInfo createNewObjectStore(const String&amp; name, const IDBKeyPath&amp;, bool autoIncrement);
</span><span class="cx">     void addExistingObjectStore(const IDBObjectStoreInfo&amp;);
</span><ins>+    const IDBObjectStoreInfo* infoForExistingObjectStore(uint64_t objectStoreIdentifier) const;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;String&gt; objectStoreNames() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBErrorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -51,6 +51,22 @@
</span><span class="cx">         static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;InvalidStateError&quot;);
</span><span class="cx">         return entry;
</span><span class="cx">     }
</span><ins>+    case IDBExceptionCode::DataError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;DataError&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::TransactionInactiveError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;TransactionInactiveError&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::ReadOnlyError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;ReadOnlyError&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::DataCloneError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;DataCloneError&quot;);
+        return entry;
+    }
</ins><span class="cx">     case IDBExceptionCode::None:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="lines">@@ -77,6 +93,22 @@
</span><span class="cx">         static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;Operation was called on an object on which it is not allowed or at a time when it is not allowed.&quot;);
</span><span class="cx">         return entry;
</span><span class="cx">     }
</span><ins>+    case IDBExceptionCode::DataError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;Data provided to an operation does not meet requirements.&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::TransactionInactiveError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;Request was placed against a transaction which is currently not active, or which is finished.&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::ReadOnlyError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;A mutating operation was attempted in a \&quot;readonly\&quot; transaction.&quot;);
+        return entry;
+    }
+    case IDBExceptionCode::DataCloneError: {
+        static NeverDestroyed&lt;String&gt; entry = ASCIILiteral(&quot;Data being stored could not be cloned by the structured cloning algorithm.&quot;);
+        return entry;
+    }
</ins><span class="cx">     case IDBExceptionCode::None:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBErrorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBError.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -36,10 +36,14 @@
</span><span class="cx">     None = 0,
</span><span class="cx">     Unknown,
</span><span class="cx">     ConstraintError,
</span><ins>+    DataError,
+    TransactionInactiveError,
+    ReadOnlyError,
</ins><span class="cx">     VersionError,
</span><span class="cx"> 
</span><span class="cx">     // Indexed DB existing exception codes with IDB-specific error messages:
</span><span class="cx">     InvalidStateError,
</span><ins>+    DataCloneError,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class IDBError {
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -34,20 +34,25 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> IDBRequestData::IDBRequestData(const IDBClient::IDBConnectionToServer&amp; connection, const IDBClient::IDBOpenDBRequest&amp; request)
</span><del>-    : m_requestIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(connection, request))
</del><ins>+    : m_serverConnectionIdentifier(connection.identifier())
+    , m_requestIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(connection, request))
</ins><span class="cx">     , m_databaseIdentifier(request.databaseIdentifier())
</span><span class="cx">     , m_requestedVersion(request.version())
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBRequestData::IDBRequestData(IDBClient::TransactionOperation&amp; operation)
</span><del>-    : m_requestIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(operation.identifier()))
</del><ins>+    : m_serverConnectionIdentifier(operation.transaction().database().serverConnection().identifier())
+    , m_requestIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(operation.identifier()))
</ins><span class="cx">     , m_transactionIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(operation.transactionIdentifier()))
</span><ins>+    , m_objectStoreIdentifier(operation.objectStoreIdentifier())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBRequestData::IDBRequestData(const IDBRequestData&amp; other)
</span><del>-    : m_databaseIdentifier(other.m_databaseIdentifier)
</del><ins>+    : m_serverConnectionIdentifier(other.m_serverConnectionIdentifier)
+    , m_objectStoreIdentifier(other.m_objectStoreIdentifier)
+    , m_databaseIdentifier(other.m_databaseIdentifier)
</ins><span class="cx">     , m_requestedVersion(other.m_requestedVersion)
</span><span class="cx"> {
</span><span class="cx">     if (other.m_requestIdentifier)
</span><span class="lines">@@ -56,6 +61,12 @@
</span><span class="cx">         m_transactionIdentifier = std::make_unique&lt;IDBResourceIdentifier&gt;(*other.m_transactionIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint64_t IDBRequestData::serverConnectionIdentifier() const
+{
+    ASSERT(m_serverConnectionIdentifier);
+    return m_serverConnectionIdentifier;
+}
+
</ins><span class="cx"> IDBResourceIdentifier IDBRequestData::requestIdentifier() const
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_requestIdentifier);
</span><span class="lines">@@ -68,6 +79,12 @@
</span><span class="cx">     return *m_transactionIdentifier;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint64_t IDBRequestData::objectStoreIdentifier() const
+{
+    RELEASE_ASSERT(m_objectStoreIdentifier);
+    return m_objectStoreIdentifier;
+}
+
</ins><span class="cx"> uint64_t IDBRequestData::requestedVersion() const
</span><span class="cx"> {
</span><span class="cx">     return m_requestedVersion;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -46,8 +46,10 @@
</span><span class="cx">     explicit IDBRequestData(IDBClient::TransactionOperation&amp;);
</span><span class="cx">     IDBRequestData(const IDBRequestData&amp;);
</span><span class="cx"> 
</span><ins>+    uint64_t serverConnectionIdentifier() const;
</ins><span class="cx">     IDBResourceIdentifier requestIdentifier() const;
</span><span class="cx">     IDBResourceIdentifier transactionIdentifier() const;
</span><ins>+    uint64_t objectStoreIdentifier() const;
</ins><span class="cx"> 
</span><span class="cx">     const IDBDatabaseIdentifier&amp; databaseIdentifier() const { return m_databaseIdentifier; }
</span><span class="cx">     uint64_t requestedVersion() const;
</span><span class="lines">@@ -55,8 +57,10 @@
</span><span class="cx">     IDBRequestData isolatedCopy();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    uint64_t m_serverConnectionIdentifier { 0 };
</ins><span class="cx">     std::unique_ptr&lt;IDBResourceIdentifier&gt; m_requestIdentifier;
</span><span class="cx">     std::unique_ptr&lt;IDBResourceIdentifier&gt; m_transactionIdentifier;
</span><ins>+    uint64_t m_objectStoreIdentifier { 0 };
</ins><span class="cx"> 
</span><span class="cx">     IDBDatabaseIdentifier m_databaseIdentifier;
</span><span class="cx">     uint64_t m_requestedVersion { 0 };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBResultDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -50,11 +50,14 @@
</span><span class="cx">     , m_requestIdentifier(other.m_requestIdentifier)
</span><span class="cx">     , m_error(other.m_error)
</span><span class="cx">     , m_databaseConnectionIdentifier(other.m_databaseConnectionIdentifier)
</span><ins>+    , m_resultData(other.m_resultData)
</ins><span class="cx"> {
</span><span class="cx">     if (other.m_databaseInfo)
</span><span class="cx">         m_databaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(*other.m_databaseInfo);
</span><span class="cx">     if (other.m_transactionInfo)
</span><span class="cx">         m_transactionInfo = std::make_unique&lt;IDBTransactionInfo&gt;(*other.m_transactionInfo);
</span><ins>+    if (other.m_resultKey)
+        m_resultKey = std::make_unique&lt;IDBKeyData&gt;(*other.m_resultKey);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBResultData IDBResultData::error(const IDBResourceIdentifier&amp; requestIdentifier, const IDBError&amp; error)
</span><span class="lines">@@ -90,6 +93,20 @@
</span><span class="cx">     return { IDBResultType::CreateObjectStoreSuccess, requestIdentifier };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBResultData IDBResultData::putOrAddSuccess(const IDBResourceIdentifier&amp; requestIdentifier, const IDBKeyData&amp; resultKey)
+{
+    IDBResultData result(IDBResultType::PutOrAddSuccess, requestIdentifier);
+    result.m_resultKey = std::make_unique&lt;IDBKeyData&gt;(resultKey);
+    return result;
+}
+
+IDBResultData IDBResultData::getRecordSuccess(const IDBResourceIdentifier&amp; requestIdentifier, const ThreadSafeDataBuffer&amp; valueData)
+{
+    IDBResultData result(IDBResultType::GetRecordSuccess, requestIdentifier);
+    result.m_resultData = valueData;
+    return result;
+}
+
</ins><span class="cx"> const IDBDatabaseInfo&amp; IDBResultData::databaseInfo() const
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_databaseInfo);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBResultDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,31 +30,38 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBDatabaseInfo.h&quot;
</span><span class="cx"> #include &quot;IDBError.h&quot;
</span><ins>+#include &quot;IDBKeyData.h&quot;
</ins><span class="cx"> #include &quot;IDBResourceIdentifier.h&quot;
</span><span class="cx"> #include &quot;IDBTransactionInfo.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class IDBResourceIdentifier;
</span><ins>+class ThreadSafeDataBuffer;
</ins><span class="cx"> 
</span><del>-namespace IDBServer {
-class UniqueIDBDatabaseConnection;
-class UniqueIDBDatabaseTransaction;
-}
-
</del><span class="cx"> enum class IDBResultType {
</span><span class="cx">     Error,
</span><span class="cx">     OpenDatabaseSuccess,
</span><span class="cx">     OpenDatabaseUpgradeNeeded,
</span><span class="cx">     CreateObjectStoreSuccess,
</span><ins>+    PutOrAddSuccess,
+    GetRecordSuccess,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+namespace IDBServer {
+class UniqueIDBDatabaseConnection;
+class UniqueIDBDatabaseTransaction;
+}
+
</ins><span class="cx"> class IDBResultData {
</span><span class="cx"> public:
</span><span class="cx">     static IDBResultData error(const IDBResourceIdentifier&amp;, const IDBError&amp;);
</span><span class="cx">     static IDBResultData openDatabaseSuccess(const IDBResourceIdentifier&amp;, IDBServer::UniqueIDBDatabaseConnection&amp;);
</span><span class="cx">     static IDBResultData openDatabaseUpgradeNeeded(const IDBResourceIdentifier&amp;, IDBServer::UniqueIDBDatabaseTransaction&amp;);
</span><span class="cx">     static IDBResultData createObjectStoreSuccess(const IDBResourceIdentifier&amp;);
</span><ins>+    static IDBResultData putOrAddSuccess(const IDBResourceIdentifier&amp;, const IDBKeyData&amp;);
+    static IDBResultData getRecordSuccess(const IDBResourceIdentifier&amp;, const ThreadSafeDataBuffer&amp; valueData);
</ins><span class="cx"> 
</span><span class="cx">     IDBResultData(const IDBResultData&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -67,6 +74,9 @@
</span><span class="cx">     const IDBDatabaseInfo&amp; databaseInfo() const;
</span><span class="cx">     const IDBTransactionInfo&amp; transactionInfo() const;
</span><span class="cx"> 
</span><ins>+    const IDBKeyData* resultKey() const { return m_resultKey.get(); }
+    const ThreadSafeDataBuffer&amp; resultData() const { return m_resultData; }
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBResultData(const IDBResourceIdentifier&amp;);
</span><span class="cx">     IDBResultData(IDBResultType, const IDBResourceIdentifier&amp;);
</span><span class="lines">@@ -78,6 +88,8 @@
</span><span class="cx">     uint64_t m_databaseConnectionIdentifier { 0 };
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_databaseInfo;
</span><span class="cx">     std::unique_ptr&lt;IDBTransactionInfo&gt; m_transactionInfo;
</span><ins>+    std::unique_ptr&lt;IDBKeyData&gt; m_resultKey;
+    ThreadSafeDataBuffer m_resultData;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBConnectionToClient.h&quot;
</span><span class="cx"> #include &quot;IDBConnectionToServer.h&quot;
</span><ins>+#include &quot;IDBKeyData.h&quot;
</ins><span class="cx"> #include &quot;IDBOpenDBRequestImpl.h&quot;
</span><span class="cx"> #include &quot;IDBRequestData.h&quot;
</span><span class="cx"> #include &quot;IDBResultData.h&quot;
</span><span class="lines">@@ -126,6 +127,22 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InProcessIDBServer::didPutOrAdd(const IDBResultData&amp; resultData)
+{
+    RefPtr&lt;InProcessIDBServer&gt; self(this);
+    RunLoop::current().dispatch([this, self, resultData] {
+        m_connectionToServer-&gt;didPutOrAdd(resultData);
+    });
+}
+
+void InProcessIDBServer::didGetRecord(const IDBResultData&amp; resultData)
+{
+    RefPtr&lt;InProcessIDBServer&gt; self(this);
+    RunLoop::current().dispatch([this, self, resultData] {
+        m_connectionToServer-&gt;didGetRecord(resultData);
+    });
+}
+
</ins><span class="cx"> void InProcessIDBServer::abortTransaction(IDBResourceIdentifier&amp; resourceIdentifier)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;InProcessIDBServer&gt; self(this);
</span><span class="lines">@@ -150,6 +167,27 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InProcessIDBServer::putOrAdd(const IDBRequestData&amp; requestData, IDBKey* key, SerializedScriptValue&amp; value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+{
+    RefPtr&lt;InProcessIDBServer&gt; self(this);
+    IDBKeyData keyData(key);
+    auto valueData = ThreadSafeDataBuffer::copyVector(value.data());
+
+    RunLoop::current().dispatch([this, self, requestData, keyData, valueData, overwriteMode] {
+        m_server-&gt;putOrAdd(requestData, keyData, valueData, overwriteMode);
+    });
+}
+
+void InProcessIDBServer::getRecord(const IDBRequestData&amp; requestData, IDBKey* key)
+{
+    RefPtr&lt;InProcessIDBServer&gt; self(this);
+    IDBKeyData keyData(key);
+
+    RunLoop::current().dispatch([this, self, requestData, keyData] {
+        m_server-&gt;getRecord(requestData, keyData);
+    });
+}
+
</ins><span class="cx"> void InProcessIDBServer::fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&amp; connection, uint64_t requestedVersion)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;InProcessIDBServer&gt; self(this);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedInProcessIDBServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -59,6 +59,8 @@
</span><span class="cx">     virtual void abortTransaction(IDBResourceIdentifier&amp;) override final;
</span><span class="cx">     virtual void commitTransaction(IDBResourceIdentifier&amp;) override final;
</span><span class="cx">     virtual void createObjectStore(const IDBRequestData&amp;, const IDBObjectStoreInfo&amp;) override final;
</span><ins>+    virtual void putOrAdd(const IDBRequestData&amp;, IDBKey*, SerializedScriptValue&amp;, const IndexedDB::ObjectStoreOverwriteMode) override final;
+    virtual void getRecord(const IDBRequestData&amp;, IDBKey*) override final;
</ins><span class="cx">     virtual void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) override final;
</span><span class="cx"> 
</span><span class="cx">     // IDBConnectionToClient
</span><span class="lines">@@ -68,6 +70,8 @@
</span><span class="cx">     virtual void didAbortTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;) override final;
</span><span class="cx">     virtual void didCommitTransaction(const IDBResourceIdentifier&amp; transactionIdentifier, const IDBError&amp;) override final;
</span><span class="cx">     virtual void didCreateObjectStore(const IDBResultData&amp;) override final;
</span><ins>+    virtual void didPutOrAdd(const IDBResultData&amp;) override final;
+    virtual void didGetRecord(const IDBResultData&amp;) override final;
</ins><span class="cx">     virtual void fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&amp;, uint64_t requestedVersion) override final;
</span><span class="cx"> 
</span><span class="cx">     virtual void ref() override { RefCounted&lt;InProcessIDBServer&gt;::ref(); }
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -2181,6 +2181,8 @@
</span><span class="cx">                 51D0C5160DAA90B7003B3831 /* JSStorageCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D0C5150DAA90B7003B3831 /* JSStorageCustom.cpp */; };
</span><span class="cx">                 51D7236C1BB6174900478CA3 /* IDBResultData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D7236A1BB60BFE00478CA3 /* IDBResultData.cpp */; };
</span><span class="cx">                 51D7236D1BB6174900478CA3 /* IDBResultData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51D7236B1BB60BFE00478CA3 /* IDBResultData.h */; };
</span><ins>+                51D7EFEA1BDE8F8C00E93E10 /* ThreadSafeDataBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 511FAEA91BDC989A00B4AFE4 /* ThreadSafeDataBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                51D7EFEC1BDEFA5100E93E10 /* TransactionOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D7EFEB1BDEFA4700E93E10 /* TransactionOperation.cpp */; };
</ins><span class="cx">                 51DCE8020CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */; };
</span><span class="cx">                 51DF6D7E0B92A16D00C2DC85 /* ThreadCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */; };
</span><span class="lines">@@ -9345,6 +9347,7 @@
</span><span class="cx">                 511EF2CC17F0FDF100E4FA16 /* JSIDBAnyCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBAnyCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 511EF2CD17F0FDF100E4FA16 /* JSIDBDatabaseCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBDatabaseCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBObjectStoreCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                511FAEA91BDC989A00B4AFE4 /* ThreadSafeDataBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadSafeDataBuffer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5123AF161890A4CA0031CDC9 /* IDBKeyRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBKeyRangeData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5123AF171890A4CA0031CDC9 /* IDBKeyRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBKeyRangeData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5123AF1C18918AE40031CDC9 /* IDBGetResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBGetResult.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -9592,6 +9595,7 @@
</span><span class="cx">                 51D719B3181106E00016DC51 /* WorkerGlobalScopeIndexedDatabase.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WorkerGlobalScopeIndexedDatabase.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51D7236A1BB60BFE00478CA3 /* IDBResultData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBResultData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51D7236B1BB60BFE00478CA3 /* IDBResultData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBResultData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                51D7EFEB1BDEFA4700E93E10 /* TransactionOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransactionOperation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLResultSetRowListCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ThreadCheck.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -16805,6 +16809,7 @@
</span><span class="cx">                                 5198F7B31BBE001D00E2CC5F /* IDBTransactionImpl.h */,
</span><span class="cx">                                 5198F7B61BC3141700E2CC5F /* IDBVersionChangeEventImpl.cpp */,
</span><span class="cx">                                 5198F7B71BC3141700E2CC5F /* IDBVersionChangeEventImpl.h */,
</span><ins>+                                51D7EFEB1BDEFA4700E93E10 /* TransactionOperation.cpp */,
</ins><span class="cx">                                 5160712B1BD8305300DBC4F2 /* TransactionOperation.h */,
</span><span class="cx">                         );
</span><span class="cx">                         path = client;
</span><span class="lines">@@ -22525,6 +22530,7 @@
</span><span class="cx">                                 51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */,
</span><span class="cx">                                 E1FF57A50F01256B00891EBB /* ThreadGlobalData.cpp */,
</span><span class="cx">                                 E1FF57A20F01255B00891EBB /* ThreadGlobalData.h */,
</span><ins>+                                511FAEA91BDC989A00B4AFE4 /* ThreadSafeDataBuffer.h */,
</ins><span class="cx">                                 185BCF260F3279CE000EA262 /* ThreadTimers.cpp */,
</span><span class="cx">                                 185BCF270F3279CE000EA262 /* ThreadTimers.h */,
</span><span class="cx">                                 93309EA1099EB78C0056E581 /* Timer.cpp */,
</span><span class="lines">@@ -26311,6 +26317,7 @@
</span><span class="cx">                                 B2FA3DAF0AB75A6F000E5AC4 /* JSSVGMetadataElement.h in Headers */,
</span><span class="cx">                                 B27B282A0CEF0C0700D39D54 /* JSSVGMissingGlyphElement.h in Headers */,
</span><span class="cx">                                 4496E3A0139813A5003EE32A /* JSSVGMPathElement.h in Headers */,
</span><ins>+                                51D7EFEA1BDE8F8C00E93E10 /* ThreadSafeDataBuffer.h in Headers */,
</ins><span class="cx">                                 8542A7970AE5C94300DF58DF /* JSSVGNumber.h in Headers */,
</span><span class="cx">                                 B2FA3DB10AB75A6F000E5AC4 /* JSSVGNumberList.h in Headers */,
</span><span class="cx">                                 B2FA3DB30AB75A6F000E5AC4 /* JSSVGPaint.h in Headers */,
</span><span class="lines">@@ -31119,6 +31126,7 @@
</span><span class="cx">                                 2D4F96F51A1ECC240098BF88 /* TextIndicator.cpp in Sources */,
</span><span class="cx">                                 2D4F96F81A1ECC240098BF88 /* TextIndicatorWindow.mm in Sources */,
</span><span class="cx">                                 F55B3DD91251F12D003EF269 /* TextInputType.cpp in Sources */,
</span><ins>+                                51D7EFEC1BDEFA5100E93E10 /* TransactionOperation.cpp in Sources */,
</ins><span class="cx">                                 CECADFCD1537791D00E37068 /* TextInsertionBaseCommand.cpp in Sources */,
</span><span class="cx">                                 93309E1B099E64920056E581 /* TextIterator.cpp in Sources */,
</span><span class="cx">                                 E4D988B617BFEB210084FB88 /* TextNodeTraversal.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;JSDOMBinding.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;SharedBuffer.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #include &lt;runtime/DateInstance.h&gt;
</span><span class="cx"> #include &lt;runtime/ObjectConstructor.h&gt;
</span><span class="lines">@@ -77,12 +78,14 @@
</span><span class="cx"> 
</span><span class="cx"> static JSValue idbKeyToJSValue(ExecState* exec, JSDOMGlobalObject* globalObject, IDBKey* key)
</span><span class="cx"> {
</span><del>-    if (!key) {
</del><ins>+    if (!key || !exec) {
</ins><span class="cx">         // This should be undefined, not null.
</span><span class="cx">         // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBKeyRange
</span><span class="cx">         return jsUndefined();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    Locker&lt;JSLock&gt; locker(exec-&gt;vm().apiLock());
+
</ins><span class="cx">     switch (key-&gt;type()) {
</span><span class="cx">     case KeyType::Array:
</span><span class="cx">         {
</span><span class="lines">@@ -279,10 +282,41 @@
</span><span class="cx">     return internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath.string());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;IDBKey&gt; maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState&amp; exec, const Deprecated::ScriptValue&amp; value, const IDBKeyPath&amp; keyPath)
+{
+    ASSERT(!keyPath.isNull());
+
+    if (keyPath.type() == IndexedDB::KeyPathType::Array) {
+        Vector&lt;RefPtr&lt;IDBKey&gt;&gt; result;
+        const Vector&lt;String&gt;&amp; array = keyPath.array();
+        for (size_t i = 0; i &lt; array.size(); i++) {
+            RefPtr&lt;IDBKey&gt; key = internalCreateIDBKeyFromScriptValueAndKeyPath(&amp;exec, value, array[i]);
+            if (!key)
+                return nullptr;
+            result.append(key);
+        }
+        return IDBKey::createArray(result);
+    }
+
+    ASSERT(keyPath.type() == IndexedDB::KeyPathType::String);
+    return internalCreateIDBKeyFromScriptValueAndKeyPath(&amp;exec, value, keyPath.string());
+}
+
</ins><span class="cx"> bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Deprecated::ScriptValue&amp; scriptValue, const IDBKeyPath&amp; keyPath)
</span><span class="cx"> {
</span><span class="cx">     LOG(StorageAPI, &quot;canInjectIDBKeyIntoScriptValue&quot;);
</span><span class="cx"> 
</span><ins>+    JSC::ExecState* exec = requestState-&gt;exec();
+    if (!exec)
+        return false;
+
+    return canInjectIDBKeyIntoScriptValue(*exec, scriptValue, keyPath);
+}
+
+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&amp; execState, const Deprecated::ScriptValue&amp; scriptValue, const IDBKeyPath&amp; keyPath)
+{
+    LOG(StorageAPI, &quot;canInjectIDBKeyIntoScriptValue&quot;);
+
</ins><span class="cx">     ASSERT(keyPath.type() == IndexedDB::KeyPathType::String);
</span><span class="cx">     Vector&lt;String&gt; keyPathElements;
</span><span class="cx">     IDBKeyPathParseError error;
</span><span class="lines">@@ -292,8 +326,7 @@
</span><span class="cx">     if (!keyPathElements.size())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    JSC::ExecState* exec = requestState-&gt;exec();
-    return canInjectNthValueOnKeyPath(exec, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1);
</del><ins>+    return canInjectNthValueOnKeyPath(&amp;execState, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Deprecated::ScriptValue deserializeIDBValue(DOMRequestState* requestState, PassRefPtr&lt;SerializedScriptValue&gt; prpValue)
</span><span class="lines">@@ -308,6 +341,28 @@
</span><span class="cx">     return Deprecated::ScriptValue(exec-&gt;vm(), result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&amp; context, const ThreadSafeDataBuffer&amp; valueData)
+{
+    DOMRequestState state(&amp;context);
+    auto* execState = state.exec();
+
+    if (!valueData.data())
+        return Deprecated::ScriptValue(execState-&gt;vm(), jsUndefined());
+
+    const Vector&lt;uint8_t&gt;&amp; data = *valueData.data();
+    JSValue result;
+    if (data.size()) {
+        RefPtr&lt;SerializedScriptValue&gt; serializedValue = SerializedScriptValue::createFromWireBytes(data);
+
+        execState-&gt;vm().apiLock().lock();
+        result = serializedValue-&gt;deserialize(execState, execState-&gt;lexicalGlobalObject(), 0, NonThrowing);
+        execState-&gt;vm().apiLock().unlock();
+    } else
+        result = jsNull();
+
+    return Deprecated::ScriptValue(execState-&gt;vm(), result);
+}
+
</ins><span class="cx"> Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState* requestState, PassRefPtr&lt;SharedBuffer&gt; prpBuffer, bool keyIsDefined)
</span><span class="cx"> {
</span><span class="cx">     if (prpBuffer) {
</span><span class="lines">@@ -350,6 +405,11 @@
</span><span class="cx">     return createIDBKeyFromValue(exec, scriptValue.jsValue());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;IDBKey&gt; scriptValueToIDBKey(ExecState&amp; exec, const Deprecated::ScriptValue&amp; scriptValue)
+{
+    return createIDBKeyFromValue(&amp;exec, scriptValue.jsValue());
+}
+
</ins><span class="cx"> void generateIndexKeysForValue(ExecState* exec, const IDBIndexMetadata&amp; indexMetadata, const Deprecated::ScriptValue&amp; objectValue, Vector&lt;IDBKeyData&gt;&amp; indexKeys)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;IDBKey&gt; indexKey = createIDBKeyFromScriptValueAndKeyPath(exec, objectValue, indexMetadata.keyPath);
</span><span class="lines">@@ -375,6 +435,13 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Deprecated::ScriptValue idbKeyDataToScriptValue(ScriptExecutionContext* context, const IDBKeyData&amp; keyData)
+{
+    RefPtr&lt;IDBKey&gt; key = keyData.maybeCreateIDBKey();
+    DOMRequestState requestState(context);
+    return idbKeyToScriptValue(&amp;requestState, key.get());
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> class IDBKey;
</span><span class="cx"> class IDBKeyPath;
</span><span class="cx"> class SharedBuffer;
</span><ins>+class ThreadSafeDataBuffer;
</ins><span class="cx"> 
</span><span class="cx"> struct IDBIndexMetadata;
</span><span class="cx"> class IDBKeyData;
</span><span class="lines">@@ -45,15 +46,23 @@
</span><span class="cx"> IDBKeyPath idbKeyPathFromValue(JSC::ExecState*, JSC::JSValue);
</span><span class="cx"> 
</span><span class="cx"> bool injectIDBKeyIntoScriptValue(DOMRequestState*, PassRefPtr&lt;IDBKey&gt;, Deprecated::ScriptValue&amp;, const IDBKeyPath&amp;);
</span><ins>+
</ins><span class="cx"> RefPtr&lt;IDBKey&gt; createIDBKeyFromScriptValueAndKeyPath(JSC::ExecState*, const Deprecated::ScriptValue&amp;, const IDBKeyPath&amp;);
</span><ins>+RefPtr&lt;IDBKey&gt; maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&amp;, const Deprecated::ScriptValue&amp;, const IDBKeyPath&amp;);
+
</ins><span class="cx"> bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const Deprecated::ScriptValue&amp;, const IDBKeyPath&amp;);
</span><ins>+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&amp;, const Deprecated::ScriptValue&amp;, const IDBKeyPath&amp;);
+
</ins><span class="cx"> Deprecated::ScriptValue deserializeIDBValue(DOMRequestState*, PassRefPtr&lt;SerializedScriptValue&gt;);
</span><ins>+Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&amp;, const ThreadSafeDataBuffer&amp; valueData);
</ins><span class="cx"> Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState*, PassRefPtr&lt;SharedBuffer&gt;, bool keyIsDefined);
</span><span class="cx"> WEBCORE_EXPORT Deprecated::ScriptValue deserializeIDBValueBuffer(JSC::ExecState*, const Vector&lt;uint8_t&gt;&amp;, bool keyIsDefined);
</span><span class="cx"> Deprecated::ScriptValue idbKeyToScriptValue(DOMRequestState*, PassRefPtr&lt;IDBKey&gt;);
</span><span class="cx"> RefPtr&lt;IDBKey&gt; scriptValueToIDBKey(DOMRequestState*, const Deprecated::ScriptValue&amp;);
</span><ins>+RefPtr&lt;IDBKey&gt; scriptValueToIDBKey(JSC::ExecState&amp;, const Deprecated::ScriptValue&amp;);
</ins><span class="cx"> WEBCORE_EXPORT void generateIndexKeysForValue(JSC::ExecState*, const IDBIndexMetadata&amp;, const Deprecated::ScriptValue&amp; objectValue, Vector&lt;IDBKeyData&gt;&amp; indexKeys);
</span><span class="cx"> 
</span><ins>+Deprecated::ScriptValue idbKeyDataToScriptValue(ScriptExecutionContext*, const IDBKeyData&amp;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformCrossThreadCopiercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/CrossThreadCopier.cpp (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/CrossThreadCopier.cpp        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/platform/CrossThreadCopier.cpp        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;ResourceResponse.h&quot;
</span><span class="cx"> #include &quot;SerializedScriptValue.h&quot;
</span><span class="cx"> #include &quot;SessionID.h&quot;
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
</ins><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -86,6 +87,11 @@
</span><span class="cx">     return sessionID;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CrossThreadCopierBase&lt;false, false, ThreadSafeDataBuffer&gt;::Type CrossThreadCopierBase&lt;false, false, ThreadSafeDataBuffer&gt;::copy(const ThreadSafeDataBuffer&amp; buffer)
+{
+    return ThreadSafeDataBuffer(buffer);
+}
+
</ins><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><span class="cx"> IndexedDB::TransactionMode CrossThreadCopierBase&lt;false, false, IndexedDB::TransactionMode&gt;::copy(const IndexedDB::TransactionMode&amp; mode)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformCrossThreadCopierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/CrossThreadCopier.h (191634 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/CrossThreadCopier.h        2015-10-27 20:09:29 UTC (rev 191634)
+++ trunk/Source/WebCore/platform/CrossThreadCopier.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx">     class ResourceRequest;
</span><span class="cx">     class ResourceResponse;
</span><span class="cx">     class SessionID;
</span><ins>+    class ThreadSafeDataBuffer;
</ins><span class="cx">     struct CrossThreadResourceResponseData;
</span><span class="cx">     struct CrossThreadResourceRequestData;
</span><span class="cx">     struct ThreadableLoaderOptions;
</span><span class="lines">@@ -139,6 +140,11 @@
</span><span class="cx">         static Type copy(const SessionID&amp;);
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    template&lt;&gt; struct CrossThreadCopierBase&lt;false, false, ThreadSafeDataBuffer&gt; {
+        typedef ThreadSafeDataBuffer Type;
+        static Type copy(const ThreadSafeDataBuffer&amp;);
+    };
+
</ins><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx">     namespace IndexedDB {
</span><span class="cx">         enum class TransactionMode;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformThreadSafeDataBufferh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/ThreadSafeDataBuffer.h (0 => 191635)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ThreadSafeDataBuffer.h                                (rev 0)
+++ trunk/Source/WebCore/platform/ThreadSafeDataBuffer.h        2015-10-27 20:39:40 UTC (rev 191635)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThreadSafeDataBuffer_h
+#define ThreadSafeDataBuffer_h
+
+#include &lt;wtf/ThreadSafeRefCounted.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WebCore {
+
+class ThreadSafeDataBuffer;
+
+class ThreadSafeDataBufferImpl : public ThreadSafeRefCounted&lt;ThreadSafeDataBufferImpl&gt; {
+friend class ThreadSafeDataBuffer;
+private:
+    enum AdoptVectorTag { AdoptVector };
+    ThreadSafeDataBufferImpl(Vector&lt;uint8_t&gt;&amp; data, AdoptVectorTag)
+    {
+        m_data.swap(data);
+    }
+
+    ThreadSafeDataBufferImpl(const Vector&lt;uint8_t&gt;&amp; data)
+        : m_data(data)
+    {
+    }
+
+    Vector&lt;uint8_t&gt; m_data;
+};
+
+class ThreadSafeDataBuffer {
+public:
+    static ThreadSafeDataBuffer adoptVector(Vector&lt;uint8_t&gt;&amp; data)
+    {
+        return ThreadSafeDataBuffer(data, ThreadSafeDataBufferImpl::AdoptVector);
+    }
+    
+    static ThreadSafeDataBuffer copyVector(const Vector&lt;uint8_t&gt;&amp; data)
+    {
+        return ThreadSafeDataBuffer(data);
+    }
+
+    ThreadSafeDataBuffer()
+    {
+    }
+    
+    const Vector&lt;uint8_t&gt;* data() const
+    {
+        return m_impl ? &amp;m_impl-&gt;m_data : nullptr;
+    }
+
+private:
+    explicit ThreadSafeDataBuffer(Vector&lt;uint8_t&gt;&amp; data, ThreadSafeDataBufferImpl::AdoptVectorTag tag)
+    {
+        m_impl = adoptRef(new ThreadSafeDataBufferImpl(data, tag));
+    }
+
+    explicit ThreadSafeDataBuffer(const Vector&lt;uint8_t&gt;&amp; data)
+    {
+        m_impl = adoptRef(new ThreadSafeDataBufferImpl(data));
+    }
+
+    RefPtr&lt;ThreadSafeDataBufferImpl&gt; m_impl;
+};
+
+} // namespace WebCore
+
+#endif // ThreadSafeDataBuffer_h
</ins></span></pre>
</div>
</div>

</body>
</html>