OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "bindings/core/v8/ScriptValueSerializer.h" | 6 #include "bindings/core/v8/ScriptValueSerializer.h" |
7 | 7 |
8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
9 #include "bindings/core/v8/V8ArrayBufferView.h" | 9 #include "bindings/core/v8/V8ArrayBufferView.h" |
10 #include "bindings/core/v8/V8Blob.h" | 10 #include "bindings/core/v8/V8Blob.h" |
11 #include "bindings/core/v8/V8File.h" | 11 #include "bindings/core/v8/V8File.h" |
12 #include "bindings/core/v8/V8FileList.h" | 12 #include "bindings/core/v8/V8FileList.h" |
13 #include "bindings/core/v8/V8ImageData.h" | 13 #include "bindings/core/v8/V8ImageData.h" |
14 #include "bindings/core/v8/V8MessagePort.h" | 14 #include "bindings/core/v8/V8MessagePort.h" |
15 #include "bindings/modules/v8/V8CryptoKey.h" | |
16 #include "bindings/modules/v8/V8DOMFileSystem.h" | |
17 #include "core/dom/DOMDataView.h" | 15 #include "core/dom/DOMDataView.h" |
18 #include "core/fileapi/Blob.h" | 16 #include "core/fileapi/Blob.h" |
19 #include "core/fileapi/File.h" | 17 #include "core/fileapi/File.h" |
20 #include "core/fileapi/FileList.h" | 18 #include "core/fileapi/FileList.h" |
21 #include "public/platform/Platform.h" | 19 #include "public/platform/Platform.h" |
22 #include "public/platform/WebBlobInfo.h" | 20 #include "public/platform/WebBlobInfo.h" |
23 #include "wtf/text/StringHash.h" | 21 #include "wtf/text/StringHash.h" |
24 #include "wtf/text/StringUTF8Adaptor.h" | 22 #include "wtf/text/StringUTF8Adaptor.h" |
25 | 23 |
26 // FIXME: consider crashing in debug mode on deserialization errors | 24 // FIXME: consider crashing in debug mode on deserialization errors |
27 // NOTE: be sure to change wireFormatVersion as necessary! | 25 // NOTE: be sure to change wireFormatVersion as necessary! |
28 | 26 |
29 namespace blink { | 27 namespace blink { |
30 | 28 |
31 namespace SerializedScriptValueInternal { | |
32 | |
33 // This code implements the HTML5 Structured Clone algorithm: | 29 // This code implements the HTML5 Structured Clone algorithm: |
34 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa
ssing-of-structured-data | 30 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa
ssing-of-structured-data |
35 | 31 |
36 // ZigZag encoding helps VarInt encoding stay small for negative | 32 // ZigZag encoding helps VarInt encoding stay small for negative |
37 // numbers with small absolute values. | 33 // numbers with small absolute values. |
38 class ZigZag { | 34 class ZigZag { |
39 public: | 35 public: |
40 static uint32_t encode(uint32_t value) | 36 static uint32_t encode(uint32_t value) |
41 { | 37 { |
42 if (value & (1U << 31)) | 38 if (value & (1U << 31)) |
(...skipping 20 matching lines...) Expand all Loading... |
63 | 59 |
64 static bool shouldCheckForCycles(int depth) | 60 static bool shouldCheckForCycles(int depth) |
65 { | 61 { |
66 ASSERT(depth >= 0); | 62 ASSERT(depth >= 0); |
67 // Since we are not required to spot the cycle as soon as it | 63 // Since we are not required to spot the cycle as soon as it |
68 // happens we can check for cycles only when the current depth | 64 // happens we can check for cycles only when the current depth |
69 // is a power of two. | 65 // is a power of two. |
70 return !(depth & (depth - 1)); | 66 return !(depth & (depth - 1)); |
71 } | 67 } |
72 | 68 |
73 void Writer::writeUndefined() | 69 void SerializedScriptValueWriter::writeUndefined() |
74 { | 70 { |
75 append(UndefinedTag); | 71 append(UndefinedTag); |
76 } | 72 } |
77 | 73 |
78 void Writer::writeNull() | 74 void SerializedScriptValueWriter::writeNull() |
79 { | 75 { |
80 append(NullTag); | 76 append(NullTag); |
81 } | 77 } |
82 | 78 |
83 void Writer::writeTrue() | 79 void SerializedScriptValueWriter::writeTrue() |
84 { | 80 { |
85 append(TrueTag); | 81 append(TrueTag); |
86 } | 82 } |
87 | 83 |
88 void Writer::writeFalse() | 84 void SerializedScriptValueWriter::writeFalse() |
89 { | 85 { |
90 append(FalseTag); | 86 append(FalseTag); |
91 } | 87 } |
92 | 88 |
93 void Writer::writeBooleanObject(bool value) | 89 void SerializedScriptValueWriter::writeBooleanObject(bool value) |
94 { | 90 { |
95 append(value ? TrueObjectTag : FalseObjectTag); | 91 append(value ? TrueObjectTag : FalseObjectTag); |
96 } | 92 } |
97 | 93 |
98 void Writer::writeOneByteString(v8::Handle<v8::String>& string) | 94 void SerializedScriptValueWriter::writeOneByteString(v8::Handle<v8::String>& str
ing) |
99 { | 95 { |
100 int stringLength = string->Length(); | 96 int stringLength = string->Length(); |
101 int utf8Length = string->Utf8Length(); | 97 int utf8Length = string->Utf8Length(); |
102 ASSERT(stringLength >= 0 && utf8Length >= 0); | 98 ASSERT(stringLength >= 0 && utf8Length >= 0); |
103 | 99 |
104 append(StringTag); | 100 append(StringTag); |
105 doWriteUint32(static_cast<uint32_t>(utf8Length)); | 101 doWriteUint32(static_cast<uint32_t>(utf8Length)); |
106 ensureSpace(utf8Length); | 102 ensureSpace(utf8Length); |
107 | 103 |
108 // ASCII fast path. | 104 // ASCII fast path. |
109 if (stringLength == utf8Length) { | 105 if (stringLength == utf8Length) { |
110 string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOpt
ions()); | 106 string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOpt
ions()); |
111 } else { | 107 } else { |
112 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); | 108 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); |
113 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); | 109 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); |
114 } | 110 } |
115 m_position += utf8Length; | 111 m_position += utf8Length; |
116 } | 112 } |
117 | 113 |
118 void Writer::writeUCharString(v8::Handle<v8::String>& string) | 114 void SerializedScriptValueWriter::writeUCharString(v8::Handle<v8::String>& strin
g) |
119 { | 115 { |
120 int length = string->Length(); | 116 int length = string->Length(); |
121 ASSERT(length >= 0); | 117 ASSERT(length >= 0); |
122 | 118 |
123 int size = length * sizeof(UChar); | 119 int size = length * sizeof(UChar); |
124 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); | 120 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); |
125 if ((m_position + 1 + bytes) & 1) | 121 if ((m_position + 1 + bytes) & 1) |
126 append(PaddingTag); | 122 append(PaddingTag); |
127 | 123 |
128 append(StringUCharTag); | 124 append(StringUCharTag); |
129 doWriteUint32(static_cast<uint32_t>(size)); | 125 doWriteUint32(static_cast<uint32_t>(size)); |
130 ensureSpace(size); | 126 ensureSpace(size); |
131 | 127 |
132 ASSERT(!(m_position & 1)); | 128 ASSERT(!(m_position & 1)); |
133 uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position)); | 129 uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position)); |
134 string->Write(buffer, 0, length, v8StringWriteOptions()); | 130 string->Write(buffer, 0, length, v8StringWriteOptions()); |
135 m_position += size; | 131 m_position += size; |
136 } | 132 } |
137 | 133 |
138 void Writer::writeStringObject(const char* data, int length) | 134 void SerializedScriptValueWriter::writeStringObject(const char* data, int length
) |
139 { | 135 { |
140 ASSERT(length >= 0); | 136 ASSERT(length >= 0); |
141 append(StringObjectTag); | 137 append(StringObjectTag); |
142 doWriteString(data, length); | 138 doWriteString(data, length); |
143 } | 139 } |
144 | 140 |
145 void Writer::writeWebCoreString(const String& string) | 141 void SerializedScriptValueWriter::writeWebCoreString(const String& string) |
146 { | 142 { |
147 // Uses UTF8 encoding so we can read it back as either V8 or | 143 // Uses UTF8 encoding so we can read it back as either V8 or |
148 // WebCore string. | 144 // WebCore string. |
149 append(StringTag); | 145 append(StringTag); |
150 doWriteWebCoreString(string); | 146 doWriteWebCoreString(string); |
151 } | 147 } |
152 | 148 |
153 void Writer::writeVersion() | 149 void SerializedScriptValueWriter::writeVersion() |
154 { | 150 { |
155 append(VersionTag); | 151 append(VersionTag); |
156 doWriteUint32(SerializedScriptValue::wireFormatVersion); | 152 doWriteUint32(SerializedScriptValue::wireFormatVersion); |
157 } | 153 } |
158 | 154 |
159 void Writer::writeInt32(int32_t value) | 155 void SerializedScriptValueWriter::writeInt32(int32_t value) |
160 { | 156 { |
161 append(Int32Tag); | 157 append(Int32Tag); |
162 doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); | 158 doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); |
163 } | 159 } |
164 | 160 |
165 void Writer::writeUint32(uint32_t value) | 161 void SerializedScriptValueWriter::writeUint32(uint32_t value) |
166 { | 162 { |
167 append(Uint32Tag); | 163 append(Uint32Tag); |
168 doWriteUint32(value); | 164 doWriteUint32(value); |
169 } | 165 } |
170 | 166 |
171 void Writer::writeDate(double numberValue) | 167 void SerializedScriptValueWriter::writeDate(double numberValue) |
172 { | 168 { |
173 append(DateTag); | 169 append(DateTag); |
174 doWriteNumber(numberValue); | 170 doWriteNumber(numberValue); |
175 } | 171 } |
176 | 172 |
177 void Writer::writeNumber(double number) | 173 void SerializedScriptValueWriter::writeNumber(double number) |
178 { | 174 { |
179 append(NumberTag); | 175 append(NumberTag); |
180 doWriteNumber(number); | 176 doWriteNumber(number); |
181 } | 177 } |
182 | 178 |
183 void Writer::writeNumberObject(double number) | 179 void SerializedScriptValueWriter::writeNumberObject(double number) |
184 { | 180 { |
185 append(NumberObjectTag); | 181 append(NumberObjectTag); |
186 doWriteNumber(number); | 182 doWriteNumber(number); |
187 } | 183 } |
188 | 184 |
189 void Writer::writeBlob(const String& uuid, const String& type, unsigned long lon
g size) | 185 void SerializedScriptValueWriter::writeBlob(const String& uuid, const String& ty
pe, unsigned long long size) |
190 { | 186 { |
191 append(BlobTag); | 187 append(BlobTag); |
192 doWriteWebCoreString(uuid); | 188 doWriteWebCoreString(uuid); |
193 doWriteWebCoreString(type); | 189 doWriteWebCoreString(type); |
194 doWriteUint64(size); | 190 doWriteUint64(size); |
195 } | 191 } |
196 | 192 |
197 void Writer::writeDOMFileSystem(int type, const String& name, const String& url) | 193 void SerializedScriptValueWriter::writeBlobIndex(int blobIndex) |
198 { | |
199 append(DOMFileSystemTag); | |
200 doWriteUint32(type); | |
201 doWriteWebCoreString(name); | |
202 doWriteWebCoreString(url); | |
203 } | |
204 | |
205 void Writer::writeBlobIndex(int blobIndex) | |
206 { | 194 { |
207 ASSERT(blobIndex >= 0); | 195 ASSERT(blobIndex >= 0); |
208 append(BlobIndexTag); | 196 append(BlobIndexTag); |
209 doWriteUint32(blobIndex); | 197 doWriteUint32(blobIndex); |
210 } | 198 } |
211 | 199 |
212 void Writer::writeFile(const File& file) | 200 void SerializedScriptValueWriter::writeFile(const File& file) |
213 { | 201 { |
214 append(FileTag); | 202 append(FileTag); |
215 doWriteFile(file); | 203 doWriteFile(file); |
216 } | 204 } |
217 | 205 |
218 void Writer::writeFileIndex(int blobIndex) | 206 void SerializedScriptValueWriter::writeFileIndex(int blobIndex) |
219 { | 207 { |
220 append(FileIndexTag); | 208 append(FileIndexTag); |
221 doWriteUint32(blobIndex); | 209 doWriteUint32(blobIndex); |
222 } | 210 } |
223 | 211 |
224 void Writer::writeFileList(const FileList& fileList) | 212 void SerializedScriptValueWriter::writeFileList(const FileList& fileList) |
225 { | 213 { |
226 append(FileListTag); | 214 append(FileListTag); |
227 uint32_t length = fileList.length(); | 215 uint32_t length = fileList.length(); |
228 doWriteUint32(length); | 216 doWriteUint32(length); |
229 for (unsigned i = 0; i < length; ++i) | 217 for (unsigned i = 0; i < length; ++i) |
230 doWriteFile(*fileList.item(i)); | 218 doWriteFile(*fileList.item(i)); |
231 } | 219 } |
232 | 220 |
233 void Writer::writeFileListIndex(const Vector<int>& blobIndices) | 221 void SerializedScriptValueWriter::writeFileListIndex(const Vector<int>& blobIndi
ces) |
234 { | 222 { |
235 append(FileListIndexTag); | 223 append(FileListIndexTag); |
236 uint32_t length = blobIndices.size(); | 224 uint32_t length = blobIndices.size(); |
237 doWriteUint32(length); | 225 doWriteUint32(length); |
238 for (unsigned i = 0; i < length; ++i) | 226 for (unsigned i = 0; i < length; ++i) |
239 doWriteUint32(blobIndices[i]); | 227 doWriteUint32(blobIndices[i]); |
240 } | 228 } |
241 | 229 |
242 bool Writer::writeCryptoKey(const WebCryptoKey& key) | 230 void SerializedScriptValueWriter::writeArrayBuffer(const DOMArrayBuffer& arrayBu
ffer) |
243 { | |
244 append(static_cast<uint8_t>(CryptoKeyTag)); | |
245 | |
246 switch (key.algorithm().paramsType()) { | |
247 case WebCryptoKeyAlgorithmParamsTypeAes: | |
248 doWriteAesKey(key); | |
249 break; | |
250 case WebCryptoKeyAlgorithmParamsTypeHmac: | |
251 doWriteHmacKey(key); | |
252 break; | |
253 case WebCryptoKeyAlgorithmParamsTypeRsaHashed: | |
254 doWriteRsaHashedKey(key); | |
255 break; | |
256 case WebCryptoKeyAlgorithmParamsTypeEc: | |
257 doWriteEcKey(key); | |
258 break; | |
259 case WebCryptoKeyAlgorithmParamsTypeNone: | |
260 ASSERT_NOT_REACHED(); | |
261 return false; | |
262 } | |
263 | |
264 doWriteKeyUsages(key.usages(), key.extractable()); | |
265 | |
266 WebVector<uint8_t> keyData; | |
267 if (!Platform::current()->crypto()->serializeKeyForClone(key, keyData)) | |
268 return false; | |
269 | |
270 doWriteUint32(keyData.size()); | |
271 append(keyData.data(), keyData.size()); | |
272 return true; | |
273 } | |
274 | |
275 void Writer::writeArrayBuffer(const DOMArrayBuffer& arrayBuffer) | |
276 { | 231 { |
277 append(ArrayBufferTag); | 232 append(ArrayBufferTag); |
278 doWriteArrayBuffer(arrayBuffer); | 233 doWriteArrayBuffer(arrayBuffer); |
279 } | 234 } |
280 | 235 |
281 void Writer::writeArrayBufferView(const DOMArrayBufferView& arrayBufferView) | 236 void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView&
arrayBufferView) |
282 { | 237 { |
283 append(ArrayBufferViewTag); | 238 append(ArrayBufferViewTag); |
284 #if ENABLE(ASSERT) | 239 #if ENABLE(ASSERT) |
285 const DOMArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); | 240 const DOMArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); |
286 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt
eOffset() == | 241 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt
eOffset() == |
287 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); | 242 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); |
288 #endif | 243 #endif |
289 DOMArrayBufferView::ViewType type = arrayBufferView.type(); | 244 DOMArrayBufferView::ViewType type = arrayBufferView.type(); |
290 | 245 |
291 switch (type) { | 246 switch (type) { |
(...skipping 27 matching lines...) Expand all Loading... |
319 case DOMArrayBufferView::TypeDataView: | 274 case DOMArrayBufferView::TypeDataView: |
320 append(DataViewTag); | 275 append(DataViewTag); |
321 break; | 276 break; |
322 default: | 277 default: |
323 ASSERT_NOT_REACHED(); | 278 ASSERT_NOT_REACHED(); |
324 } | 279 } |
325 doWriteUint32(arrayBufferView.byteOffset()); | 280 doWriteUint32(arrayBufferView.byteOffset()); |
326 doWriteUint32(arrayBufferView.byteLength()); | 281 doWriteUint32(arrayBufferView.byteLength()); |
327 } | 282 } |
328 | 283 |
329 void Writer::writeImageData(uint32_t width, uint32_t height, const uint8_t* pixe
lData, uint32_t pixelDataLength) | 284 void SerializedScriptValueWriter::writeImageData(uint32_t width, uint32_t height
, const uint8_t* pixelData, uint32_t pixelDataLength) |
330 { | 285 { |
331 append(ImageDataTag); | 286 append(ImageDataTag); |
332 doWriteUint32(width); | 287 doWriteUint32(width); |
333 doWriteUint32(height); | 288 doWriteUint32(height); |
334 doWriteUint32(pixelDataLength); | 289 doWriteUint32(pixelDataLength); |
335 append(pixelData, pixelDataLength); | 290 append(pixelData, pixelDataLength); |
336 } | 291 } |
337 | 292 |
338 void Writer::writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) | 293 void SerializedScriptValueWriter::writeRegExp(v8::Local<v8::String> pattern, v8:
:RegExp::Flags flags) |
339 { | 294 { |
340 append(RegExpTag); | 295 append(RegExpTag); |
341 v8::String::Utf8Value patternUtf8Value(pattern); | 296 v8::String::Utf8Value patternUtf8Value(pattern); |
342 doWriteString(*patternUtf8Value, patternUtf8Value.length()); | 297 doWriteString(*patternUtf8Value, patternUtf8Value.length()); |
343 doWriteUint32(static_cast<uint32_t>(flags)); | 298 doWriteUint32(static_cast<uint32_t>(flags)); |
344 } | 299 } |
345 | 300 |
346 void Writer::writeTransferredMessagePort(uint32_t index) | 301 void SerializedScriptValueWriter::writeTransferredMessagePort(uint32_t index) |
347 { | 302 { |
348 append(MessagePortTag); | 303 append(MessagePortTag); |
349 doWriteUint32(index); | 304 doWriteUint32(index); |
350 } | 305 } |
351 | 306 |
352 void Writer::writeTransferredArrayBuffer(uint32_t index) | 307 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) |
353 { | 308 { |
354 append(ArrayBufferTransferTag); | 309 append(ArrayBufferTransferTag); |
355 doWriteUint32(index); | 310 doWriteUint32(index); |
356 } | 311 } |
357 | 312 |
358 void Writer::writeObjectReference(uint32_t reference) | 313 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) |
359 { | 314 { |
360 append(ObjectReferenceTag); | 315 append(ObjectReferenceTag); |
361 doWriteUint32(reference); | 316 doWriteUint32(reference); |
362 } | 317 } |
363 | 318 |
364 void Writer::writeObject(uint32_t numProperties) | 319 void SerializedScriptValueWriter::writeObject(uint32_t numProperties) |
365 { | 320 { |
366 append(ObjectTag); | 321 append(ObjectTag); |
367 doWriteUint32(numProperties); | 322 doWriteUint32(numProperties); |
368 } | 323 } |
369 | 324 |
370 void Writer::writeSparseArray(uint32_t numProperties, uint32_t length) | 325 void SerializedScriptValueWriter::writeSparseArray(uint32_t numProperties, uint3
2_t length) |
371 { | 326 { |
372 append(SparseArrayTag); | 327 append(SparseArrayTag); |
373 doWriteUint32(numProperties); | 328 doWriteUint32(numProperties); |
374 doWriteUint32(length); | 329 doWriteUint32(length); |
375 } | 330 } |
376 | 331 |
377 void Writer::writeDenseArray(uint32_t numProperties, uint32_t length) | 332 void SerializedScriptValueWriter::writeDenseArray(uint32_t numProperties, uint32
_t length) |
378 { | 333 { |
379 append(DenseArrayTag); | 334 append(DenseArrayTag); |
380 doWriteUint32(numProperties); | 335 doWriteUint32(numProperties); |
381 doWriteUint32(length); | 336 doWriteUint32(length); |
382 } | 337 } |
383 | 338 |
384 String Writer::takeWireString() | 339 String SerializedScriptValueWriter::takeWireString() |
385 { | 340 { |
386 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 341 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
387 fillHole(); | 342 fillHole(); |
388 String data = String(m_buffer.data(), m_buffer.size()); | 343 String data = String(m_buffer.data(), m_buffer.size()); |
389 data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueT
ype)); | 344 data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueT
ype)); |
390 return data; | 345 return data; |
391 } | 346 } |
392 | 347 |
393 void Writer::writeReferenceCount(uint32_t numberOfReferences) | 348 void SerializedScriptValueWriter::writeReferenceCount(uint32_t numberOfReference
s) |
394 { | 349 { |
395 append(ReferenceCountTag); | 350 append(ReferenceCountTag); |
396 doWriteUint32(numberOfReferences); | 351 doWriteUint32(numberOfReferences); |
397 } | 352 } |
398 | 353 |
399 void Writer::writeGenerateFreshObject() | 354 void SerializedScriptValueWriter::writeGenerateFreshObject() |
400 { | 355 { |
401 append(GenerateFreshObjectTag); | 356 append(GenerateFreshObjectTag); |
402 } | 357 } |
403 | 358 |
404 void Writer::writeGenerateFreshSparseArray(uint32_t length) | 359 void SerializedScriptValueWriter::writeGenerateFreshSparseArray(uint32_t length) |
405 { | 360 { |
406 append(GenerateFreshSparseArrayTag); | 361 append(GenerateFreshSparseArrayTag); |
407 doWriteUint32(length); | 362 doWriteUint32(length); |
408 } | 363 } |
409 | 364 |
410 void Writer::writeGenerateFreshDenseArray(uint32_t length) | 365 void SerializedScriptValueWriter::writeGenerateFreshDenseArray(uint32_t length) |
411 { | 366 { |
412 append(GenerateFreshDenseArrayTag); | 367 append(GenerateFreshDenseArrayTag); |
413 doWriteUint32(length); | 368 doWriteUint32(length); |
414 } | 369 } |
415 | 370 |
416 void Writer::doWriteFile(const File& file) | 371 void SerializedScriptValueWriter::doWriteFile(const File& file) |
417 { | 372 { |
418 doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); | 373 doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); |
419 doWriteWebCoreString(file.name()); | 374 doWriteWebCoreString(file.name()); |
420 doWriteWebCoreString(file.webkitRelativePath()); | 375 doWriteWebCoreString(file.webkitRelativePath()); |
421 doWriteWebCoreString(file.uuid()); | 376 doWriteWebCoreString(file.uuid()); |
422 doWriteWebCoreString(file.type()); | 377 doWriteWebCoreString(file.type()); |
423 | 378 |
424 // FIXME don't use 1 byte to encode a flag. | 379 // FIXME don't use 1 byte to encode a flag. |
425 if (file.hasValidSnapshotMetadata()) { | 380 if (file.hasValidSnapshotMetadata()) { |
426 doWriteUint32(static_cast<uint8_t>(1)); | 381 doWriteUint32(static_cast<uint8_t>(1)); |
427 | 382 |
428 long long size; | 383 long long size; |
429 double lastModified; | 384 double lastModified; |
430 file.captureSnapshot(size, lastModified); | 385 file.captureSnapshot(size, lastModified); |
431 doWriteUint64(static_cast<uint64_t>(size)); | 386 doWriteUint64(static_cast<uint64_t>(size)); |
432 doWriteNumber(lastModified); | 387 doWriteNumber(lastModified); |
433 } else { | 388 } else { |
434 doWriteUint32(static_cast<uint8_t>(0)); | 389 doWriteUint32(static_cast<uint8_t>(0)); |
435 } | 390 } |
436 | 391 |
437 doWriteUint32(static_cast<uint8_t>((file.userVisibility() == File::IsUserVis
ible) ? 1 : 0)); | 392 doWriteUint32(static_cast<uint8_t>((file.userVisibility() == File::IsUserVis
ible) ? 1 : 0)); |
438 } | 393 } |
439 | 394 |
440 void Writer::doWriteArrayBuffer(const DOMArrayBuffer& arrayBuffer) | 395 void SerializedScriptValueWriter::doWriteArrayBuffer(const DOMArrayBuffer& array
Buffer) |
441 { | 396 { |
442 uint32_t byteLength = arrayBuffer.byteLength(); | 397 uint32_t byteLength = arrayBuffer.byteLength(); |
443 doWriteUint32(byteLength); | 398 doWriteUint32(byteLength); |
444 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); | 399 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); |
445 } | 400 } |
446 | 401 |
447 void Writer::doWriteString(const char* data, int length) | 402 void SerializedScriptValueWriter::doWriteString(const char* data, int length) |
448 { | 403 { |
449 doWriteUint32(static_cast<uint32_t>(length)); | 404 doWriteUint32(static_cast<uint32_t>(length)); |
450 append(reinterpret_cast<const uint8_t*>(data), length); | 405 append(reinterpret_cast<const uint8_t*>(data), length); |
451 } | 406 } |
452 | 407 |
453 void Writer::doWriteWebCoreString(const String& string) | 408 void SerializedScriptValueWriter::doWriteWebCoreString(const String& string) |
454 { | 409 { |
455 StringUTF8Adaptor stringUTF8(string); | 410 StringUTF8Adaptor stringUTF8(string); |
456 doWriteString(stringUTF8.data(), stringUTF8.length()); | 411 doWriteString(stringUTF8.data(), stringUTF8.length()); |
457 } | 412 } |
458 | 413 |
459 void Writer::doWriteHmacKey(const WebCryptoKey& key) | 414 int SerializedScriptValueWriter::bytesNeededToWireEncode(uint32_t value) |
460 { | |
461 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeHmac); | |
462 | |
463 append(static_cast<uint8_t>(HmacKeyTag)); | |
464 ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8)); | |
465 doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8); | |
466 doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id()); | |
467 } | |
468 | |
469 void Writer::doWriteAesKey(const WebCryptoKey& key) | |
470 { | |
471 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeAes); | |
472 | |
473 append(static_cast<uint8_t>(AesKeyTag)); | |
474 doWriteAlgorithmId(key.algorithm().id()); | |
475 // Converting the key length from bits to bytes is lossless and makes | |
476 // it fit in 1 byte. | |
477 ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8)); | |
478 doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8); | |
479 } | |
480 | |
481 void Writer::doWriteRsaHashedKey(const WebCryptoKey& key) | |
482 { | |
483 ASSERT(key.algorithm().rsaHashedParams()); | |
484 append(static_cast<uint8_t>(RsaHashedKeyTag)); | |
485 | |
486 doWriteAlgorithmId(key.algorithm().id()); | |
487 doWriteAsymmetricKeyType(key.type()); | |
488 | |
489 const WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHash
edParams(); | |
490 doWriteUint32(params->modulusLengthBits()); | |
491 doWriteUint32(params->publicExponent().size()); | |
492 append(params->publicExponent().data(), params->publicExponent().size()); | |
493 doWriteAlgorithmId(params->hash().id()); | |
494 } | |
495 | |
496 void Writer::doWriteEcKey(const WebCryptoKey& key) | |
497 { | |
498 ASSERT(key.algorithm().ecParams()); | |
499 append(static_cast<uint8_t>(EcKeyTag)); | |
500 | |
501 doWriteAlgorithmId(key.algorithm().id()); | |
502 doWriteAsymmetricKeyType(key.type()); | |
503 doWriteNamedCurve(key.algorithm().ecParams()->namedCurve()); | |
504 } | |
505 | |
506 void Writer::doWriteAlgorithmId(WebCryptoAlgorithmId id) | |
507 { | |
508 switch (id) { | |
509 case WebCryptoAlgorithmIdAesCbc: | |
510 return doWriteUint32(AesCbcTag); | |
511 case WebCryptoAlgorithmIdHmac: | |
512 return doWriteUint32(HmacTag); | |
513 case WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | |
514 return doWriteUint32(RsaSsaPkcs1v1_5Tag); | |
515 case WebCryptoAlgorithmIdSha1: | |
516 return doWriteUint32(Sha1Tag); | |
517 case WebCryptoAlgorithmIdSha256: | |
518 return doWriteUint32(Sha256Tag); | |
519 case WebCryptoAlgorithmIdSha384: | |
520 return doWriteUint32(Sha384Tag); | |
521 case WebCryptoAlgorithmIdSha512: | |
522 return doWriteUint32(Sha512Tag); | |
523 case WebCryptoAlgorithmIdAesGcm: | |
524 return doWriteUint32(AesGcmTag); | |
525 case WebCryptoAlgorithmIdRsaOaep: | |
526 return doWriteUint32(RsaOaepTag); | |
527 case WebCryptoAlgorithmIdAesCtr: | |
528 return doWriteUint32(AesCtrTag); | |
529 case WebCryptoAlgorithmIdAesKw: | |
530 return doWriteUint32(AesKwTag); | |
531 case WebCryptoAlgorithmIdRsaPss: | |
532 return doWriteUint32(RsaPssTag); | |
533 case WebCryptoAlgorithmIdEcdsa: | |
534 return doWriteUint32(EcdsaTag); | |
535 } | |
536 ASSERT_NOT_REACHED(); | |
537 } | |
538 | |
539 void Writer::doWriteAsymmetricKeyType(WebCryptoKeyType keyType) | |
540 { | |
541 switch (keyType) { | |
542 case WebCryptoKeyTypePublic: | |
543 doWriteUint32(PublicKeyType); | |
544 break; | |
545 case WebCryptoKeyTypePrivate: | |
546 doWriteUint32(PrivateKeyType); | |
547 break; | |
548 case WebCryptoKeyTypeSecret: | |
549 ASSERT_NOT_REACHED(); | |
550 } | |
551 } | |
552 | |
553 void Writer::doWriteNamedCurve(WebCryptoNamedCurve namedCurve) | |
554 { | |
555 switch (namedCurve) { | |
556 case WebCryptoNamedCurveP256: | |
557 return doWriteUint32(P256Tag); | |
558 case WebCryptoNamedCurveP384: | |
559 return doWriteUint32(P384Tag); | |
560 case WebCryptoNamedCurveP521: | |
561 return doWriteUint32(P521Tag); | |
562 } | |
563 ASSERT_NOT_REACHED(); | |
564 } | |
565 | |
566 void Writer::doWriteKeyUsages(const WebCryptoKeyUsageMask usages, bool extractab
le) | |
567 { | |
568 // Reminder to update this when adding new key usages. | |
569 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
570 | |
571 uint32_t value = 0; | |
572 | |
573 if (extractable) | |
574 value |= ExtractableUsage; | |
575 | |
576 if (usages & WebCryptoKeyUsageEncrypt) | |
577 value |= EncryptUsage; | |
578 if (usages & WebCryptoKeyUsageDecrypt) | |
579 value |= DecryptUsage; | |
580 if (usages & WebCryptoKeyUsageSign) | |
581 value |= SignUsage; | |
582 if (usages & WebCryptoKeyUsageVerify) | |
583 value |= VerifyUsage; | |
584 if (usages & WebCryptoKeyUsageDeriveKey) | |
585 value |= DeriveKeyUsage; | |
586 if (usages & WebCryptoKeyUsageWrapKey) | |
587 value |= WrapKeyUsage; | |
588 if (usages & WebCryptoKeyUsageUnwrapKey) | |
589 value |= UnwrapKeyUsage; | |
590 if (usages & WebCryptoKeyUsageDeriveBits) | |
591 value |= DeriveBitsUsage; | |
592 | |
593 doWriteUint32(value); | |
594 } | |
595 | |
596 int Writer::bytesNeededToWireEncode(uint32_t value) | |
597 { | 415 { |
598 int bytes = 1; | 416 int bytes = 1; |
599 while (true) { | 417 while (true) { |
600 value >>= SerializedScriptValue::varIntShift; | 418 value >>= SerializedScriptValue::varIntShift; |
601 if (!value) | 419 if (!value) |
602 break; | 420 break; |
603 ++bytes; | 421 ++bytes; |
604 } | 422 } |
605 | 423 |
606 return bytes; | 424 return bytes; |
607 } | 425 } |
608 | 426 |
609 void Writer::doWriteUint32(uint32_t value) | 427 void SerializedScriptValueWriter::doWriteUint32(uint32_t value) |
610 { | 428 { |
611 doWriteUintHelper(value); | 429 doWriteUintHelper(value); |
612 } | 430 } |
613 | 431 |
614 void Writer::doWriteUint64(uint64_t value) | 432 void SerializedScriptValueWriter::doWriteUint64(uint64_t value) |
615 { | 433 { |
616 doWriteUintHelper(value); | 434 doWriteUintHelper(value); |
617 } | 435 } |
618 | 436 |
619 void Writer::doWriteNumber(double number) | 437 void SerializedScriptValueWriter::doWriteNumber(double number) |
620 { | 438 { |
621 append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); | 439 append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); |
622 } | 440 } |
623 | 441 |
624 void Writer::append(SerializationTag tag) | 442 void SerializedScriptValueWriter::append(SerializationTag tag) |
625 { | 443 { |
626 append(static_cast<uint8_t>(tag)); | 444 append(static_cast<uint8_t>(tag)); |
627 } | 445 } |
628 | 446 |
629 void Writer::append(uint8_t b) | 447 void SerializedScriptValueWriter::append(uint8_t b) |
630 { | 448 { |
631 ensureSpace(1); | 449 ensureSpace(1); |
632 *byteAt(m_position++) = b; | 450 *byteAt(m_position++) = b; |
633 } | 451 } |
634 | 452 |
635 void Writer::append(const uint8_t* data, int length) | 453 void SerializedScriptValueWriter::append(const uint8_t* data, int length) |
636 { | 454 { |
637 ensureSpace(length); | 455 ensureSpace(length); |
638 memcpy(byteAt(m_position), data, length); | 456 memcpy(byteAt(m_position), data, length); |
639 m_position += length; | 457 m_position += length; |
640 } | 458 } |
641 | 459 |
642 void Writer::ensureSpace(unsigned extra) | 460 void SerializedScriptValueWriter::ensureSpace(unsigned extra) |
643 { | 461 { |
644 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 462 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
645 m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1
" to round up. | 463 m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1
" to round up. |
646 } | 464 } |
647 | 465 |
648 void Writer::fillHole() | 466 void SerializedScriptValueWriter::fillHole() |
649 { | 467 { |
650 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 468 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
651 // If the writer is at odd position in the buffer, then one of | 469 // If the writer is at odd position in the buffer, then one of |
652 // the bytes in the last UChar is not initialized. | 470 // the bytes in the last UChar is not initialized. |
653 if (m_position % 2) | 471 if (m_position % 2) |
654 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); | 472 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); |
655 } | 473 } |
656 | 474 |
657 uint8_t* Writer::byteAt(int position) | 475 uint8_t* SerializedScriptValueWriter::byteAt(int position) |
658 { | 476 { |
659 return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; | 477 return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; |
660 } | 478 } |
661 | 479 |
662 int Writer::v8StringWriteOptions() | 480 int SerializedScriptValueWriter::v8StringWriteOptions() |
663 { | 481 { |
664 return v8::String::NO_NULL_TERMINATION; | 482 return v8::String::NO_NULL_TERMINATION; |
665 } | 483 } |
666 | 484 |
667 Serializer::StateBase* Serializer::AbstractObjectState::serializeProperties(bool
ignoreIndexed, Serializer& serializer) | 485 ScriptValueSerializer::StateBase* ScriptValueSerializer::AbstractObjectState::se
rializeProperties(bool ignoreIndexed, ScriptValueSerializer& serializer) |
668 { | 486 { |
669 while (m_index < m_propertyNames->Length()) { | 487 while (m_index < m_propertyNames->Length()) { |
670 if (!m_nameDone) { | 488 if (!m_nameDone) { |
671 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); | 489 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); |
672 if (StateBase* newState = serializer.checkException(this)) | 490 if (StateBase* newState = serializer.checkException(this)) |
673 return newState; | 491 return newState; |
674 if (propertyName.IsEmpty()) | 492 if (propertyName.IsEmpty()) |
675 return serializer.handleError(InputError, "Empty property names
cannot be cloned.", this); | 493 return serializer.handleError(InputError, "Empty property names
cannot be cloned.", this); |
676 bool hasStringProperty = propertyName->IsString() && composite()->Ha
sRealNamedProperty(propertyName.As<v8::String>()); | 494 bool hasStringProperty = propertyName->IsString() && composite()->Ha
sRealNamedProperty(propertyName.As<v8::String>()); |
677 if (StateBase* newState = serializer.checkException(this)) | 495 if (StateBase* newState = serializer.checkException(this)) |
(...skipping 23 matching lines...) Expand all Loading... |
701 ++m_numSerializedProperties; | 519 ++m_numSerializedProperties; |
702 // If we return early here, it's either because we have pushed a new sta
te onto the | 520 // If we return early here, it's either because we have pushed a new sta
te onto the |
703 // serialization state stack or because we have encountered an error (an
d in both cases | 521 // serialization state stack or because we have encountered an error (an
d in both cases |
704 // we are unwinding the native stack). | 522 // we are unwinding the native stack). |
705 if (StateBase* newState = serializer.doSerialize(value, this)) | 523 if (StateBase* newState = serializer.doSerialize(value, this)) |
706 return newState; | 524 return newState; |
707 } | 525 } |
708 return objectDone(m_numSerializedProperties, serializer); | 526 return objectDone(m_numSerializedProperties, serializer); |
709 } | 527 } |
710 | 528 |
711 Serializer::StateBase* Serializer::ObjectState::advance(Serializer& serializer) | 529 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::advance(Sc
riptValueSerializer& serializer) |
712 { | 530 { |
713 if (m_propertyNames.IsEmpty()) { | 531 if (m_propertyNames.IsEmpty()) { |
714 m_propertyNames = composite()->GetPropertyNames(); | 532 m_propertyNames = composite()->GetPropertyNames(); |
715 if (StateBase* newState = serializer.checkException(this)) | 533 if (StateBase* newState = serializer.checkException(this)) |
716 return newState; | 534 return newState; |
717 if (m_propertyNames.IsEmpty()) | 535 if (m_propertyNames.IsEmpty()) |
718 return serializer.handleError(InputError, "Empty property names cann
ot be cloned.", nextState()); | 536 return serializer.handleError(InputError, "Empty property names cann
ot be cloned.", nextState()); |
719 } | 537 } |
720 return serializeProperties(false, serializer); | 538 return serializeProperties(false, serializer); |
721 } | 539 } |
722 | 540 |
723 Serializer::StateBase* Serializer::ObjectState::objectDone(unsigned numPropertie
s, Serializer& serializer) | 541 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::objectDone
(unsigned numProperties, ScriptValueSerializer& serializer) |
724 { | 542 { |
725 return serializer.writeObject(numProperties, this); | 543 return serializer.writeObject(numProperties, this); |
726 } | 544 } |
727 | 545 |
728 Serializer::StateBase* Serializer::DenseArrayState::advance(Serializer& serializ
er) | 546 ScriptValueSerializer::StateBase* ScriptValueSerializer::DenseArrayState::advanc
e(ScriptValueSerializer& serializer) |
729 { | 547 { |
730 while (m_arrayIndex < m_arrayLength) { | 548 while (m_arrayIndex < m_arrayLength) { |
731 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIn
dex); | 549 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIn
dex); |
732 m_arrayIndex++; | 550 m_arrayIndex++; |
733 if (StateBase* newState = serializer.checkException(this)) | 551 if (StateBase* newState = serializer.checkException(this)) |
734 return newState; | 552 return newState; |
735 if (StateBase* newState = serializer.doSerialize(value, this)) | 553 if (StateBase* newState = serializer.doSerialize(value, this)) |
736 return newState; | 554 return newState; |
737 } | 555 } |
738 return serializeProperties(true, serializer); | 556 return serializeProperties(true, serializer); |
739 } | 557 } |
740 | 558 |
741 Serializer::StateBase* Serializer::DenseArrayState::objectDone(unsigned numPrope
rties, Serializer& serializer) | 559 ScriptValueSerializer::StateBase* ScriptValueSerializer::DenseArrayState::object
Done(unsigned numProperties, ScriptValueSerializer& serializer) |
742 { | 560 { |
743 return serializer.writeDenseArray(numProperties, m_arrayLength, this); | 561 return serializer.writeDenseArray(numProperties, m_arrayLength, this); |
744 } | 562 } |
745 | 563 |
746 Serializer::StateBase* Serializer::SparseArrayState::advance(Serializer& seriali
zer) | 564 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::advan
ce(ScriptValueSerializer& serializer) |
747 { | 565 { |
748 return serializeProperties(false, serializer); | 566 return serializeProperties(false, serializer); |
749 } | 567 } |
750 | 568 |
751 Serializer::StateBase* Serializer::SparseArrayState::objectDone(unsigned numProp
erties, Serializer& serializer) | 569 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::objec
tDone(unsigned numProperties, ScriptValueSerializer& serializer) |
752 { | 570 { |
753 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>(
)->Length(), this); | 571 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>(
)->Length(), this); |
754 } | 572 } |
755 | 573 |
756 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec
t> creationContext, v8::Isolate* isolate) | 574 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec
t> creationContext, v8::Isolate* isolate) |
757 { | 575 { |
758 if (!impl) | 576 if (!impl) |
759 return v8::Handle<v8::Object>(); | 577 return v8::Handle<v8::Object>(); |
760 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 578 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
761 ASSERT(wrapper->IsObject()); | 579 ASSERT(wrapper->IsObject()); |
(...skipping 13 matching lines...) Expand all Loading... |
775 // HTML5 structured clone algorithm. | 593 // HTML5 structured clone algorithm. |
776 static bool isHostObject(v8::Handle<v8::Object> object) | 594 static bool isHostObject(v8::Handle<v8::Object> object) |
777 { | 595 { |
778 // If the object has any internal fields, then we won't be able to serialize
or deserialize | 596 // If the object has any internal fields, then we won't be able to serialize
or deserialize |
779 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because | 597 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because |
780 // the mechanism for these relies on data stored in these fields. We should | 598 // the mechanism for these relies on data stored in these fields. We should |
781 // catch external array data as a special case. | 599 // catch external array data as a special case. |
782 return object->InternalFieldCount() || object->HasIndexedPropertiesInExterna
lArrayData(); | 600 return object->InternalFieldCount() || object->HasIndexedPropertiesInExterna
lArrayData(); |
783 } | 601 } |
784 | 602 |
785 Serializer::Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBuff
erArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHa
ndles, v8::TryCatch& tryCatch, ScriptState* scriptState) | 603 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer
, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArr
ay* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, Script
State* scriptState) |
786 : m_scriptState(scriptState) | 604 : m_scriptState(scriptState) |
787 , m_writer(writer) | 605 , m_writer(writer) |
788 , m_tryCatch(tryCatch) | 606 , m_tryCatch(tryCatch) |
789 , m_depth(0) | 607 , m_depth(0) |
790 , m_status(Success) | 608 , m_status(Success) |
791 , m_nextObjectReference(0) | 609 , m_nextObjectReference(0) |
792 , m_blobInfo(blobInfo) | 610 , m_blobInfo(blobInfo) |
793 , m_blobDataHandles(blobDataHandles) | 611 , m_blobDataHandles(blobDataHandles) |
794 { | 612 { |
795 ASSERT(!tryCatch.HasCaught()); | 613 ASSERT(!tryCatch.HasCaught()); |
796 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); | 614 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); |
797 if (messagePorts) { | 615 if (messagePorts) { |
798 for (size_t i = 0; i < messagePorts->size(); i++) | 616 for (size_t i = 0; i < messagePorts->size(); i++) |
799 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); | 617 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); |
800 } | 618 } |
801 if (arrayBuffers) { | 619 if (arrayBuffers) { |
802 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 620 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
803 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i
).get(), creationContext, isolate()); | 621 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i
).get(), creationContext, isolate()); |
804 // Coalesce multiple occurences of the same buffer to the first inde
x. | 622 // Coalesce multiple occurences of the same buffer to the first inde
x. |
805 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) | 623 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) |
806 m_transferredArrayBuffers.set(v8ArrayBuffer, i); | 624 m_transferredArrayBuffers.set(v8ArrayBuffer, i); |
807 } | 625 } |
808 } | 626 } |
809 } | 627 } |
810 | 628 |
811 Serializer::Status Serializer::serialize(v8::Handle<v8::Value> value) | 629 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Handle<v8::Va
lue> value) |
812 { | 630 { |
813 v8::HandleScope scope(isolate()); | 631 v8::HandleScope scope(isolate()); |
814 m_writer.writeVersion(); | 632 m_writer.writeVersion(); |
815 StateBase* state = doSerialize(value, 0); | 633 StateBase* state = doSerialize(value, 0); |
816 while (state) | 634 while (state) |
817 state = state->advance(*this); | 635 state = state->advance(*this); |
818 return m_status; | 636 return m_status; |
819 } | 637 } |
820 | 638 |
821 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Seri
alizer::StateBase* next) | 639 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerialize(v8::Handle<
v8::Value> value, ScriptValueSerializer::StateBase* next) |
822 { | 640 { |
823 m_writer.writeReferenceCount(m_nextObjectReference); | 641 m_writer.writeReferenceCount(m_nextObjectReference); |
824 uint32_t objectReference; | 642 uint32_t objectReference; |
825 uint32_t arrayBufferIndex; | |
826 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) | 643 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) |
827 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { | 644 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { |
828 // Note that IsObject() also detects wrappers (eg, it will catch the thi
ngs | 645 // Note that IsObject() also detects wrappers (eg, it will catch the thi
ngs |
829 // that we grey and write below). | 646 // that we grey and write below). |
830 ASSERT(!value->IsString()); | 647 ASSERT(!value->IsString()); |
831 m_writer.writeObjectReference(objectReference); | 648 m_writer.writeObjectReference(objectReference); |
832 } else if (value.IsEmpty()) { | 649 } else { |
| 650 return doSerializeValue(value, next); |
| 651 } |
| 652 return 0; |
| 653 } |
| 654 |
| 655 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeValue(v8::Ha
ndle<v8::Value> value, ScriptValueSerializer::StateBase* next) |
| 656 { |
| 657 uint32_t arrayBufferIndex; |
| 658 if (value.IsEmpty()) |
833 return handleError(InputError, "The empty property name cannot be cloned
.", next); | 659 return handleError(InputError, "The empty property name cannot be cloned
.", next); |
834 } else if (value->IsUndefined()) { | 660 if (value->IsUndefined()) { |
835 m_writer.writeUndefined(); | 661 m_writer.writeUndefined(); |
836 } else if (value->IsNull()) { | 662 } else if (value->IsNull()) { |
837 m_writer.writeNull(); | 663 m_writer.writeNull(); |
838 } else if (value->IsTrue()) { | 664 } else if (value->IsTrue()) { |
839 m_writer.writeTrue(); | 665 m_writer.writeTrue(); |
840 } else if (value->IsFalse()) { | 666 } else if (value->IsFalse()) { |
841 m_writer.writeFalse(); | 667 m_writer.writeFalse(); |
842 } else if (value->IsInt32()) { | 668 } else if (value->IsInt32()) { |
843 m_writer.writeInt32(value->Int32Value()); | 669 m_writer.writeInt32(value->Int32Value()); |
844 } else if (value->IsUint32()) { | 670 } else if (value->IsUint32()) { |
(...skipping 25 matching lines...) Expand all Loading... |
870 } else if (value->IsNumberObject()) { | 696 } else if (value->IsNumberObject()) { |
871 writeNumberObject(value); | 697 writeNumberObject(value); |
872 } else if (value->IsBooleanObject()) { | 698 } else if (value->IsBooleanObject()) { |
873 writeBooleanObject(value); | 699 writeBooleanObject(value); |
874 } else if (value->IsArray()) { | 700 } else if (value->IsArray()) { |
875 return startArrayState(value.As<v8::Array>(), next); | 701 return startArrayState(value.As<v8::Array>(), next); |
876 } else if (V8File::hasInstance(value, isolate())) { | 702 } else if (V8File::hasInstance(value, isolate())) { |
877 return writeFile(value, next); | 703 return writeFile(value, next); |
878 } else if (V8Blob::hasInstance(value, isolate())) { | 704 } else if (V8Blob::hasInstance(value, isolate())) { |
879 return writeBlob(value, next); | 705 return writeBlob(value, next); |
880 } else if (V8DOMFileSystem::hasInstance(value, isolate())) { | |
881 return writeDOMFileSystem(value, next); | |
882 } else if (V8FileList::hasInstance(value, isolate())) { | 706 } else if (V8FileList::hasInstance(value, isolate())) { |
883 return writeFileList(value, next); | 707 return writeFileList(value, next); |
884 } else if (V8CryptoKey::hasInstance(value, isolate())) { | |
885 if (!writeCryptoKey(value)) | |
886 return handleError(DataCloneError, "Couldn't serialize key data"
, next); | |
887 } else if (V8ImageData::hasInstance(value, isolate())) { | 708 } else if (V8ImageData::hasInstance(value, isolate())) { |
888 writeImageData(value); | 709 writeImageData(value); |
889 } else if (value->IsRegExp()) { | 710 } else if (value->IsRegExp()) { |
890 writeRegExp(value); | 711 writeRegExp(value); |
891 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { | 712 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { |
892 return writeArrayBuffer(value, next); | 713 return writeArrayBuffer(value, next); |
893 } else if (value->IsObject()) { | 714 } else if (value->IsObject()) { |
894 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat
iveError()) | 715 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat
iveError()) |
895 return handleError(DataCloneError, "An object could not be clone
d.", next); | 716 return handleError(DataCloneError, "An object could not be clone
d.", next); |
896 return startObjectState(jsObject, next); | 717 return startObjectState(jsObject, next); |
897 } else { | 718 } else { |
898 return handleError(DataCloneError, "A value could not be cloned.", n
ext); | 719 return handleError(DataCloneError, "A value could not be cloned.", n
ext); |
899 } | 720 } |
900 } | 721 } |
901 return 0; | 722 return 0; |
902 } | 723 } |
903 | 724 |
904 Serializer::StateBase* Serializer::doSerializeArrayBuffer(v8::Handle<v8::Value>
arrayBuffer, Serializer::StateBase* next) | 725 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer(
v8::Handle<v8::Value> arrayBuffer, ScriptValueSerializer::StateBase* next) |
905 { | 726 { |
906 return doSerialize(arrayBuffer, next); | 727 return doSerialize(arrayBuffer, next); |
907 } | 728 } |
908 | 729 |
909 Serializer::StateBase* Serializer::checkException(Serializer::StateBase* state) | 730 ScriptValueSerializer::StateBase* ScriptValueSerializer::checkException(ScriptVa
lueSerializer::StateBase* state) |
910 { | 731 { |
911 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0; | 732 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0; |
912 } | 733 } |
913 | 734 |
914 Serializer::StateBase* Serializer::writeObject(uint32_t numProperties, Serialize
r::StateBase* state) | 735 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeObject(uint32_t nu
mProperties, ScriptValueSerializer::StateBase* state) |
915 { | 736 { |
916 m_writer.writeObject(numProperties); | 737 m_writer.writeObject(numProperties); |
917 return pop(state); | 738 return pop(state); |
918 } | 739 } |
919 | 740 |
920 Serializer::StateBase* Serializer::writeSparseArray(uint32_t numProperties, uint
32_t length, Serializer::StateBase* state) | 741 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSparseArray(uint32
_t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) |
921 { | 742 { |
922 m_writer.writeSparseArray(numProperties, length); | 743 m_writer.writeSparseArray(numProperties, length); |
923 return pop(state); | 744 return pop(state); |
924 } | 745 } |
925 | 746 |
926 Serializer::StateBase* Serializer::writeDenseArray(uint32_t numProperties, uint3
2_t length, Serializer::StateBase* state) | 747 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_
t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) |
927 { | 748 { |
928 m_writer.writeDenseArray(numProperties, length); | 749 m_writer.writeDenseArray(numProperties, length); |
929 return pop(state); | 750 return pop(state); |
930 } | 751 } |
931 | 752 |
932 Serializer::StateBase* Serializer::handleError(Serializer::Status errorStatus, c
onst String& message, Serializer::StateBase* state) | 753 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue
Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St
ateBase* state) |
933 { | 754 { |
934 ASSERT(errorStatus != Success); | 755 ASSERT(errorStatus != Success); |
935 m_status = errorStatus; | 756 m_status = errorStatus; |
936 m_errorMessage = message; | 757 m_errorMessage = message; |
937 while (state) { | 758 while (state) { |
938 StateBase* tmp = state->nextState(); | 759 StateBase* tmp = state->nextState(); |
939 delete state; | 760 delete state; |
940 state = tmp; | 761 state = tmp; |
941 } | 762 } |
942 return new ErrorState; | 763 return new ErrorState; |
943 } | 764 } |
944 | 765 |
945 bool Serializer::checkComposite(Serializer::StateBase* top) | 766 bool ScriptValueSerializer::checkComposite(ScriptValueSerializer::StateBase* top
) |
946 { | 767 { |
947 ASSERT(top); | 768 ASSERT(top); |
948 if (m_depth > maxDepth) | 769 if (m_depth > maxDepth) |
949 return false; | 770 return false; |
950 if (!shouldCheckForCycles(m_depth)) | 771 if (!shouldCheckForCycles(m_depth)) |
951 return true; | 772 return true; |
952 v8::Handle<v8::Value> composite = top->composite(); | 773 v8::Handle<v8::Value> composite = top->composite(); |
953 for (StateBase* state = top->nextState(); state; state = state->nextState())
{ | 774 for (StateBase* state = top->nextState(); state; state = state->nextState())
{ |
954 if (state->composite() == composite) | 775 if (state->composite() == composite) |
955 return false; | 776 return false; |
956 } | 777 } |
957 return true; | 778 return true; |
958 } | 779 } |
959 | 780 |
960 void Serializer::writeString(v8::Handle<v8::Value> value) | 781 void ScriptValueSerializer::writeString(v8::Handle<v8::Value> value) |
961 { | 782 { |
962 v8::Handle<v8::String> string = value.As<v8::String>(); | 783 v8::Handle<v8::String> string = value.As<v8::String>(); |
963 if (!string->Length() || string->IsOneByte()) | 784 if (!string->Length() || string->IsOneByte()) |
964 m_writer.writeOneByteString(string); | 785 m_writer.writeOneByteString(string); |
965 else | 786 else |
966 m_writer.writeUCharString(string); | 787 m_writer.writeUCharString(string); |
967 } | 788 } |
968 | 789 |
969 void Serializer::writeStringObject(v8::Handle<v8::Value> value) | 790 void ScriptValueSerializer::writeStringObject(v8::Handle<v8::Value> value) |
970 { | 791 { |
971 v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>(); | 792 v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>(); |
972 v8::String::Utf8Value stringValue(stringObject->ValueOf()); | 793 v8::String::Utf8Value stringValue(stringObject->ValueOf()); |
973 m_writer.writeStringObject(*stringValue, stringValue.length()); | 794 m_writer.writeStringObject(*stringValue, stringValue.length()); |
974 } | 795 } |
975 | 796 |
976 void Serializer::writeNumberObject(v8::Handle<v8::Value> value) | 797 void ScriptValueSerializer::writeNumberObject(v8::Handle<v8::Value> value) |
977 { | 798 { |
978 v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); | 799 v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); |
979 m_writer.writeNumberObject(numberObject->ValueOf()); | 800 m_writer.writeNumberObject(numberObject->ValueOf()); |
980 } | 801 } |
981 | 802 |
982 void Serializer::writeBooleanObject(v8::Handle<v8::Value> value) | 803 void ScriptValueSerializer::writeBooleanObject(v8::Handle<v8::Value> value) |
983 { | 804 { |
984 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); | 805 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); |
985 m_writer.writeBooleanObject(booleanObject->ValueOf()); | 806 m_writer.writeBooleanObject(booleanObject->ValueOf()); |
986 } | 807 } |
987 | 808 |
988 Serializer::StateBase* Serializer::writeBlob(v8::Handle<v8::Value> value, Serial
izer::StateBase* next) | 809 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeBlob(v8::Handle<v8
::Value> value, ScriptValueSerializer::StateBase* next) |
989 { | 810 { |
990 Blob* blob = V8Blob::toImpl(value.As<v8::Object>()); | 811 Blob* blob = V8Blob::toImpl(value.As<v8::Object>()); |
991 if (!blob) | 812 if (!blob) |
992 return 0; | 813 return 0; |
993 if (blob->hasBeenClosed()) | 814 if (blob->hasBeenClosed()) |
994 return handleError(DataCloneError, "A Blob object has been closed, and c
ould therefore not be cloned.", next); | 815 return handleError(DataCloneError, "A Blob object has been closed, and c
ould therefore not be cloned.", next); |
995 int blobIndex = -1; | 816 int blobIndex = -1; |
996 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); | 817 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); |
997 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) | 818 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) |
998 m_writer.writeBlobIndex(blobIndex); | 819 m_writer.writeBlobIndex(blobIndex); |
999 else | 820 else |
1000 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); | 821 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); |
1001 return 0; | 822 return 0; |
1002 } | 823 } |
1003 | 824 |
1004 Serializer::StateBase* Serializer::writeDOMFileSystem(v8::Handle<v8::Value> valu
e, StateBase* next) | 825 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFile(v8::Handle<v8
::Value> value, ScriptValueSerializer::StateBase* next) |
1005 { | |
1006 DOMFileSystem* fs = V8DOMFileSystem::toImpl(value.As<v8::Object>()); | |
1007 if (!fs) | |
1008 return 0; | |
1009 if (!fs->clonable()) | |
1010 return handleError(DataCloneError, "A FileSystem object could not be clo
ned.", next); | |
1011 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string()); | |
1012 return 0; | |
1013 } | |
1014 | |
1015 Serializer::StateBase* Serializer::writeFile(v8::Handle<v8::Value> value, Serial
izer::StateBase* next) | |
1016 { | 826 { |
1017 File* file = V8File::toImpl(value.As<v8::Object>()); | 827 File* file = V8File::toImpl(value.As<v8::Object>()); |
1018 if (!file) | 828 if (!file) |
1019 return 0; | 829 return 0; |
1020 if (file->hasBeenClosed()) | 830 if (file->hasBeenClosed()) |
1021 return handleError(DataCloneError, "A File object has been closed, and c
ould therefore not be cloned.", next); | 831 return handleError(DataCloneError, "A File object has been closed, and c
ould therefore not be cloned.", next); |
1022 int blobIndex = -1; | 832 int blobIndex = -1; |
1023 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); | 833 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); |
1024 if (appendFileInfo(file, &blobIndex)) { | 834 if (appendFileInfo(file, &blobIndex)) { |
1025 ASSERT(blobIndex >= 0); | 835 ASSERT(blobIndex >= 0); |
1026 m_writer.writeFileIndex(blobIndex); | 836 m_writer.writeFileIndex(blobIndex); |
1027 } else { | 837 } else { |
1028 m_writer.writeFile(*file); | 838 m_writer.writeFile(*file); |
1029 } | 839 } |
1030 return 0; | 840 return 0; |
1031 } | 841 } |
1032 | 842 |
1033 Serializer::StateBase* Serializer::writeFileList(v8::Handle<v8::Value> value, Se
rializer::StateBase* next) | 843 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFileList(v8::Handl
e<v8::Value> value, ScriptValueSerializer::StateBase* next) |
1034 { | 844 { |
1035 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>()); | 845 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>()); |
1036 if (!fileList) | 846 if (!fileList) |
1037 return 0; | 847 return 0; |
1038 unsigned length = fileList->length(); | 848 unsigned length = fileList->length(); |
1039 Vector<int> blobIndices; | 849 Vector<int> blobIndices; |
1040 for (unsigned i = 0; i < length; ++i) { | 850 for (unsigned i = 0; i < length; ++i) { |
1041 int blobIndex = -1; | 851 int blobIndex = -1; |
1042 const File* file = fileList->item(i); | 852 const File* file = fileList->item(i); |
1043 if (file->hasBeenClosed()) | 853 if (file->hasBeenClosed()) |
1044 return handleError(DataCloneError, "A File object has been closed, a
nd could therefore not be cloned.", next); | 854 return handleError(DataCloneError, "A File object has been closed, a
nd could therefore not be cloned.", next); |
1045 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); | 855 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); |
1046 if (appendFileInfo(file, &blobIndex)) { | 856 if (appendFileInfo(file, &blobIndex)) { |
1047 ASSERT(!i || blobIndex > 0); | 857 ASSERT(!i || blobIndex > 0); |
1048 ASSERT(blobIndex >= 0); | 858 ASSERT(blobIndex >= 0); |
1049 blobIndices.append(blobIndex); | 859 blobIndices.append(blobIndex); |
1050 } | 860 } |
1051 } | 861 } |
1052 if (!blobIndices.isEmpty()) | 862 if (!blobIndices.isEmpty()) |
1053 m_writer.writeFileListIndex(blobIndices); | 863 m_writer.writeFileListIndex(blobIndices); |
1054 else | 864 else |
1055 m_writer.writeFileList(*fileList); | 865 m_writer.writeFileList(*fileList); |
1056 return 0; | 866 return 0; |
1057 } | 867 } |
1058 | 868 |
1059 bool Serializer::writeCryptoKey(v8::Handle<v8::Value> value) | 869 void ScriptValueSerializer::writeImageData(v8::Handle<v8::Value> value) |
1060 { | |
1061 CryptoKey* key = V8CryptoKey::toImpl(value.As<v8::Object>()); | |
1062 if (!key) | |
1063 return false; | |
1064 return m_writer.writeCryptoKey(key->key()); | |
1065 } | |
1066 | |
1067 void Serializer::writeImageData(v8::Handle<v8::Value> value) | |
1068 { | 870 { |
1069 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); | 871 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); |
1070 if (!imageData) | 872 if (!imageData) |
1071 return; | 873 return; |
1072 Uint8ClampedArray* pixelArray = imageData->data(); | 874 Uint8ClampedArray* pixelArray = imageData->data(); |
1073 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray-
>data(), pixelArray->length()); | 875 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray-
>data(), pixelArray->length()); |
1074 } | 876 } |
1075 | 877 |
1076 void Serializer::writeRegExp(v8::Handle<v8::Value> value) | 878 void ScriptValueSerializer::writeRegExp(v8::Handle<v8::Value> value) |
1077 { | 879 { |
1078 v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); | 880 v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); |
1079 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); | 881 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); |
1080 } | 882 } |
1081 | 883 |
1082 Serializer::StateBase* Serializer::writeAndGreyArrayBufferView(v8::Handle<v8::Ob
ject> object, Serializer::StateBase* next) | 884 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer
View(v8::Handle<v8::Object> object, ScriptValueSerializer::StateBase* next) |
1083 { | 885 { |
1084 ASSERT(!object.IsEmpty()); | 886 ASSERT(!object.IsEmpty()); |
1085 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); | 887 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); |
1086 if (!arrayBufferView) | 888 if (!arrayBufferView) |
1087 return 0; | 889 return 0; |
1088 if (!arrayBufferView->buffer()) | 890 if (!arrayBufferView->buffer()) |
1089 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); | 891 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); |
1090 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_s
criptState->context()->Global(), isolate()); | 892 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_s
criptState->context()->Global(), isolate()); |
1091 if (underlyingBuffer.IsEmpty()) | 893 if (underlyingBuffer.IsEmpty()) |
1092 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); | 894 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); |
1093 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); | 895 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); |
1094 if (stateOut) | 896 if (stateOut) |
1095 return stateOut; | 897 return stateOut; |
1096 m_writer.writeArrayBufferView(*arrayBufferView); | 898 m_writer.writeArrayBufferView(*arrayBufferView); |
1097 // This should be safe: we serialize something that we know to be a wrapper
(see | 899 // This should be safe: we serialize something that we know to be a wrapper
(see |
1098 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe
r | 900 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe
r |
1099 // cause the system stack to overflow nor should it have potential to reach | 901 // cause the system stack to overflow nor should it have potential to reach |
1100 // this ArrayBufferView again. | 902 // this ArrayBufferView again. |
1101 // | 903 // |
1102 // We do need to grey the underlying buffer before we grey its view, however
; | 904 // We do need to grey the underlying buffer before we grey its view, however
; |
1103 // ArrayBuffers may be shared, so they need to be given reference IDs, and a
n | 905 // ArrayBuffers may be shared, so they need to be given reference IDs, and a
n |
1104 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer | 906 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer |
1105 // (or without an additional tag that would allow us to do two-stage constru
ction | 907 // (or without an additional tag that would allow us to do two-stage constru
ction |
1106 // like we do for Objects and Arrays). | 908 // like we do for Objects and Arrays). |
1107 greyObject(object); | 909 greyObject(object); |
1108 return 0; | 910 return 0; |
1109 } | 911 } |
1110 | 912 |
1111 Serializer::StateBase* Serializer::writeArrayBuffer(v8::Handle<v8::Value> value,
Serializer::StateBase* next) | 913 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeArrayBuffer(v8::Ha
ndle<v8::Value> value, ScriptValueSerializer::StateBase* next) |
1112 { | 914 { |
1113 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 915 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
1114 if (!arrayBuffer) | 916 if (!arrayBuffer) |
1115 return 0; | 917 return 0; |
1116 if (arrayBuffer->isNeutered()) | 918 if (arrayBuffer->isNeutered()) |
1117 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); | 919 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); |
1118 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); | 920 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); |
1119 m_writer.writeArrayBuffer(*arrayBuffer); | 921 m_writer.writeArrayBuffer(*arrayBuffer); |
1120 return 0; | 922 return 0; |
1121 } | 923 } |
1122 | 924 |
1123 Serializer::StateBase* Serializer::writeTransferredArrayBuffer(v8::Handle<v8::Va
lue> value, uint32_t index, Serializer::StateBase* next) | 925 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredArrayBu
ffer(v8::Handle<v8::Value> value, uint32_t index, ScriptValueSerializer::StateBa
se* next) |
1124 { | 926 { |
1125 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 927 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
1126 if (!arrayBuffer) | 928 if (!arrayBuffer) |
1127 return 0; | 929 return 0; |
1128 if (arrayBuffer->isNeutered()) | 930 if (arrayBuffer->isNeutered()) |
1129 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); | 931 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); |
1130 m_writer.writeTransferredArrayBuffer(index); | 932 m_writer.writeTransferredArrayBuffer(index); |
1131 return 0; | 933 return 0; |
1132 } | 934 } |
1133 | 935 |
1134 bool Serializer::shouldSerializeDensely(uint32_t length, uint32_t propertyCount) | 936 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro
pertyCount) |
1135 { | 937 { |
1136 // Let K be the cost of serializing all property values that are there | 938 // Let K be the cost of serializing all property values that are there |
1137 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k
ey) | 939 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k
ey) |
1138 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a
ll properties that are not there) | 940 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a
ll properties that are not there) |
1139 // so densely is better than sparsly whenever 6*propertyCount > length | 941 // so densely is better than sparsly whenever 6*propertyCount > length |
1140 return 6 * propertyCount >= length; | 942 return 6 * propertyCount >= length; |
1141 } | 943 } |
1142 | 944 |
1143 Serializer::StateBase* Serializer::startArrayState(v8::Handle<v8::Array> array,
Serializer::StateBase* next) | 945 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Han
dle<v8::Array> array, ScriptValueSerializer::StateBase* next) |
1144 { | 946 { |
1145 v8::Handle<v8::Array> propertyNames = array->GetPropertyNames(); | 947 v8::Handle<v8::Array> propertyNames = array->GetPropertyNames(); |
1146 if (StateBase* newState = checkException(next)) | 948 if (StateBase* newState = checkException(next)) |
1147 return newState; | 949 return newState; |
1148 uint32_t length = array->Length(); | 950 uint32_t length = array->Length(); |
1149 | 951 |
1150 if (shouldSerializeDensely(length, propertyNames->Length())) { | 952 if (shouldSerializeDensely(length, propertyNames->Length())) { |
1151 m_writer.writeGenerateFreshDenseArray(length); | 953 m_writer.writeGenerateFreshDenseArray(length); |
1152 return push(new DenseArrayState(array, propertyNames, next, isolate())); | 954 return push(new DenseArrayState(array, propertyNames, next, isolate())); |
1153 } | 955 } |
1154 | 956 |
1155 m_writer.writeGenerateFreshSparseArray(length); | 957 m_writer.writeGenerateFreshSparseArray(length); |
1156 return push(new SparseArrayState(array, propertyNames, next, isolate())); | 958 return push(new SparseArrayState(array, propertyNames, next, isolate())); |
1157 } | 959 } |
1158 | 960 |
1159 Serializer::StateBase* Serializer::startObjectState(v8::Handle<v8::Object> objec
t, Serializer::StateBase* next) | 961 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Ha
ndle<v8::Object> object, ScriptValueSerializer::StateBase* next) |
1160 { | 962 { |
1161 m_writer.writeGenerateFreshObject(); | 963 m_writer.writeGenerateFreshObject(); |
1162 // FIXME: check not a wrapper | 964 // FIXME: check not a wrapper |
1163 return push(new ObjectState(object, next)); | 965 return push(new ObjectState(object, next)); |
1164 } | 966 } |
1165 | 967 |
1166 // Marks object as having been visited by the serializer and assigns it a unique
object reference ID. | 968 // Marks object as having been visited by the serializer and assigns it a unique
object reference ID. |
1167 // An object may only be greyed once. | 969 // An object may only be greyed once. |
1168 void Serializer::greyObject(const v8::Handle<v8::Object>& object) | 970 void ScriptValueSerializer::greyObject(const v8::Handle<v8::Object>& object) |
1169 { | 971 { |
1170 ASSERT(!m_objectPool.contains(object)); | 972 ASSERT(!m_objectPool.contains(object)); |
1171 uint32_t objectReference = m_nextObjectReference++; | 973 uint32_t objectReference = m_nextObjectReference++; |
1172 m_objectPool.set(object, objectReference); | 974 m_objectPool.set(object, objectReference); |
1173 } | 975 } |
1174 | 976 |
1175 bool Serializer::appendBlobInfo(const String& uuid, const String& type, unsigned
long long size, int* index) | 977 bool ScriptValueSerializer::appendBlobInfo(const String& uuid, const String& typ
e, unsigned long long size, int* index) |
1176 { | 978 { |
1177 if (!m_blobInfo) | 979 if (!m_blobInfo) |
1178 return false; | 980 return false; |
1179 *index = m_blobInfo->size(); | 981 *index = m_blobInfo->size(); |
1180 m_blobInfo->append(WebBlobInfo(uuid, type, size)); | 982 m_blobInfo->append(WebBlobInfo(uuid, type, size)); |
1181 return true; | 983 return true; |
1182 } | 984 } |
1183 | 985 |
1184 bool Serializer::appendFileInfo(const File* file, int* index) | 986 bool ScriptValueSerializer::appendFileInfo(const File* file, int* index) |
1185 { | 987 { |
1186 if (!m_blobInfo) | 988 if (!m_blobInfo) |
1187 return false; | 989 return false; |
1188 | 990 |
1189 long long size = -1; | 991 long long size = -1; |
1190 double lastModified = invalidFileTime(); | 992 double lastModified = invalidFileTime(); |
1191 file->captureSnapshot(size, lastModified); | 993 file->captureSnapshot(size, lastModified); |
1192 *index = m_blobInfo->size(); | 994 *index = m_blobInfo->size(); |
1193 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil
e->type(), lastModified, size)); | 995 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil
e->type(), lastModified, size)); |
1194 return true; | 996 return true; |
1195 } | 997 } |
1196 | 998 |
1197 bool Reader::read(v8::Handle<v8::Value>* value, CompositeCreator& creator) | 999 bool SerializedScriptValueReader::read(v8::Handle<v8::Value>* value, ScriptValue
CompositeCreator& creator) |
1198 { | 1000 { |
1199 SerializationTag tag; | 1001 SerializationTag tag; |
1200 if (!readTag(&tag)) | 1002 if (!readTag(&tag)) |
1201 return false; | 1003 return false; |
| 1004 return readWithTag(tag, value, creator); |
| 1005 } |
| 1006 |
| 1007 bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Handle<v
8::Value>* value, ScriptValueCompositeCreator& creator) |
| 1008 { |
1202 switch (tag) { | 1009 switch (tag) { |
1203 case ReferenceCountTag: { | 1010 case ReferenceCountTag: { |
1204 if (!m_version) | 1011 if (!m_version) |
1205 return false; | 1012 return false; |
1206 uint32_t referenceTableSize; | 1013 uint32_t referenceTableSize; |
1207 if (!doReadUint32(&referenceTableSize)) | 1014 if (!doReadUint32(&referenceTableSize)) |
1208 return false; | 1015 return false; |
1209 // If this test fails, then the serializer and deserializer disagree abo
ut the assignment | 1016 // If this test fails, then the serializer and deserializer disagree abo
ut the assignment |
1210 // of object reference IDs. On the deserialization side, this means ther
e are too many or too few | 1017 // of object reference IDs. On the deserialization side, this means ther
e are too many or too few |
1211 // calls to pushObjectReference. | 1018 // calls to pushObjectReference. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 if (!readBlob(value, tag == BlobIndexTag)) | 1084 if (!readBlob(value, tag == BlobIndexTag)) |
1278 return false; | 1085 return false; |
1279 creator.pushObjectReference(*value); | 1086 creator.pushObjectReference(*value); |
1280 break; | 1087 break; |
1281 case FileTag: | 1088 case FileTag: |
1282 case FileIndexTag: | 1089 case FileIndexTag: |
1283 if (!readFile(value, tag == FileIndexTag)) | 1090 if (!readFile(value, tag == FileIndexTag)) |
1284 return false; | 1091 return false; |
1285 creator.pushObjectReference(*value); | 1092 creator.pushObjectReference(*value); |
1286 break; | 1093 break; |
1287 case DOMFileSystemTag: | |
1288 if (!readDOMFileSystem(value)) | |
1289 return false; | |
1290 creator.pushObjectReference(*value); | |
1291 break; | |
1292 case FileListTag: | 1094 case FileListTag: |
1293 case FileListIndexTag: | 1095 case FileListIndexTag: |
1294 if (!readFileList(value, tag == FileListIndexTag)) | 1096 if (!readFileList(value, tag == FileListIndexTag)) |
1295 return false; | 1097 return false; |
1296 creator.pushObjectReference(*value); | 1098 creator.pushObjectReference(*value); |
1297 break; | 1099 break; |
1298 case CryptoKeyTag: | |
1299 if (!readCryptoKey(value)) | |
1300 return false; | |
1301 creator.pushObjectReference(*value); | |
1302 break; | |
1303 case ImageDataTag: | 1100 case ImageDataTag: |
1304 if (!readImageData(value)) | 1101 if (!readImageData(value)) |
1305 return false; | 1102 return false; |
1306 creator.pushObjectReference(*value); | 1103 creator.pushObjectReference(*value); |
1307 break; | 1104 break; |
1308 | 1105 |
1309 case RegExpTag: | 1106 case RegExpTag: |
1310 if (!readRegExp(value)) | 1107 if (!readRegExp(value)) |
1311 return false; | 1108 return false; |
1312 creator.pushObjectReference(*value); | 1109 creator.pushObjectReference(*value); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 case ObjectReferenceTag: { | 1204 case ObjectReferenceTag: { |
1408 if (!m_version) | 1205 if (!m_version) |
1409 return false; | 1206 return false; |
1410 uint32_t reference; | 1207 uint32_t reference; |
1411 if (!doReadUint32(&reference)) | 1208 if (!doReadUint32(&reference)) |
1412 return false; | 1209 return false; |
1413 if (!creator.tryGetObjectFromObjectReference(reference, value)) | 1210 if (!creator.tryGetObjectFromObjectReference(reference, value)) |
1414 return false; | 1211 return false; |
1415 break; | 1212 break; |
1416 } | 1213 } |
| 1214 case DOMFileSystemTag: |
| 1215 case CryptoKeyTag: |
| 1216 ASSERT_NOT_REACHED(); |
1417 default: | 1217 default: |
1418 return false; | 1218 return false; |
1419 } | 1219 } |
1420 return !value->IsEmpty(); | 1220 return !value->IsEmpty(); |
1421 } | 1221 } |
1422 | 1222 |
1423 bool Reader::readVersion(uint32_t& version) | 1223 bool SerializedScriptValueReader::readVersion(uint32_t& version) |
1424 { | 1224 { |
1425 SerializationTag tag; | 1225 SerializationTag tag; |
1426 if (!readTag(&tag)) { | 1226 if (!readTag(&tag)) { |
1427 // This is a nullary buffer. We're still version 0. | 1227 // This is a nullary buffer. We're still version 0. |
1428 version = 0; | 1228 version = 0; |
1429 return true; | 1229 return true; |
1430 } | 1230 } |
1431 if (tag != VersionTag) { | 1231 if (tag != VersionTag) { |
1432 // Versions of the format past 0 start with the version tag. | 1232 // Versions of the format past 0 start with the version tag. |
1433 version = 0; | 1233 version = 0; |
1434 // Put back the tag. | 1234 // Put back the tag. |
1435 undoReadTag(); | 1235 undoReadTag(); |
1436 return true; | 1236 return true; |
1437 } | 1237 } |
1438 // Version-bearing messages are obligated to finish the version tag. | 1238 // Version-bearing messages are obligated to finish the version tag. |
1439 return doReadUint32(&version); | 1239 return doReadUint32(&version); |
1440 } | 1240 } |
1441 | 1241 |
1442 void Reader::setVersion(uint32_t version) | 1242 void SerializedScriptValueReader::setVersion(uint32_t version) |
1443 { | 1243 { |
1444 m_version = version; | 1244 m_version = version; |
1445 } | 1245 } |
1446 | 1246 |
1447 bool Reader::readTag(SerializationTag* tag) | 1247 bool SerializedScriptValueReader::readTag(SerializationTag* tag) |
1448 { | 1248 { |
1449 if (m_position >= m_length) | 1249 if (m_position >= m_length) |
1450 return false; | 1250 return false; |
1451 *tag = static_cast<SerializationTag>(m_buffer[m_position++]); | 1251 *tag = static_cast<SerializationTag>(m_buffer[m_position++]); |
1452 return true; | 1252 return true; |
1453 } | 1253 } |
1454 | 1254 |
1455 void Reader::undoReadTag() | 1255 void SerializedScriptValueReader::undoReadTag() |
1456 { | 1256 { |
1457 if (m_position > 0) | 1257 if (m_position > 0) |
1458 --m_position; | 1258 --m_position; |
1459 } | 1259 } |
1460 | 1260 |
1461 bool Reader::readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag) | 1261 bool SerializedScriptValueReader::readArrayBufferViewSubTag(ArrayBufferViewSubTa
g* tag) |
1462 { | 1262 { |
1463 if (m_position >= m_length) | 1263 if (m_position >= m_length) |
1464 return false; | 1264 return false; |
1465 *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]); | 1265 *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]); |
1466 return true; | 1266 return true; |
1467 } | 1267 } |
1468 | 1268 |
1469 bool Reader::readString(v8::Handle<v8::Value>* value) | 1269 bool SerializedScriptValueReader::readString(v8::Handle<v8::Value>* value) |
1470 { | 1270 { |
1471 uint32_t length; | 1271 uint32_t length; |
1472 if (!doReadUint32(&length)) | 1272 if (!doReadUint32(&length)) |
1473 return false; | 1273 return false; |
1474 if (m_position + length > m_length) | 1274 if (m_position + length > m_length) |
1475 return false; | 1275 return false; |
1476 *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_
buffer + m_position), v8::String::kNormalString, length); | 1276 *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_
buffer + m_position), v8::String::kNormalString, length); |
1477 m_position += length; | 1277 m_position += length; |
1478 return true; | 1278 return true; |
1479 } | 1279 } |
1480 | 1280 |
1481 bool Reader::readUCharString(v8::Handle<v8::Value>* value) | 1281 bool SerializedScriptValueReader::readUCharString(v8::Handle<v8::Value>* value) |
1482 { | 1282 { |
1483 uint32_t length; | 1283 uint32_t length; |
1484 if (!doReadUint32(&length) || (length & 1)) | 1284 if (!doReadUint32(&length) || (length & 1)) |
1485 return false; | 1285 return false; |
1486 if (m_position + length > m_length) | 1286 if (m_position + length > m_length) |
1487 return false; | 1287 return false; |
1488 ASSERT(!(m_position & 1)); | 1288 ASSERT(!(m_position & 1)); |
1489 *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16
_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar)); | 1289 *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16
_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar)); |
1490 m_position += length; | 1290 m_position += length; |
1491 return true; | 1291 return true; |
1492 } | 1292 } |
1493 | 1293 |
1494 bool Reader::readStringObject(v8::Handle<v8::Value>* value) | 1294 bool SerializedScriptValueReader::readStringObject(v8::Handle<v8::Value>* value) |
1495 { | 1295 { |
1496 v8::Handle<v8::Value> stringValue; | 1296 v8::Handle<v8::Value> stringValue; |
1497 if (!readString(&stringValue) || !stringValue->IsString()) | 1297 if (!readString(&stringValue) || !stringValue->IsString()) |
1498 return false; | 1298 return false; |
1499 *value = v8::StringObject::New(stringValue.As<v8::String>()); | 1299 *value = v8::StringObject::New(stringValue.As<v8::String>()); |
1500 return true; | 1300 return true; |
1501 } | 1301 } |
1502 | 1302 |
1503 bool Reader::readWebCoreString(String* string) | 1303 bool SerializedScriptValueReader::readWebCoreString(String* string) |
1504 { | 1304 { |
1505 uint32_t length; | 1305 uint32_t length; |
1506 if (!doReadUint32(&length)) | 1306 if (!doReadUint32(&length)) |
1507 return false; | 1307 return false; |
1508 if (m_position + length > m_length) | 1308 if (m_position + length > m_length) |
1509 return false; | 1309 return false; |
1510 *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_positi
on), length); | 1310 *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_positi
on), length); |
1511 m_position += length; | 1311 m_position += length; |
1512 return true; | 1312 return true; |
1513 } | 1313 } |
1514 | 1314 |
1515 bool Reader::readInt32(v8::Handle<v8::Value>* value) | 1315 bool SerializedScriptValueReader::readInt32(v8::Handle<v8::Value>* value) |
1516 { | 1316 { |
1517 uint32_t rawValue; | 1317 uint32_t rawValue; |
1518 if (!doReadUint32(&rawValue)) | 1318 if (!doReadUint32(&rawValue)) |
1519 return false; | 1319 return false; |
1520 *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(raw
Value))); | 1320 *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(raw
Value))); |
1521 return true; | 1321 return true; |
1522 } | 1322 } |
1523 | 1323 |
1524 bool Reader::readUint32(v8::Handle<v8::Value>* value) | 1324 bool SerializedScriptValueReader::readUint32(v8::Handle<v8::Value>* value) |
1525 { | 1325 { |
1526 uint32_t rawValue; | 1326 uint32_t rawValue; |
1527 if (!doReadUint32(&rawValue)) | 1327 if (!doReadUint32(&rawValue)) |
1528 return false; | 1328 return false; |
1529 *value = v8::Integer::NewFromUnsigned(isolate(), rawValue); | 1329 *value = v8::Integer::NewFromUnsigned(isolate(), rawValue); |
1530 return true; | 1330 return true; |
1531 } | 1331 } |
1532 | 1332 |
1533 bool Reader::readDate(v8::Handle<v8::Value>* value) | 1333 bool SerializedScriptValueReader::readDate(v8::Handle<v8::Value>* value) |
1534 { | 1334 { |
1535 double numberValue; | 1335 double numberValue; |
1536 if (!doReadNumber(&numberValue)) | 1336 if (!doReadNumber(&numberValue)) |
1537 return false; | 1337 return false; |
1538 *value = v8DateOrNaN(numberValue, isolate()); | 1338 *value = v8DateOrNaN(numberValue, isolate()); |
1539 return true; | 1339 return true; |
1540 } | 1340 } |
1541 | 1341 |
1542 bool Reader::readNumber(v8::Handle<v8::Value>* value) | 1342 bool SerializedScriptValueReader::readNumber(v8::Handle<v8::Value>* value) |
1543 { | 1343 { |
1544 double number; | 1344 double number; |
1545 if (!doReadNumber(&number)) | 1345 if (!doReadNumber(&number)) |
1546 return false; | 1346 return false; |
1547 *value = v8::Number::New(isolate(), number); | 1347 *value = v8::Number::New(isolate(), number); |
1548 return true; | 1348 return true; |
1549 } | 1349 } |
1550 | 1350 |
1551 bool Reader::readNumberObject(v8::Handle<v8::Value>* value) | 1351 bool SerializedScriptValueReader::readNumberObject(v8::Handle<v8::Value>* value) |
1552 { | 1352 { |
1553 double number; | 1353 double number; |
1554 if (!doReadNumber(&number)) | 1354 if (!doReadNumber(&number)) |
1555 return false; | 1355 return false; |
1556 *value = v8::NumberObject::New(isolate(), number); | 1356 *value = v8::NumberObject::New(isolate(), number); |
1557 return true; | 1357 return true; |
1558 } | 1358 } |
1559 | 1359 |
1560 bool Reader::readImageData(v8::Handle<v8::Value>* value) | 1360 bool SerializedScriptValueReader::readImageData(v8::Handle<v8::Value>* value) |
1561 { | 1361 { |
1562 uint32_t width; | 1362 uint32_t width; |
1563 uint32_t height; | 1363 uint32_t height; |
1564 uint32_t pixelDataLength; | 1364 uint32_t pixelDataLength; |
1565 if (!doReadUint32(&width)) | 1365 if (!doReadUint32(&width)) |
1566 return false; | 1366 return false; |
1567 if (!doReadUint32(&height)) | 1367 if (!doReadUint32(&height)) |
1568 return false; | 1368 return false; |
1569 if (!doReadUint32(&pixelDataLength)) | 1369 if (!doReadUint32(&pixelDataLength)) |
1570 return false; | 1370 return false; |
1571 if (m_position + pixelDataLength > m_length) | 1371 if (m_position + pixelDataLength > m_length) |
1572 return false; | 1372 return false; |
1573 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, h
eight)); | 1373 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, h
eight)); |
1574 Uint8ClampedArray* pixelArray = imageData->data(); | 1374 Uint8ClampedArray* pixelArray = imageData->data(); |
1575 ASSERT(pixelArray); | 1375 ASSERT(pixelArray); |
1576 ASSERT(pixelArray->length() >= pixelDataLength); | 1376 ASSERT(pixelArray->length() >= pixelDataLength); |
1577 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); | 1377 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); |
1578 m_position += pixelDataLength; | 1378 m_position += pixelDataLength; |
1579 *value = toV8(imageData.release(), m_scriptState->context()->Global(), isola
te()); | 1379 *value = toV8(imageData.release(), m_scriptState->context()->Global(), isola
te()); |
1580 return true; | 1380 return true; |
1581 } | 1381 } |
1582 | 1382 |
1583 PassRefPtr<DOMArrayBuffer> Reader::doReadArrayBuffer() | 1383 PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() |
1584 { | 1384 { |
1585 uint32_t byteLength; | 1385 uint32_t byteLength; |
1586 if (!doReadUint32(&byteLength)) | 1386 if (!doReadUint32(&byteLength)) |
1587 return nullptr; | 1387 return nullptr; |
1588 if (m_position + byteLength > m_length) | 1388 if (m_position + byteLength > m_length) |
1589 return nullptr; | 1389 return nullptr; |
1590 const void* bufferStart = m_buffer + m_position; | 1390 const void* bufferStart = m_buffer + m_position; |
1591 m_position += byteLength; | 1391 m_position += byteLength; |
1592 return DOMArrayBuffer::create(bufferStart, byteLength); | 1392 return DOMArrayBuffer::create(bufferStart, byteLength); |
1593 } | 1393 } |
1594 | 1394 |
1595 bool Reader::readArrayBuffer(v8::Handle<v8::Value>* value) | 1395 bool SerializedScriptValueReader::readArrayBuffer(v8::Handle<v8::Value>* value) |
1596 { | 1396 { |
1597 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBuffer(); | 1397 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBuffer(); |
1598 if (!arrayBuffer) | 1398 if (!arrayBuffer) |
1599 return false; | 1399 return false; |
1600 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso
late()); | 1400 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso
late()); |
1601 return true; | 1401 return true; |
1602 } | 1402 } |
1603 | 1403 |
1604 bool Reader::readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator&
creator) | 1404 bool SerializedScriptValueReader::readArrayBufferView(v8::Handle<v8::Value>* val
ue, ScriptValueCompositeCreator& creator) |
1605 { | 1405 { |
1606 ArrayBufferViewSubTag subTag; | 1406 ArrayBufferViewSubTag subTag; |
1607 uint32_t byteOffset; | 1407 uint32_t byteOffset; |
1608 uint32_t byteLength; | 1408 uint32_t byteLength; |
1609 RefPtr<DOMArrayBuffer> arrayBuffer; | 1409 RefPtr<DOMArrayBuffer> arrayBuffer; |
1610 v8::Handle<v8::Value> arrayBufferV8Value; | 1410 v8::Handle<v8::Value> arrayBufferV8Value; |
1611 if (!readArrayBufferViewSubTag(&subTag)) | 1411 if (!readArrayBufferViewSubTag(&subTag)) |
1612 return false; | 1412 return false; |
1613 if (!doReadUint32(&byteOffset)) | 1413 if (!doReadUint32(&byteOffset)) |
1614 return false; | 1414 return false; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 case DoubleArrayTag: | 1494 case DoubleArrayTag: |
1695 *value = toV8(DOMFloat64Array::create(arrayBuffer.release(), byteOffset,
numElements), creationContext, isolate()); | 1495 *value = toV8(DOMFloat64Array::create(arrayBuffer.release(), byteOffset,
numElements), creationContext, isolate()); |
1696 break; | 1496 break; |
1697 case DataViewTag: | 1497 case DataViewTag: |
1698 *value = toV8(DOMDataView::create(arrayBuffer.release(), byteOffset, byt
eLength), creationContext, isolate()); | 1498 *value = toV8(DOMDataView::create(arrayBuffer.release(), byteOffset, byt
eLength), creationContext, isolate()); |
1699 break; | 1499 break; |
1700 } | 1500 } |
1701 return !value->IsEmpty(); | 1501 return !value->IsEmpty(); |
1702 } | 1502 } |
1703 | 1503 |
1704 bool Reader::readRegExp(v8::Handle<v8::Value>* value) | 1504 bool SerializedScriptValueReader::readRegExp(v8::Handle<v8::Value>* value) |
1705 { | 1505 { |
1706 v8::Handle<v8::Value> pattern; | 1506 v8::Handle<v8::Value> pattern; |
1707 if (!readString(&pattern)) | 1507 if (!readString(&pattern)) |
1708 return false; | 1508 return false; |
1709 uint32_t flags; | 1509 uint32_t flags; |
1710 if (!doReadUint32(&flags)) | 1510 if (!doReadUint32(&flags)) |
1711 return false; | 1511 return false; |
1712 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::F
lags>(flags)); | 1512 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::F
lags>(flags)); |
1713 return true; | 1513 return true; |
1714 } | 1514 } |
1715 | 1515 |
1716 bool Reader::readBlob(v8::Handle<v8::Value>* value, bool isIndexed) | 1516 bool SerializedScriptValueReader::readBlob(v8::Handle<v8::Value>* value, bool is
Indexed) |
1717 { | 1517 { |
1718 if (m_version < 3) | 1518 if (m_version < 3) |
1719 return false; | 1519 return false; |
1720 Blob* blob = nullptr; | 1520 Blob* blob = nullptr; |
1721 if (isIndexed) { | 1521 if (isIndexed) { |
1722 if (m_version < 6) | 1522 if (m_version < 6) |
1723 return false; | 1523 return false; |
1724 ASSERT(m_blobInfo); | 1524 ASSERT(m_blobInfo); |
1725 uint32_t index; | 1525 uint32_t index; |
1726 if (!doReadUint32(&index) || index >= m_blobInfo->size()) | 1526 if (!doReadUint32(&index) || index >= m_blobInfo->size()) |
(...skipping 11 matching lines...) Expand all Loading... |
1738 if (!readWebCoreString(&type)) | 1538 if (!readWebCoreString(&type)) |
1739 return false; | 1539 return false; |
1740 if (!doReadUint64(&size)) | 1540 if (!doReadUint64(&size)) |
1741 return false; | 1541 return false; |
1742 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); | 1542 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); |
1743 } | 1543 } |
1744 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); | 1544 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); |
1745 return true; | 1545 return true; |
1746 } | 1546 } |
1747 | 1547 |
1748 bool Reader::readDOMFileSystem(v8::Handle<v8::Value>* value) | 1548 bool SerializedScriptValueReader::readFile(v8::Handle<v8::Value>* value, bool is
Indexed) |
1749 { | |
1750 uint32_t type; | |
1751 String name; | |
1752 String url; | |
1753 if (!doReadUint32(&type)) | |
1754 return false; | |
1755 if (!readWebCoreString(&name)) | |
1756 return false; | |
1757 if (!readWebCoreString(&url)) | |
1758 return false; | |
1759 DOMFileSystem* fs = DOMFileSystem::create(m_scriptState->executionContext(),
name, static_cast<FileSystemType>(type), KURL(ParsedURLString, url)); | |
1760 *value = toV8(fs, m_scriptState->context()->Global(), isolate()); | |
1761 return true; | |
1762 } | |
1763 | |
1764 bool Reader::readFile(v8::Handle<v8::Value>* value, bool isIndexed) | |
1765 { | 1549 { |
1766 File* file = nullptr; | 1550 File* file = nullptr; |
1767 if (isIndexed) { | 1551 if (isIndexed) { |
1768 if (m_version < 6) | 1552 if (m_version < 6) |
1769 return false; | 1553 return false; |
1770 file = readFileIndexHelper(); | 1554 file = readFileIndexHelper(); |
1771 } else { | 1555 } else { |
1772 file = readFileHelper(); | 1556 file = readFileHelper(); |
1773 } | 1557 } |
1774 if (!file) | 1558 if (!file) |
1775 return false; | 1559 return false; |
1776 *value = toV8(file, m_scriptState->context()->Global(), isolate()); | 1560 *value = toV8(file, m_scriptState->context()->Global(), isolate()); |
1777 return true; | 1561 return true; |
1778 } | 1562 } |
1779 | 1563 |
1780 bool Reader::readFileList(v8::Handle<v8::Value>* value, bool isIndexed) | 1564 bool SerializedScriptValueReader::readFileList(v8::Handle<v8::Value>* value, boo
l isIndexed) |
1781 { | 1565 { |
1782 if (m_version < 3) | 1566 if (m_version < 3) |
1783 return false; | 1567 return false; |
1784 uint32_t length; | 1568 uint32_t length; |
1785 if (!doReadUint32(&length)) | 1569 if (!doReadUint32(&length)) |
1786 return false; | 1570 return false; |
1787 FileList* fileList = FileList::create(); | 1571 FileList* fileList = FileList::create(); |
1788 for (unsigned i = 0; i < length; ++i) { | 1572 for (unsigned i = 0; i < length; ++i) { |
1789 File* file = nullptr; | 1573 File* file = nullptr; |
1790 if (isIndexed) { | 1574 if (isIndexed) { |
1791 if (m_version < 6) | 1575 if (m_version < 6) |
1792 return false; | 1576 return false; |
1793 file = readFileIndexHelper(); | 1577 file = readFileIndexHelper(); |
1794 } else { | 1578 } else { |
1795 file = readFileHelper(); | 1579 file = readFileHelper(); |
1796 } | 1580 } |
1797 if (!file) | 1581 if (!file) |
1798 return false; | 1582 return false; |
1799 fileList->append(file); | 1583 fileList->append(file); |
1800 } | 1584 } |
1801 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); | 1585 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); |
1802 return true; | 1586 return true; |
1803 } | 1587 } |
1804 | 1588 |
1805 bool Reader::readCryptoKey(v8::Handle<v8::Value>* value) | 1589 File* SerializedScriptValueReader::readFileHelper() |
1806 { | |
1807 uint32_t rawKeyType; | |
1808 if (!doReadUint32(&rawKeyType)) | |
1809 return false; | |
1810 | |
1811 WebCryptoKeyAlgorithm algorithm; | |
1812 WebCryptoKeyType type = WebCryptoKeyTypeSecret; | |
1813 | |
1814 switch (static_cast<CryptoKeySubTag>(rawKeyType)) { | |
1815 case AesKeyTag: | |
1816 if (!doReadAesKey(algorithm, type)) | |
1817 return false; | |
1818 break; | |
1819 case HmacKeyTag: | |
1820 if (!doReadHmacKey(algorithm, type)) | |
1821 return false; | |
1822 break; | |
1823 case RsaHashedKeyTag: | |
1824 if (!doReadRsaHashedKey(algorithm, type)) | |
1825 return false; | |
1826 break; | |
1827 case EcKeyTag: | |
1828 if (!doReadEcKey(algorithm, type)) | |
1829 return false; | |
1830 break; | |
1831 default: | |
1832 return false; | |
1833 } | |
1834 | |
1835 WebCryptoKeyUsageMask usages; | |
1836 bool extractable; | |
1837 if (!doReadKeyUsages(usages, extractable)) | |
1838 return false; | |
1839 | |
1840 uint32_t keyDataLength; | |
1841 if (!doReadUint32(&keyDataLength)) | |
1842 return false; | |
1843 | |
1844 if (m_position + keyDataLength > m_length) | |
1845 return false; | |
1846 | |
1847 const uint8_t* keyData = m_buffer + m_position; | |
1848 m_position += keyDataLength; | |
1849 | |
1850 WebCryptoKey key = WebCryptoKey::createNull(); | |
1851 if (!Platform::current()->crypto()->deserializeKeyForClone( | |
1852 algorithm, type, extractable, usages, keyData, keyDataLength, key)) { | |
1853 return false; | |
1854 } | |
1855 | |
1856 *value = toV8(CryptoKey::create(key), m_scriptState->context()->Global(), is
olate()); | |
1857 return true; | |
1858 } | |
1859 | |
1860 File* Reader::readFileHelper() | |
1861 { | 1590 { |
1862 if (m_version < 3) | 1591 if (m_version < 3) |
1863 return nullptr; | 1592 return nullptr; |
1864 ASSERT(!m_blobInfo); | 1593 ASSERT(!m_blobInfo); |
1865 String path; | 1594 String path; |
1866 String name; | 1595 String name; |
1867 String relativePath; | 1596 String relativePath; |
1868 String uuid; | 1597 String uuid; |
1869 String type; | 1598 String type; |
1870 uint32_t hasSnapshot = 0; | 1599 uint32_t hasSnapshot = 0; |
(...skipping 17 matching lines...) Expand all Loading... |
1888 if (!doReadNumber(&lastModified)) | 1617 if (!doReadNumber(&lastModified)) |
1889 return nullptr; | 1618 return nullptr; |
1890 } | 1619 } |
1891 uint32_t isUserVisible = 1; | 1620 uint32_t isUserVisible = 1; |
1892 if (m_version >= 7 && !doReadUint32(&isUserVisible)) | 1621 if (m_version >= 7 && !doReadUint32(&isUserVisible)) |
1893 return nullptr; | 1622 return nullptr; |
1894 const File::UserVisibility userVisibility = (isUserVisible > 0) ? File::IsUs
erVisible : File::IsNotUserVisible; | 1623 const File::UserVisibility userVisibility = (isUserVisible > 0) ? File::IsUs
erVisible : File::IsNotUserVisible; |
1895 return File::createFromSerialization(path, name, relativePath, userVisibilit
y, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type)); | 1624 return File::createFromSerialization(path, name, relativePath, userVisibilit
y, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type)); |
1896 } | 1625 } |
1897 | 1626 |
1898 File* Reader::readFileIndexHelper() | 1627 File* SerializedScriptValueReader::readFileIndexHelper() |
1899 { | 1628 { |
1900 if (m_version < 3) | 1629 if (m_version < 3) |
1901 return nullptr; | 1630 return nullptr; |
1902 ASSERT(m_blobInfo); | 1631 ASSERT(m_blobInfo); |
1903 uint32_t index; | 1632 uint32_t index; |
1904 if (!doReadUint32(&index) || index >= m_blobInfo->size()) | 1633 if (!doReadUint32(&index) || index >= m_blobInfo->size()) |
1905 return nullptr; | 1634 return nullptr; |
1906 const WebBlobInfo& info = (*m_blobInfo)[index]; | 1635 const WebBlobInfo& info = (*m_blobInfo)[index]; |
1907 return File::createFromIndexedSerialization(info.filePath(), info.fileName()
, info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.
type(), info.size())); | 1636 return File::createFromIndexedSerialization(info.filePath(), info.fileName()
, info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.
type(), info.size())); |
1908 } | 1637 } |
1909 | 1638 |
1910 bool Reader::doReadUint32(uint32_t* value) | 1639 bool SerializedScriptValueReader::doReadUint32(uint32_t* value) |
1911 { | 1640 { |
1912 return doReadUintHelper(value); | 1641 return doReadUintHelper(value); |
1913 } | 1642 } |
1914 | 1643 |
1915 bool Reader::doReadUint64(uint64_t* value) | 1644 bool SerializedScriptValueReader::doReadUint64(uint64_t* value) |
1916 { | 1645 { |
1917 return doReadUintHelper(value); | 1646 return doReadUintHelper(value); |
1918 } | 1647 } |
1919 | 1648 |
1920 bool Reader::doReadNumber(double* number) | 1649 bool SerializedScriptValueReader::doReadNumber(double* number) |
1921 { | 1650 { |
1922 if (m_position + sizeof(double) > m_length) | 1651 if (m_position + sizeof(double) > m_length) |
1923 return false; | 1652 return false; |
1924 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); | 1653 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); |
1925 for (unsigned i = 0; i < sizeof(double); ++i) | 1654 for (unsigned i = 0; i < sizeof(double); ++i) |
1926 numberAsByteArray[i] = m_buffer[m_position++]; | 1655 numberAsByteArray[i] = m_buffer[m_position++]; |
1927 return true; | 1656 return true; |
1928 } | 1657 } |
1929 | 1658 |
1930 PassRefPtr<BlobDataHandle> Reader::getOrCreateBlobDataHandle(const String& uuid,
const String& type, long long size) | 1659 PassRefPtr<BlobDataHandle> SerializedScriptValueReader::getOrCreateBlobDataHandl
e(const String& uuid, const String& type, long long size) |
1931 { | 1660 { |
1932 // The containing ssv may have a BDH for this uuid if this ssv is just being | 1661 // The containing ssv may have a BDH for this uuid if this ssv is just being |
1933 // passed from main to worker thread (for example). We use those values when
creating | 1662 // passed from main to worker thread (for example). We use those values when
creating |
1934 // the new blob instead of cons'ing up a new BDH. | 1663 // the new blob instead of cons'ing up a new BDH. |
1935 // | 1664 // |
1936 // FIXME: Maybe we should require that it work that way where the ssv must h
ave a BDH for any | 1665 // FIXME: Maybe we should require that it work that way where the ssv must h
ave a BDH for any |
1937 // blobs it comes across during deserialization. Would require callers to ex
plicitly populate | 1666 // blobs it comes across during deserialization. Would require callers to ex
plicitly populate |
1938 // the collection of BDH's for blobs to work, which would encourage lifetime
s to be considered | 1667 // the collection of BDH's for blobs to work, which would encourage lifetime
s to be considered |
1939 // when passing ssv's around cross process. At present, we get 'lucky' in so
me cases because | 1668 // when passing ssv's around cross process. At present, we get 'lucky' in so
me cases because |
1940 // the blob in the src process happens to still exist at the time the dest p
rocess is deserializing. | 1669 // the blob in the src process happens to still exist at the time the dest p
rocess is deserializing. |
1941 // For example in sharedWorker.postMessage(...). | 1670 // For example in sharedWorker.postMessage(...). |
1942 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); | 1671 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); |
1943 if (it != m_blobDataHandles.end()) { | 1672 if (it != m_blobDataHandles.end()) { |
1944 // make assertions about type and size? | 1673 // make assertions about type and size? |
1945 return it->value; | 1674 return it->value; |
1946 } | 1675 } |
1947 return BlobDataHandle::create(uuid, type, size); | 1676 return BlobDataHandle::create(uuid, type, size); |
1948 } | 1677 } |
1949 | 1678 |
1950 bool Reader::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& t
ype) | 1679 v8::Handle<v8::Value> ScriptValueDeserializer::deserialize() |
1951 { | |
1952 uint32_t lengthBytes; | |
1953 if (!doReadUint32(&lengthBytes)) | |
1954 return false; | |
1955 WebCryptoAlgorithmId hash; | |
1956 if (!doReadAlgorithmId(hash)) | |
1957 return false; | |
1958 algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8); | |
1959 type = WebCryptoKeyTypeSecret; | |
1960 return !algorithm.isNull(); | |
1961 } | |
1962 | |
1963 bool Reader::doReadAesKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& ty
pe) | |
1964 { | |
1965 WebCryptoAlgorithmId id; | |
1966 if (!doReadAlgorithmId(id)) | |
1967 return false; | |
1968 uint32_t lengthBytes; | |
1969 if (!doReadUint32(&lengthBytes)) | |
1970 return false; | |
1971 algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8); | |
1972 type = WebCryptoKeyTypeSecret; | |
1973 return !algorithm.isNull(); | |
1974 } | |
1975 | |
1976 bool Reader::doReadRsaHashedKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyTy
pe& type) | |
1977 { | |
1978 WebCryptoAlgorithmId id; | |
1979 if (!doReadAlgorithmId(id)) | |
1980 return false; | |
1981 | |
1982 if (!doReadAsymmetricKeyType(type)) | |
1983 return false; | |
1984 | |
1985 uint32_t modulusLengthBits; | |
1986 if (!doReadUint32(&modulusLengthBits)) | |
1987 return false; | |
1988 | |
1989 uint32_t publicExponentSize; | |
1990 if (!doReadUint32(&publicExponentSize)) | |
1991 return false; | |
1992 | |
1993 if (m_position + publicExponentSize > m_length) | |
1994 return false; | |
1995 | |
1996 const uint8_t* publicExponent = m_buffer + m_position; | |
1997 m_position += publicExponentSize; | |
1998 | |
1999 WebCryptoAlgorithmId hash; | |
2000 if (!doReadAlgorithmId(hash)) | |
2001 return false; | |
2002 algorithm = WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, pu
blicExponent, publicExponentSize, hash); | |
2003 | |
2004 return !algorithm.isNull(); | |
2005 } | |
2006 | |
2007 bool Reader::doReadEcKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& typ
e) | |
2008 { | |
2009 WebCryptoAlgorithmId id; | |
2010 if (!doReadAlgorithmId(id)) | |
2011 return false; | |
2012 | |
2013 if (!doReadAsymmetricKeyType(type)) | |
2014 return false; | |
2015 | |
2016 WebCryptoNamedCurve namedCurve; | |
2017 if (!doReadNamedCurve(namedCurve)) | |
2018 return false; | |
2019 | |
2020 algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve); | |
2021 return !algorithm.isNull(); | |
2022 } | |
2023 | |
2024 bool Reader::doReadAlgorithmId(WebCryptoAlgorithmId& id) | |
2025 { | |
2026 uint32_t rawId; | |
2027 if (!doReadUint32(&rawId)) | |
2028 return false; | |
2029 | |
2030 switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) { | |
2031 case AesCbcTag: | |
2032 id = WebCryptoAlgorithmIdAesCbc; | |
2033 return true; | |
2034 case HmacTag: | |
2035 id = WebCryptoAlgorithmIdHmac; | |
2036 return true; | |
2037 case RsaSsaPkcs1v1_5Tag: | |
2038 id = WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | |
2039 return true; | |
2040 case Sha1Tag: | |
2041 id = WebCryptoAlgorithmIdSha1; | |
2042 return true; | |
2043 case Sha256Tag: | |
2044 id = WebCryptoAlgorithmIdSha256; | |
2045 return true; | |
2046 case Sha384Tag: | |
2047 id = WebCryptoAlgorithmIdSha384; | |
2048 return true; | |
2049 case Sha512Tag: | |
2050 id = WebCryptoAlgorithmIdSha512; | |
2051 return true; | |
2052 case AesGcmTag: | |
2053 id = WebCryptoAlgorithmIdAesGcm; | |
2054 return true; | |
2055 case RsaOaepTag: | |
2056 id = WebCryptoAlgorithmIdRsaOaep; | |
2057 return true; | |
2058 case AesCtrTag: | |
2059 id = WebCryptoAlgorithmIdAesCtr; | |
2060 return true; | |
2061 case AesKwTag: | |
2062 id = WebCryptoAlgorithmIdAesKw; | |
2063 return true; | |
2064 case RsaPssTag: | |
2065 id = WebCryptoAlgorithmIdRsaPss; | |
2066 return true; | |
2067 case EcdsaTag: | |
2068 id = WebCryptoAlgorithmIdEcdsa; | |
2069 return true; | |
2070 } | |
2071 | |
2072 return false; | |
2073 } | |
2074 | |
2075 bool Reader::doReadAsymmetricKeyType(WebCryptoKeyType& type) | |
2076 { | |
2077 uint32_t rawType; | |
2078 if (!doReadUint32(&rawType)) | |
2079 return false; | |
2080 | |
2081 switch (static_cast<AssymetricCryptoKeyType>(rawType)) { | |
2082 case PublicKeyType: | |
2083 type = WebCryptoKeyTypePublic; | |
2084 return true; | |
2085 case PrivateKeyType: | |
2086 type = WebCryptoKeyTypePrivate; | |
2087 return true; | |
2088 } | |
2089 | |
2090 return false; | |
2091 } | |
2092 | |
2093 bool Reader::doReadNamedCurve(WebCryptoNamedCurve& namedCurve) | |
2094 { | |
2095 uint32_t rawName; | |
2096 if (!doReadUint32(&rawName)) | |
2097 return false; | |
2098 | |
2099 switch (static_cast<NamedCurveTag>(rawName)) { | |
2100 case P256Tag: | |
2101 namedCurve = WebCryptoNamedCurveP256; | |
2102 return true; | |
2103 case P384Tag: | |
2104 namedCurve = WebCryptoNamedCurveP384; | |
2105 return true; | |
2106 case P521Tag: | |
2107 namedCurve = WebCryptoNamedCurveP521; | |
2108 return true; | |
2109 } | |
2110 | |
2111 return false; | |
2112 } | |
2113 | |
2114 bool Reader::doReadKeyUsages(WebCryptoKeyUsageMask& usages, bool& extractable) | |
2115 { | |
2116 // Reminder to update this when adding new key usages. | |
2117 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
2118 const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | Decrypt
Usage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage
| DeriveBitsUsage; | |
2119 | |
2120 uint32_t rawUsages; | |
2121 if (!doReadUint32(&rawUsages)) | |
2122 return false; | |
2123 | |
2124 // Make sure it doesn't contain an unrecognized usage value. | |
2125 if (rawUsages & ~allPossibleUsages) | |
2126 return false; | |
2127 | |
2128 usages = 0; | |
2129 | |
2130 extractable = rawUsages & ExtractableUsage; | |
2131 | |
2132 if (rawUsages & EncryptUsage) | |
2133 usages |= WebCryptoKeyUsageEncrypt; | |
2134 if (rawUsages & DecryptUsage) | |
2135 usages |= WebCryptoKeyUsageDecrypt; | |
2136 if (rawUsages & SignUsage) | |
2137 usages |= WebCryptoKeyUsageSign; | |
2138 if (rawUsages & VerifyUsage) | |
2139 usages |= WebCryptoKeyUsageVerify; | |
2140 if (rawUsages & DeriveKeyUsage) | |
2141 usages |= WebCryptoKeyUsageDeriveKey; | |
2142 if (rawUsages & WrapKeyUsage) | |
2143 usages |= WebCryptoKeyUsageWrapKey; | |
2144 if (rawUsages & UnwrapKeyUsage) | |
2145 usages |= WebCryptoKeyUsageUnwrapKey; | |
2146 if (rawUsages & DeriveBitsUsage) | |
2147 usages |= WebCryptoKeyUsageDeriveBits; | |
2148 | |
2149 return true; | |
2150 } | |
2151 | |
2152 v8::Handle<v8::Value> Deserializer::deserialize() | |
2153 { | 1680 { |
2154 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1681 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
2155 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w
ireFormatVersion) | 1682 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w
ireFormatVersion) |
2156 return v8::Null(isolate); | 1683 return v8::Null(isolate); |
2157 m_reader.setVersion(m_version); | 1684 m_reader.setVersion(m_version); |
2158 v8::EscapableHandleScope scope(isolate); | 1685 v8::EscapableHandleScope scope(isolate); |
2159 while (!m_reader.isEof()) { | 1686 while (!m_reader.isEof()) { |
2160 if (!doDeserialize()) | 1687 if (!doDeserialize()) |
2161 return v8::Null(isolate); | 1688 return v8::Null(isolate); |
2162 } | 1689 } |
2163 if (stackDepth() != 1 || m_openCompositeReferenceStack.size()) | 1690 if (stackDepth() != 1 || m_openCompositeReferenceStack.size()) |
2164 return v8::Null(isolate); | 1691 return v8::Null(isolate); |
2165 v8::Handle<v8::Value> result = scope.Escape(element(0)); | 1692 v8::Handle<v8::Value> result = scope.Escape(element(0)); |
2166 return result; | 1693 return result; |
2167 } | 1694 } |
2168 | 1695 |
2169 bool Deserializer::newSparseArray(uint32_t) | 1696 bool ScriptValueDeserializer::newSparseArray(uint32_t) |
2170 { | 1697 { |
2171 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(
), 0); | 1698 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(
), 0); |
2172 openComposite(array); | 1699 openComposite(array); |
2173 return true; | 1700 return true; |
2174 } | 1701 } |
2175 | 1702 |
2176 bool Deserializer::newDenseArray(uint32_t length) | 1703 bool ScriptValueDeserializer::newDenseArray(uint32_t length) |
2177 { | 1704 { |
2178 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(
), length); | 1705 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(
), length); |
2179 openComposite(array); | 1706 openComposite(array); |
2180 return true; | 1707 return true; |
2181 } | 1708 } |
2182 | 1709 |
2183 bool Deserializer::consumeTopOfStack(v8::Handle<v8::Value>* object) | 1710 bool ScriptValueDeserializer::consumeTopOfStack(v8::Handle<v8::Value>* object) |
2184 { | 1711 { |
2185 if (stackDepth() < 1) | 1712 if (stackDepth() < 1) |
2186 return false; | 1713 return false; |
2187 *object = element(stackDepth() - 1); | 1714 *object = element(stackDepth() - 1); |
2188 pop(1); | 1715 pop(1); |
2189 return true; | 1716 return true; |
2190 } | 1717 } |
2191 | 1718 |
2192 bool Deserializer::newObject() | 1719 bool ScriptValueDeserializer::newObject() |
2193 { | 1720 { |
2194 v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isola
te()); | 1721 v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isola
te()); |
2195 if (object.IsEmpty()) | 1722 if (object.IsEmpty()) |
2196 return false; | 1723 return false; |
2197 openComposite(object); | 1724 openComposite(object); |
2198 return true; | 1725 return true; |
2199 } | 1726 } |
2200 | 1727 |
2201 bool Deserializer::completeObject(uint32_t numProperties, v8::Handle<v8::Value>*
value) | 1728 bool ScriptValueDeserializer::completeObject(uint32_t numProperties, v8::Handle<
v8::Value>* value) |
2202 { | 1729 { |
2203 v8::Local<v8::Object> object; | 1730 v8::Local<v8::Object> object; |
2204 if (m_version > 0) { | 1731 if (m_version > 0) { |
2205 v8::Local<v8::Value> composite; | 1732 v8::Local<v8::Value> composite; |
2206 if (!closeComposite(&composite)) | 1733 if (!closeComposite(&composite)) |
2207 return false; | 1734 return false; |
2208 object = composite.As<v8::Object>(); | 1735 object = composite.As<v8::Object>(); |
2209 } else { | 1736 } else { |
2210 object = v8::Object::New(m_reader.scriptState()->isolate()); | 1737 object = v8::Object::New(m_reader.scriptState()->isolate()); |
2211 } | 1738 } |
2212 if (object.IsEmpty()) | 1739 if (object.IsEmpty()) |
2213 return false; | 1740 return false; |
2214 return initializeObject(object, numProperties, value); | 1741 return initializeObject(object, numProperties, value); |
2215 } | 1742 } |
2216 | 1743 |
2217 bool Deserializer::completeSparseArray(uint32_t numProperties, uint32_t length,
v8::Handle<v8::Value>* value) | 1744 bool ScriptValueDeserializer::completeSparseArray(uint32_t numProperties, uint32
_t length, v8::Handle<v8::Value>* value) |
2218 { | 1745 { |
2219 v8::Local<v8::Array> array; | 1746 v8::Local<v8::Array> array; |
2220 if (m_version > 0) { | 1747 if (m_version > 0) { |
2221 v8::Local<v8::Value> composite; | 1748 v8::Local<v8::Value> composite; |
2222 if (!closeComposite(&composite)) | 1749 if (!closeComposite(&composite)) |
2223 return false; | 1750 return false; |
2224 array = composite.As<v8::Array>(); | 1751 array = composite.As<v8::Array>(); |
2225 } else { | 1752 } else { |
2226 array = v8::Array::New(m_reader.scriptState()->isolate()); | 1753 array = v8::Array::New(m_reader.scriptState()->isolate()); |
2227 } | 1754 } |
2228 if (array.IsEmpty()) | 1755 if (array.IsEmpty()) |
2229 return false; | 1756 return false; |
2230 return initializeObject(array, numProperties, value); | 1757 return initializeObject(array, numProperties, value); |
2231 } | 1758 } |
2232 | 1759 |
2233 bool Deserializer::completeDenseArray(uint32_t numProperties, uint32_t length, v
8::Handle<v8::Value>* value) | 1760 bool ScriptValueDeserializer::completeDenseArray(uint32_t numProperties, uint32_
t length, v8::Handle<v8::Value>* value) |
2234 { | 1761 { |
2235 v8::Local<v8::Array> array; | 1762 v8::Local<v8::Array> array; |
2236 if (m_version > 0) { | 1763 if (m_version > 0) { |
2237 v8::Local<v8::Value> composite; | 1764 v8::Local<v8::Value> composite; |
2238 if (!closeComposite(&composite)) | 1765 if (!closeComposite(&composite)) |
2239 return false; | 1766 return false; |
2240 array = composite.As<v8::Array>(); | 1767 array = composite.As<v8::Array>(); |
2241 } | 1768 } |
2242 if (array.IsEmpty()) | 1769 if (array.IsEmpty()) |
2243 return false; | 1770 return false; |
2244 if (!initializeObject(array, numProperties, value)) | 1771 if (!initializeObject(array, numProperties, value)) |
2245 return false; | 1772 return false; |
2246 if (length > stackDepth()) | 1773 if (length > stackDepth()) |
2247 return false; | 1774 return false; |
2248 for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stac
kPos++) { | 1775 for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stac
kPos++) { |
2249 v8::Local<v8::Value> elem = element(stackPos); | 1776 v8::Local<v8::Value> elem = element(stackPos); |
2250 if (!elem->IsUndefined()) | 1777 if (!elem->IsUndefined()) |
2251 array->Set(i, elem); | 1778 array->Set(i, elem); |
2252 } | 1779 } |
2253 pop(length); | 1780 pop(length); |
2254 return true; | 1781 return true; |
2255 } | 1782 } |
2256 | 1783 |
2257 void Deserializer::pushObjectReference(const v8::Handle<v8::Value>& object) | 1784 void ScriptValueDeserializer::pushObjectReference(const v8::Handle<v8::Value>& o
bject) |
2258 { | 1785 { |
2259 m_objectPool.append(object); | 1786 m_objectPool.append(object); |
2260 } | 1787 } |
2261 | 1788 |
2262 bool Deserializer::tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::V
alue>* object) | 1789 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::H
andle<v8::Value>* object) |
2263 { | 1790 { |
2264 if (!m_transferredMessagePorts) | 1791 if (!m_transferredMessagePorts) |
2265 return false; | 1792 return false; |
2266 if (index >= m_transferredMessagePorts->size()) | 1793 if (index >= m_transferredMessagePorts->size()) |
2267 return false; | 1794 return false; |
2268 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->
Global(); | 1795 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->
Global(); |
2269 *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext,
m_reader.scriptState()->isolate()); | 1796 *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext,
m_reader.scriptState()->isolate()); |
2270 return true; | 1797 return true; |
2271 } | 1798 } |
2272 | 1799 |
2273 bool Deserializer::tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::V
alue>* object) | 1800 bool ScriptValueDeserializer::tryGetTransferredArrayBuffer(uint32_t index, v8::H
andle<v8::Value>* object) |
2274 { | 1801 { |
2275 if (!m_arrayBufferContents) | 1802 if (!m_arrayBufferContents) |
2276 return false; | 1803 return false; |
2277 if (index >= m_arrayBuffers.size()) | 1804 if (index >= m_arrayBuffers.size()) |
2278 return false; | 1805 return false; |
2279 v8::Handle<v8::Value> result = m_arrayBuffers.at(index); | 1806 v8::Handle<v8::Value> result = m_arrayBuffers.at(index); |
2280 if (result.IsEmpty()) { | 1807 if (result.IsEmpty()) { |
2281 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(m_arrayBufferCont
ents->at(index)); | 1808 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(m_arrayBufferCont
ents->at(index)); |
2282 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1809 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
2283 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context
()->Global(); | 1810 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context
()->Global(); |
2284 result = toV8(buffer.get(), creationContext, isolate); | 1811 result = toV8(buffer.get(), creationContext, isolate); |
2285 m_arrayBuffers[index] = result; | 1812 m_arrayBuffers[index] = result; |
2286 } | 1813 } |
2287 *object = result; | 1814 *object = result; |
2288 return true; | 1815 return true; |
2289 } | 1816 } |
2290 | 1817 |
2291 bool Deserializer::tryGetObjectFromObjectReference(uint32_t reference, v8::Handl
e<v8::Value>* object) | 1818 bool ScriptValueDeserializer::tryGetObjectFromObjectReference(uint32_t reference
, v8::Handle<v8::Value>* object) |
2292 { | 1819 { |
2293 if (reference >= m_objectPool.size()) | 1820 if (reference >= m_objectPool.size()) |
2294 return false; | 1821 return false; |
2295 *object = m_objectPool[reference]; | 1822 *object = m_objectPool[reference]; |
2296 return object; | 1823 return object; |
2297 } | 1824 } |
2298 | 1825 |
2299 uint32_t Deserializer::objectReferenceCount() | 1826 uint32_t ScriptValueDeserializer::objectReferenceCount() |
2300 { | 1827 { |
2301 return m_objectPool.size(); | 1828 return m_objectPool.size(); |
2302 } | 1829 } |
2303 | 1830 |
2304 bool Deserializer::initializeObject(v8::Handle<v8::Object> object, uint32_t numP
roperties, v8::Handle<v8::Value>* value) | 1831 bool ScriptValueDeserializer::initializeObject(v8::Handle<v8::Object> object, ui
nt32_t numProperties, v8::Handle<v8::Value>* value) |
2305 { | 1832 { |
2306 unsigned length = 2 * numProperties; | 1833 unsigned length = 2 * numProperties; |
2307 if (length > stackDepth()) | 1834 if (length > stackDepth()) |
2308 return false; | 1835 return false; |
2309 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { | 1836 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { |
2310 v8::Local<v8::Value> propertyName = element(i); | 1837 v8::Local<v8::Value> propertyName = element(i); |
2311 v8::Local<v8::Value> propertyValue = element(i + 1); | 1838 v8::Local<v8::Value> propertyValue = element(i + 1); |
2312 object->Set(propertyName, propertyValue); | 1839 object->Set(propertyName, propertyValue); |
2313 } | 1840 } |
2314 pop(length); | 1841 pop(length); |
2315 *value = object; | 1842 *value = object; |
2316 return true; | 1843 return true; |
2317 } | 1844 } |
2318 | 1845 |
2319 bool Deserializer::read(v8::Local<v8::Value>* value) | 1846 bool ScriptValueDeserializer::read(v8::Local<v8::Value>* value) |
2320 { | 1847 { |
2321 return m_reader.read(value, *this); | 1848 return m_reader.read(value, *this); |
2322 } | 1849 } |
2323 | 1850 |
2324 bool Deserializer::doDeserialize() | 1851 bool ScriptValueDeserializer::doDeserialize() |
2325 { | 1852 { |
2326 v8::Local<v8::Value> value; | 1853 v8::Local<v8::Value> value; |
2327 if (!read(&value)) | 1854 if (!read(&value)) |
2328 return false; | 1855 return false; |
2329 if (!value.IsEmpty()) | 1856 if (!value.IsEmpty()) |
2330 push(value); | 1857 push(value); |
2331 return true; | 1858 return true; |
2332 } | 1859 } |
2333 | 1860 |
2334 v8::Local<v8::Value> Deserializer::element(unsigned index) | 1861 v8::Local<v8::Value> ScriptValueDeserializer::element(unsigned index) |
2335 { | 1862 { |
2336 ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size()); | 1863 ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size()); |
2337 return m_stack[index]; | 1864 return m_stack[index]; |
2338 } | 1865 } |
2339 | 1866 |
2340 void Deserializer::openComposite(const v8::Local<v8::Value>& object) | 1867 void ScriptValueDeserializer::openComposite(const v8::Local<v8::Value>& object) |
2341 { | 1868 { |
2342 uint32_t newObjectReference = m_objectPool.size(); | 1869 uint32_t newObjectReference = m_objectPool.size(); |
2343 m_openCompositeReferenceStack.append(newObjectReference); | 1870 m_openCompositeReferenceStack.append(newObjectReference); |
2344 m_objectPool.append(object); | 1871 m_objectPool.append(object); |
2345 } | 1872 } |
2346 | 1873 |
2347 bool Deserializer::closeComposite(v8::Handle<v8::Value>* object) | 1874 bool ScriptValueDeserializer::closeComposite(v8::Handle<v8::Value>* object) |
2348 { | 1875 { |
2349 if (!m_openCompositeReferenceStack.size()) | 1876 if (!m_openCompositeReferenceStack.size()) |
2350 return false; | 1877 return false; |
2351 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; | 1878 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; |
2352 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); | 1879 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); |
2353 if (objectReference >= m_objectPool.size()) | 1880 if (objectReference >= m_objectPool.size()) |
2354 return false; | 1881 return false; |
2355 *object = m_objectPool[objectReference]; | 1882 *object = m_objectPool[objectReference]; |
2356 return true; | 1883 return true; |
2357 } | 1884 } |
2358 | 1885 |
2359 } // SerializedScriptValueInternal | |
2360 | |
2361 } // namespace blink | 1886 } // namespace blink |
OLD | NEW |