JSValue toJS(ExecState& state, JSGlobalObject& globalObject, IDBKey* key) { if (!key) { // This must be undefined, not null. // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBKeyRange return jsUndefined(); } VM& vm = state.vm(); Locker<JSLock> locker(vm.apiLock()); auto scope = DECLARE_THROW_SCOPE(vm); switch (key->type()) { case IndexedDB::KeyType::Array: { auto& inArray = key->array(); unsigned size = inArray.size(); auto outArray = constructEmptyArray(&state, 0, &globalObject, size); RETURN_IF_EXCEPTION(scope, JSValue()); for (size_t i = 0; i < size; ++i) { outArray->putDirectIndex(&state, i, toJS(state, globalObject, inArray.at(i).get())); RETURN_IF_EXCEPTION(scope, JSValue()); } return outArray; } case IndexedDB::KeyType::Binary: { auto* data = key->binary().data(); if (!data) { ASSERT_NOT_REACHED(); return jsNull(); } auto arrayBuffer = ArrayBuffer::create(data->data(), data->size()); Structure* structure = globalObject.arrayBufferStructure(arrayBuffer->sharingMode()); if (!structure) return jsNull(); return JSArrayBuffer::create(state.vm(), structure, WTFMove(arrayBuffer)); } case IndexedDB::KeyType::String: return jsStringWithCache(&state, key->string()); case IndexedDB::KeyType::Date: // FIXME: This should probably be toJS<IDLDate>(...) as per: // http://w3c.github.io/IndexedDB/#request-convert-a-key-to-a-value return toJS<IDLNullable<IDLDate>>(state, key->date()); case IndexedDB::KeyType::Number: return jsNumber(key->number()); case IndexedDB::KeyType::Min: case IndexedDB::KeyType::Max: case IndexedDB::KeyType::Invalid: ASSERT_NOT_REACHED(); return jsUndefined(); } ASSERT_NOT_REACHED(); return jsUndefined(); }