mirror of
https://github.com/servo/servo.git
synced 2025-09-22 12:50:08 +01:00
Implement indexeddb array conversion (#38288)
Implement conversion from js arrays into rust. Testing: WPT Fixes: None --------- Signed-off-by: Ashwin Naren <arihant2math@gmail.com> Signed-off-by: Josh Matthews <josh@joshmatthews.net> Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
8590c4edcf
commit
8a59c2cf56
13 changed files with 98 additions and 203 deletions
|
@ -218,17 +218,35 @@ impl IDBObjectStore {
|
|||
serialized_key = Some(convert_value_to_key(cx, key, None)?.into_result()?);
|
||||
} else {
|
||||
// Step 11: We should use in-line keys instead
|
||||
if let Some(Ok(ExtractionResult::Key(kpk))) = self
|
||||
// Step 11.1: Let kpk be the result of running the steps to extract a
|
||||
// key from a value using a key path with clone and store’s key path.
|
||||
let extraction_result = self
|
||||
.key_path
|
||||
.as_ref()
|
||||
.map(|p| extract_key(cx, value, p, None))
|
||||
{
|
||||
serialized_key = Some(kpk);
|
||||
} else {
|
||||
.map(|p| extract_key(cx, value, p, None));
|
||||
|
||||
match extraction_result {
|
||||
Some(Ok(ExtractionResult::Failure)) | None => {
|
||||
// Step 11.4. Otherwise:
|
||||
// Step 11.4.1. If store does not have a key generator, throw
|
||||
// a "DataError" DOMException.
|
||||
if !self.has_key_generator() {
|
||||
return Err(Error::Data);
|
||||
}
|
||||
// Stept 11.4.2. Otherwise, if the steps to check that a key could
|
||||
// be injected into a value with clone and store’s key path return
|
||||
// false, throw a "DataError" DOMException.
|
||||
// TODO
|
||||
serialized_key = None;
|
||||
},
|
||||
// Step 11.1. Rethrow any exceptions.
|
||||
Some(extraction_result) => match extraction_result? {
|
||||
// Step 11.2. If kpk is invalid, throw a "DataError" DOMException.
|
||||
ExtractionResult::Invalid => return Err(Error::Data),
|
||||
// Step 11.3. If kpk is not failure, let key be kpk.
|
||||
ExtractionResult::Key(kpk) => serialized_key = Some(kpk),
|
||||
ExtractionResult::Failure => unreachable!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,12 +11,13 @@ use itertools::Itertools;
|
|||
use js::conversions::jsstr_to_string;
|
||||
use js::gc::MutableHandle;
|
||||
use js::jsapi::{
|
||||
ClippedTime, ESClass, GetBuiltinClass, IsArrayBufferObject, JS_GetStringLength,
|
||||
JS_IsArrayBufferViewObject, JS_NewObject, NewDateObject,
|
||||
ClippedTime, ESClass, GetArrayLength, GetBuiltinClass, IsArrayBufferObject, JS_GetStringLength,
|
||||
JS_HasOwnPropertyById, JS_IndexToId, JS_IsArrayBufferViewObject, JS_NewObject, NewDateObject,
|
||||
PropertyKey,
|
||||
};
|
||||
use js::jsval::{DoubleValue, UndefinedValue};
|
||||
use js::rust::wrappers::{IsArrayObject, JS_GetProperty, JS_HasOwnProperty, JS_IsIdentifier};
|
||||
use js::rust::{HandleValue, MutableHandleValue};
|
||||
use js::rust::{HandleValue, IntoHandle, IntoMutableHandle, MutableHandleValue};
|
||||
use net_traits::indexeddb_thread::{BackendResult, IndexedDBKeyRange, IndexedDBKeyType};
|
||||
use profile_traits::ipc;
|
||||
use profile_traits::ipc::IpcReceiver;
|
||||
|
@ -158,7 +159,7 @@ pub fn convert_value_to_key(
|
|||
seen: Option<Vec<HandleValue>>,
|
||||
) -> Result<ConversionResult, Error> {
|
||||
// Step 1: If seen was not given, then let seen be a new empty set.
|
||||
let _seen = seen.unwrap_or_default();
|
||||
let mut seen = seen.unwrap_or_default();
|
||||
|
||||
// Step 2: If seen contains input, then return invalid.
|
||||
// FIXME:(arihant2math) implement this
|
||||
|
@ -189,13 +190,13 @@ pub fn convert_value_to_key(
|
|||
let mut built_in_class = ESClass::Other;
|
||||
|
||||
if !GetBuiltinClass(*cx, object.handle().into(), &mut built_in_class) {
|
||||
return Err(Error::Data);
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
if let ESClass::Date = built_in_class {
|
||||
let mut f = f64::NAN;
|
||||
if !js::jsapi::DateGetMsecSinceEpoch(*cx, object.handle().into(), &mut f) {
|
||||
return Err(Error::Data);
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
if f.is_nan() {
|
||||
return Err(Error::Data);
|
||||
|
@ -212,9 +213,45 @@ pub fn convert_value_to_key(
|
|||
}
|
||||
|
||||
if let ESClass::Array = built_in_class {
|
||||
// FIXME:(arihant2math)
|
||||
error!("Arrays as keys is currently unsupported");
|
||||
return Err(Error::NotSupported);
|
||||
let mut len = 0;
|
||||
if !GetArrayLength(*cx, object.handle().into_handle(), &mut len) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
seen.push(input);
|
||||
let mut values = vec![];
|
||||
for i in 0..len {
|
||||
rooted!(in(*cx) let mut id: PropertyKey);
|
||||
if !JS_IndexToId(*cx, i, js::jsapi::MutableHandleId::from(id.handle_mut())) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
let mut has_own = false;
|
||||
if !JS_HasOwnPropertyById(
|
||||
*cx,
|
||||
object.handle().into_handle(),
|
||||
id.handle().into_handle(),
|
||||
&mut has_own,
|
||||
) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
if !has_own {
|
||||
return Ok(ConversionResult::Invalid);
|
||||
}
|
||||
rooted!(in(*cx) let mut item = UndefinedValue());
|
||||
if !js::jsapi::JS_GetPropertyById(
|
||||
*cx,
|
||||
object.handle().into_handle(),
|
||||
id.handle().into_handle(),
|
||||
item.handle_mut().into_handle_mut(),
|
||||
) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
let key = match convert_value_to_key(cx, item.handle(), Some(seen.clone()))? {
|
||||
ConversionResult::Valid(key) => key,
|
||||
ConversionResult::Invalid => return Ok(ConversionResult::Invalid),
|
||||
};
|
||||
values.push(key);
|
||||
}
|
||||
return Ok(ConversionResult::Valid(IndexedDBKeyType::Array(values)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[idb-partitioned-coverage.sub.html]
|
||||
expected: CRASH
|
||||
[ - advance]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[idbcursor-continuePrimaryKey-exceptions.any.worker.html]
|
||||
[IDBCursor continuePrimaryKey() on object store cursor]
|
||||
expected: FAIL
|
||||
|
||||
[IDBCursor continuePrimaryKey() on "nextunique" cursor]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbfactory_cmp.any.html]
|
||||
[Array vs. Binary]
|
||||
expected: FAIL
|
||||
|
||||
[Compare in unsigned octet values (in the range [0, 255\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -13,9 +10,6 @@
|
|||
|
||||
|
||||
[idbfactory_cmp.any.worker.html]
|
||||
[Array vs. Binary]
|
||||
expected: FAIL
|
||||
|
||||
[Compare in unsigned octet values (in the range [0, 255\])]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[idbkeyrange-includes.any.html]
|
||||
expected: CRASH
|
||||
[IDBKeyRange.includes() with invalid input]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -13,6 +14,7 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbkeyrange-includes.any.worker.html]
|
||||
expected: CRASH
|
||||
[IDBKeyRange.includes() with invalid input]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
[idbkeyrange_incorrect.any.html]
|
||||
[IDBKeyRange.bound(DOMString/Date/Array, 1) - A DOMString, Date and Array are greater than a float.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbkeyrange_incorrect.any.worker.html]
|
||||
[IDBKeyRange.bound(DOMString/Date/Array, 1) - A DOMString, Date and Array are greater than a float.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbkeyrange_incorrect.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
[Get all values with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with transaction.commit()]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAll.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
@ -40,6 +43,9 @@
|
|||
[Get all values with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with transaction.commit()]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAll.any.sharedworker.html]
|
||||
expected: ERROR
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbobjectstore_openKeyCursor.any.html]
|
||||
expected: CRASH
|
||||
[IDBObjectStore.openKeyCursor() - forward iteration]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -22,6 +23,7 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbobjectstore_openKeyCursor.any.worker.html]
|
||||
expected: CRASH
|
||||
[IDBObjectStore.openKeyCursor() - forward iteration]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,54 +2,12 @@
|
|||
expected: ERROR
|
||||
|
||||
[key-conversion-exceptions.any.worker.html]
|
||||
[IDBFactory cmp() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange only() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange lowerBound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange upperBound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange bound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBCursor continue() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IndexedDB: Exceptions thrown during key conversion]
|
||||
expected: FAIL
|
||||
|
||||
[IDBCursor update() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore add() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore put() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore delete() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore get() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getKey() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore count() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore openCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore openKeyCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex get() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -65,12 +23,6 @@
|
|||
[IDBIndex openKeyCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getAll() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getAllKeys() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex getAll() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -82,54 +34,12 @@
|
|||
|
||||
|
||||
[key-conversion-exceptions.any.html]
|
||||
[IDBFactory cmp() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange only() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange lowerBound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange upperBound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKeyRange bound() static with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBCursor continue() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IndexedDB: Exceptions thrown during key conversion]
|
||||
expected: FAIL
|
||||
|
||||
[IDBCursor update() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore add() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore put() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore delete() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore get() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getKey() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore count() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore openCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore openKeyCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex get() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -145,12 +55,6 @@
|
|||
[IDBIndex openKeyCursor() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getAll() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore getAllKeys() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex getAll() method with throwing/invalid keys]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
expected: ERROR
|
||||
|
||||
[key_invalid.any.worker.html]
|
||||
expected: CRASH
|
||||
[Invalid key - [{}\]]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -40,6 +41,7 @@
|
|||
expected: ERROR
|
||||
|
||||
[key_invalid.any.html]
|
||||
expected: CRASH
|
||||
[Invalid key - [{}\]]
|
||||
expected: FAIL
|
||||
|
||||
|
|
72
tests/wpt/meta/IndexedDB/keyorder.any.js.ini
vendored
72
tests/wpt/meta/IndexedDB/keyorder.any.js.ini
vendored
|
@ -5,149 +5,77 @@
|
|||
[Database readback sort - String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < String]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < String]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < Date]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < Date]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < Date < String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < Date < String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - -1.1 < 1 < 1.01337 < 1.013373 < 2]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - -1.1 < 1 < 1.01337 < 1.013373 < 2]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - -Infinity < -0.01 < 0 < Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - -Infinity < -0.01 < 0 < Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - "" < "a" < "ab" < "b" < "ba"]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - "" < "a" < "ab" < "b" < "ba"]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Arrays]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Arrays]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Array.length: 10,000 < Array.length: 10,001]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Array.length: 10,000 < Array.length: 10,001]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Infinity inside arrays]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Infinity inside arrays]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Test different stuff at once]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Test different stuff at once]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[keyorder.any.html]
|
||||
[Database readback sort - String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < String]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < String]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < Date]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < Date]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - float < Date < String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - float < Date < String < Array]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - -1.1 < 1 < 1.01337 < 1.013373 < 2]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - -1.1 < 1 < 1.01337 < 1.013373 < 2]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - -Infinity < -0.01 < 0 < Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - -Infinity < -0.01 < 0 < Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - "" < "a" < "ab" < "b" < "ba"]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - "" < "a" < "ab" < "b" < "ba"]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Arrays]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Arrays]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Array.length: 10,000 < Array.length: 10,001]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Array.length: 10,000 < Array.length: 10,001]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Infinity inside arrays]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Infinity inside arrays]
|
||||
expected: FAIL
|
||||
|
||||
[Database readback sort - Test different stuff at once]
|
||||
expected: FAIL
|
||||
|
||||
[IDBKey.cmp sort - Test different stuff at once]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[keyorder.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
[keypath-exceptions.any.html]
|
||||
expected: CRASH
|
||||
[Array key conversion should not invoke prototype getters]
|
||||
expected: FAIL
|
||||
|
||||
[The last element of keypath is validated]
|
||||
expected: FAIL
|
||||
|
||||
[Key path evaluation: Exceptions from non-enumerable getters]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[keypath-exceptions.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
@ -11,6 +16,11 @@
|
|||
expected: ERROR
|
||||
|
||||
[keypath-exceptions.any.worker.html]
|
||||
expected: CRASH
|
||||
[Array key conversion should not invoke prototype getters]
|
||||
expected: FAIL
|
||||
|
||||
[The last element of keypath is validated]
|
||||
expected: FAIL
|
||||
|
||||
[Key path evaluation: Exceptions from non-enumerable getters]
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue