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 |