| 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/v8/IDBBindingUtilities.h" | |
| 28 | |
| 29 #include "bindings/core/v8/V8DOMStringList.h" | |
| 30 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h" | |
| 31 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h" | |
| 32 #include "bindings/modules/v8/V8IDBCursor.h" | |
| 33 #include "bindings/modules/v8/V8IDBCursorWithValue.h" | |
| 34 #include "bindings/modules/v8/V8IDBDatabase.h" | |
| 35 #include "bindings/modules/v8/V8IDBIndex.h" | |
| 36 #include "bindings/modules/v8/V8IDBKeyRange.h" | |
| 37 #include "bindings/modules/v8/V8IDBObjectStore.h" | |
| 38 #include "bindings/modules/v8/V8IDBRequest.h" | |
| 39 #include "bindings/modules/v8/V8IDBTransaction.h" | |
| 40 #include "bindings/v8/SerializedScriptValue.h" | |
| 41 #include "bindings/v8/V8Binding.h" | |
| 42 #include "bindings/v8/V8HiddenValue.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/ArrayBufferView.h" | |
| 50 #include "wtf/MathExtras.h" | |
| 51 #include "wtf/Uint8Array.h" | |
| 52 #include "wtf/Vector.h" | |
| 53 | |
| 54 namespace WebCore { | |
| 55 | |
| 56 static v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate*, SharedBuffe
r*, const Vector<blink::WebBlobInfo>*); | |
| 57 | |
| 58 static v8::Handle<v8::Value> toV8(const IDBKeyPath& value, v8::Handle<v8::Object
> creationContext, v8::Isolate* isolate) | |
| 59 { | |
| 60 switch (value.type()) { | |
| 61 case IDBKeyPath::NullType: | |
| 62 return v8::Null(isolate); | |
| 63 case IDBKeyPath::StringType: | |
| 64 return v8String(isolate, value.string()); | |
| 65 case IDBKeyPath::ArrayType: | |
| 66 RefPtrWillBeRawPtr<DOMStringList> keyPaths = DOMStringList::create(); | |
| 67 for (Vector<String>::const_iterator it = value.array().begin(); it != va
lue.array().end(); ++it) | |
| 68 keyPaths->append(*it); | |
| 69 return toV8(keyPaths.release(), creationContext, isolate); | |
| 70 } | |
| 71 ASSERT_NOT_REACHED(); | |
| 72 return v8::Undefined(isolate); | |
| 73 } | |
| 74 | |
| 75 static v8::Handle<v8::Value> toV8(const IDBKey* key, v8::Handle<v8::Object> crea
tionContext, v8::Isolate* isolate) | |
| 76 { | |
| 77 if (!key) { | |
| 78 // This should be undefined, not null. | |
| 79 // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-
def-IDBKeyRange | |
| 80 return v8Undefined(); | |
| 81 } | |
| 82 | |
| 83 switch (key->type()) { | |
| 84 case IDBKey::InvalidType: | |
| 85 case IDBKey::MinType: | |
| 86 ASSERT_NOT_REACHED(); | |
| 87 return v8Undefined(); | |
| 88 case IDBKey::NumberType: | |
| 89 return v8::Number::New(isolate, key->number()); | |
| 90 case IDBKey::StringType: | |
| 91 return v8String(isolate, key->string()); | |
| 92 case IDBKey::BinaryType: | |
| 93 return toV8(Uint8Array::create(reinterpret_cast<const unsigned char*>(ke
y->binary()->data()), key->binary()->size()), creationContext, isolate); | |
| 94 case IDBKey::DateType: | |
| 95 return v8::Date::New(isolate, key->date()); | |
| 96 case IDBKey::ArrayType: | |
| 97 { | |
| 98 v8::Local<v8::Array> array = v8::Array::New(isolate, key->array().si
ze()); | |
| 99 for (size_t i = 0; i < key->array().size(); ++i) | |
| 100 array->Set(i, toV8(key->array()[i].get(), creationContext, isola
te)); | |
| 101 return array; | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 ASSERT_NOT_REACHED(); | |
| 106 return v8Undefined(); | |
| 107 } | |
| 108 | |
| 109 static v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> cre
ationContext, v8::Isolate* isolate) | |
| 110 { | |
| 111 if (!impl) | |
| 112 return v8::Null(isolate); | |
| 113 | |
| 114 switch (impl->type()) { | |
| 115 case IDBAny::UndefinedType: | |
| 116 return v8::Undefined(isolate); | |
| 117 case IDBAny::NullType: | |
| 118 return v8::Null(isolate); | |
| 119 case IDBAny::DOMStringListType: | |
| 120 return toV8(impl->domStringList(), creationContext, isolate); | |
| 121 case IDBAny::IDBCursorType: { | |
| 122 // Ensure request wrapper is kept alive at least as long as the cursor w
rapper, | |
| 123 // so that event listeners are retained. | |
| 124 v8::Handle<v8::Value> cursor = toV8(impl->idbCursor(), creationContext,
isolate); | |
| 125 v8::Handle<v8::Value> request = toV8(impl->idbCursor()->request(), creat
ionContext, isolate); | |
| 126 V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue
::idbCursorRequest(isolate), request); | |
| 127 return cursor; | |
| 128 } | |
| 129 case IDBAny::IDBCursorWithValueType: { | |
| 130 // Ensure request wrapper is kept alive at least as long as the cursor w
rapper, | |
| 131 // so that event listeners are retained. | |
| 132 v8::Handle<v8::Value> cursor = toV8(impl->idbCursorWithValue(), creation
Context, isolate); | |
| 133 v8::Handle<v8::Value> request = toV8(impl->idbCursorWithValue()->request
(), creationContext, isolate); | |
| 134 V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue
::idbCursorRequest(isolate), request); | |
| 135 return cursor; | |
| 136 } | |
| 137 case IDBAny::IDBDatabaseType: | |
| 138 return toV8(impl->idbDatabase(), creationContext, isolate); | |
| 139 case IDBAny::IDBIndexType: | |
| 140 return toV8(impl->idbIndex(), creationContext, isolate); | |
| 141 case IDBAny::IDBObjectStoreType: | |
| 142 return toV8(impl->idbObjectStore(), creationContext, isolate); | |
| 143 case IDBAny::IDBTransactionType: | |
| 144 return toV8(impl->idbTransaction(), creationContext, isolate); | |
| 145 case IDBAny::BufferType: | |
| 146 return deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo
()); | |
| 147 case IDBAny::StringType: | |
| 148 return v8String(isolate, impl->string()); | |
| 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::KeyPathType: | |
| 154 return toV8(impl->keyPath(), creationContext, isolate); | |
| 155 case IDBAny::BufferKeyAndKeyPathType: { | |
| 156 v8::Handle<v8::Value> value = deserializeIDBValueBuffer(isolate, impl->b
uffer(), impl->blobInfo()); | |
| 157 v8::Handle<v8::Value> key = toV8(impl->key(), creationContext, isolate); | |
| 158 bool injected = injectV8KeyIntoV8Value(isolate, key, value, impl->keyPat
h()); | |
| 159 ASSERT_UNUSED(injected, injected); | |
| 160 return value; | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 ASSERT_NOT_REACHED(); | |
| 165 return v8::Undefined(isolate); | |
| 166 } | |
| 167 | |
| 168 static const size_t maximumDepth = 2000; | |
| 169 | |
| 170 static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value>
value, Vector<v8::Handle<v8::Array> >& stack, bool allowExperimentalTypes = fal
se) | |
| 171 { | |
| 172 if (value->IsNumber() && !std::isnan(value->NumberValue())) | |
| 173 return IDBKey::createNumber(value->NumberValue()); | |
| 174 if (value->IsString()) | |
| 175 return IDBKey::createString(toCoreString(value.As<v8::String>())); | |
| 176 if (value->IsDate() && !std::isnan(value->NumberValue())) | |
| 177 return IDBKey::createDate(value->NumberValue()); | |
| 178 if (value->IsUint8Array() && (allowExperimentalTypes || RuntimeEnabledFeatur
es::indexedDBExperimentalEnabled())) { | |
| 179 // Per discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=2333
2 the | |
| 180 // input type is constrained to Uint8Array to match the output type. | |
| 181 ArrayBufferView* view = WebCore::V8ArrayBufferView::toNative(value->ToOb
ject()); | |
| 182 const char* start = static_cast<const char*>(view->baseAddress()); | |
| 183 size_t length = view->byteLength(); | |
| 184 return IDBKey::createBinary(SharedBuffer::create(start, length)); | |
| 185 } | |
| 186 if (value->IsArray()) { | |
| 187 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); | |
| 188 | |
| 189 if (stack.contains(array)) | |
| 190 return 0; | |
| 191 if (stack.size() >= maximumDepth) | |
| 192 return 0; | |
| 193 stack.append(array); | |
| 194 | |
| 195 IDBKey::KeyArray subkeys; | |
| 196 uint32_t length = array->Length(); | |
| 197 for (uint32_t i = 0; i < length; ++i) { | |
| 198 v8::Local<v8::Value> item = array->Get(v8::Int32::New(isolate, i)); | |
| 199 IDBKey* subkey = createIDBKeyFromValue(isolate, item, stack, allowEx
perimentalTypes); | |
| 200 if (!subkey) | |
| 201 subkeys.append(IDBKey::createInvalid()); | |
| 202 else | |
| 203 subkeys.append(subkey); | |
| 204 } | |
| 205 | |
| 206 stack.removeLast(); | |
| 207 return IDBKey::createArray(subkeys); | |
| 208 } | |
| 209 return 0; | |
| 210 } | |
| 211 | |
| 212 static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value>
value, bool allowExperimentalTypes = false) | |
| 213 { | |
| 214 Vector<v8::Handle<v8::Array> > stack; | |
| 215 if (IDBKey* key = createIDBKeyFromValue(isolate, value, stack, allowExperime
ntalTypes)) | |
| 216 return key; | |
| 217 return IDBKey::createInvalid(); | |
| 218 } | |
| 219 | |
| 220 template<typename T> | |
| 221 static bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value) | |
| 222 { | |
| 223 v8::Local<v8::Object> object = v8Value->ToObject(); | |
| 224 if (!object->Has(indexOrName)) | |
| 225 return false; | |
| 226 v8Value = object->Get(indexOrName); | |
| 227 return true; | |
| 228 } | |
| 229 | |
| 230 template<typename T> | |
| 231 static bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::H
andle<v8::Value>& v8Value) | |
| 232 { | |
| 233 v8::Local<v8::Object> object = v8Object->ToObject(); | |
| 234 return object->Set(indexOrName, v8Value); | |
| 235 } | |
| 236 | |
| 237 static bool get(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const Strin
g& keyPathElement, v8::Handle<v8::Value>& result) | |
| 238 { | |
| 239 if (object->IsString() && keyPathElement == "length") { | |
| 240 int32_t length = v8::Handle<v8::String>::Cast(object)->Length(); | |
| 241 result = v8::Number::New(isolate, length); | |
| 242 return true; | |
| 243 } | |
| 244 return object->IsObject() && getValueFrom(v8String(isolate, keyPathElement),
result); | |
| 245 } | |
| 246 | |
| 247 static bool canSet(v8::Handle<v8::Value>& object, const String& keyPathElement) | |
| 248 { | |
| 249 return object->IsObject(); | |
| 250 } | |
| 251 | |
| 252 static bool set(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const Strin
g& keyPathElement, const v8::Handle<v8::Value>& v8Value) | |
| 253 { | |
| 254 return canSet(object, keyPathElement) && setValue(object, v8String(isolate,
keyPathElement), v8Value); | |
| 255 } | |
| 256 | |
| 257 static v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Isolate* isolate, v8::Hand
le<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index) | |
| 258 { | |
| 259 v8::Handle<v8::Value> currentValue(rootValue); | |
| 260 ASSERT(index <= keyPathElements.size()); | |
| 261 for (size_t i = 0; i < index; ++i) { | |
| 262 v8::Handle<v8::Value> parentValue(currentValue); | |
| 263 if (!get(isolate, parentValue, keyPathElements[i], currentValue)) | |
| 264 return v8Undefined(); | |
| 265 } | |
| 266 | |
| 267 return currentValue; | |
| 268 } | |
| 269 | |
| 270 static bool canInjectNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Valu
e>& rootValue, const Vector<String>& keyPathElements, size_t index) | |
| 271 { | |
| 272 if (!rootValue->IsObject()) | |
| 273 return false; | |
| 274 | |
| 275 v8::Handle<v8::Value> currentValue(rootValue); | |
| 276 | |
| 277 ASSERT(index <= keyPathElements.size()); | |
| 278 for (size_t i = 0; i < index; ++i) { | |
| 279 v8::Handle<v8::Value> parentValue(currentValue); | |
| 280 const String& keyPathElement = keyPathElements[i]; | |
| 281 if (!get(isolate, parentValue, keyPathElement, currentValue)) | |
| 282 return canSet(parentValue, keyPathElement); | |
| 283 } | |
| 284 return true; | |
| 285 } | |
| 286 | |
| 287 | |
| 288 static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Isolate* isolate, v8::H
andle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index
) | |
| 289 { | |
| 290 v8::Handle<v8::Value> currentValue(rootValue); | |
| 291 | |
| 292 ASSERT(index <= keyPathElements.size()); | |
| 293 for (size_t i = 0; i < index; ++i) { | |
| 294 v8::Handle<v8::Value> parentValue(currentValue); | |
| 295 const String& keyPathElement = keyPathElements[i]; | |
| 296 if (!get(isolate, parentValue, keyPathElement, currentValue)) { | |
| 297 v8::Handle<v8::Object> object = v8::Object::New(isolate); | |
| 298 if (!set(isolate, parentValue, keyPathElement, object)) | |
| 299 return v8Undefined(); | |
| 300 currentValue = object; | |
| 301 } | |
| 302 } | |
| 303 | |
| 304 return currentValue; | |
| 305 } | |
| 306 | |
| 307 static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolat
e, const ScriptValue& value, const String& keyPath, bool allowExperimentalTypes) | |
| 308 { | |
| 309 Vector<String> keyPathElements; | |
| 310 IDBKeyPathParseError error; | |
| 311 IDBParseKeyPath(keyPath, keyPathElements, error); | |
| 312 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 313 ASSERT(isolate->InContext()); | |
| 314 | |
| 315 v8::HandleScope handleScope(isolate); | |
| 316 v8::Handle<v8::Value> v8Value(value.v8Value()); | |
| 317 v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(isolate, v8Value, keyPathEl
ements, keyPathElements.size())); | |
| 318 if (v8Key.IsEmpty()) | |
| 319 return 0; | |
| 320 return createIDBKeyFromValue(isolate, v8Key, allowExperimentalTypes); | |
| 321 } | |
| 322 | |
| 323 static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolat
e, const ScriptValue& value, const IDBKeyPath& keyPath, bool allowExperimentalTy
pes = false) | |
| 324 { | |
| 325 ASSERT(!keyPath.isNull()); | |
| 326 v8::HandleScope handleScope(isolate); | |
| 327 if (keyPath.type() == IDBKeyPath::ArrayType) { | |
| 328 IDBKey::KeyArray result; | |
| 329 const Vector<String>& array = keyPath.array(); | |
| 330 for (size_t i = 0; i < array.size(); ++i) { | |
| 331 IDBKey* key = createIDBKeyFromScriptValueAndKeyPathInternal(isolate,
value, array[i], allowExperimentalTypes); | |
| 332 if (!key) | |
| 333 return 0; | |
| 334 result.append(key); | |
| 335 } | |
| 336 return IDBKey::createArray(result); | |
| 337 } | |
| 338 | |
| 339 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 340 return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath
.string(), allowExperimentalTypes); | |
| 341 } | |
| 342 | |
| 343 IDBKey* createIDBKeyFromScriptValueAndKeyPath(v8::Isolate* isolate, const Script
Value& value, const IDBKeyPath& keyPath) | |
| 344 { | |
| 345 IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath"); | |
| 346 return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath
); | |
| 347 } | |
| 348 | |
| 349 static v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate* isolate, Sha
redBuffer* buffer, const Vector<blink::WebBlobInfo>* blobInfo) | |
| 350 { | |
| 351 ASSERT(isolate->InContext()); | |
| 352 if (!buffer) | |
| 353 return v8::Null(isolate); | |
| 354 | |
| 355 // FIXME: The extra copy here can be eliminated by allowing SerializedScript
Value to take a raw const char* or const uint8_t*. | |
| 356 Vector<uint8_t> value; | |
| 357 value.append(buffer->data(), buffer->size()); | |
| 358 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::creat
eFromWireBytes(value); | |
| 359 return serializedValue->deserialize(isolate, 0, blobInfo); | |
| 360 } | |
| 361 | |
| 362 bool injectV8KeyIntoV8Value(v8::Isolate* isolate, v8::Handle<v8::Value> key, v8:
:Handle<v8::Value> value, const IDBKeyPath& keyPath) | |
| 363 { | |
| 364 IDB_TRACE("injectIDBV8KeyIntoV8Value"); | |
| 365 ASSERT(isolate->InContext()); | |
| 366 | |
| 367 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 368 Vector<String> keyPathElements; | |
| 369 IDBKeyPathParseError error; | |
| 370 IDBParseKeyPath(keyPath.string(), keyPathElements, error); | |
| 371 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 372 | |
| 373 if (!keyPathElements.size()) | |
| 374 return false; | |
| 375 | |
| 376 v8::HandleScope handleScope(isolate); | |
| 377 v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(isolate, value, keyPath
Elements, keyPathElements.size() - 1)); | |
| 378 if (parent.IsEmpty()) | |
| 379 return false; | |
| 380 | |
| 381 if (!set(isolate, parent, keyPathElements.last(), key)) | |
| 382 return false; | |
| 383 | |
| 384 return true; | |
| 385 } | |
| 386 | |
| 387 bool canInjectIDBKeyIntoScriptValue(v8::Isolate* isolate, const ScriptValue& scr
iptValue, const IDBKeyPath& keyPath) | |
| 388 { | |
| 389 IDB_TRACE("canInjectIDBKeyIntoScriptValue"); | |
| 390 ASSERT(keyPath.type() == IDBKeyPath::StringType); | |
| 391 Vector<String> keyPathElements; | |
| 392 IDBKeyPathParseError error; | |
| 393 IDBParseKeyPath(keyPath.string(), keyPathElements, error); | |
| 394 ASSERT(error == IDBKeyPathParseErrorNone); | |
| 395 | |
| 396 if (!keyPathElements.size()) | |
| 397 return false; | |
| 398 | |
| 399 v8::Handle<v8::Value> v8Value(scriptValue.v8Value()); | |
| 400 return canInjectNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPath
Elements.size() - 1); | |
| 401 } | |
| 402 | |
| 403 ScriptValue idbAnyToScriptValue(ScriptState* scriptState, IDBAny* any) | |
| 404 { | |
| 405 v8::Isolate* isolate = scriptState->isolate(); | |
| 406 v8::HandleScope handleScope(isolate); | |
| 407 v8::Handle<v8::Value> v8Value(toV8(any, scriptState->context()->Global(), is
olate)); | |
| 408 return ScriptValue(scriptState, v8Value); | |
| 409 } | |
| 410 | |
| 411 ScriptValue idbKeyToScriptValue(ScriptState* scriptState, IDBKey* key) | |
| 412 { | |
| 413 v8::Isolate* isolate = scriptState->isolate(); | |
| 414 v8::HandleScope handleScope(isolate); | |
| 415 v8::Handle<v8::Value> v8Value(toV8(key, scriptState->context()->Global(), is
olate)); | |
| 416 return ScriptValue(scriptState, v8Value); | |
| 417 } | |
| 418 | |
| 419 IDBKey* scriptValueToIDBKey(v8::Isolate* isolate, const ScriptValue& scriptValue
) | |
| 420 { | |
| 421 ASSERT(isolate->InContext()); | |
| 422 v8::HandleScope handleScope(isolate); | |
| 423 v8::Handle<v8::Value> v8Value(scriptValue.v8Value()); | |
| 424 return createIDBKeyFromValue(isolate, v8Value); | |
| 425 } | |
| 426 | |
| 427 IDBKeyRange* scriptValueToIDBKeyRange(v8::Isolate* isolate, const ScriptValue& s
criptValue) | |
| 428 { | |
| 429 v8::HandleScope handleScope(isolate); | |
| 430 v8::Handle<v8::Value> value(scriptValue.v8Value()); | |
| 431 return V8IDBKeyRange::toNativeWithTypeCheck(isolate, value); | |
| 432 } | |
| 433 | |
| 434 #ifndef NDEBUG | |
| 435 void assertPrimaryKeyValidOrInjectable(ScriptState* scriptState, PassRefPtr<Shar
edBuffer> buffer, const Vector<blink::WebBlobInfo>* blobInfo, IDBKey* key, const
IDBKeyPath& keyPath) | |
| 436 { | |
| 437 ScriptState::Scope scope(scriptState); | |
| 438 v8::Isolate* isolate = scriptState->isolate(); | |
| 439 ScriptValue keyValue = idbKeyToScriptValue(scriptState, key); | |
| 440 ScriptValue scriptValue(scriptState, deserializeIDBValueBuffer(isolate, buff
er.get(), blobInfo)); | |
| 441 | |
| 442 // This assertion is about already persisted data, so allow experimental typ
es. | |
| 443 const bool allowExperimentalTypes = true; | |
| 444 IDBKey* expectedKey = createIDBKeyFromScriptValueAndKeyPathInternal(isolate,
scriptValue, keyPath, allowExperimentalTypes); | |
| 445 ASSERT(!expectedKey || expectedKey->isEqual(key)); | |
| 446 | |
| 447 bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptVa
lue.v8Value(), keyPath); | |
| 448 ASSERT_UNUSED(injected, injected); | |
| 449 } | |
| 450 #endif | |
| 451 | |
| 452 } // namespace WebCore | |
| OLD | NEW |