IDB: Date objects don't work as keys or values.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Nov 2015 04:34:49 +0000 (04:34 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Nov 2015 04:34:49 +0000 (04:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150743

Reviewed by Darin Adler.

Source/WebCore:

Test: storage/indexeddb/modern/date-basic.html

The combination of the autogenerated bindings with Deprecated::ScriptValue was
losing the fidelity of "Date" objects being Dates, and not just normal Objects.

This was breaking their usage as IDBKeys.

Custom binding + reworking the IDBObjectStore IDLs to use JSValue instead of ScriptValue
fixes this handily.

* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/IDBObjectStore.idl:

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

* Modules/indexeddb/legacy/LegacyObjectStore.cpp:
(WebCore::LegacyObjectStore::add):
(WebCore::LegacyObjectStore::put):
* Modules/indexeddb/legacy/LegacyObjectStore.h:

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::internalCreateIDBKeyFromScriptValueAndKeyPath):
(WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
(WebCore::canInjectIDBKeyIntoScriptValue):
(WebCore::scriptValueToIDBKey):
* bindings/js/IDBBindingUtilities.h:

* bindings/js/JSIDBObjectStoreCustom.cpp:
(WebCore::putOrAdd):
(WebCore::JSIDBObjectStore::putRecord):
(WebCore::JSIDBObjectStore::add):

LayoutTests:

* storage/indexeddb/modern/date-basic-expected.txt: Added.
* storage/indexeddb/modern/date-basic.html: Added.
* storage/indexeddb/modern/get-keyrange-expected.txt:
* storage/indexeddb/modern/get-keyrange.html:

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/modern/date-basic-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/date-basic.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/get-keyrange-expected.txt
LayoutTests/storage/indexeddb/modern/get-keyrange.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBObjectStore.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.idl
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h
Source/WebCore/Modules/indexeddb/legacy/LegacyObjectStore.cpp
Source/WebCore/Modules/indexeddb/legacy/LegacyObjectStore.h
Source/WebCore/bindings/js/IDBBindingUtilities.cpp
Source/WebCore/bindings/js/IDBBindingUtilities.h
Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp

index 2b133a65f46a29a3db7549ca37dbef5c9ecdaa55..af1243faa418aaaf027cfeda56e62ce132d6419b 100644 (file)
@@ -1,3 +1,15 @@
+2015-10-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Date objects don't work as keys or values.
+        https://bugs.webkit.org/show_bug.cgi?id=150743
+
+        Reviewed by Darin Adler.
+
+        * storage/indexeddb/modern/date-basic-expected.txt: Added.
+        * storage/indexeddb/modern/date-basic.html: Added.
+        * storage/indexeddb/modern/get-keyrange-expected.txt:
+        * storage/indexeddb/modern/get-keyrange.html:
+
 2015-10-31  Brady Eidson  <beidson@apple.com>
 
         storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html is flaky.
diff --git a/LayoutTests/storage/indexeddb/modern/date-basic-expected.txt b/LayoutTests/storage/indexeddb/modern/date-basic-expected.txt
new file mode 100644 (file)
index 0000000..1b7eb01
--- /dev/null
@@ -0,0 +1,17 @@
+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Success getting key 'Fri Nov 04 1955 17:00:00 GMT-0700 (PDT)' of type object, result is 'Flux capacitor' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'Sat Nov 12 1955 10:00:00 GMT-0800 (PST)' of type object, result is 'Fish under the sea' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'Wed Oct 21 2015 09:00:00 GMT-0700 (PDT)' of type object, result is 'Hoverboards' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'a' of type string, result is 'Fri Nov 04 1955 17:00:00 GMT-0700 (PDT)' of type object
+ALERT: Result is a Date object, btw
+ALERT: Success getting key 'b' of type string, result is 'Sat Nov 12 1955 10:00:00 GMT-0800 (PST)' of type object
+ALERT: Result is a Date object, btw
+ALERT: Success getting key 'c' of type string, result is 'Wed Oct 21 2015 09:00:00 GMT-0700 (PDT)' of type object
+ALERT: Result is a Date object, btw
+ALERT: readonly transaction complete
+ALERT: Done
+This tests using Date objects as keys and values.
diff --git a/LayoutTests/storage/indexeddb/modern/date-basic.html b/LayoutTests/storage/indexeddb/modern/date-basic.html
new file mode 100644 (file)
index 0000000..f589348
--- /dev/null
@@ -0,0 +1,100 @@
+This tests using Date objects as keys and values.
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open("DateBasicDatabase", 1);
+var database;
+
+var date1 = new Date("1955-11-05T00:00:00");
+var date2 = new Date("1955-11-12T18:00:00");
+var date3 = new Date("2015-10-21T16:00:00");
+    
+createRequest.onupgradeneeded = function(event) {
+    alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    var objectStore = database.createObjectStore("TestObjectStore");
+
+    objectStore.put("Flux capacitor", date1);
+    objectStore.put("Fish under the sea", date2);
+    objectStore.put("Hoverboards", date3);
+    
+    objectStore.put(date1, "a");
+    objectStore.put(date2, "b");
+    objectStore.put(date3, "c");
+    
+    versionTransaction.onabort = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected aborted");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert("Initial upgrade versionchange transaction complete");
+        continueTest1();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+var objectStore;
+
+function testGet(key) {
+    var request = objectStore.get(key);
+    request.onsuccess = function()
+    {
+        alert("Success getting key '" + key + "' of type " + typeof(key) + ", result is '" + request.result + "' of type " + typeof(request.result));
+        if (key instanceof Date)
+            alert("Key is a Date object, btw");
+        if (request.result instanceof Date)
+            alert("Result is a Date object, btw");
+    }
+    request.onerror = function()
+    {
+        alert("Expected error getting key '" + key + "'");
+    }
+}
+
+function continueTest1()
+{
+    var transaction = database.transaction("TestObjectStore", "readonly");
+    objectStore = transaction.objectStore("TestObjectStore");
+    
+    testGet(date1);
+    testGet(date2);
+    testGet(date3);
+    testGet("a");
+    testGet("b");
+    testGet("c");
+    
+    transaction.onabort = function(event) {
+        alert("readonly transaction unexpected abort" + event);
+        done();
+    }
+
+    transaction.oncomplete = function(event) {
+        alert("readonly transaction complete");
+        done();
+    }
+
+    transaction.onerror = function(event) {
+        alert("readonly transaction unexpected error" + event);
+        done();
+    }
+}
+
+</script>
index c114180940c4e1b4c10f48ece57029fefa9bc7d2..7a47f766b263e64db402cbc0c1206529d1a61d11 100644 (file)
@@ -77,11 +77,11 @@ ALERT: Result is undefined
 ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
 ALERT: Result is PosInf
 ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
 ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
 ALERT: Result is PosInf
 ALERT: Success getting keyRange [Infinity (Open), a (Open)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
 ALERT: Success getting keyRange [AS (Closed), a (Closed)]
 ALERT: Result is AS
 ALERT: Success getting keyRange [AS (Open), a (Closed)]
@@ -93,11 +93,35 @@ ALERT: Result is As
 ALERT: Success getting keyRange [Infinity (Closed),  (Closed)]
 ALERT: Result is PosInf
 ALERT: Success getting keyRange [Infinity (Open),  (Closed)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
 ALERT: Success getting keyRange [Infinity (Closed),  (Open)]
 ALERT: Result is PosInf
 ALERT: Success getting keyRange [Infinity (Open),  (Open)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Closed), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Open), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Closed)]
+ALERT: Result is Fish under the sea
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Closed), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Open), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Open)]
+ALERT: Result is Fish under the sea
 ALERT: readonly transaction complete
 ALERT: Done
 This test exercises IDBObjectStore.get() with an IDBKeyRange as the parameter.
index fef9f7979a2322a916a782254bee232da40cb5c9..4260fa9242f55ff736053b4c71cda0a93144eb63 100644 (file)
@@ -16,12 +16,21 @@ function done()
 var createRequest = window.indexedDB.open("GetKeyRangeDatabase", 1);
 var database;
 
+var date1 = new Date("1955-11-05T00:00:00");
+var date2 = new Date("1955-11-12T18:00:00");
+var date3 = new Date("2015-10-21T16:00:00");
+    
 createRequest.onupgradeneeded = function(event) {
     alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
 
     var versionTransaction = createRequest.transaction;
     database = event.target.result;
     var objectStore = database.createObjectStore("TestObjectStore");
+
+    objectStore.put("Flux capacitor", date1);
+    objectStore.put("Fish under the sea", date2);
+    objectStore.put("Hoverboards", date3);
+
     for (var i = 0; i < 100; ++i)
         objectStore.put("\"" + i + "\"", i);
 
@@ -127,6 +136,21 @@ function continueTest1()
     testGet(IDBKeyRange.bound(Infinity, [], true));
     testGet(IDBKeyRange.bound(Infinity, [], false, true));
     testGet(IDBKeyRange.bound(Infinity, [], true, true));
+
+    testGet(IDBKeyRange.bound(Infinity, "a"));
+    testGet(IDBKeyRange.bound(Infinity, "a", true));
+    testGet(IDBKeyRange.bound(Infinity, "a", false, true));
+    testGet(IDBKeyRange.bound(Infinity, "a", true, true));
+
+    testGet(IDBKeyRange.bound(Infinity, "a"));
+    testGet(IDBKeyRange.bound(Infinity, "a", true));
+    testGet(IDBKeyRange.bound(Infinity, "a", false, true));
+    testGet(IDBKeyRange.bound(Infinity, "a", true, true));
+
+    testGet(IDBKeyRange.bound(date1, date3));
+    testGet(IDBKeyRange.bound(date1, date3, true));
+    testGet(IDBKeyRange.bound(date1, date3, false, true));
+    testGet(IDBKeyRange.bound(date1, date3, true, true));
     
     transaction.onabort = function(event) {
         alert("readonly transaction unexpected abort" + event);
index 887cc55296125929db53db159430590e0e930959..dae9e2e627e8b3a8bd94b65b1045f354150957c7 100644 (file)
@@ -1,3 +1,46 @@
+2015-10-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Date objects don't work as keys or values.
+        https://bugs.webkit.org/show_bug.cgi?id=150743
+
+        Reviewed by Darin Adler.
+
+        Test: storage/indexeddb/modern/date-basic.html
+
+        The combination of the autogenerated bindings with Deprecated::ScriptValue was
+        losing the fidelity of "Date" objects being Dates, and not just normal Objects.
+        
+        This was breaking their usage as IDBKeys.
+        
+        Custom binding + reworking the IDBObjectStore IDLs to use JSValue instead of ScriptValue
+        fixes this handily.
+        
+        * Modules/indexeddb/IDBObjectStore.h:
+        * Modules/indexeddb/IDBObjectStore.idl:
+        
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::add):
+        (WebCore::IDBClient::IDBObjectStore::put):
+        (WebCore::IDBClient::IDBObjectStore::putOrAdd):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+        
+        * Modules/indexeddb/legacy/LegacyObjectStore.cpp:
+        (WebCore::LegacyObjectStore::add):
+        (WebCore::LegacyObjectStore::put):
+        * Modules/indexeddb/legacy/LegacyObjectStore.h:
+        
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::internalCreateIDBKeyFromScriptValueAndKeyPath):
+        (WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
+        (WebCore::canInjectIDBKeyIntoScriptValue):
+        (WebCore::scriptValueToIDBKey):
+        * bindings/js/IDBBindingUtilities.h:
+
+        * bindings/js/JSIDBObjectStoreCustom.cpp:
+        (WebCore::putOrAdd):
+        (WebCore::JSIDBObjectStore::putRecord):
+        (WebCore::JSIDBObjectStore::add):
+
 2015-10-31  Andreas Kling  <akling@apple.com>
 
         Add a debug overlay with information about web process resource usage.
index b57f0c60fbb197a7c0777407066d6fcf90d458bd..8113ede573fff82a8398575f892542d8052ad784 100644 (file)
@@ -41,6 +41,7 @@ class ScriptValue;
 
 namespace JSC {
 class ExecState;
+class JSValue;
 }
 
 namespace WebCore {
@@ -66,8 +67,8 @@ public:
     virtual RefPtr<IDBTransaction> transaction() = 0;
     virtual bool autoIncrement() const = 0;
 
-    virtual RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
@@ -76,8 +77,8 @@ public:
 
     virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
-    virtual RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
+    virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
     virtual RefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) = 0;
index af020dfcce1ae3246ff291e23bc809cb0f291e55..13ccc0c11b420d961cc3d6b8ed8096d50b1e5462 100644 (file)
@@ -34,8 +34,8 @@
     readonly attribute IDBTransaction transaction;
     readonly attribute boolean autoIncrement;
 
-    [CallWith=ScriptState, RaisesException] IDBRequest put(any value, optional any key);
-    [CallWith=ScriptState, RaisesException] IDBRequest add(any value, optional any key);
+    [CallWith=ScriptExecutionContext, Custom, ImplementedAs=putFunction, RaisesException] IDBRequest put(any value, optional any key);
+    [CallWith=ScriptExecutionContext, Custom, RaisesException] IDBRequest add(any value, optional any key);
     [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(IDBKeyRange? keyRange);
     [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key);
     [CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(IDBKeyRange? key);
index 66f99eae22918d97eca584db589dd286ae3a42da..00e3bacac933d5790aeccd97c64a50c707369b8c 100644 (file)
@@ -87,16 +87,6 @@ bool IDBObjectStore::autoIncrement() const
     return m_info.autoIncrement();
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
-{
-    return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
-}
-
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
-{
-    return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
-}
-
 RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext*, ExceptionCode&)
 {
     RELEASE_ASSERT_NOT_REACHED();
@@ -183,19 +173,29 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context,
     return WTF::move(request);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+{
+    return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
+}
+
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
 {
     auto idbKey = scriptValueToIDBKey(execState, key);
     return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
 {
     auto idbKey = scriptValueToIDBKey(execState, key);
     return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
 }
 
-RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, Deprecated::ScriptValue& value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+{
+    return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
+}
+
+RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode& ec)
 {
     LOG(IndexedDB, "IDBObjectStore::putOrAdd");
 
@@ -214,7 +214,7 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, Depr
         return nullptr;
     }
 
-    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value.jsValue(), nullptr, nullptr);
+    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
     if (state.hadException()) {
         ec = DATA_CLONE_ERR;
         return nullptr;
index dc27cef8fa67d409f8d4595bcfe9992a5986b31b..4bd5049796f4809e5fc81b315b33a2289ca80dcd 100644 (file)
@@ -54,8 +54,8 @@ public:
     virtual RefPtr<WebCore::IDBTransaction> transaction() override final;
     virtual bool autoIncrement() const override final;
 
-    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
@@ -63,8 +63,8 @@ public:
     virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
-    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
+    virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) override final;
@@ -82,7 +82,7 @@ public:
 private:
     IDBObjectStore(const IDBObjectStoreInfo&, IDBTransaction&);
 
-    RefPtr<WebCore::IDBRequest> putOrAdd(JSC::ExecState&, Deprecated::ScriptValue&, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, ExceptionCode&);
+    RefPtr<WebCore::IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, ExceptionCode&);
 
     IDBObjectStoreInfo m_info;
     Ref<IDBTransaction> m_transaction;
index 970013b620811074d3e01fc5694f29bc6fd1f617..c8c65d4ec9b4bc4c6d1d8a40cd11d28a7b6ef94a 100644 (file)
@@ -96,28 +96,33 @@ RefPtr<IDBRequest> LegacyObjectStore::get(ScriptExecutionContext* context, const
     return get(context, keyRange.get(), ec);
 }
 
-RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
 {
     LOG(StorageAPI, "LegacyObjectStore::add");
-    return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, value, key, ec);
+    auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+    auto dKey = Deprecated::ScriptValue(state.vm(), key);
+    return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, deprecatedValue, dKey, ec);
 }
 
-RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
 {
     LOG(StorageAPI, "LegacyObjectStore::add");
-    return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, value, static_cast<IDBKey*>(nullptr), ec);
+    auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+    return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, deprecatedValue, static_cast<IDBKey*>(nullptr), ec);
 }
 
-RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
 {
     LOG(StorageAPI, "LegacyObjectStore::put");
-    return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, value, key, ec);
+    auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+    return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, deprecatedValue, Deprecated::ScriptValue(state.vm(), key), ec);
 }
 
-RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
 {
     LOG(StorageAPI, "LegacyObjectStore::put");
-    return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, value, static_cast<IDBKey*>(nullptr), ec);
+    auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+    return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, deprecatedValue, static_cast<IDBKey*>(nullptr), ec);
 }
 
 RefPtr<IDBRequest> LegacyObjectStore::put(IDBDatabaseBackend::PutMode putMode, RefPtr<LegacyAny> source, JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& keyValue, ExceptionCode& ec)
index 735379cc610307b77638e8201c85787b1e7502ca..05ff0dfa822068aef5c2db1e8a54b8058c81b32a 100644 (file)
@@ -67,8 +67,8 @@ public:
     RefPtr<IDBTransaction> transaction() { return m_transaction; }
     bool autoIncrement() const { return m_metadata.autoIncrement; }
 
-    RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&);
-    RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&);
+    RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&);
+    RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&);
     RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&);
     RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&);
     RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&);
@@ -78,8 +78,8 @@ public:
 
     RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&);
     RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&);
-    RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
-    RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
+    RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&);
+    RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&);
     RefPtr<IDBRequest> put(IDBDatabaseBackend::PutMode, RefPtr<LegacyAny>, JSC::ExecState&, Deprecated::ScriptValue&, RefPtr<IDBKey>, ExceptionCode&);
     RefPtr<IDBRequest> put(IDBDatabaseBackend::PutMode, RefPtr<LegacyAny> source, JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
 
index 08af04c1feedc71935571845a1a0d3c9f83850d0..74b636d6186a4ffeaae140e4f78c8e5c5406f8ca 100644 (file)
@@ -185,14 +185,14 @@ static JSValue getNthValueOnKeyPath(ExecState* exec, JSValue rootValue, const Ve
     return currentValue;
 }
 
-static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const Deprecated::ScriptValue& value, const String& keyPath)
+static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const JSC::JSValue& value, const String& keyPath)
 {
     Vector<String> keyPathElements;
     IDBKeyPathParseError error;
     IDBParseKeyPath(keyPath, keyPathElements, error);
     ASSERT(error == IDBKeyPathParseError::None);
 
-    JSValue jsValue = value.jsValue();
+    JSValue jsValue = value;
     jsValue = getNthValueOnKeyPath(exec, jsValue, keyPathElements, keyPathElements.size());
     if (jsValue.isUndefined())
         return nullptr;
@@ -302,7 +302,28 @@ RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const
     return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string());
 }
 
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath)
+RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const JSC::JSValue& value, const IDBKeyPath& keyPath)
+{
+    ASSERT(!keyPath.isNull());
+
+    if (keyPath.type() == IndexedDB::KeyPathType::Array) {
+        const Vector<String>& array = keyPath.array();
+        Vector<RefPtr<IDBKey>> result;
+        result.reserveInitialCapacity(array.size());
+        for (auto& string : array) {
+            RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, string);
+            if (!key)
+                return nullptr;
+            result.uncheckedAppend(WTF::move(key));
+        }
+        return IDBKey::createArray(WTF::move(result));
+    }
+
+    ASSERT(keyPath.type() == IndexedDB::KeyPathType::String);
+    return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string());
+}
+
+bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const JSC::JSValue& scriptValue, const IDBKeyPath& keyPath)
 {
     LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");
 
@@ -313,7 +334,7 @@ bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Depreca
     return canInjectIDBKeyIntoScriptValue(*exec, scriptValue, keyPath);
 }
 
-bool canInjectIDBKeyIntoScriptValue(JSC::ExecState& execState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath)
+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState& execState, const JSC::JSValue& scriptValue, const IDBKeyPath& keyPath)
 {
     LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");
 
@@ -326,7 +347,7 @@ bool canInjectIDBKeyIntoScriptValue(JSC::ExecState& execState, const Deprecated:
     if (!keyPathElements.size())
         return false;
 
-    return canInjectNthValueOnKeyPath(&execState, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1);
+    return canInjectNthValueOnKeyPath(&execState, scriptValue, keyPathElements, keyPathElements.size() - 1);
 }
 
 Deprecated::ScriptValue deserializeIDBValue(DOMRequestState* requestState, PassRefPtr<SerializedScriptValue> prpValue)
@@ -402,15 +423,15 @@ Deprecated::ScriptValue idbKeyToScriptValue(DOMRequestState* requestState, PassR
     return Deprecated::ScriptValue(exec->vm(), idbKeyToJSValue(exec, jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), key.get()));
 }
 
-RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue)
+RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const JSC::JSValue& scriptValue)
 {
     ExecState* exec = requestState->exec();
-    return createIDBKeyFromValue(exec, scriptValue.jsValue());
+    return createIDBKeyFromValue(exec, scriptValue);
 }
 
-RefPtr<IDBKey> scriptValueToIDBKey(ExecState& exec, const Deprecated::ScriptValue& scriptValue)
+RefPtr<IDBKey> scriptValueToIDBKey(ExecState& exec, const JSC::JSValue& scriptValue)
 {
-    return createIDBKeyFromValue(&exec, scriptValue.jsValue());
+    return createIDBKeyFromValue(&exec, scriptValue);
 }
 
 void generateIndexKeysForValue(ExecState* exec, const IDBIndexMetadata& indexMetadata, const Deprecated::ScriptValue& objectValue, Vector<IDBKeyData>& indexKeys)
index 42b7b39bc3e03d9fdf2dfe93991360c6dad15256..dd25762ca79882f11cdf383e74c84cf420e7a78b 100644 (file)
@@ -49,17 +49,18 @@ bool injectIDBKeyIntoScriptValue(DOMRequestState*, PassRefPtr<IDBKey>, Deprecate
 
 RefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(JSC::ExecState*, const Deprecated::ScriptValue&, const IDBKeyPath&);
 RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&, const Deprecated::ScriptValue&, const IDBKeyPath&);
+RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
 
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const Deprecated::ScriptValue&, const IDBKeyPath&);
-bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const Deprecated::ScriptValue&, const IDBKeyPath&);
+bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const JSC::JSValue&, const IDBKeyPath&);
+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
 
 Deprecated::ScriptValue deserializeIDBValue(DOMRequestState*, PassRefPtr<SerializedScriptValue>);
 Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&, const ThreadSafeDataBuffer& valueData);
 Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState*, PassRefPtr<SharedBuffer>, bool keyIsDefined);
 WEBCORE_EXPORT Deprecated::ScriptValue deserializeIDBValueBuffer(JSC::ExecState*, const Vector<uint8_t>&, bool keyIsDefined);
 Deprecated::ScriptValue idbKeyToScriptValue(DOMRequestState*, PassRefPtr<IDBKey>);
-RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState*, const Deprecated::ScriptValue&);
-RefPtr<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const Deprecated::ScriptValue&);
+RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState*, const JSC::JSValue&);
+RefPtr<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const JSC::JSValue&);
 WEBCORE_EXPORT void generateIndexKeysForValue(JSC::ExecState*, const IDBIndexMetadata&, const Deprecated::ScriptValue& objectValue, Vector<IDBKeyData>& indexKeys);
 
 Deprecated::ScriptValue idbKeyDataToScriptValue(ScriptExecutionContext*, const IDBKeyData&);
index 01288c6eacaf7578434c412185d054d56828b9da..29c5ee40865510ef6448e0c8bb03a9b4c64cce71 100644 (file)
@@ -36,6 +36,7 @@
 #include "IDBObjectStore.h"
 #include "JSDOMBinding.h"
 #include "JSIDBIndex.h"
+#include "JSIDBRequest.h"
 #include <runtime/Error.h>
 #include <runtime/JSString.h>
 
@@ -43,6 +44,55 @@ using namespace JSC;
 
 namespace WebCore {
 
+static JSValue putOrAdd(JSC::ExecState& state, bool overwrite)
+{
+    JSValue thisValue = state.thisValue();
+    JSIDBObjectStore* castedThis = jsDynamicCast<JSIDBObjectStore*>(thisValue);
+    if (UNLIKELY(!castedThis))
+        return JSValue::decode(throwThisTypeError(state, "IDBObjectStore", "put"));
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSIDBObjectStore::info());
+    auto& impl = castedThis->impl();
+
+    size_t argsCount = state.argumentCount();
+    if (UNLIKELY(argsCount < 1))
+        return JSValue::decode(throwVMError(&state, createNotEnoughArgumentsError(&state)));
+
+    ExceptionCode ec = 0;
+    auto value = state.uncheckedArgument(0);
+
+    if (argsCount == 1) {
+        JSValue result;
+        if (overwrite)
+            result = toJS(&state, castedThis->globalObject(), impl.put(state, value, ec).get());
+        else
+            result = toJS(&state, castedThis->globalObject(), impl.add(state, value, ec).get());
+
+        setDOMException(&state, ec);
+        return result;
+    }
+
+    auto key = state.uncheckedArgument(1);
+    JSValue result;
+    if (overwrite)
+        result = toJS(&state, castedThis->globalObject(), impl.put(state, value, key, ec).get());
+    else
+        result = toJS(&state, castedThis->globalObject(), impl.add(state, value, key, ec).get());
+
+    setDOMException(&state, ec);
+    return result;
+}
+
+JSValue JSIDBObjectStore::putFunction(JSC::ExecState& state)
+{
+    return putOrAdd(state, true);
+}
+
+JSValue JSIDBObjectStore::add(JSC::ExecState& state)
+{
+    return putOrAdd(state, false);
+}
+
 JSValue JSIDBObjectStore::createIndex(ExecState& state)
 {
     ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject())->scriptExecutionContext();