| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * | |
| 8 * 1. Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 * notice, this list of conditions and the following disclaimer in the | |
| 12 * documentation and/or other materials provided with the distribution. | |
| 13 * | |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
| 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
| 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #include "config.h" | |
| 27 #include "bindings/modules/v8/IDBBindingUtilities.h" | |
| 28 | |
| 29 #include "bindings/core/v8/SerializedScriptValue.h" | |
| 30 #include "bindings/core/v8/SerializedScriptValueFactory.h" | |
| 31 #include "bindings/core/v8/V8ArrayBufferView.h" | |
| 32 #include "bindings/core/v8/V8Binding.h" | |
| 33 #include "bindings/core/v8/V8DOMStringList.h" | |
| 34 #include "bindings/core/v8/V8HiddenValue.h" | |
| 35 #include "bindings/core/v8/V8Uint8Array.h" | |
| 36 #include "bindings/modules/v8/V8IDBCursor.h" | |
| 37 #include "bindings/modules/v8/V8IDBCursorWithValue.h" | |
| 38 #include "bindings/modules/v8/V8IDBDatabase.h" | |
| 39 #include "bindings/modules/v8/V8IDBIndex.h" | |
| 40 #include "bindings/modules/v8/V8IDBKeyRange.h" | |
| 41 #include "bindings/modules/v8/V8IDBObjectStore.h" | |
| 42 #include "bindings/modules/v8/V8IDBRequest.h" | |
| 43 #include "modules/indexeddb/IDBKey.h" | |
| 44 #include "modules/indexeddb/IDBKeyPath.h" | |
| 45 #include "modules/indexeddb/IDBKeyRange.h" | |
| 46 #include "modules/indexeddb/IDBTracing.h" | |
| 47 #include "platform/RuntimeEnabledFeatures.h" | |
| 48 #include "platform/SharedBuffer.h" | |
| 49 #include "wtf/MathExtras.h" | |
| 50 #include "wtf/Vector.h" | |
| 51 | |
| 52 namespace blink { | |
| 53 | |
| 54 static v8::Local<v8::Value> deserializeIDBValueBuffer(v8::Isolate*, SharedBuffer
*, const Vector<blink::WebBlobInfo>*); | |
| 55 | |
| 56 static v8::Local<v8::Value> toV8(const IDBKeyPath& value, v8::Local<v8::Object>
creationContext, v8::Isolate* isolate) | |
| 57 { | |
| 58 switch (value.type()) { | |
| 59 case IDBKeyPath::NullType: | |
| 60 return v8::Null(isolate); | |
| 61 case IDBKeyPath::StringType: | |
| 62 return v8String(isolate, value.string()); | |
| 63 case IDBKeyPath::ArrayType: | |
| 64 RefPtrWillBeRawPtr<DOMStringList> keyPaths = DOMStringList::create(); | |
| 65 for (Vector<String>::const_iterator it = value.array().begin(); it != va
lue.array().end(); ++it) | |
| 66 keyPaths->append(*it); | |
| 67 return toV8(keyPaths.release(), creationContext, isolate); | |
| 68 } | |
| 69 ASSERT_NOT_REACHED(); | |
| 70 return v8::Undefined(isolate); | |
| 71 } | |
| 72 | |
| 73 static v8::Local<v8::Value> toV8(const IDBKey* key, v8::Local<v8::Object> creati
onContext, v8::Isolate* isolate) | |
| 74 { | |
| 75 if (!key) { | |
| 76 // This should be undefined, not null. | |
| 77 // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-
def-IDBKeyRange | |
| 78 return v8Undefined(); | |
| 79 } | |
| 80 | |
| 81 switch (key->type()) { | |
| 82 case IDBKey::InvalidType: | |
| 83 case IDBKey::MinType: | |
| 84 ASSERT_NOT_REACHED(); | |
| 85 return v8Undefined(); | |
| 86 case IDBKey::NumberType: | |
| 87 return v8::Number::New(isolate, key->number()); | |
| 88 case IDBKey::StringType: | |
| 89 return v8String(isolate, key->string()); | |
| 90 case IDBKey::BinaryType: | |
| 91 return toV8(DOMUint8Array::create(reinterpret_cast<const unsigned char*>
(key->binary()->data()), key->binary()->size()), creationContext, isolate); | |
| 92 case IDBKey::DateType: | |
| 93 return v8::Date::New(isolate, key->date()); | |
| 94 case IDBKey::ArrayType: | |
| 95 { | |
| 96 v8::Local<v8::Array> array = v8::Array::New(isolate, key->array().si
ze()); | |
| 97 for (size_t i = 0; i < key->array().size(); ++i) | |
| 98 array->Set(i, toV8(key->array()[i].get(), creationContext, isola
te)); | |
| 99 return array; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 ASSERT_NOT_REACHED(); | |
| 104 return v8Undefined(); | |
| 105 } | |
| 106 | |
| 107 static v8::Local<v8::Value> toV8(const IDBAny* impl, v8::Local<v8::Object> creat
ionContext, v8::Isolate* isolate) | |
| 108 { | |
| 109 if (!impl) | |
| 110 return v8::Null(isolate); | |
| 111 | |
| 112 switch (impl->type()) { | |
| 113 case IDBAny::UndefinedType: | |
| 114 return v8::Undefined(isolate); | |
| 115 case IDBAny::NullType: | |
| 116 return v8::Null(isolate); | |
| 117 case IDBAny::DOMStringListType: | |
| 118 return toV8(impl->domStringList(), creationContext, isolate); | |
| 119 case IDBAny::IDBCursorType: { | |
| 120 // Ensure request wrapper is kept alive at least as long as the cursor w
rapper, | |
| 121 // so that event listeners are retained. | |
| 122 v8::Local<v8::Value> cursor = toV8(impl->idbCursor(), creationContext, i
solate); | |
| 123 v8::Local<v8::Value> request = toV8(impl->idbCursor()->request(), creati
onContext, isolate); | |
| 124 | |
| 125 // FIXME: Due to race at worker shutdown, V8 may return empty handles. | |
| 126 if (!cursor.IsEmpty()) | |
| 127 V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(isolate), V8
HiddenValue::idbCursorRequest(isolate), request); | |
| 128 return cursor; | |
| 129 } | |
| 130 case IDBAny::IDBCursorWithValueType: { | |
| 131 // Ensure request wrapper is kept alive at least as long as the cursor w
rapper, | |
| 132 // so that event listeners are retained. | |
| 133 v8::Local<v8::Value> cursor = toV8(impl->idbCursorWithValue(), creationC
ontext, isolate); | |
| 134 v8::Local<v8::Value> request = toV8(impl->idbCursorWithValue()->request(
), creationContext, isolate); | |
| 135 | |
| 136 // FIXME: Due to race at worker shutdown, V8 may return empty handles. | |
| 137 if (!cursor.IsEmpty()) | |
| 138 V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(isolate), V8
HiddenValue::idbCursorRequest(isolate), request); | |
| 139 return cursor; | |
| 140 } | |
| 141 case IDBAny::IDBDatabaseType: | |
| 142 return toV8(impl->idbDatabase(), creationContext, isolate); | |
| 143 case IDBAny::IDBIndexType: | |
| 144 return toV8(impl->idbIndex(), creationContext, isolate); | |
| 145 case IDBAny::IDBObjectStoreType: | |
| 146 return toV8(impl->idbObjectStore(), creationContext, isolate); | |
| 147 case IDBAny::BufferType: | |
| 148 return deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo
()); | |
| 149 case IDBAny::IntegerType: | |
| 150 return v8::Number::New(isolate, impl->integer()); | |
| 151 case IDBAny::KeyType: | |
| 152 return toV8(impl->key(), creationContext, isolate); | |
| 153 case IDBAny::BufferKeyAndKeyPathType: { | |
| 154 v8::Local<v8::Value> value = deserializeIDBValueBuffer(isolate, impl->bu
ffer(), impl->blobInfo()); | |
| 155 v8::Local<v8::Value> key = toV8(impl->key(), creationContext, isolate); | |
| 156 bool injected = injectV8KeyIntoV8Value(isolate, key, value, impl->keyPat
h()); | |
| 157 ASSERT_UNUSED(injected, injected); | |
| 158 return value; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 ASSERT_NOT_REACHED(); | |
| 163 return v8::Undefined(isolate); | |
| 164 } | |
| 165 | |
| 166 static const size_t maximumDepth = 2000; | |
| 167 | |
| 168 static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Local<v8::Value>
value, Vector<v8::Local<v8::Array>>& stack, bool allowExperimentalTypes = false) | |
| 169 { | |
| 170 if (value->IsNumber() && !std::isnan(value->NumberValue())) | |
| 171 return IDBKey::createNumber(value->NumberValue()); | |
| 172 if (value->IsString()) | |
| 173 return IDBKey::createString(toCoreString(value.As<v8::String>())); | |
| 174 if (value->IsDate() && !std::isnan(value->NumberValue())) | |
| 175 return IDBKey::createDate(value->NumberValue()); | |
| 176 if (value->IsUint8Array() && (allowExperimentalTypes || RuntimeEnabledFeatur
es::indexedDBExperimentalEnabled())) { | |
| 177 // Per discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=2333
2 the | |
| 178 // input type is constrained to Uint8Array to match the output type. | |
| 179 DOMArrayBufferView* view = blink::V8ArrayBufferView::toImpl(value->ToObj
ect(isolate)); | |
| 180 const char* start = static_cast<const char*>(view->baseAddress()); | |
| 181 size_t length = view->byteLength(); | |
| 182 return IDBKey::createBinary(SharedBuffer::create(start, length)); | |
| 183 } | |
| 184 if (value->IsArray()) { | |
| 185 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); | |
| 186 | |
| 187 if (stack.contains(array)) | |
| 188 return 0; | |
| 189 if (stack.size() >= maximumDepth) | |
| 190 return 0; | |
| 191 stack.append(array); | |
| 192 | |
| 193 IDBKey::KeyArray subkeys; | |
| 194 uint32_t length = array->Length(); | |
| 195 for (uint32_t i = 0; i < length; ++i) { | |
| 196 v8::Local<v8::Value> item = array->Get(v8::Int32::New(isolate, i)); | |
| 197 IDBKey* subkey = createIDBKeyFromValue(isolate, item, stack, allowEx
perimentalTypes); | |
| 198 if (!subkey) | |
| 199 subkeys.append(IDBKey::createInvalid()); | |
| 200 else | |
| 201 subkeys.append(subkey); | |
| 202 } | |
| 203 | |
| 204 stack.removeLast(); | |
| 205 return IDBKey::createArray(subkeys); | |
| 206 } | |
| 207 return 0; | |
| 208 } | |
| 209 | |
| 210 static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Local<v8::Value>
value, bool allowExperimentalTypes = false) | |
| 211 { | |
| 212 Vector<v8::Local<v8::Array>> stack; | |
| 213 if (IDBKey* key = createIDBKeyFromValue(isolate, value, stack, allowExperime
ntalTypes)) | |
| 214 return key; | |
| 215 return IDBKey::createInvalid(); | |
| 216 } | |
| 217 | |
| 218 template<typename T> | |
| 219 static bool getValueFrom(T indexOrName, v8::Local<v8::Value>& v8Value, v8::Isola
te* isolate) | |
| 220 { | |
| 221 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | |
| 222 if (!object->Has(indexOrName)) | |
| 223 return false; | |
| 224 v8Value = object->Get(indexOrName); | |
| 225 return true; | |
| 226 } | |
| 227 | |
| 228 template<typename T> | |
| 229 static bool setValue(v8::Local<v8::Value>& v8Object, T indexOrName, const v8::Lo
cal<v8::Value>& v8Value) | |
| 230 { | |
| 231 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Object); | |
| 232 return object->Set(indexOrName, v8Value); | |
| 233 } | |
| 234 | |
| 235 static bool get(v8::Isolate* isolate, v8::Local<v8::Value>& object, const String
& keyPathElement, v8::Local<v8::Value>& result) | |
| 236 { | |
| 237 if (object->IsString() && keyPathElement == "length") { | |
| 238 int32_t length = v8::Local<v8::String>::Cast(object)->Length(); | |
| 239 result = v8::Number::New(isolate, length); | |
| 240 return true; | |
| 241 } | |
| 242 return object->IsObject() && getValueFrom(v8String(isolate, keyPathElement),
result, isolate); | |
| 243 } | |
| 244 | |
| 245 static bool canSet(v8::Local<v8::Value>& object, const String& keyPathElement) | |
| 246 { | |
| 247 return object->IsObject(); | |
| 248 } | |
| 249 | |
| 250 static bool set(v8::Isolate* isolate, v8::Local<v8::Value>& object, const String
& keyPathElement, const v8::Local<v8::Value>& v8Value) | |
| 251 { | |
| 252 return canSet(object, keyPathElement) && setValue(object, v8String(isolate,
keyPathElement), v8Value); | |
| 253 } | |
| 254 | |
| 255 static v8::Local<v8::Value> getNthValueOnKeyPath(v8::Isolate* isolate, v8::Local
<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index) | |
| 256 { | |
| 257 v8::Local<v8::Value> currentValue(rootValue); | |
| 258 ASSERT(index <= keyPathElements.size()); | |
| 259 for (size_t i = 0; i < index; ++i) { | |
| 260 v8::Local<v8::Value> parentValue(currentValue); | |
| 261 if (!get(isolate, parentValue, keyPathElements[i], currentValue)) | |
| 262 return v8Undefined(); | |
| 263 } | |
| 264 | |
| 265 return currentValue; | |
| 266 } | |
| 267 | |
| 268 static bool canInjectNthValueOnKeyPath(v8::Isolate* isolate, v8::Local<v8::Value
>& rootValue, const Vector<String>& keyPathElements, size_t index) | |
| 269 { | |
| 270 if (!rootValue->IsObject()) | |
| 271 return false; | |
| 272 | |
| 273 v8::Local<v8::Value> currentValue(rootValue); | |
| 274 | |
| 275 ASSERT(index <= keyPathElements.size()); | |
| 276 for (size_t i = 0; i < index; ++i) { | |
| 277 v8::Local<v8::Value> parentValue(currentValue); | |
| 278 const String& keyPathElement = keyPathElements[i]; | |
| 279 if (!get(isolate, parentValue, keyPathElement, currentValue)) | |
| 280 return canSet(parentValue, keyPathElement); | |
| 281 } | |
| 282 return true; | |
| 283 } | |
| 284 | |
| 285 | |
| 286 static v8::Local<v8::Value> ensureNthValueOnKeyPath(v8::Isolate* isolate, v8::Lo
cal<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index) | |
| 287 { | |
| 288 v8::Local<v8::Value> currentValue(rootValue); | |
| 289 | |
| 290 ASSERT(index <= keyPathElements.size()); | |
| 291 for (size_t i = 0; i < index; ++i) { | |
| 292 v8::Local<v8::Value> parentValue(currentValue); | |
| 293 const String& keyPathElement = keyPathElements[i]; | |
| 294 if (!get(isolate, parentValue, keyPathElement, currentValue)) { | |
| 295 v8::Local<v8::Object> object = v8::Object::New(isolate); | |
| 296 if (!set(isolate, parentValue, keyPathElement, object)) | |
| 297 return v8Undefined(); | |
| 298 currentValue = object; | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 return currentValue; | |
| 303 } | |
| 304 | |
| 305 static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolat
e, const ScriptValue& value, const String& keyPath, bool allowExperimentalTypes) | |
| 306 { | |
| 307 Vector<String> keyPathElements; | |
| 308 IDBKeyPathParseError error; | |
| 309 IDBParseKeyPath(keyPath, keyPathElements, error); | |
| 310 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 311 ASSERT(isolate->InContext()); | |
| 312 | |
| 313 v8::HandleScope handleScope(isolate); | |
| 314 v8::Local<v8::Value> v8Value(value.v8Value()); | |
| 315 v8::Local<v8::Value> v8Key(getNthValueOnKeyPath(isolate, v8Value, keyPathEle
ments, keyPathElements.size())); | |
| 316 if (v8Key.IsEmpty()) | |
| 317 return 0; | |
| 318 return createIDBKeyFromValue(isolate, v8Key, allowExperimentalTypes); | |
| 319 } | |
| 320 | |
| 321 static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolat
e, const ScriptValue& value, const IDBKeyPath& keyPath, bool allowExperimentalTy
pes = false) | |
| 322 { | |
| 323 ASSERT(!keyPath.isNull()); | |
| 324 v8::HandleScope handleScope(isolate); | |
| 325 if (keyPath.type() == IDBKeyPath::ArrayType) { | |
| 326 IDBKey::KeyArray result; | |
| 327 const Vector<String>& array = keyPath.array(); | |
| 328 for (size_t i = 0; i < array.size(); ++i) { | |
| 329 IDBKey* key = createIDBKeyFromScriptValueAndKeyPathInternal(isolate,
value, array[i], allowExperimentalTypes); | |
| 330 if (!key) | |
| 331 return 0; | |
| 332 result.append(key); | |
| 333 } | |
| 334 return IDBKey::createArray(result); | |
| 335 } | |
| 336 | |
| 337 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 338 return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath
.string(), allowExperimentalTypes); | |
| 339 } | |
| 340 | |
| 341 IDBKey* createIDBKeyFromScriptValueAndKeyPath(v8::Isolate* isolate, const Script
Value& value, const IDBKeyPath& keyPath) | |
| 342 { | |
| 343 IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); | |
| 344 return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath
); | |
| 345 } | |
| 346 | |
| 347 static v8::Local<v8::Value> deserializeIDBValueBuffer(v8::Isolate* isolate, Shar
edBuffer* buffer, const Vector<blink::WebBlobInfo>* blobInfo) | |
| 348 { | |
| 349 ASSERT(isolate->InContext()); | |
| 350 if (!buffer) | |
| 351 return v8::Null(isolate); | |
| 352 | |
| 353 // FIXME: The extra copy here can be eliminated by allowing SerializedScript
Value to take a raw const char* or const uint8_t*. | |
| 354 Vector<uint8_t> value; | |
| 355 value.append(buffer->data(), buffer->size()); | |
| 356 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValueFactory
::instance().createFromWireBytes(value); | |
| 357 return serializedValue->deserialize(isolate, 0, blobInfo); | |
| 358 } | |
| 359 | |
| 360 bool injectV8KeyIntoV8Value(v8::Isolate* isolate, v8::Local<v8::Value> key, v8::
Local<v8::Value> value, const IDBKeyPath& keyPath) | |
| 361 { | |
| 362 IDB_TRACE("injectIDBV8KeyIntoV8Value"); | |
| 363 ASSERT(isolate->InContext()); | |
| 364 | |
| 365 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 366 Vector<String> keyPathElements; | |
| 367 IDBKeyPathParseError error; | |
| 368 IDBParseKeyPath(keyPath.string(), keyPathElements, error); | |
| 369 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 370 | |
| 371 if (!keyPathElements.size()) | |
| 372 return false; | |
| 373 | |
| 374 v8::HandleScope handleScope(isolate); | |
| 375 v8::Local<v8::Value> parent(ensureNthValueOnKeyPath(isolate, value, keyPathE
lements, keyPathElements.size() - 1)); | |
| 376 if (parent.IsEmpty()) | |
| 377 return false; | |
| 378 | |
| 379 if (!set(isolate, parent, keyPathElements.last(), key)) | |
| 380 return false; | |
| 381 | |
| 382 return true; | |
| 383 } | |
| 384 | |
| 385 bool canInjectIDBKeyIntoScriptValue(v8::Isolate* isolate, const ScriptValue& scr
iptValue, const IDBKeyPath& keyPath) | |
| 386 { | |
| 387 IDB_TRACE("canInjectIDBKeyIntoScriptValue"); | |
| 388 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 389 Vector<String> keyPathElements; | |
| 390 IDBKeyPathParseError error; | |
| 391 IDBParseKeyPath(keyPath.string(), keyPathElements, error); | |
| 392 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 393 | |
| 394 if (!keyPathElements.size()) | |
| 395 return false; | |
| 396 | |
| 397 v8::Local<v8::Value> v8Value(scriptValue.v8Value()); | |
| 398 return canInjectNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPath
Elements.size() - 1); | |
| 399 } | |
| 400 | |
| 401 ScriptValue idbAnyToScriptValue(ScriptState* scriptState, IDBAny* any) | |
| 402 { | |
| 403 v8::Isolate* isolate = scriptState->isolate(); | |
| 404 v8::HandleScope handleScope(isolate); | |
| 405 v8::Local<v8::Value> v8Value(toV8(any, scriptState->context()->Global(), iso
late)); | |
| 406 return ScriptValue(scriptState, v8Value); | |
| 407 } | |
| 408 | |
| 409 ScriptValue idbKeyToScriptValue(ScriptState* scriptState, const IDBKey* key) | |
| 410 { | |
| 411 v8::Isolate* isolate = scriptState->isolate(); | |
| 412 v8::HandleScope handleScope(isolate); | |
| 413 v8::Local<v8::Value> v8Value(toV8(key, scriptState->context()->Global(), iso
late)); | |
| 414 return ScriptValue(scriptState, v8Value); | |
| 415 } | |
| 416 | |
| 417 ScriptValue idbKeyPathToScriptValue(ScriptState* scriptState, const IDBKeyPath&
keyPath) | |
| 418 { | |
| 419 v8::Isolate* isolate = scriptState->isolate(); | |
| 420 v8::HandleScope handleScope(isolate); | |
| 421 v8::Local<v8::Value> v8Value(toV8(keyPath, scriptState->context()->Global(),
isolate)); | |
| 422 return ScriptValue(scriptState, v8Value); | |
| 423 } | |
| 424 | |
| 425 IDBKey* scriptValueToIDBKey(v8::Isolate* isolate, const ScriptValue& scriptValue
) | |
| 426 { | |
| 427 ASSERT(isolate->InContext()); | |
| 428 v8::HandleScope handleScope(isolate); | |
| 429 v8::Local<v8::Value> v8Value(scriptValue.v8Value()); | |
| 430 return createIDBKeyFromValue(isolate, v8Value); | |
| 431 } | |
| 432 | |
| 433 IDBKeyRange* scriptValueToIDBKeyRange(v8::Isolate* isolate, const ScriptValue& s
criptValue) | |
| 434 { | |
| 435 v8::HandleScope handleScope(isolate); | |
| 436 v8::Local<v8::Value> value(scriptValue.v8Value()); | |
| 437 return V8IDBKeyRange::toImplWithTypeCheck(isolate, value); | |
| 438 } | |
| 439 | |
| 440 ScriptValue deserializeScriptValue(ScriptState* scriptState, SerializedScriptVal
ue* serializedValue, const Vector<blink::WebBlobInfo>* blobInfo) | |
| 441 { | |
| 442 v8::Isolate* isolate = scriptState->isolate(); | |
| 443 v8::HandleScope handleScope(isolate); | |
| 444 if (serializedValue) | |
| 445 return ScriptValue(scriptState, serializedValue->deserialize(isolate, 0,
blobInfo)); | |
| 446 return ScriptValue(scriptState, v8::Null(isolate)); | |
| 447 } | |
| 448 | |
| 449 #if ENABLE(ASSERT) | |
| 450 void assertPrimaryKeyValidOrInjectable(ScriptState* scriptState, PassRefPtr<Shar
edBuffer> buffer, const Vector<blink::WebBlobInfo>* blobInfo, IDBKey* key, const
IDBKeyPath& keyPath) | |
| 451 { | |
| 452 ScriptState::Scope scope(scriptState); | |
| 453 v8::Isolate* isolate = scriptState->isolate(); | |
| 454 ScriptValue keyValue = idbKeyToScriptValue(scriptState, key); | |
| 455 ScriptValue scriptValue(scriptState, deserializeIDBValueBuffer(isolate, buff
er.get(), blobInfo)); | |
| 456 | |
| 457 // This assertion is about already persisted data, so allow experimental typ
es. | |
| 458 const bool allowExperimentalTypes = true; | |
| 459 IDBKey* expectedKey = createIDBKeyFromScriptValueAndKeyPathInternal(isolate,
scriptValue, keyPath, allowExperimentalTypes); | |
| 460 ASSERT(!expectedKey || expectedKey->isEqual(key)); | |
| 461 | |
| 462 bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptVa
lue.v8Value(), keyPath); | |
| 463 ASSERT_UNUSED(injected, injected); | |
| 464 } | |
| 465 #endif | |
| 466 | |
| 467 } // namespace blink | |
| OLD | NEW |