Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / v8 / SerializedScriptValue.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "bindings/v8/SerializedScriptValue.h"
33
34 #include "V8Blob.h"
35 #include "V8DOMFileSystem.h"
36 #include "V8File.h"
37 #include "V8FileList.h"
38 #include "V8ImageData.h"
39 #include "V8Key.h"
40 #include "V8MessagePort.h"
41 #include "bindings/v8/ExceptionState.h"
42 #include "bindings/v8/V8Binding.h"
43 #include "bindings/v8/WorkerScriptController.h"
44 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
45 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
46 #include "bindings/v8/custom/V8DataViewCustom.h"
47 #include "bindings/v8/custom/V8Float32ArrayCustom.h"
48 #include "bindings/v8/custom/V8Float64ArrayCustom.h"
49 #include "bindings/v8/custom/V8Int16ArrayCustom.h"
50 #include "bindings/v8/custom/V8Int32ArrayCustom.h"
51 #include "bindings/v8/custom/V8Int8ArrayCustom.h"
52 #include "bindings/v8/custom/V8Uint16ArrayCustom.h"
53 #include "bindings/v8/custom/V8Uint32ArrayCustom.h"
54 #include "bindings/v8/custom/V8Uint8ArrayCustom.h"
55 #include "bindings/v8/custom/V8Uint8ClampedArrayCustom.h"
56 #include "core/dom/ExceptionCode.h"
57 #include "core/dom/MessagePort.h"
58 #include "core/fileapi/Blob.h"
59 #include "core/fileapi/File.h"
60 #include "core/fileapi/FileList.h"
61 #include "core/html/ImageData.h"
62 #include "core/html/canvas/DataView.h"
63 #include "platform/SharedBuffer.h"
64 #include "platform/heap/Handle.h"
65 #include "public/platform/Platform.h"
66 #include "public/platform/WebBlobInfo.h"
67 #include "public/platform/WebCrypto.h"
68 #include "public/platform/WebCryptoKey.h"
69 #include "public/platform/WebCryptoKeyAlgorithm.h"
70 #include "wtf/ArrayBuffer.h"
71 #include "wtf/ArrayBufferContents.h"
72 #include "wtf/ArrayBufferView.h"
73 #include "wtf/Assertions.h"
74 #include "wtf/ByteOrder.h"
75 #include "wtf/Float32Array.h"
76 #include "wtf/Float64Array.h"
77 #include "wtf/Int16Array.h"
78 #include "wtf/Int32Array.h"
79 #include "wtf/Int8Array.h"
80 #include "wtf/RefCounted.h"
81 #include "wtf/Uint16Array.h"
82 #include "wtf/Uint32Array.h"
83 #include "wtf/Uint8Array.h"
84 #include "wtf/Uint8ClampedArray.h"
85 #include "wtf/Vector.h"
86 #include "wtf/text/StringBuffer.h"
87 #include "wtf/text/StringUTF8Adaptor.h"
88
89 // FIXME: consider crashing in debug mode on deserialization errors
90 // NOTE: be sure to change wireFormatVersion as necessary!
91
92 namespace WebCore {
93
94 namespace {
95
96 // This code implements the HTML5 Structured Clone algorithm:
97 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-passing-of-structured-data
98
99 // V8ObjectMap is a map from V8 objects to arbitrary values of type T.
100 // V8 objects (or handles to V8 objects) cannot be used as keys in ordinary wtf::HashMaps;
101 // this class should be used instead. GCObject must be a subtype of v8::Object.
102 // Suggested usage:
103 //     V8ObjectMap<v8::Object, int> map;
104 //     v8::Handle<v8::Object> obj = ...;
105 //     map.set(obj, 42);
106 template<typename GCObject, typename T>
107 class V8ObjectMap {
108 public:
109     bool contains(const v8::Handle<GCObject>& handle)
110     {
111         return m_map.contains(*handle);
112     }
113
114     bool tryGet(const v8::Handle<GCObject>& handle, T* valueOut)
115     {
116         typename HandleToT::iterator result = m_map.find(*handle);
117         if (result != m_map.end()) {
118             *valueOut = result->value;
119             return true;
120         }
121         return false;
122     }
123
124     void set(const v8::Handle<GCObject>& handle, const T& value)
125     {
126         m_map.set(*handle, value);
127     }
128
129 private:
130     // This implementation uses GetIdentityHash(), which sets a hidden property on the object containing
131     // a random integer (or returns the one that had been previously set). This ensures that the table
132     // never needs to be rebuilt across garbage collections at the expense of doing additional allocation
133     // and making more round trips into V8. Note that since GetIdentityHash() is defined only on
134     // v8::Objects, this V8ObjectMap cannot be used to map v8::Strings to T (because the public V8 API
135     // considers a v8::String to be a v8::Primitive).
136
137     // If V8 exposes a way to get at the address of the object held by a handle, then we can produce
138     // an alternate implementation that does not need to do any V8-side allocation; however, it will
139     // need to rehash after every garbage collection because a key object may have been moved.
140     template<typename G>
141     struct V8HandlePtrHash {
142         static v8::Handle<G> unsafeHandleFromRawValue(const G* value)
143         {
144             const v8::Handle<G>* handle = reinterpret_cast<const v8::Handle<G>*>(&value);
145             return *handle;
146         }
147
148         static unsigned hash(const G* key)
149         {
150             return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdentityHash());
151         }
152         static bool equal(const G* a, const G* b)
153         {
154             return unsafeHandleFromRawValue(a) == unsafeHandleFromRawValue(b);
155         }
156         // For HashArg.
157         static const bool safeToCompareToEmptyOrDeleted = false;
158     };
159
160     typedef WTF::HashMap<GCObject*, T, V8HandlePtrHash<GCObject> > HandleToT;
161     HandleToT m_map;
162 };
163
164 typedef UChar BufferValueType;
165
166 // Serialization format is a sequence of tags followed by zero or more data arguments.
167 // Tags always take exactly one byte. A serialized stream first begins with
168 // a complete VersionTag. If the stream does not begin with a VersionTag, we assume that
169 // the stream is in format 0.
170
171 // This format is private to the implementation of SerializedScriptValue. Do not rely on it
172 // externally. It is safe to persist a SerializedScriptValue as a binary blob, but this
173 // code should always be used to interpret it.
174
175 // WebCoreStrings are read as (length:uint32_t, string:UTF8[length]).
176 // RawStrings are read as (length:uint32_t, string:UTF8[length]).
177 // RawUCharStrings are read as (length:uint32_t, string:UChar[length/sizeof(UChar)]).
178 // RawFiles are read as (path:WebCoreString, url:WebCoreStrng, type:WebCoreString).
179 // There is a reference table that maps object references (uint32_t) to v8::Values.
180 // Tokens marked with (ref) are inserted into the reference table and given the next object reference ID after decoding.
181 // All tags except InvalidTag, PaddingTag, ReferenceCountTag, VersionTag, GenerateFreshObjectTag
182 //     and GenerateFreshArrayTag push their results to the deserialization stack.
183 // There is also an 'open' stack that is used to resolve circular references. Objects or arrays may
184 //     contain self-references. Before we begin to deserialize the contents of these values, they
185 //     are first given object reference IDs (by GenerateFreshObjectTag/GenerateFreshArrayTag);
186 //     these reference IDs are then used with ObjectReferenceTag to tie the recursive knot.
187 enum SerializationTag {
188     InvalidTag = '!', // Causes deserialization to fail.
189     PaddingTag = '\0', // Is ignored (but consumed).
190     UndefinedTag = '_', // -> <undefined>
191     NullTag = '0', // -> <null>
192     TrueTag = 'T', // -> <true>
193     FalseTag = 'F', // -> <false>
194     StringTag = 'S', // string:RawString -> string
195     StringUCharTag = 'c', // string:RawUCharString -> string
196     Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer
197     Uint32Tag = 'U', // value:uint32_t -> Integer
198     DateTag = 'D', // value:double -> Date (ref)
199     MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with transferred MessagePort.
200     NumberTag = 'N', // value:double -> Number
201     BlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
202     BlobIndexTag = 'i', // index:int32_t -> Blob (ref)
203     FileTag = 'f', // file:RawFile -> File (ref)
204     FileIndexTag = 'e', // index:int32_t -> File (ref)
205     DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, uuid:WebCoreString -> FileSystem (ref)
206     FileListTag = 'l', // length:uint32_t, files:RawFile[length] -> FileList (ref)
207     FileListIndexTag = 'L', // length:uint32_t, files:int32_t[length] -> FileList (ref)
208     ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint32_t, data:byte[pixelDataLength] -> ImageData (ref)
209     ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the open stack;
210                      //                           fills it with the last numProperties name,value pairs pushed onto the deserialization stack
211     SparseArrayTag = '@', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack;
212                           //                                            fills it with the last numProperties name,value pairs pushed onto the deserialization stack
213     DenseArrayTag = '$', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack;
214                          //                                            fills it with the last length elements and numProperties name,value pairs pushed onto deserialization stack
215     RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref)
216     ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> ArrayBuffer (ref)
217     ArrayBufferTransferTag = 't', // index:uint32_t -> ArrayBuffer. For ArrayBuffer transfer
218     ArrayBufferViewTag = 'V', // subtag:byte, byteOffset:uint32_t, byteLength:uint32_t -> ArrayBufferView (ref). Consumes an ArrayBuffer from the top of the deserialization stack.
219     CryptoKeyTag = 'K', // subtag:byte, props, usages:uint32_t, keyDataLength:uint32_t, keyData:byte[keyDataLength]
220                         //   If subtag=AesKeyTag:
221                         //       props = keyLengthBytes:uint32_t, algorithmId:uint32_t
222                         //   If subtag=HmacKeyTag:
223                         //       props = keyLengthBytes:uint32_t, hashId:uint32_t
224                         //   If subtag=RsaKeyTag:
225                         //       props = algorithmId:uint32_t, type:uint32_t, modulusLengthBits:uint32_t, publicExponentLength:uint32_t, publicExponent:byte[publicExponentLength]
226                         //   If subtag=RsaHashedKeyTag:
227                         //       props = <same as for RsaKeyTag>, hashId:uint32_t
228     ObjectReferenceTag = '^', // ref:uint32_t -> reference table[ref]
229     GenerateFreshObjectTag = 'o', // -> empty object allocated an object ID and pushed onto the open stack (ref)
230     GenerateFreshSparseArrayTag = 'a', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref)
231     GenerateFreshDenseArrayTag = 'A', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref)
232     ReferenceCountTag = '?', // refTableSize:uint32_t -> If the reference table is not refTableSize big, fails.
233     StringObjectTag = 's', //  string:RawString -> new String(string) (ref)
234     NumberObjectTag = 'n', // value:double -> new Number(value) (ref)
235     TrueObjectTag = 'y', // new Boolean(true) (ref)
236     FalseObjectTag = 'x', // new Boolean(false) (ref)
237     VersionTag = 0xFF // version:uint32_t -> Uses this as the file version.
238 };
239
240 enum ArrayBufferViewSubTag {
241     ByteArrayTag = 'b',
242     UnsignedByteArrayTag = 'B',
243     UnsignedByteClampedArrayTag = 'C',
244     ShortArrayTag = 'w',
245     UnsignedShortArrayTag = 'W',
246     IntArrayTag = 'd',
247     UnsignedIntArrayTag = 'D',
248     FloatArrayTag = 'f',
249     DoubleArrayTag = 'F',
250     DataViewTag = '?'
251 };
252
253 enum CryptoKeySubTag {
254     AesKeyTag = 1,
255     HmacKeyTag = 2,
256     RsaKeyTag = 3,
257     RsaHashedKeyTag = 4,
258     // Maximum allowed value is 255
259 };
260
261 enum AssymetricCryptoKeyType {
262     PublicKeyType = 1,
263     PrivateKeyType = 2,
264     // Maximum allowed value is 2^32-1
265 };
266
267 enum CryptoKeyAlgorithmTag {
268     AesCbcTag = 1,
269     HmacTag = 2,
270     RsaSsaPkcs1v1_5Tag = 3,
271     RsaEsPkcs1v1_5Tag = 4,
272     Sha1Tag = 5,
273     Sha256Tag = 6,
274     Sha384Tag = 7,
275     Sha512Tag = 8,
276     AesGcmTag = 9,
277     RsaOaepTag = 10,
278     AesCtrTag = 11,
279     AesKwTag = 12,
280     // Maximum allowed value is 2^32-1
281 };
282
283 enum CryptoKeyUsage {
284     // Extractability is not a "usage" in the WebCryptoKeyUsages sense, however
285     // it fits conveniently into this bitfield.
286     ExtractableUsage = 1 << 0,
287
288     EncryptUsage = 1 << 1,
289     DecryptUsage = 1 << 2,
290     SignUsage = 1 << 3,
291     VerifyUsage = 1 << 4,
292     DeriveKeyUsage = 1 << 5,
293     WrapKeyUsage = 1 << 6,
294     UnwrapKeyUsage = 1 << 7,
295     DeriveBitsUsage = 1 << 8,
296     // Maximum allowed value is 1 << 31
297 };
298
299 static bool shouldCheckForCycles(int depth)
300 {
301     ASSERT(depth >= 0);
302     // Since we are not required to spot the cycle as soon as it
303     // happens we can check for cycles only when the current depth
304     // is a power of two.
305     return !(depth & (depth - 1));
306 }
307
308 static const int maxDepth = 20000;
309
310 // VarInt encoding constants.
311 static const int varIntShift = 7;
312 static const int varIntMask = (1 << varIntShift) - 1;
313
314 // ZigZag encoding helps VarInt encoding stay small for negative
315 // numbers with small absolute values.
316 class ZigZag {
317 public:
318     static uint32_t encode(uint32_t value)
319     {
320         if (value & (1U << 31))
321             value = ((~value) << 1) + 1;
322         else
323             value <<= 1;
324         return value;
325     }
326
327     static uint32_t decode(uint32_t value)
328     {
329         if (value & 1)
330             value = ~(value >> 1);
331         else
332             value >>= 1;
333         return value;
334     }
335
336 private:
337     ZigZag();
338 };
339
340 // Writer is responsible for serializing primitive types and storing
341 // information used to reconstruct composite types.
342 class Writer {
343     WTF_MAKE_NONCOPYABLE(Writer);
344 public:
345     Writer()
346         : m_position(0)
347     {
348     }
349
350     // Write functions for primitive types.
351
352     void writeUndefined() { append(UndefinedTag); }
353
354     void writeNull() { append(NullTag); }
355
356     void writeTrue() { append(TrueTag); }
357
358     void writeFalse() { append(FalseTag); }
359
360     void writeBooleanObject(bool value)
361     {
362         append(value ? TrueObjectTag : FalseObjectTag);
363     }
364
365     void writeOneByteString(v8::Handle<v8::String>& string)
366     {
367         int stringLength = string->Length();
368         int utf8Length = string->Utf8Length();
369         ASSERT(stringLength >= 0 && utf8Length >= 0);
370
371         append(StringTag);
372         doWriteUint32(static_cast<uint32_t>(utf8Length));
373         ensureSpace(utf8Length);
374
375         // ASCII fast path.
376         if (stringLength == utf8Length)
377             string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOptions());
378         else {
379             char* buffer = reinterpret_cast<char*>(byteAt(m_position));
380             string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions());
381         }
382         m_position += utf8Length;
383     }
384
385     void writeUCharString(v8::Handle<v8::String>& string)
386     {
387         int length = string->Length();
388         ASSERT(length >= 0);
389
390         int size = length * sizeof(UChar);
391         int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size));
392         if ((m_position + 1 + bytes) & 1)
393             append(PaddingTag);
394
395         append(StringUCharTag);
396         doWriteUint32(static_cast<uint32_t>(size));
397         ensureSpace(size);
398
399         ASSERT(!(m_position & 1));
400         uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position));
401         string->Write(buffer, 0, length, v8StringWriteOptions());
402         m_position += size;
403     }
404
405     void writeStringObject(const char* data, int length)
406     {
407         ASSERT(length >= 0);
408         append(StringObjectTag);
409         doWriteString(data, length);
410     }
411
412     void writeWebCoreString(const String& string)
413     {
414         // Uses UTF8 encoding so we can read it back as either V8 or
415         // WebCore string.
416         append(StringTag);
417         doWriteWebCoreString(string);
418     }
419
420     void writeVersion()
421     {
422         append(VersionTag);
423         doWriteUint32(SerializedScriptValue::wireFormatVersion);
424     }
425
426     void writeInt32(int32_t value)
427     {
428         append(Int32Tag);
429         doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
430     }
431
432     void writeUint32(uint32_t value)
433     {
434         append(Uint32Tag);
435         doWriteUint32(value);
436     }
437
438     void writeDate(double numberValue)
439     {
440         append(DateTag);
441         doWriteNumber(numberValue);
442     }
443
444     void writeNumber(double number)
445     {
446         append(NumberTag);
447         doWriteNumber(number);
448     }
449
450     void writeNumberObject(double number)
451     {
452         append(NumberObjectTag);
453         doWriteNumber(number);
454     }
455
456     void writeBlob(const String& uuid, const String& type, unsigned long long size)
457     {
458         append(BlobTag);
459         doWriteWebCoreString(uuid);
460         doWriteWebCoreString(type);
461         doWriteUint64(size);
462     }
463
464     void writeBlobIndex(int blobIndex)
465     {
466         ASSERT(blobIndex >= 0);
467         append(BlobIndexTag);
468         doWriteUint32(blobIndex);
469     }
470
471     void writeDOMFileSystem(int type, const String& name, const String& url)
472     {
473         append(DOMFileSystemTag);
474         doWriteUint32(type);
475         doWriteWebCoreString(name);
476         doWriteWebCoreString(url);
477     }
478
479     void writeFile(const File& file)
480     {
481         append(FileTag);
482         doWriteFile(file);
483     }
484
485     void writeFileIndex(int blobIndex)
486     {
487         append(FileIndexTag);
488         doWriteUint32(blobIndex);
489     }
490
491     void writeFileList(const FileList& fileList)
492     {
493         append(FileListTag);
494         uint32_t length = fileList.length();
495         doWriteUint32(length);
496         for (unsigned i = 0; i < length; ++i)
497             doWriteFile(*fileList.item(i));
498     }
499
500     void writeFileListIndex(const Vector<int>& blobIndices)
501     {
502         append(FileListIndexTag);
503         uint32_t length = blobIndices.size();
504         doWriteUint32(length);
505         for (unsigned i = 0; i < length; ++i)
506             doWriteUint32(blobIndices[i]);
507     }
508
509     bool writeCryptoKey(const blink::WebCryptoKey& key)
510     {
511         append(static_cast<uint8_t>(CryptoKeyTag));
512
513         switch (key.algorithm().paramsType()) {
514         case blink::WebCryptoKeyAlgorithmParamsTypeAes:
515             doWriteAesKey(key);
516             break;
517         case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
518             doWriteHmacKey(key);
519             break;
520         case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
521         case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
522             doWriteRsaKey(key);
523             break;
524         case blink::WebCryptoKeyAlgorithmParamsTypeNone:
525             ASSERT_NOT_REACHED();
526             return false;
527         }
528
529         doWriteKeyUsages(key.usages(), key.extractable());
530
531         blink::WebVector<uint8_t> keyData;
532         if (!blink::Platform::current()->crypto()->serializeKeyForClone(key, keyData))
533             return false;
534
535         doWriteUint32(keyData.size());
536         append(keyData.data(), keyData.size());
537         return true;
538     }
539
540     void writeArrayBuffer(const ArrayBuffer& arrayBuffer)
541     {
542         append(ArrayBufferTag);
543         doWriteArrayBuffer(arrayBuffer);
544     }
545
546     void writeArrayBufferView(const ArrayBufferView& arrayBufferView)
547     {
548         append(ArrayBufferViewTag);
549 #ifndef NDEBUG
550         const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer();
551         ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byteOffset() ==
552                static_cast<const uint8_t*>(arrayBufferView.baseAddress()));
553 #endif
554         ArrayBufferView::ViewType type = arrayBufferView.type();
555
556         if (type == ArrayBufferView::TypeInt8)
557             append(ByteArrayTag);
558         else if (type == ArrayBufferView::TypeUint8Clamped)
559             append(UnsignedByteClampedArrayTag);
560         else if (type == ArrayBufferView::TypeUint8)
561             append(UnsignedByteArrayTag);
562         else if (type == ArrayBufferView::TypeInt16)
563             append(ShortArrayTag);
564         else if (type == ArrayBufferView::TypeUint16)
565             append(UnsignedShortArrayTag);
566         else if (type == ArrayBufferView::TypeInt32)
567             append(IntArrayTag);
568         else if (type == ArrayBufferView::TypeUint32)
569             append(UnsignedIntArrayTag);
570         else if (type == ArrayBufferView::TypeFloat32)
571             append(FloatArrayTag);
572         else if (type == ArrayBufferView::TypeFloat64)
573             append(DoubleArrayTag);
574         else if (type == ArrayBufferView::TypeDataView)
575             append(DataViewTag);
576         else
577             ASSERT_NOT_REACHED();
578         doWriteUint32(arrayBufferView.byteOffset());
579         doWriteUint32(arrayBufferView.byteLength());
580     }
581
582     void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
583     {
584         append(ImageDataTag);
585         doWriteUint32(width);
586         doWriteUint32(height);
587         doWriteUint32(pixelDataLength);
588         append(pixelData, pixelDataLength);
589     }
590
591     void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags)
592     {
593         append(RegExpTag);
594         v8::String::Utf8Value patternUtf8Value(pattern);
595         doWriteString(*patternUtf8Value, patternUtf8Value.length());
596         doWriteUint32(static_cast<uint32_t>(flags));
597     }
598
599     void writeTransferredMessagePort(uint32_t index)
600     {
601         append(MessagePortTag);
602         doWriteUint32(index);
603     }
604
605     void writeTransferredArrayBuffer(uint32_t index)
606     {
607         append(ArrayBufferTransferTag);
608         doWriteUint32(index);
609     }
610
611     void writeObjectReference(uint32_t reference)
612     {
613         append(ObjectReferenceTag);
614         doWriteUint32(reference);
615     }
616
617     void writeObject(uint32_t numProperties)
618     {
619         append(ObjectTag);
620         doWriteUint32(numProperties);
621     }
622
623     void writeSparseArray(uint32_t numProperties, uint32_t length)
624     {
625         append(SparseArrayTag);
626         doWriteUint32(numProperties);
627         doWriteUint32(length);
628     }
629
630     void writeDenseArray(uint32_t numProperties, uint32_t length)
631     {
632         append(DenseArrayTag);
633         doWriteUint32(numProperties);
634         doWriteUint32(length);
635     }
636
637     String takeWireString()
638     {
639         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
640         fillHole();
641         String data = String(m_buffer.data(), m_buffer.size());
642         data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueType));
643         return data;
644     }
645
646     void writeReferenceCount(uint32_t numberOfReferences)
647     {
648         append(ReferenceCountTag);
649         doWriteUint32(numberOfReferences);
650     }
651
652     void writeGenerateFreshObject()
653     {
654         append(GenerateFreshObjectTag);
655     }
656
657     void writeGenerateFreshSparseArray(uint32_t length)
658     {
659         append(GenerateFreshSparseArrayTag);
660         doWriteUint32(length);
661     }
662
663     void writeGenerateFreshDenseArray(uint32_t length)
664     {
665         append(GenerateFreshDenseArrayTag);
666         doWriteUint32(length);
667     }
668
669 private:
670     void doWriteFile(const File& file)
671     {
672         doWriteWebCoreString(file.hasBackingFile() ? file.path() : "");
673         doWriteWebCoreString(file.name());
674         doWriteWebCoreString(file.webkitRelativePath());
675         doWriteWebCoreString(file.uuid());
676         doWriteWebCoreString(file.type());
677
678         // FIXME don't use 4 bytes to encode a flag.
679         if (file.hasValidSnapshotMetadata()) {
680             doWriteUint32(static_cast<uint8_t>(1));
681
682             long long size;
683             double lastModified;
684             file.captureSnapshot(size, lastModified);
685             doWriteUint64(static_cast<uint64_t>(size));
686             doWriteNumber(lastModified);
687         } else {
688             append(static_cast<uint8_t>(0));
689         }
690     }
691
692     void doWriteArrayBuffer(const ArrayBuffer& arrayBuffer)
693     {
694         uint32_t byteLength = arrayBuffer.byteLength();
695         doWriteUint32(byteLength);
696         append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength);
697     }
698
699     void doWriteString(const char* data, int length)
700     {
701         doWriteUint32(static_cast<uint32_t>(length));
702         append(reinterpret_cast<const uint8_t*>(data), length);
703     }
704
705     void doWriteWebCoreString(const String& string)
706     {
707         StringUTF8Adaptor stringUTF8(string);
708         doWriteString(stringUTF8.data(), stringUTF8.length());
709     }
710
711     void doWriteHmacKey(const blink::WebCryptoKey& key)
712     {
713         ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeHmac);
714
715         append(static_cast<uint8_t>(HmacKeyTag));
716         ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8));
717         doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8);
718         doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id());
719     }
720
721     void doWriteAesKey(const blink::WebCryptoKey& key)
722     {
723         ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeAes);
724
725         append(static_cast<uint8_t>(AesKeyTag));
726         doWriteAlgorithmId(key.algorithm().id());
727         // Converting the key length from bits to bytes is lossless and makes
728         // it fit in 1 byte.
729         ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8));
730         doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8);
731     }
732
733     void doWriteRsaKey(const blink::WebCryptoKey& key)
734     {
735         if (key.algorithm().rsaHashedParams())
736             append(static_cast<uint8_t>(RsaHashedKeyTag));
737         else
738             append(static_cast<uint8_t>(RsaKeyTag));
739
740         doWriteAlgorithmId(key.algorithm().id());
741
742         switch (key.type()) {
743         case blink::WebCryptoKeyTypePublic:
744             doWriteUint32(PublicKeyType);
745             break;
746         case blink::WebCryptoKeyTypePrivate:
747             doWriteUint32(PrivateKeyType);
748             break;
749         case blink::WebCryptoKeyTypeSecret:
750             ASSERT_NOT_REACHED();
751         }
752
753         const blink::WebCryptoRsaKeyAlgorithmParams* params = key.algorithm().rsaParams();
754         doWriteUint32(params->modulusLengthBits());
755         doWriteUint32(params->publicExponent().size());
756         append(params->publicExponent().data(), params->publicExponent().size());
757
758         if (key.algorithm().rsaHashedParams())
759             doWriteAlgorithmId(key.algorithm().rsaHashedParams()->hash().id());
760     }
761
762     void doWriteAlgorithmId(blink::WebCryptoAlgorithmId id)
763     {
764         switch (id) {
765         case blink::WebCryptoAlgorithmIdAesCbc:
766             return doWriteUint32(AesCbcTag);
767         case blink::WebCryptoAlgorithmIdHmac:
768             return doWriteUint32(HmacTag);
769         case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
770             return doWriteUint32(RsaSsaPkcs1v1_5Tag);
771         case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
772             return doWriteUint32(RsaEsPkcs1v1_5Tag);
773         case blink::WebCryptoAlgorithmIdSha1:
774             return doWriteUint32(Sha1Tag);
775         case blink::WebCryptoAlgorithmIdSha256:
776             return doWriteUint32(Sha256Tag);
777         case blink::WebCryptoAlgorithmIdSha384:
778             return doWriteUint32(Sha384Tag);
779         case blink::WebCryptoAlgorithmIdSha512:
780             return doWriteUint32(Sha512Tag);
781         case blink::WebCryptoAlgorithmIdAesGcm:
782             return doWriteUint32(AesGcmTag);
783         case blink::WebCryptoAlgorithmIdRsaOaep:
784             return doWriteUint32(RsaOaepTag);
785         case blink::WebCryptoAlgorithmIdAesCtr:
786             return doWriteUint32(AesCtrTag);
787         case blink::WebCryptoAlgorithmIdAesKw:
788             return doWriteUint32(AesKwTag);
789         }
790         ASSERT_NOT_REACHED();
791     }
792
793     void doWriteKeyUsages(const blink::WebCryptoKeyUsageMask usages, bool extractable)
794     {
795         // Reminder to update this when adding new key usages.
796         COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
797
798         uint32_t value = 0;
799
800         if (extractable)
801             value |= ExtractableUsage;
802
803         if (usages & blink::WebCryptoKeyUsageEncrypt)
804             value |= EncryptUsage;
805         if (usages & blink::WebCryptoKeyUsageDecrypt)
806             value |= DecryptUsage;
807         if (usages & blink::WebCryptoKeyUsageSign)
808             value |= SignUsage;
809         if (usages & blink::WebCryptoKeyUsageVerify)
810             value |= VerifyUsage;
811         if (usages & blink::WebCryptoKeyUsageDeriveKey)
812             value |= DeriveKeyUsage;
813         if (usages & blink::WebCryptoKeyUsageWrapKey)
814             value |= WrapKeyUsage;
815         if (usages & blink::WebCryptoKeyUsageUnwrapKey)
816             value |= UnwrapKeyUsage;
817         if (usages & blink::WebCryptoKeyUsageDeriveBits)
818             value |= DeriveBitsUsage;
819
820         doWriteUint32(value);
821     }
822
823     int bytesNeededToWireEncode(uint32_t value)
824     {
825         int bytes = 1;
826         while (true) {
827             value >>= varIntShift;
828             if (!value)
829                 break;
830             ++bytes;
831         }
832
833         return bytes;
834     }
835
836     template<class T>
837     void doWriteUintHelper(T value)
838     {
839         while (true) {
840             uint8_t b = (value & varIntMask);
841             value >>= varIntShift;
842             if (!value) {
843                 append(b);
844                 break;
845             }
846             append(b | (1 << varIntShift));
847         }
848     }
849
850     void doWriteUint32(uint32_t value)
851     {
852         doWriteUintHelper(value);
853     }
854
855     void doWriteUint64(uint64_t value)
856     {
857         doWriteUintHelper(value);
858     }
859
860     void doWriteNumber(double number)
861     {
862         append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
863     }
864
865     void append(SerializationTag tag)
866     {
867         append(static_cast<uint8_t>(tag));
868     }
869
870     void append(uint8_t b)
871     {
872         ensureSpace(1);
873         *byteAt(m_position++) = b;
874     }
875
876     void append(const uint8_t* data, int length)
877     {
878         ensureSpace(length);
879         memcpy(byteAt(m_position), data, length);
880         m_position += length;
881     }
882
883     void ensureSpace(unsigned extra)
884     {
885         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
886         m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1" to round up.
887     }
888
889     void fillHole()
890     {
891         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
892         // If the writer is at odd position in the buffer, then one of
893         // the bytes in the last UChar is not initialized.
894         if (m_position % 2)
895             *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
896     }
897
898     uint8_t* byteAt(int position)
899     {
900         return reinterpret_cast<uint8_t*>(m_buffer.data()) + position;
901     }
902
903     int v8StringWriteOptions()
904     {
905         return v8::String::NO_NULL_TERMINATION;
906     }
907
908     Vector<BufferValueType> m_buffer;
909     unsigned m_position;
910 };
911
912 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Isolate* isolate)
913 {
914     if (!impl)
915         return v8::Handle<v8::Object>();
916     v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
917     ASSERT(wrapper->IsObject());
918     return wrapper.As<v8::Object>();
919 }
920
921 static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Isolate* isolate)
922 {
923     if (!impl)
924         return v8::Handle<v8::ArrayBuffer>();
925     v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
926     ASSERT(wrapper->IsArrayBuffer());
927     return wrapper.As<v8::ArrayBuffer>();
928 }
929
930 class Serializer {
931     class StateBase;
932 public:
933     enum Status {
934         Success,
935         InputError,
936         DataCloneError,
937         JSException
938     };
939
940     Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::Isolate* isolate)
941         : m_writer(writer)
942         , m_tryCatch(tryCatch)
943         , m_depth(0)
944         , m_status(Success)
945         , m_nextObjectReference(0)
946         , m_blobInfo(blobInfo)
947         , m_blobDataHandles(blobDataHandles)
948         , m_isolate(isolate)
949     {
950         ASSERT(!tryCatch.HasCaught());
951         if (messagePorts) {
952             for (size_t i = 0; i < messagePorts->size(); i++)
953                 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), isolate), i);
954         }
955         if (arrayBuffers) {
956             for (size_t i = 0; i < arrayBuffers->size(); i++)  {
957                 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), isolate);
958                 // Coalesce multiple occurences of the same buffer to the first index.
959                 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
960                     m_transferredArrayBuffers.set(v8ArrayBuffer, i);
961             }
962         }
963     }
964
965     Status serialize(v8::Handle<v8::Value> value)
966     {
967         v8::HandleScope scope(m_isolate);
968         m_writer.writeVersion();
969         StateBase* state = doSerialize(value, 0);
970         while (state)
971             state = state->advance(*this);
972         return m_status;
973     }
974
975     String errorMessage() { return m_errorMessage; }
976
977     // Functions used by serialization states.
978     StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next);
979
980     StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBase* next)
981     {
982         return doSerialize(arrayBuffer, next);
983     }
984
985     StateBase* checkException(StateBase* state)
986     {
987         return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0;
988     }
989
990     StateBase* writeObject(uint32_t numProperties, StateBase* state)
991     {
992         m_writer.writeObject(numProperties);
993         return pop(state);
994     }
995
996     StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
997     {
998         m_writer.writeSparseArray(numProperties, length);
999         return pop(state);
1000     }
1001
1002     StateBase* writeDenseArray(uint32_t numProperties, uint32_t length, StateBase* state)
1003     {
1004         m_writer.writeDenseArray(numProperties, length);
1005         return pop(state);
1006     }
1007
1008
1009 private:
1010     class StateBase {
1011         WTF_MAKE_NONCOPYABLE(StateBase);
1012     public:
1013         virtual ~StateBase() { }
1014
1015         // Link to the next state to form a stack.
1016         StateBase* nextState() { return m_next; }
1017
1018         // Composite object we're processing in this state.
1019         v8::Handle<v8::Value> composite() { return m_composite; }
1020
1021         // Serializes (a part of) the current composite and returns
1022         // the next state to process or null when this is the final
1023         // state.
1024         virtual StateBase* advance(Serializer&) = 0;
1025
1026     protected:
1027         StateBase(v8::Handle<v8::Value> composite, StateBase* next)
1028             : m_composite(composite)
1029             , m_next(next)
1030         {
1031         }
1032
1033     private:
1034         v8::Handle<v8::Value> m_composite;
1035         StateBase* m_next;
1036     };
1037
1038     // Dummy state that is used to signal serialization errors.
1039     class ErrorState FINAL : public StateBase {
1040     public:
1041         ErrorState()
1042             : StateBase(v8Undefined(), 0)
1043         {
1044         }
1045
1046         virtual StateBase* advance(Serializer&) OVERRIDE
1047         {
1048             delete this;
1049             return 0;
1050         }
1051     };
1052
1053     template <typename T>
1054     class State : public StateBase {
1055     public:
1056         v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
1057
1058     protected:
1059         State(v8::Handle<T> composite, StateBase* next)
1060             : StateBase(composite, next)
1061         {
1062         }
1063     };
1064
1065     class AbstractObjectState : public State<v8::Object> {
1066     public:
1067         AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
1068             : State<v8::Object>(object, next)
1069             , m_index(0)
1070             , m_numSerializedProperties(0)
1071             , m_nameDone(false)
1072         {
1073         }
1074
1075     protected:
1076         virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
1077
1078         StateBase* serializeProperties(bool ignoreIndexed, Serializer& serializer)
1079         {
1080             while (m_index < m_propertyNames->Length()) {
1081                 if (!m_nameDone) {
1082                     v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
1083                     if (StateBase* newState = serializer.checkException(this))
1084                         return newState;
1085                     if (propertyName.IsEmpty())
1086                         return serializer.handleError(InputError, "Empty property names cannot be cloned.", this);
1087                     bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>());
1088                     if (StateBase* newState = serializer.checkException(this))
1089                         return newState;
1090                     bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value());
1091                     if (StateBase* newState = serializer.checkException(this))
1092                         return newState;
1093                     if (hasStringProperty || (hasIndexedProperty && !ignoreIndexed))
1094                         m_propertyName = propertyName;
1095                     else {
1096                         ++m_index;
1097                         continue;
1098                     }
1099                 }
1100                 ASSERT(!m_propertyName.IsEmpty());
1101                 if (!m_nameDone) {
1102                     m_nameDone = true;
1103                     if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
1104                         return newState;
1105                 }
1106                 v8::Local<v8::Value> value = composite()->Get(m_propertyName);
1107                 if (StateBase* newState = serializer.checkException(this))
1108                     return newState;
1109                 m_nameDone = false;
1110                 m_propertyName.Clear();
1111                 ++m_index;
1112                 ++m_numSerializedProperties;
1113                 // If we return early here, it's either because we have pushed a new state onto the
1114                 // serialization state stack or because we have encountered an error (and in both cases
1115                 // we are unwinding the native stack).
1116                 if (StateBase* newState = serializer.doSerialize(value, this))
1117                     return newState;
1118             }
1119             return objectDone(m_numSerializedProperties, serializer);
1120         }
1121
1122         v8::Local<v8::Array> m_propertyNames;
1123
1124     private:
1125         v8::Local<v8::Value> m_propertyName;
1126         unsigned m_index;
1127         unsigned m_numSerializedProperties;
1128         bool m_nameDone;
1129     };
1130
1131     class ObjectState FINAL : public AbstractObjectState {
1132     public:
1133         ObjectState(v8::Handle<v8::Object> object, StateBase* next)
1134             : AbstractObjectState(object, next)
1135         {
1136         }
1137
1138         virtual StateBase* advance(Serializer& serializer) OVERRIDE
1139         {
1140             if (m_propertyNames.IsEmpty()) {
1141                 m_propertyNames = composite()->GetPropertyNames();
1142                 if (StateBase* newState = serializer.checkException(this))
1143                     return newState;
1144                 if (m_propertyNames.IsEmpty())
1145                     return serializer.handleError(InputError, "Empty property names cannot be cloned.", nextState());
1146             }
1147             return serializeProperties(false, serializer);
1148         }
1149
1150     protected:
1151         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
1152         {
1153             return serializer.writeObject(numProperties, this);
1154         }
1155     };
1156
1157     class DenseArrayState FINAL : public AbstractObjectState {
1158     public:
1159         DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
1160             : AbstractObjectState(array, next)
1161             , m_arrayIndex(0)
1162             , m_arrayLength(array->Length())
1163         {
1164             m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
1165         }
1166
1167         virtual StateBase* advance(Serializer& serializer) OVERRIDE
1168         {
1169             while (m_arrayIndex < m_arrayLength) {
1170                 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIndex);
1171                 m_arrayIndex++;
1172                 if (StateBase* newState = serializer.checkException(this))
1173                     return newState;
1174                 if (StateBase* newState = serializer.doSerialize(value, this))
1175                     return newState;
1176             }
1177             return serializeProperties(true, serializer);
1178         }
1179
1180     protected:
1181         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
1182         {
1183             return serializer.writeDenseArray(numProperties, m_arrayLength, this);
1184         }
1185
1186     private:
1187         uint32_t m_arrayIndex;
1188         uint32_t m_arrayLength;
1189     };
1190
1191     class SparseArrayState FINAL : public AbstractObjectState {
1192     public:
1193         SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
1194             : AbstractObjectState(array, next)
1195         {
1196             m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
1197         }
1198
1199         virtual StateBase* advance(Serializer& serializer) OVERRIDE
1200         {
1201             return serializeProperties(false, serializer);
1202         }
1203
1204     protected:
1205         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
1206         {
1207             return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
1208         }
1209     };
1210
1211     StateBase* push(StateBase* state)
1212     {
1213         ASSERT(state);
1214         ++m_depth;
1215         return checkComposite(state) ? state : handleError(InputError, "Value being cloned is either cyclic or too deeply nested.", state);
1216     }
1217
1218     StateBase* pop(StateBase* state)
1219     {
1220         ASSERT(state);
1221         --m_depth;
1222         StateBase* next = state->nextState();
1223         delete state;
1224         return next;
1225     }
1226
1227     StateBase* handleError(Status errorStatus, const String& message, StateBase* state)
1228     {
1229         ASSERT(errorStatus != Success);
1230         m_status = errorStatus;
1231         m_errorMessage = message;
1232         while (state) {
1233             StateBase* tmp = state->nextState();
1234             delete state;
1235             state = tmp;
1236         }
1237         return new ErrorState;
1238     }
1239
1240     bool checkComposite(StateBase* top)
1241     {
1242         ASSERT(top);
1243         if (m_depth > maxDepth)
1244             return false;
1245         if (!shouldCheckForCycles(m_depth))
1246             return true;
1247         v8::Handle<v8::Value> composite = top->composite();
1248         for (StateBase* state = top->nextState(); state; state = state->nextState()) {
1249             if (state->composite() == composite)
1250                 return false;
1251         }
1252         return true;
1253     }
1254
1255     void writeString(v8::Handle<v8::Value> value)
1256     {
1257         v8::Handle<v8::String> string = value.As<v8::String>();
1258         if (!string->Length() || string->IsOneByte())
1259             m_writer.writeOneByteString(string);
1260         else
1261             m_writer.writeUCharString(string);
1262     }
1263
1264     void writeStringObject(v8::Handle<v8::Value> value)
1265     {
1266         v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>();
1267         v8::String::Utf8Value stringValue(stringObject->ValueOf());
1268         m_writer.writeStringObject(*stringValue, stringValue.length());
1269     }
1270
1271     void writeNumberObject(v8::Handle<v8::Value> value)
1272     {
1273         v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>();
1274         m_writer.writeNumberObject(numberObject->ValueOf());
1275     }
1276
1277     void writeBooleanObject(v8::Handle<v8::Value> value)
1278     {
1279         v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>();
1280         m_writer.writeBooleanObject(booleanObject->ValueOf());
1281     }
1282
1283     StateBase* writeBlob(v8::Handle<v8::Value> value, StateBase* next)
1284     {
1285         Blob* blob = V8Blob::toNative(value.As<v8::Object>());
1286         if (!blob)
1287             return 0;
1288         if (blob->hasBeenClosed())
1289             return handleError(DataCloneError, "A Blob object has been closed, and could therefore not be cloned.", next);
1290         int blobIndex = -1;
1291         m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle());
1292         if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex))
1293             m_writer.writeBlobIndex(blobIndex);
1294         else
1295             m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
1296         return 0;
1297     }
1298
1299     StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next)
1300     {
1301         DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>());
1302         if (!fs)
1303             return 0;
1304         if (!fs->clonable())
1305             return handleError(DataCloneError, "A FileSystem object could not be cloned.", next);
1306         m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string());
1307         return 0;
1308     }
1309
1310     StateBase* writeFile(v8::Handle<v8::Value> value, StateBase* next)
1311     {
1312         File* file = V8File::toNative(value.As<v8::Object>());
1313         if (!file)
1314             return 0;
1315         if (file->hasBeenClosed())
1316             return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
1317         int blobIndex = -1;
1318         m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
1319         if (appendFileInfo(file->uuid(), file->path(), file->name(), file->type(), &blobIndex)) {
1320             ASSERT(blobIndex >= 0);
1321             m_writer.writeFileIndex(blobIndex);
1322         } else {
1323             m_writer.writeFile(*file);
1324         }
1325         return 0;
1326     }
1327
1328     StateBase* writeFileList(v8::Handle<v8::Value> value, StateBase* next)
1329     {
1330         FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
1331         if (!fileList)
1332             return 0;
1333         unsigned length = fileList->length();
1334         Vector<int> blobIndices;
1335         for (unsigned i = 0; i < length; ++i) {
1336             int blobIndex = -1;
1337             const File* file = fileList->item(i);
1338             if (file->hasBeenClosed())
1339                 return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
1340             m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
1341             if (appendFileInfo(file->uuid(), file->path(), file->name(), file->type(), &blobIndex)) {
1342                 ASSERT(!i || blobIndex > 0);
1343                 ASSERT(blobIndex >= 0);
1344                 blobIndices.append(blobIndex);
1345             }
1346         }
1347         if (!blobIndices.isEmpty())
1348             m_writer.writeFileListIndex(blobIndices);
1349         else
1350             m_writer.writeFileList(*fileList);
1351         return 0;
1352     }
1353
1354     bool writeCryptoKey(v8::Handle<v8::Value> value)
1355     {
1356         Key* key = V8Key::toNative(value.As<v8::Object>());
1357         if (!key)
1358             return false;
1359         return m_writer.writeCryptoKey(key->key());
1360     }
1361
1362     void writeImageData(v8::Handle<v8::Value> value)
1363     {
1364         ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
1365         if (!imageData)
1366             return;
1367         Uint8ClampedArray* pixelArray = imageData->data();
1368         m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
1369     }
1370
1371     void writeRegExp(v8::Handle<v8::Value> value)
1372     {
1373         v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>();
1374         m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
1375     }
1376
1377     StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object> object, StateBase* next)
1378     {
1379         ASSERT(!object.IsEmpty());
1380         ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object);
1381         if (!arrayBufferView)
1382             return 0;
1383         if (!arrayBufferView->buffer())
1384             return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
1385         v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_isolate);
1386         if (underlyingBuffer.IsEmpty())
1387             return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
1388         StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1389         if (stateOut)
1390             return stateOut;
1391         m_writer.writeArrayBufferView(*arrayBufferView);
1392         // This should be safe: we serialize something that we know to be a wrapper (see
1393         // the toV8 call above), so the call to doSerializeArrayBuffer should neither
1394         // cause the system stack to overflow nor should it have potential to reach
1395         // this ArrayBufferView again.
1396         //
1397         // We do need to grey the underlying buffer before we grey its view, however;
1398         // ArrayBuffers may be shared, so they need to be given reference IDs, and an
1399         // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer
1400         // (or without an additional tag that would allow us to do two-stage construction
1401         // like we do for Objects and Arrays).
1402         greyObject(object);
1403         return 0;
1404     }
1405
1406     StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next)
1407     {
1408         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>());
1409         if (!arrayBuffer)
1410             return 0;
1411         if (arrayBuffer->isNeutered())
1412             return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1413         ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
1414         m_writer.writeArrayBuffer(*arrayBuffer);
1415         return 0;
1416     }
1417
1418     StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next)
1419     {
1420         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>());
1421         if (!arrayBuffer)
1422             return 0;
1423         if (arrayBuffer->isNeutered())
1424             return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1425         m_writer.writeTransferredArrayBuffer(index);
1426         return 0;
1427     }
1428
1429     static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount)
1430     {
1431         // Let K be the cost of serializing all property values that are there
1432         // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t key)
1433         // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for all properties that are not there)
1434         // so densely is better than sparsly whenever 6*propertyCount > length
1435         return 6 * propertyCount >= length;
1436     }
1437
1438     StateBase* startArrayState(v8::Handle<v8::Array> array, StateBase* next)
1439     {
1440         v8::Handle<v8::Array> propertyNames = array->GetPropertyNames();
1441         if (StateBase* newState = checkException(next))
1442             return newState;
1443         uint32_t length = array->Length();
1444
1445         if (shouldSerializeDensely(length, propertyNames->Length())) {
1446             m_writer.writeGenerateFreshDenseArray(length);
1447             return push(new DenseArrayState(array, propertyNames, next, m_isolate));
1448         }
1449
1450         m_writer.writeGenerateFreshSparseArray(length);
1451         return push(new SparseArrayState(array, propertyNames, next, m_isolate));
1452     }
1453
1454     StateBase* startObjectState(v8::Handle<v8::Object> object, StateBase* next)
1455     {
1456         m_writer.writeGenerateFreshObject();
1457         // FIXME: check not a wrapper
1458         return push(new ObjectState(object, next));
1459     }
1460
1461     // Marks object as having been visited by the serializer and assigns it a unique object reference ID.
1462     // An object may only be greyed once.
1463     void greyObject(const v8::Handle<v8::Object>& object)
1464     {
1465         ASSERT(!m_objectPool.contains(object));
1466         uint32_t objectReference = m_nextObjectReference++;
1467         m_objectPool.set(object, objectReference);
1468     }
1469
1470     bool appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index)
1471     {
1472         if (!m_blobInfo)
1473             return false;
1474         *index = m_blobInfo->size();
1475         m_blobInfo->append(blink::WebBlobInfo(uuid, type, size));
1476         return true;
1477     }
1478
1479     bool appendFileInfo(const String& uuid, const String& filePath, const String& fileName, const String& type, int* index)
1480     {
1481         if (!m_blobInfo)
1482             return false;
1483         *index = m_blobInfo->size();
1484         m_blobInfo->append(blink::WebBlobInfo(uuid, filePath, fileName, type));
1485         return true;
1486     }
1487
1488     Writer& m_writer;
1489     v8::TryCatch& m_tryCatch;
1490     int m_depth;
1491     Status m_status;
1492     String m_errorMessage;
1493     typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool;
1494     ObjectPool m_objectPool;
1495     ObjectPool m_transferredMessagePorts;
1496     ObjectPool m_transferredArrayBuffers;
1497     uint32_t m_nextObjectReference;
1498     WebBlobInfoArray* m_blobInfo;
1499     BlobDataHandleMap& m_blobDataHandles;
1500     v8::Isolate* m_isolate;
1501 };
1502
1503 // Returns true if the provided object is to be considered a 'host object', as used in the
1504 // HTML5 structured clone algorithm.
1505 static bool isHostObject(v8::Handle<v8::Object> object)
1506 {
1507     // If the object has any internal fields, then we won't be able to serialize or deserialize
1508     // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
1509     // the mechanism for these relies on data stored in these fields. We should
1510     // catch external array data as a special case.
1511     return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData();
1512 }
1513
1514 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
1515 {
1516     m_writer.writeReferenceCount(m_nextObjectReference);
1517     uint32_t objectReference;
1518     uint32_t arrayBufferIndex;
1519     if ((value->IsObject() || value->IsDate() || value->IsRegExp())
1520         && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
1521         // Note that IsObject() also detects wrappers (eg, it will catch the things
1522         // that we grey and write below).
1523         ASSERT(!value->IsString());
1524         m_writer.writeObjectReference(objectReference);
1525     } else if (value.IsEmpty()) {
1526         return handleError(InputError, "The empty property name cannot be cloned.", next);
1527     } else if (value->IsUndefined())
1528         m_writer.writeUndefined();
1529     else if (value->IsNull())
1530         m_writer.writeNull();
1531     else if (value->IsTrue())
1532         m_writer.writeTrue();
1533     else if (value->IsFalse())
1534         m_writer.writeFalse();
1535     else if (value->IsInt32())
1536         m_writer.writeInt32(value->Int32Value());
1537     else if (value->IsUint32())
1538         m_writer.writeUint32(value->Uint32Value());
1539     else if (value->IsNumber())
1540         m_writer.writeNumber(value.As<v8::Number>()->Value());
1541     else if (V8ArrayBufferView::hasInstance(value, m_isolate))
1542         return writeAndGreyArrayBufferView(value.As<v8::Object>(), next);
1543     else if (value->IsString())
1544         writeString(value);
1545     else if (V8MessagePort::hasInstance(value, m_isolate)) {
1546         uint32_t messagePortIndex;
1547         if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePortIndex))
1548                 m_writer.writeTransferredMessagePort(messagePortIndex);
1549             else
1550                 return handleError(DataCloneError, "A MessagePort could not be cloned.", next);
1551     } else if (V8ArrayBuffer::hasInstance(value, m_isolate) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex))
1552         return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
1553     else {
1554         v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
1555         if (jsObject.IsEmpty())
1556             return handleError(DataCloneError, "An object could not be cloned.", next);
1557         greyObject(jsObject);
1558         if (value->IsDate())
1559             m_writer.writeDate(value->NumberValue());
1560         else if (value->IsStringObject())
1561             writeStringObject(value);
1562         else if (value->IsNumberObject())
1563             writeNumberObject(value);
1564         else if (value->IsBooleanObject())
1565             writeBooleanObject(value);
1566         else if (value->IsArray()) {
1567             return startArrayState(value.As<v8::Array>(), next);
1568         } else if (V8File::hasInstance(value, m_isolate))
1569             return writeFile(value, next);
1570         else if (V8Blob::hasInstance(value, m_isolate))
1571             return writeBlob(value, next);
1572         else if (V8DOMFileSystem::hasInstance(value, m_isolate))
1573             return writeDOMFileSystem(value, next);
1574         else if (V8FileList::hasInstance(value, m_isolate))
1575             return writeFileList(value, next);
1576         else if (V8Key::hasInstance(value, m_isolate)) {
1577             if (!writeCryptoKey(value))
1578                 return handleError(DataCloneError, "Couldn't serialize key data", next);
1579         } else if (V8ImageData::hasInstance(value, m_isolate))
1580             writeImageData(value);
1581         else if (value->IsRegExp())
1582             writeRegExp(value);
1583         else if (V8ArrayBuffer::hasInstance(value, m_isolate))
1584             return writeArrayBuffer(value, next);
1585         else if (value->IsObject()) {
1586             if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNativeError())
1587                 return handleError(DataCloneError, "An object could not be cloned.", next);
1588             return startObjectState(jsObject, next);
1589         } else
1590             return handleError(DataCloneError, "A value could not be cloned.", next);
1591     }
1592     return 0;
1593 }
1594
1595 // Interface used by Reader to create objects of composite types.
1596 class CompositeCreator {
1597 public:
1598     virtual ~CompositeCreator() { }
1599
1600     virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0;
1601     virtual uint32_t objectReferenceCount() = 0;
1602     virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0;
1603     virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) = 0;
1604     virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) = 0;
1605     virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>*) = 0;
1606     virtual bool newSparseArray(uint32_t length) = 0;
1607     virtual bool newDenseArray(uint32_t length) = 0;
1608     virtual bool newObject() = 0;
1609     virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0;
1610     virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0;
1611     virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0;
1612 };
1613
1614 // Reader is responsible for deserializing primitive types and
1615 // restoring information about saved objects of composite types.
1616 class Reader {
1617 public:
1618     Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles)
1619         : m_buffer(buffer)
1620         , m_length(length)
1621         , m_position(0)
1622         , m_version(0)
1623         , m_isolate(isolate)
1624         , m_blobInfo(blobInfo)
1625         , m_blobDataHandles(blobDataHandles)
1626     {
1627         ASSERT(!(reinterpret_cast<size_t>(buffer) & 1));
1628         ASSERT(length >= 0);
1629     }
1630
1631     bool isEof() const { return m_position >= m_length; }
1632
1633     v8::Isolate* isolate() const { return m_isolate; }
1634
1635     bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
1636     {
1637         SerializationTag tag;
1638         if (!readTag(&tag))
1639             return false;
1640         switch (tag) {
1641         case ReferenceCountTag: {
1642             if (!m_version)
1643                 return false;
1644             uint32_t referenceTableSize;
1645             if (!doReadUint32(&referenceTableSize))
1646                 return false;
1647             // If this test fails, then the serializer and deserializer disagree about the assignment
1648             // of object reference IDs. On the deserialization side, this means there are too many or too few
1649             // calls to pushObjectReference.
1650             if (referenceTableSize != creator.objectReferenceCount())
1651                 return false;
1652             return true;
1653         }
1654         case InvalidTag:
1655             return false;
1656         case PaddingTag:
1657             return true;
1658         case UndefinedTag:
1659             *value = v8::Undefined(m_isolate);
1660             break;
1661         case NullTag:
1662             *value = v8::Null(m_isolate);
1663             break;
1664         case TrueTag:
1665             *value = v8Boolean(true, m_isolate);
1666             break;
1667         case FalseTag:
1668             *value = v8Boolean(false, m_isolate);
1669             break;
1670         case TrueObjectTag:
1671             *value = v8::BooleanObject::New(true);
1672             creator.pushObjectReference(*value);
1673             break;
1674         case FalseObjectTag:
1675             *value = v8::BooleanObject::New(false);
1676             creator.pushObjectReference(*value);
1677             break;
1678         case StringTag:
1679             if (!readString(value))
1680                 return false;
1681             break;
1682         case StringUCharTag:
1683             if (!readUCharString(value))
1684                 return false;
1685             break;
1686         case StringObjectTag:
1687             if (!readStringObject(value))
1688                 return false;
1689             creator.pushObjectReference(*value);
1690             break;
1691         case Int32Tag:
1692             if (!readInt32(value))
1693                 return false;
1694             break;
1695         case Uint32Tag:
1696             if (!readUint32(value))
1697                 return false;
1698             break;
1699         case DateTag:
1700             if (!readDate(value))
1701                 return false;
1702             creator.pushObjectReference(*value);
1703             break;
1704         case NumberTag:
1705             if (!readNumber(value))
1706                 return false;
1707             break;
1708         case NumberObjectTag:
1709             if (!readNumberObject(value))
1710                 return false;
1711             creator.pushObjectReference(*value);
1712             break;
1713         case BlobTag:
1714         case BlobIndexTag:
1715             if (!readBlob(value, tag == BlobIndexTag))
1716                 return false;
1717             creator.pushObjectReference(*value);
1718             break;
1719         case FileTag:
1720         case FileIndexTag:
1721             if (!readFile(value, tag == FileIndexTag))
1722                 return false;
1723             creator.pushObjectReference(*value);
1724             break;
1725         case DOMFileSystemTag:
1726             if (!readDOMFileSystem(value))
1727                 return false;
1728             creator.pushObjectReference(*value);
1729             break;
1730         case FileListTag:
1731         case FileListIndexTag:
1732             if (!readFileList(value, tag == FileListIndexTag))
1733                 return false;
1734             creator.pushObjectReference(*value);
1735             break;
1736         case CryptoKeyTag:
1737             if (!readCryptoKey(value))
1738                 return false;
1739             creator.pushObjectReference(*value);
1740             break;
1741         case ImageDataTag:
1742             if (!readImageData(value))
1743                 return false;
1744             creator.pushObjectReference(*value);
1745             break;
1746
1747         case RegExpTag:
1748             if (!readRegExp(value))
1749                 return false;
1750             creator.pushObjectReference(*value);
1751             break;
1752         case ObjectTag: {
1753             uint32_t numProperties;
1754             if (!doReadUint32(&numProperties))
1755                 return false;
1756             if (!creator.completeObject(numProperties, value))
1757                 return false;
1758             break;
1759         }
1760         case SparseArrayTag: {
1761             uint32_t numProperties;
1762             uint32_t length;
1763             if (!doReadUint32(&numProperties))
1764                 return false;
1765             if (!doReadUint32(&length))
1766                 return false;
1767             if (!creator.completeSparseArray(numProperties, length, value))
1768                 return false;
1769             break;
1770         }
1771         case DenseArrayTag: {
1772             uint32_t numProperties;
1773             uint32_t length;
1774             if (!doReadUint32(&numProperties))
1775                 return false;
1776             if (!doReadUint32(&length))
1777                 return false;
1778             if (!creator.completeDenseArray(numProperties, length, value))
1779                 return false;
1780             break;
1781         }
1782         case ArrayBufferViewTag: {
1783             if (!m_version)
1784                 return false;
1785             if (!readArrayBufferView(value, creator))
1786                 return false;
1787             creator.pushObjectReference(*value);
1788             break;
1789         }
1790         case ArrayBufferTag: {
1791             if (!m_version)
1792                 return false;
1793             if (!readArrayBuffer(value))
1794                 return false;
1795             creator.pushObjectReference(*value);
1796             break;
1797         }
1798         case GenerateFreshObjectTag: {
1799             if (!m_version)
1800                 return false;
1801             if (!creator.newObject())
1802                 return false;
1803             return true;
1804         }
1805         case GenerateFreshSparseArrayTag: {
1806             if (!m_version)
1807                 return false;
1808             uint32_t length;
1809             if (!doReadUint32(&length))
1810                 return false;
1811             if (!creator.newSparseArray(length))
1812                 return false;
1813             return true;
1814         }
1815         case GenerateFreshDenseArrayTag: {
1816             if (!m_version)
1817                 return false;
1818             uint32_t length;
1819             if (!doReadUint32(&length))
1820                 return false;
1821             if (!creator.newDenseArray(length))
1822                 return false;
1823             return true;
1824         }
1825         case MessagePortTag: {
1826             if (!m_version)
1827                 return false;
1828             uint32_t index;
1829             if (!doReadUint32(&index))
1830                 return false;
1831             if (!creator.tryGetTransferredMessagePort(index, value))
1832                 return false;
1833             break;
1834         }
1835         case ArrayBufferTransferTag: {
1836             if (!m_version)
1837                 return false;
1838             uint32_t index;
1839             if (!doReadUint32(&index))
1840                 return false;
1841             if (!creator.tryGetTransferredArrayBuffer(index, value))
1842                 return false;
1843             break;
1844         }
1845         case ObjectReferenceTag: {
1846             if (!m_version)
1847                 return false;
1848             uint32_t reference;
1849             if (!doReadUint32(&reference))
1850                 return false;
1851             if (!creator.tryGetObjectFromObjectReference(reference, value))
1852                 return false;
1853             break;
1854         }
1855         default:
1856             return false;
1857         }
1858         return !value->IsEmpty();
1859     }
1860
1861     bool readVersion(uint32_t& version)
1862     {
1863         SerializationTag tag;
1864         if (!readTag(&tag)) {
1865             // This is a nullary buffer. We're still version 0.
1866             version = 0;
1867             return true;
1868         }
1869         if (tag != VersionTag) {
1870             // Versions of the format past 0 start with the version tag.
1871             version = 0;
1872             // Put back the tag.
1873             undoReadTag();
1874             return true;
1875         }
1876         // Version-bearing messages are obligated to finish the version tag.
1877         return doReadUint32(&version);
1878     }
1879
1880     void setVersion(uint32_t version)
1881     {
1882         m_version = version;
1883     }
1884
1885     v8::Isolate* getIsolate() { return m_isolate; }
1886
1887 private:
1888     bool readTag(SerializationTag* tag)
1889     {
1890         if (m_position >= m_length)
1891             return false;
1892         *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
1893         return true;
1894     }
1895
1896     void undoReadTag()
1897     {
1898         if (m_position > 0)
1899             --m_position;
1900     }
1901
1902     bool readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag)
1903     {
1904         if (m_position >= m_length)
1905             return false;
1906         *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]);
1907         return true;
1908     }
1909
1910     bool readString(v8::Handle<v8::Value>* value)
1911     {
1912         uint32_t length;
1913         if (!doReadUint32(&length))
1914             return false;
1915         if (m_position + length > m_length)
1916             return false;
1917         *value = v8::String::NewFromUtf8(m_isolate, reinterpret_cast<const char*>(m_buffer + m_position), v8::String::kNormalString, length);
1918         m_position += length;
1919         return true;
1920     }
1921
1922     bool readUCharString(v8::Handle<v8::Value>* value)
1923     {
1924         uint32_t length;
1925         if (!doReadUint32(&length) || (length & 1))
1926             return false;
1927         if (m_position + length > m_length)
1928             return false;
1929         ASSERT(!(m_position & 1));
1930         *value = v8::String::NewFromTwoByte(m_isolate, reinterpret_cast<const uint16_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar));
1931         m_position += length;
1932         return true;
1933     }
1934
1935     bool readStringObject(v8::Handle<v8::Value>* value)
1936     {
1937         v8::Handle<v8::Value> stringValue;
1938         if (!readString(&stringValue) || !stringValue->IsString())
1939             return false;
1940         *value = v8::StringObject::New(stringValue.As<v8::String>());
1941         return true;
1942     }
1943
1944     bool readWebCoreString(String* string)
1945     {
1946         uint32_t length;
1947         if (!doReadUint32(&length))
1948             return false;
1949         if (m_position + length > m_length)
1950             return false;
1951         *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
1952         m_position += length;
1953         return true;
1954     }
1955
1956     bool readInt32(v8::Handle<v8::Value>* value)
1957     {
1958         uint32_t rawValue;
1959         if (!doReadUint32(&rawValue))
1960             return false;
1961         *value = v8::Integer::New(m_isolate, static_cast<int32_t>(ZigZag::decode(rawValue)));
1962         return true;
1963     }
1964
1965     bool readUint32(v8::Handle<v8::Value>* value)
1966     {
1967         uint32_t rawValue;
1968         if (!doReadUint32(&rawValue))
1969             return false;
1970         *value = v8::Integer::NewFromUnsigned(m_isolate, rawValue);
1971         return true;
1972     }
1973
1974     bool readDate(v8::Handle<v8::Value>* value)
1975     {
1976         double numberValue;
1977         if (!doReadNumber(&numberValue))
1978             return false;
1979         *value = v8DateOrNaN(numberValue, m_isolate);
1980         return true;
1981     }
1982
1983     bool readNumber(v8::Handle<v8::Value>* value)
1984     {
1985         double number;
1986         if (!doReadNumber(&number))
1987             return false;
1988         *value = v8::Number::New(m_isolate, number);
1989         return true;
1990     }
1991
1992     bool readNumberObject(v8::Handle<v8::Value>* value)
1993     {
1994         double number;
1995         if (!doReadNumber(&number))
1996             return false;
1997         *value = v8::NumberObject::New(m_isolate, number);
1998         return true;
1999     }
2000
2001     bool readImageData(v8::Handle<v8::Value>* value)
2002     {
2003         uint32_t width;
2004         uint32_t height;
2005         uint32_t pixelDataLength;
2006         if (!doReadUint32(&width))
2007             return false;
2008         if (!doReadUint32(&height))
2009             return false;
2010         if (!doReadUint32(&pixelDataLength))
2011             return false;
2012         if (m_position + pixelDataLength > m_length)
2013             return false;
2014         RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
2015         Uint8ClampedArray* pixelArray = imageData->data();
2016         ASSERT(pixelArray);
2017         ASSERT(pixelArray->length() >= pixelDataLength);
2018         memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
2019         m_position += pixelDataLength;
2020         *value = toV8(imageData.release(), v8::Handle<v8::Object>(), m_isolate);
2021         return true;
2022     }
2023
2024     PassRefPtr<ArrayBuffer> doReadArrayBuffer()
2025     {
2026         uint32_t byteLength;
2027         if (!doReadUint32(&byteLength))
2028             return nullptr;
2029         if (m_position + byteLength > m_length)
2030             return nullptr;
2031         const void* bufferStart = m_buffer + m_position;
2032         RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(bufferStart, byteLength);
2033         arrayBuffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
2034         m_position += byteLength;
2035         return arrayBuffer.release();
2036     }
2037
2038     bool readArrayBuffer(v8::Handle<v8::Value>* value)
2039     {
2040         RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer();
2041         if (!arrayBuffer)
2042             return false;
2043         *value = toV8(arrayBuffer.release(), v8::Handle<v8::Object>(), m_isolate);
2044         return true;
2045     }
2046
2047     bool readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator)
2048     {
2049         ArrayBufferViewSubTag subTag;
2050         uint32_t byteOffset;
2051         uint32_t byteLength;
2052         RefPtr<ArrayBuffer> arrayBuffer;
2053         v8::Handle<v8::Value> arrayBufferV8Value;
2054         if (!readArrayBufferViewSubTag(&subTag))
2055             return false;
2056         if (!doReadUint32(&byteOffset))
2057             return false;
2058         if (!doReadUint32(&byteLength))
2059             return false;
2060         if (!creator.consumeTopOfStack(&arrayBufferV8Value))
2061             return false;
2062         if (arrayBufferV8Value.IsEmpty())
2063             return false;
2064         arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>());
2065         if (!arrayBuffer)
2066             return false;
2067         switch (subTag) {
2068         case ByteArrayTag:
2069             *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
2070             break;
2071         case UnsignedByteArrayTag:
2072             *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(),  m_isolate);
2073             break;
2074         case UnsignedByteClampedArrayTag:
2075             *value = toV8(Uint8ClampedArray::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
2076             break;
2077         case ShortArrayTag: {
2078             uint32_t shortLength = byteLength / sizeof(int16_t);
2079             if (shortLength * sizeof(int16_t) != byteLength)
2080                 return false;
2081             *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
2082             break;
2083         }
2084         case UnsignedShortArrayTag: {
2085             uint32_t shortLength = byteLength / sizeof(uint16_t);
2086             if (shortLength * sizeof(uint16_t) != byteLength)
2087                 return false;
2088             *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
2089             break;
2090         }
2091         case IntArrayTag: {
2092             uint32_t intLength = byteLength / sizeof(int32_t);
2093             if (intLength * sizeof(int32_t) != byteLength)
2094                 return false;
2095             *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
2096             break;
2097         }
2098         case UnsignedIntArrayTag: {
2099             uint32_t intLength = byteLength / sizeof(uint32_t);
2100             if (intLength * sizeof(uint32_t) != byteLength)
2101                 return false;
2102             *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
2103             break;
2104         }
2105         case FloatArrayTag: {
2106             uint32_t floatLength = byteLength / sizeof(float);
2107             if (floatLength * sizeof(float) != byteLength)
2108                 return false;
2109             *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
2110             break;
2111         }
2112         case DoubleArrayTag: {
2113             uint32_t floatLength = byteLength / sizeof(double);
2114             if (floatLength * sizeof(double) != byteLength)
2115                 return false;
2116             *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
2117             break;
2118         }
2119         case DataViewTag:
2120             *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
2121             break;
2122         default:
2123             return false;
2124         }
2125         // The various *Array::create() methods will return null if the range the view expects is
2126         // mismatched with the range the buffer can provide or if the byte offset is not aligned
2127         // to the size of the element type.
2128         return !value->IsEmpty();
2129     }
2130
2131     bool readRegExp(v8::Handle<v8::Value>* value)
2132     {
2133         v8::Handle<v8::Value> pattern;
2134         if (!readString(&pattern))
2135             return false;
2136         uint32_t flags;
2137         if (!doReadUint32(&flags))
2138             return false;
2139         *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags));
2140         return true;
2141     }
2142
2143     bool readBlob(v8::Handle<v8::Value>* value, bool isIndexed)
2144     {
2145         if (m_version < 3)
2146             return false;
2147         RefPtrWillBeRawPtr<Blob> blob;
2148         if (isIndexed) {
2149             if (m_version < 6)
2150                 return false;
2151             ASSERT(m_blobInfo);
2152             uint32_t index;
2153             if (!doReadUint32(&index) || index >= m_blobInfo->size())
2154                 return false;
2155             const blink::WebBlobInfo& info = (*m_blobInfo)[index];
2156             blob = Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
2157         } else {
2158             ASSERT(!m_blobInfo);
2159             String uuid;
2160             String type;
2161             uint64_t size;
2162             ASSERT(!m_blobInfo);
2163             if (!readWebCoreString(&uuid))
2164                 return false;
2165             if (!readWebCoreString(&type))
2166                 return false;
2167             if (!doReadUint64(&size))
2168                 return false;
2169             blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
2170         }
2171         *value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate);
2172         return true;
2173     }
2174
2175     bool readDOMFileSystem(v8::Handle<v8::Value>* value)
2176     {
2177         uint32_t type;
2178         String name;
2179         String url;
2180         if (!doReadUint32(&type))
2181             return false;
2182         if (!readWebCoreString(&name))
2183             return false;
2184         if (!readWebCoreString(&url))
2185             return false;
2186         RefPtrWillBeRawPtr<DOMFileSystem> fs = DOMFileSystem::create(currentExecutionContext(m_isolate), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, url));
2187         *value = toV8(fs.release(), v8::Handle<v8::Object>(), m_isolate);
2188         return true;
2189     }
2190
2191     bool readFile(v8::Handle<v8::Value>* value, bool isIndexed)
2192     {
2193         RefPtrWillBeRawPtr<File> file;
2194         if (isIndexed) {
2195             if (m_version < 6)
2196                 return false;
2197             file = readFileIndexHelper();
2198         } else {
2199             file = readFileHelper();
2200         }
2201         if (!file)
2202             return false;
2203         *value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate);
2204         return true;
2205     }
2206
2207     bool readFileList(v8::Handle<v8::Value>* value, bool isIndexed)
2208     {
2209         if (m_version < 3)
2210             return false;
2211         uint32_t length;
2212         if (!doReadUint32(&length))
2213             return false;
2214         RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
2215         for (unsigned i = 0; i < length; ++i) {
2216             RefPtrWillBeRawPtr<File> file;
2217             if (isIndexed) {
2218                 if (m_version < 6)
2219                     return false;
2220                 file = readFileIndexHelper();
2221             } else {
2222                 file = readFileHelper();
2223             }
2224             if (!file)
2225                 return false;
2226             fileList->append(file.release());
2227         }
2228         *value = toV8(fileList.release(), v8::Handle<v8::Object>(), m_isolate);
2229         return true;
2230     }
2231
2232     bool readCryptoKey(v8::Handle<v8::Value>* value)
2233     {
2234         uint32_t rawKeyType;
2235         if (!doReadUint32(&rawKeyType))
2236             return false;
2237
2238         blink::WebCryptoKeyAlgorithm algorithm;
2239         blink::WebCryptoKeyType type;
2240
2241         switch (static_cast<CryptoKeySubTag>(rawKeyType)) {
2242         case AesKeyTag:
2243             if (!doReadAesKey(algorithm, type))
2244                 return false;
2245             break;
2246         case HmacKeyTag:
2247             if (!doReadHmacKey(algorithm, type))
2248                 return false;
2249             break;
2250         case RsaKeyTag:
2251             if (!doReadRsaKey(false, algorithm, type))
2252                 return false;
2253             break;
2254         case RsaHashedKeyTag:
2255             if (!doReadRsaKey(true, algorithm, type))
2256                 return false;
2257             break;
2258         default:
2259             return false;
2260         }
2261
2262         blink::WebCryptoKeyUsageMask usages;
2263         bool extractable;
2264         if (!doReadKeyUsages(usages, extractable))
2265             return false;
2266
2267         uint32_t keyDataLength;
2268         if (!doReadUint32(&keyDataLength))
2269             return false;
2270
2271         if (m_position + keyDataLength > m_length)
2272             return false;
2273
2274         const uint8_t* keyData = m_buffer + m_position;
2275         m_position += keyDataLength;
2276
2277         blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2278         if (!blink::Platform::current()->crypto()->deserializeKeyForClone(
2279             algorithm, type, extractable, usages, keyData, keyDataLength, key)) {
2280             return false;
2281         }
2282
2283         *value = toV8(Key::create(key), v8::Handle<v8::Object>(), m_isolate);
2284         return true;
2285     }
2286
2287     PassRefPtrWillBeRawPtr<File> readFileHelper()
2288     {
2289         if (m_version < 3)
2290             return nullptr;
2291         ASSERT(!m_blobInfo);
2292         String path;
2293         String name;
2294         String relativePath;
2295         String uuid;
2296         String type;
2297         uint32_t hasSnapshot = 0;
2298         uint64_t size = 0;
2299         double lastModified = 0;
2300         if (!readWebCoreString(&path))
2301             return nullptr;
2302         if (m_version >= 4 && !readWebCoreString(&name))
2303             return nullptr;
2304         if (m_version >= 4 && !readWebCoreString(&relativePath))
2305             return nullptr;
2306         if (!readWebCoreString(&uuid))
2307             return nullptr;
2308         if (!readWebCoreString(&type))
2309             return nullptr;
2310         if (m_version >= 4 && !doReadUint32(&hasSnapshot))
2311             return nullptr;
2312         if (hasSnapshot) {
2313             if (!doReadUint64(&size))
2314                 return nullptr;
2315             if (!doReadNumber(&lastModified))
2316                 return nullptr;
2317         }
2318         return File::create(path, name, relativePath, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type));
2319     }
2320
2321     PassRefPtrWillBeRawPtr<File> readFileIndexHelper()
2322     {
2323         if (m_version < 3)
2324             return nullptr;
2325         ASSERT(m_blobInfo);
2326         uint32_t index;
2327         if (!doReadUint32(&index) || index >= m_blobInfo->size())
2328             return nullptr;
2329         const blink::WebBlobInfo& info = (*m_blobInfo)[index];
2330         return File::create(info.filePath(), info.fileName(), info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
2331     }
2332
2333     template<class T>
2334     bool doReadUintHelper(T* value)
2335     {
2336         *value = 0;
2337         uint8_t currentByte;
2338         int shift = 0;
2339         do {
2340             if (m_position >= m_length)
2341                 return false;
2342             currentByte = m_buffer[m_position++];
2343             *value |= ((currentByte & varIntMask) << shift);
2344             shift += varIntShift;
2345         } while (currentByte & (1 << varIntShift));
2346         return true;
2347     }
2348
2349     bool doReadUint32(uint32_t* value)
2350     {
2351         return doReadUintHelper(value);
2352     }
2353
2354     bool doReadUint64(uint64_t* value)
2355     {
2356         return doReadUintHelper(value);
2357     }
2358
2359     bool doReadNumber(double* number)
2360     {
2361         if (m_position + sizeof(double) > m_length)
2362             return false;
2363         uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
2364         for (unsigned i = 0; i < sizeof(double); ++i)
2365             numberAsByteArray[i] = m_buffer[m_position++];
2366         return true;
2367     }
2368
2369     PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size = -1)
2370     {
2371         // The containing ssv may have a BDH for this uuid if this ssv is just being
2372         // passed from main to worker thread (for example). We use those values when creating
2373         // the new blob instead of cons'ing up a new BDH.
2374         //
2375         // FIXME: Maybe we should require that it work that way where the ssv must have a BDH for any
2376         // blobs it comes across during deserialization. Would require callers to explicitly populate
2377         // the collection of BDH's for blobs to work, which would encourage lifetimes to be considered
2378         // when passing ssv's around cross process. At present, we get 'lucky' in some cases because
2379         // the blob in the src process happens to still exist at the time the dest process is deserializing.
2380         // For example in sharedWorker.postMessage(...).
2381         BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
2382         if (it != m_blobDataHandles.end()) {
2383             // make assertions about type and size?
2384             return it->value;
2385         }
2386         return BlobDataHandle::create(uuid, type, size);
2387     }
2388
2389     bool doReadHmacKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
2390     {
2391         uint32_t lengthBytes;
2392         if (!doReadUint32(&lengthBytes))
2393             return false;
2394         blink::WebCryptoAlgorithmId hash;
2395         if (!doReadAlgorithmId(hash))
2396             return false;
2397         algorithm = blink::WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8);
2398         type = blink::WebCryptoKeyTypeSecret;
2399         return !algorithm.isNull();
2400     }
2401
2402     bool doReadAesKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
2403     {
2404         blink::WebCryptoAlgorithmId id;
2405         if (!doReadAlgorithmId(id))
2406             return false;
2407         uint32_t lengthBytes;
2408         if (!doReadUint32(&lengthBytes))
2409             return false;
2410         algorithm = blink::WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8);
2411         type = blink::WebCryptoKeyTypeSecret;
2412         return !algorithm.isNull();
2413     }
2414
2415     bool doReadRsaKey(bool hasHash, blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
2416     {
2417         blink::WebCryptoAlgorithmId id;
2418         if (!doReadAlgorithmId(id))
2419             return false;
2420
2421         uint32_t rawType;
2422         if (!doReadUint32(&rawType))
2423             return false;
2424
2425         switch (static_cast<AssymetricCryptoKeyType>(rawType)) {
2426         case PublicKeyType:
2427             type = blink::WebCryptoKeyTypePublic;
2428             break;
2429         case PrivateKeyType:
2430             type = blink::WebCryptoKeyTypePrivate;
2431             break;
2432         default:
2433             return false;
2434         }
2435
2436         uint32_t modulusLengthBits;
2437         if (!doReadUint32(&modulusLengthBits))
2438             return false;
2439
2440         uint32_t publicExponentSize;
2441         if (!doReadUint32(&publicExponentSize))
2442             return false;
2443
2444         if (m_position + publicExponentSize > m_length)
2445             return false;
2446
2447         const uint8_t* publicExponent = m_buffer + m_position;
2448         m_position += publicExponentSize;
2449
2450         if (hasHash) {
2451             blink::WebCryptoAlgorithmId hash;
2452             if (!doReadAlgorithmId(hash))
2453                 return false;
2454             algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, publicExponent, publicExponentSize, hash);
2455         } else {
2456             algorithm = blink::WebCryptoKeyAlgorithm::createRsa(id, modulusLengthBits, publicExponent, publicExponentSize);
2457         }
2458
2459         return !algorithm.isNull();
2460     }
2461
2462     bool doReadAlgorithmId(blink::WebCryptoAlgorithmId& id)
2463     {
2464         uint32_t rawId;
2465         if (!doReadUint32(&rawId))
2466             return false;
2467
2468         switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) {
2469         case AesCbcTag:
2470             id = blink::WebCryptoAlgorithmIdAesCbc;
2471             return true;
2472         case HmacTag:
2473             id = blink::WebCryptoAlgorithmIdHmac;
2474             return true;
2475         case RsaSsaPkcs1v1_5Tag:
2476             id = blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
2477             return true;
2478         case RsaEsPkcs1v1_5Tag:
2479             id = blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5;
2480             return true;
2481         case Sha1Tag:
2482             id = blink::WebCryptoAlgorithmIdSha1;
2483             return true;
2484         case Sha256Tag:
2485             id = blink::WebCryptoAlgorithmIdSha256;
2486             return true;
2487         case Sha384Tag:
2488             id = blink::WebCryptoAlgorithmIdSha384;
2489             return true;
2490         case Sha512Tag:
2491             id = blink::WebCryptoAlgorithmIdSha512;
2492             return true;
2493         case AesGcmTag:
2494             id = blink::WebCryptoAlgorithmIdAesGcm;
2495             return true;
2496         case RsaOaepTag:
2497             id = blink::WebCryptoAlgorithmIdRsaOaep;
2498             return true;
2499         case AesCtrTag:
2500             id = blink::WebCryptoAlgorithmIdAesCtr;
2501             return true;
2502         case AesKwTag:
2503             id = blink::WebCryptoAlgorithmIdAesKw;
2504             return true;
2505         }
2506
2507         return false;
2508     }
2509
2510     bool doReadKeyUsages(blink::WebCryptoKeyUsageMask& usages, bool& extractable)
2511     {
2512         // Reminder to update this when adding new key usages.
2513         COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
2514         const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | DecryptUsage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage;
2515
2516         uint32_t rawUsages;
2517         if (!doReadUint32(&rawUsages))
2518             return false;
2519
2520         // Make sure it doesn't contain an unrecognized usage value.
2521         if (rawUsages & ~allPossibleUsages)
2522             return false;
2523
2524         usages = 0;
2525
2526         extractable = rawUsages & ExtractableUsage;
2527
2528         if (rawUsages & EncryptUsage)
2529             usages |= blink::WebCryptoKeyUsageEncrypt;
2530         if (rawUsages & DecryptUsage)
2531             usages |= blink::WebCryptoKeyUsageDecrypt;
2532         if (rawUsages & SignUsage)
2533             usages |= blink::WebCryptoKeyUsageSign;
2534         if (rawUsages & VerifyUsage)
2535             usages |= blink::WebCryptoKeyUsageVerify;
2536         if (rawUsages & DeriveKeyUsage)
2537             usages |= blink::WebCryptoKeyUsageDeriveKey;
2538         if (rawUsages & WrapKeyUsage)
2539             usages |= blink::WebCryptoKeyUsageWrapKey;
2540         if (rawUsages & UnwrapKeyUsage)
2541             usages |= blink::WebCryptoKeyUsageUnwrapKey;
2542         if (rawUsages & DeriveBitsUsage)
2543             usages |= blink::WebCryptoKeyUsageDeriveBits;
2544
2545         return true;
2546     }
2547
2548     const uint8_t* m_buffer;
2549     const unsigned m_length;
2550     unsigned m_position;
2551     uint32_t m_version;
2552     v8::Isolate* m_isolate;
2553     const WebBlobInfoArray* m_blobInfo;
2554     const BlobDataHandleMap& m_blobDataHandles;
2555 };
2556
2557
2558 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray;
2559
2560 class Deserializer FINAL : public CompositeCreator {
2561 public:
2562     Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents)
2563         : m_reader(reader)
2564         , m_transferredMessagePorts(messagePorts)
2565         , m_arrayBufferContents(arrayBufferContents)
2566         , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0)
2567         , m_version(0)
2568     {
2569     }
2570
2571     v8::Handle<v8::Value> deserialize()
2572     {
2573         if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::wireFormatVersion)
2574             return v8::Null(m_reader.getIsolate());
2575         m_reader.setVersion(m_version);
2576         v8::EscapableHandleScope scope(m_reader.getIsolate());
2577         while (!m_reader.isEof()) {
2578             if (!doDeserialize())
2579                 return v8::Null(m_reader.getIsolate());
2580         }
2581         if (stackDepth() != 1 || m_openCompositeReferenceStack.size())
2582             return v8::Null(m_reader.getIsolate());
2583         v8::Handle<v8::Value> result = scope.Escape(element(0));
2584         return result;
2585     }
2586
2587     virtual bool newSparseArray(uint32_t) OVERRIDE
2588     {
2589         v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), 0);
2590         openComposite(array);
2591         return true;
2592     }
2593
2594     virtual bool newDenseArray(uint32_t length) OVERRIDE
2595     {
2596         v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), length);
2597         openComposite(array);
2598         return true;
2599     }
2600
2601     virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object) OVERRIDE
2602     {
2603         if (stackDepth() < 1)
2604             return false;
2605         *object = element(stackDepth() - 1);
2606         pop(1);
2607         return true;
2608     }
2609
2610     virtual bool newObject() OVERRIDE
2611     {
2612         v8::Local<v8::Object> object = v8::Object::New(m_reader.isolate());
2613         if (object.IsEmpty())
2614             return false;
2615         openComposite(object);
2616         return true;
2617     }
2618
2619     virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value) OVERRIDE
2620     {
2621         v8::Local<v8::Object> object;
2622         if (m_version > 0) {
2623             v8::Local<v8::Value> composite;
2624             if (!closeComposite(&composite))
2625                 return false;
2626             object = composite.As<v8::Object>();
2627         } else {
2628             object = v8::Object::New(m_reader.isolate());
2629         }
2630         if (object.IsEmpty())
2631             return false;
2632         return initializeObject(object, numProperties, value);
2633     }
2634
2635     virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
2636     {
2637         v8::Local<v8::Array> array;
2638         if (m_version > 0) {
2639             v8::Local<v8::Value> composite;
2640             if (!closeComposite(&composite))
2641                 return false;
2642             array = composite.As<v8::Array>();
2643         } else {
2644             array = v8::Array::New(m_reader.isolate());
2645         }
2646         if (array.IsEmpty())
2647             return false;
2648         return initializeObject(array, numProperties, value);
2649     }
2650
2651     virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
2652     {
2653         v8::Local<v8::Array> array;
2654         if (m_version > 0) {
2655             v8::Local<v8::Value> composite;
2656             if (!closeComposite(&composite))
2657                 return false;
2658             array = composite.As<v8::Array>();
2659         }
2660         if (array.IsEmpty())
2661             return false;
2662         if (!initializeObject(array, numProperties, value))
2663             return false;
2664         if (length > stackDepth())
2665             return false;
2666         for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stackPos++) {
2667             v8::Local<v8::Value> elem = element(stackPos);
2668             if (!elem->IsUndefined())
2669                 array->Set(i, elem);
2670         }
2671         pop(length);
2672         return true;
2673     }
2674
2675     virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRIDE
2676     {
2677         m_objectPool.append(object);
2678     }
2679
2680     virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
2681     {
2682         if (!m_transferredMessagePorts)
2683             return false;
2684         if (index >= m_transferredMessagePorts->size())
2685             return false;
2686         *object = toV8(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
2687         return true;
2688     }
2689
2690     virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
2691     {
2692         if (!m_arrayBufferContents)
2693             return false;
2694         if (index >= m_arrayBuffers.size())
2695             return false;
2696         v8::Handle<v8::Object> result = m_arrayBuffers.at(index);
2697         if (result.IsEmpty()) {
2698             RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferContents->at(index));
2699             buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
2700             m_reader.isolate()->AdjustAmountOfExternalAllocatedMemory(buffer->byteLength());
2701             result = toV8Object(buffer.get(), m_reader.getIsolate());
2702             m_arrayBuffers[index] = result;
2703         }
2704         *object = result;
2705         return true;
2706     }
2707
2708     virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object) OVERRIDE
2709     {
2710         if (reference >= m_objectPool.size())
2711             return false;
2712         *object = m_objectPool[reference];
2713         return object;
2714     }
2715
2716     virtual uint32_t objectReferenceCount() OVERRIDE
2717     {
2718         return m_objectPool.size();
2719     }
2720
2721 private:
2722     bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
2723     {
2724         unsigned length = 2 * numProperties;
2725         if (length > stackDepth())
2726             return false;
2727         for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
2728             v8::Local<v8::Value> propertyName = element(i);
2729             v8::Local<v8::Value> propertyValue = element(i + 1);
2730             object->Set(propertyName, propertyValue);
2731         }
2732         pop(length);
2733         *value = object;
2734         return true;
2735     }
2736
2737     bool doDeserialize()
2738     {
2739         v8::Local<v8::Value> value;
2740         if (!m_reader.read(&value, *this))
2741             return false;
2742         if (!value.IsEmpty())
2743             push(value);
2744         return true;
2745     }
2746
2747     void push(v8::Local<v8::Value> value) { m_stack.append(value); }
2748
2749     void pop(unsigned length)
2750     {
2751         ASSERT(length <= m_stack.size());
2752         m_stack.shrink(m_stack.size() - length);
2753     }
2754
2755     unsigned stackDepth() const { return m_stack.size(); }
2756
2757     v8::Local<v8::Value> element(unsigned index)
2758     {
2759         ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size());
2760         return m_stack[index];
2761     }
2762
2763     void openComposite(const v8::Local<v8::Value>& object)
2764     {
2765         uint32_t newObjectReference = m_objectPool.size();
2766         m_openCompositeReferenceStack.append(newObjectReference);
2767         m_objectPool.append(object);
2768     }
2769
2770     bool closeComposite(v8::Handle<v8::Value>* object)
2771     {
2772         if (!m_openCompositeReferenceStack.size())
2773             return false;
2774         uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1];
2775         m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2776         if (objectReference >= m_objectPool.size())
2777             return false;
2778         *object = m_objectPool[objectReference];
2779         return true;
2780     }
2781
2782     Reader& m_reader;
2783     Vector<v8::Local<v8::Value> > m_stack;
2784     Vector<v8::Handle<v8::Value> > m_objectPool;
2785     Vector<uint32_t> m_openCompositeReferenceStack;
2786     MessagePortArray* m_transferredMessagePorts;
2787     ArrayBufferContentsArray* m_arrayBufferContents;
2788     Vector<v8::Handle<v8::Object> > m_arrayBuffers;
2789     uint32_t m_version;
2790 };
2791
2792 } // namespace
2793
2794 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2795 {
2796     return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, exceptionState, isolate));
2797 }
2798
2799 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate)
2800 {
2801     TrackExceptionState exceptionState;
2802     return adoptRef(new SerializedScriptValue(value, 0, 0, 0, exceptionState, isolate));
2803 }
2804
2805 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate)
2806 {
2807     ASSERT(isolate->InContext());
2808     return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, blobInfo, exceptionState, isolate));
2809 }
2810
2811 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data)
2812 {
2813     return adoptRef(new SerializedScriptValue(data));
2814 }
2815
2816 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(const Vector<uint8_t>& data)
2817 {
2818     // Decode wire data from big endian to host byte order.
2819     ASSERT(!(data.size() % sizeof(UChar)));
2820     size_t length = data.size() / sizeof(UChar);
2821     StringBuffer<UChar> buffer(length);
2822     const UChar* src = reinterpret_cast<const UChar*>(data.data());
2823     UChar* dst = buffer.characters();
2824     for (size_t i = 0; i < length; i++)
2825         dst[i] = ntohs(src[i]);
2826
2827     return createFromWire(String::adopt(buffer));
2828 }
2829
2830 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data)
2831 {
2832     return create(data, v8::Isolate::GetCurrent());
2833 }
2834
2835 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data, v8::Isolate* isolate)
2836 {
2837     Writer writer;
2838     writer.writeWebCoreString(data);
2839     String wireData = writer.takeWireString();
2840     return adoptRef(new SerializedScriptValue(wireData));
2841 }
2842
2843 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
2844 {
2845     return adoptRef(new SerializedScriptValue());
2846 }
2847
2848 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue()
2849 {
2850     Writer writer;
2851     writer.writeNull();
2852     String wireData = writer.takeWireString();
2853     return adoptRef(new SerializedScriptValue(wireData));
2854 }
2855
2856 // Convert serialized string to big endian wire data.
2857 void SerializedScriptValue::toWireBytes(Vector<char>& result) const
2858 {
2859     ASSERT(result.isEmpty());
2860     size_t length = m_data.length();
2861     result.resize(length * sizeof(UChar));
2862     UChar* dst = reinterpret_cast<UChar*>(result.data());
2863
2864     if (m_data.is8Bit()) {
2865         const LChar* src = m_data.characters8();
2866         for (size_t i = 0; i < length; i++)
2867             dst[i] = htons(static_cast<UChar>(src[i]));
2868     } else {
2869         const UChar* src = m_data.characters16();
2870         for (size_t i = 0; i < length; i++)
2871             dst[i] = htons(src[i]);
2872     }
2873 }
2874
2875 SerializedScriptValue::SerializedScriptValue()
2876     : m_externallyAllocatedMemory(0)
2877 {
2878 }
2879
2880 static void neuterArrayBufferInAllWorlds(ArrayBuffer* object)
2881 {
2882     v8::Isolate* isolate = v8::Isolate::GetCurrent();
2883     if (isMainThread()) {
2884         Vector<RefPtr<DOMWrapperWorld> > worlds;
2885         DOMWrapperWorld::allWorldsInMainThread(worlds);
2886         for (size_t i = 0; i < worlds.size(); i++) {
2887             v8::Handle<v8::Object> wrapper = worlds[i]->domDataStore().get<V8ArrayBuffer>(object, isolate);
2888             if (!wrapper.IsEmpty()) {
2889                 ASSERT(wrapper->IsArrayBuffer());
2890                 v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
2891             }
2892         }
2893     } else {
2894         v8::Handle<v8::Object> wrapper = DOMDataStore::current(isolate).get<V8ArrayBuffer>(object, isolate);
2895         if (!wrapper.IsEmpty()) {
2896             ASSERT(wrapper->IsArrayBuffer());
2897             v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
2898         }
2899     }
2900 }
2901
2902 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2903 {
2904     ASSERT(arrayBuffers.size());
2905
2906     for (size_t i = 0; i < arrayBuffers.size(); i++) {
2907         if (arrayBuffers[i]->isNeutered()) {
2908             exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered.");
2909             return nullptr;
2910         }
2911     }
2912
2913     OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size()));
2914
2915     HashSet<ArrayBuffer*> visited;
2916     for (size_t i = 0; i < arrayBuffers.size(); i++) {
2917         if (visited.contains(arrayBuffers[i].get()))
2918             continue;
2919         visited.add(arrayBuffers[i].get());
2920
2921         bool result = arrayBuffers[i]->transfer(contents->at(i));
2922         if (!result) {
2923             exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred.");
2924             return nullptr;
2925         }
2926
2927         neuterArrayBufferInAllWorlds(arrayBuffers[i].get());
2928     }
2929     return contents.release();
2930 }
2931
2932 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate)
2933     : m_externallyAllocatedMemory(0)
2934 {
2935     Writer writer;
2936     Serializer::Status status;
2937     String errorMessage;
2938     {
2939         v8::TryCatch tryCatch;
2940         Serializer serializer(writer, messagePorts, arrayBuffers, blobInfo, m_blobDataHandles, tryCatch, isolate);
2941         status = serializer.serialize(value);
2942         if (status == Serializer::JSException) {
2943             // If there was a JS exception thrown, re-throw it.
2944             exceptionState.rethrowV8Exception(tryCatch.Exception());
2945             return;
2946         }
2947         errorMessage = serializer.errorMessage();
2948     }
2949     switch (status) {
2950     case Serializer::InputError:
2951     case Serializer::DataCloneError:
2952         exceptionState.throwDOMException(DataCloneError, errorMessage);
2953         return;
2954     case Serializer::Success:
2955         m_data = writer.takeWireString();
2956         ASSERT(m_data.impl()->hasOneRef());
2957         if (arrayBuffers && arrayBuffers->size())
2958             m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, exceptionState, isolate);
2959         return;
2960     case Serializer::JSException:
2961         ASSERT_NOT_REACHED();
2962         break;
2963     }
2964     ASSERT_NOT_REACHED();
2965 }
2966
2967 SerializedScriptValue::SerializedScriptValue(const String& wireData)
2968     : m_externallyAllocatedMemory(0)
2969 {
2970     m_data = wireData.isolatedCopy();
2971 }
2972
2973 v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts)
2974 {
2975     return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
2976 }
2977
2978 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
2979 {
2980     if (!m_data.impl())
2981         return v8::Null(isolate);
2982     COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
2983     m_data.ensure16Bit();
2984     // FIXME: SerializedScriptValue shouldn't use String for its underlying
2985     // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
2986     // information stored in m_data isn't even encoded in UTF-16. Instead,
2987     // unicode characters are encoded as UTF-8 with two code units per UChar.
2988     Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, blobInfo, m_blobDataHandles);
2989     Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get());
2990
2991     // deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
2992     // Holding a RefPtr ensures we are alive (along with our internal data) throughout the operation.
2993     RefPtr<SerializedScriptValue> protect(this);
2994     return deserializer.deserialize();
2995 }
2996
2997 bool SerializedScriptValue::extractTransferables(v8::Local<v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2998 {
2999     if (isUndefinedOrNull(value)) {
3000         ports.resize(0);
3001         arrayBuffers.resize(0);
3002         return true;
3003     }
3004
3005     uint32_t length = 0;
3006     if (value->IsArray()) {
3007         v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
3008         length = array->Length();
3009     } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
3010         exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex + 1));
3011         return false;
3012     }
3013
3014     v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value);
3015
3016     // Validate the passed array of transferrables.
3017     for (unsigned i = 0; i < length; ++i) {
3018         v8::Local<v8::Value> transferrable = transferrables->Get(i);
3019         // Validation of non-null objects, per HTML5 spec 10.3.3.
3020         if (isUndefinedOrNull(transferrable)) {
3021             exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " is an untransferable " + (transferrable->IsUndefined() ? "'undefined'" : "'null'") + " value.");
3022             return false;
3023         }
3024         // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
3025         if (V8MessagePort::hasInstance(transferrable, isolate)) {
3026             RefPtr<MessagePort> port = V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(transferrable));
3027             // Check for duplicate MessagePorts.
3028             if (ports.contains(port)) {
3029                 exceptionState.throwDOMException(DataCloneError, "Message port at index " + String::number(i) + " is a duplicate of an earlier port.");
3030                 return false;
3031             }
3032             ports.append(port.release());
3033         } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) {
3034             RefPtr<ArrayBuffer> arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(transferrable));
3035             if (arrayBuffers.contains(arrayBuffer)) {
3036                 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer.");
3037                 return false;
3038             }
3039             arrayBuffers.append(arrayBuffer.release());
3040         } else {
3041             exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " does not have a transferable type.");
3042             return false;
3043         }
3044     }
3045     return true;
3046 }
3047
3048 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext()
3049 {
3050     if (m_externallyAllocatedMemory)
3051         return;
3052     m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length());
3053     v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externallyAllocatedMemory);
3054 }
3055
3056 SerializedScriptValue::~SerializedScriptValue()
3057 {
3058     // If the allocated memory was not registered before, then this class is likely
3059     // used in a context other then Worker's onmessage environment and the presence of
3060     // current v8 context is not guaranteed. Avoid calling v8 then.
3061     if (m_externallyAllocatedMemory) {
3062         ASSERT(v8::Isolate::GetCurrent());
3063         v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
3064     }
3065 }
3066
3067 } // namespace WebCore