Upstream version 5.34.92.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 "V8MessagePort.h"
40 #include "bindings/v8/ExceptionState.h"
41 #include "bindings/v8/ScriptScope.h"
42 #include "bindings/v8/ScriptState.h"
43 #include "bindings/v8/V8Binding.h"
44 #include "bindings/v8/V8Utilities.h"
45 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
46 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
47 #include "bindings/v8/custom/V8DataViewCustom.h"
48 #include "bindings/v8/custom/V8Float32ArrayCustom.h"
49 #include "bindings/v8/custom/V8Float64ArrayCustom.h"
50 #include "bindings/v8/custom/V8Int16ArrayCustom.h"
51 #include "bindings/v8/custom/V8Int32ArrayCustom.h"
52 #include "bindings/v8/custom/V8Int8ArrayCustom.h"
53 #include "bindings/v8/custom/V8Uint16ArrayCustom.h"
54 #include "bindings/v8/custom/V8Uint32ArrayCustom.h"
55 #include "bindings/v8/custom/V8Uint8ArrayCustom.h"
56 #include "bindings/v8/custom/V8Uint8ClampedArrayCustom.h"
57 #include "core/dom/ExceptionCode.h"
58 #include "core/dom/MessagePort.h"
59 #include "core/fileapi/Blob.h"
60 #include "core/fileapi/File.h"
61 #include "core/fileapi/FileList.h"
62 #include "core/html/ImageData.h"
63 #include "core/html/canvas/DataView.h"
64 #include "platform/SharedBuffer.h"
65 #include "wtf/ArrayBuffer.h"
66 #include "wtf/ArrayBufferContents.h"
67 #include "wtf/ArrayBufferView.h"
68 #include "wtf/Assertions.h"
69 #include "wtf/ByteOrder.h"
70 #include "wtf/Float32Array.h"
71 #include "wtf/Float64Array.h"
72 #include "wtf/Int16Array.h"
73 #include "wtf/Int32Array.h"
74 #include "wtf/Int8Array.h"
75 #include "wtf/RefCounted.h"
76 #include "wtf/Uint16Array.h"
77 #include "wtf/Uint32Array.h"
78 #include "wtf/Uint8Array.h"
79 #include "wtf/Uint8ClampedArray.h"
80 #include "wtf/Vector.h"
81 #include "wtf/text/StringBuffer.h"
82 #include "wtf/text/StringUTF8Adaptor.h"
83
84 // FIXME: consider crashing in debug mode on deserialization errors
85 // NOTE: be sure to change wireFormatVersion as necessary!
86
87 namespace WebCore {
88
89 namespace {
90
91 // This code implements the HTML5 Structured Clone algorithm:
92 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-passing-of-structured-data
93
94 // V8ObjectMap is a map from V8 objects to arbitrary values of type T.
95 // V8 objects (or handles to V8 objects) cannot be used as keys in ordinary wtf::HashMaps;
96 // this class should be used instead. GCObject must be a subtype of v8::Object.
97 // Suggested usage:
98 //     V8ObjectMap<v8::Object, int> map;
99 //     v8::Handle<v8::Object> obj = ...;
100 //     map.set(obj, 42);
101 template<typename GCObject, typename T>
102 class V8ObjectMap {
103 public:
104     bool contains(const v8::Handle<GCObject>& handle)
105     {
106         return m_map.contains(*handle);
107     }
108
109     bool tryGet(const v8::Handle<GCObject>& handle, T* valueOut)
110     {
111         typename HandleToT::iterator result = m_map.find(*handle);
112         if (result != m_map.end()) {
113             *valueOut = result->value;
114             return true;
115         }
116         return false;
117     }
118
119     void set(const v8::Handle<GCObject>& handle, const T& value)
120     {
121         m_map.set(*handle, value);
122     }
123
124 private:
125     // This implementation uses GetIdentityHash(), which sets a hidden property on the object containing
126     // a random integer (or returns the one that had been previously set). This ensures that the table
127     // never needs to be rebuilt across garbage collections at the expense of doing additional allocation
128     // and making more round trips into V8. Note that since GetIdentityHash() is defined only on
129     // v8::Objects, this V8ObjectMap cannot be used to map v8::Strings to T (because the public V8 API
130     // considers a v8::String to be a v8::Primitive).
131
132     // If V8 exposes a way to get at the address of the object held by a handle, then we can produce
133     // an alternate implementation that does not need to do any V8-side allocation; however, it will
134     // need to rehash after every garbage collection because a key object may have been moved.
135     template<typename G>
136     struct V8HandlePtrHash {
137         static unsigned hash(const G* key)
138         {
139             return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdentityHash());
140         }
141         static bool equal(const G* a, const G* b)
142         {
143             return unsafeHandleFromRawValue(a) == unsafeHandleFromRawValue(b);
144         }
145         // For HashArg.
146         static const bool safeToCompareToEmptyOrDeleted = false;
147     };
148
149     typedef WTF::HashMap<GCObject*, T, V8HandlePtrHash<GCObject> > HandleToT;
150     HandleToT m_map;
151 };
152
153 typedef UChar BufferValueType;
154
155 // Serialization format is a sequence of tags followed by zero or more data arguments.
156 // Tags always take exactly one byte. A serialized stream first begins with
157 // a complete VersionTag. If the stream does not begin with a VersionTag, we assume that
158 // the stream is in format 0.
159
160 // This format is private to the implementation of SerializedScriptValue. Do not rely on it
161 // externally. It is safe to persist a SerializedScriptValue as a binary blob, but this
162 // code should always be used to interpret it.
163
164 // WebCoreStrings are read as (length:uint32_t, string:UTF8[length]).
165 // RawStrings are read as (length:uint32_t, string:UTF8[length]).
166 // RawUCharStrings are read as (length:uint32_t, string:UChar[length/sizeof(UChar)]).
167 // RawFiles are read as (path:WebCoreString, url:WebCoreStrng, type:WebCoreString).
168 // There is a reference table that maps object references (uint32_t) to v8::Values.
169 // Tokens marked with (ref) are inserted into the reference table and given the next object reference ID after decoding.
170 // All tags except InvalidTag, PaddingTag, ReferenceCountTag, VersionTag, GenerateFreshObjectTag
171 //     and GenerateFreshArrayTag push their results to the deserialization stack.
172 // There is also an 'open' stack that is used to resolve circular references. Objects or arrays may
173 //     contain self-references. Before we begin to deserialize the contents of these values, they
174 //     are first given object reference IDs (by GenerateFreshObjectTag/GenerateFreshArrayTag);
175 //     these reference IDs are then used with ObjectReferenceTag to tie the recursive knot.
176 enum SerializationTag {
177     InvalidTag = '!', // Causes deserialization to fail.
178     PaddingTag = '\0', // Is ignored (but consumed).
179     UndefinedTag = '_', // -> <undefined>
180     NullTag = '0', // -> <null>
181     TrueTag = 'T', // -> <true>
182     FalseTag = 'F', // -> <false>
183     StringTag = 'S', // string:RawString -> string
184     StringUCharTag = 'c', // string:RawUCharString -> string
185     Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer
186     Uint32Tag = 'U', // value:uint32_t -> Integer
187     DateTag = 'D', // value:double -> Date (ref)
188     MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with transferred MessagePort.
189     NumberTag = 'N', // value:double -> Number
190     BlobTag = 'b', // url:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
191     FileTag = 'f', // file:RawFile -> File (ref)
192     DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, url:WebCoreString -> FileSystem (ref)
193     FileListTag = 'l', // length:uint32_t, files:RawFile[length] -> FileList (ref)
194     ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint32_t, data:byte[pixelDataLength] -> ImageData (ref)
195     ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the open stack;
196                      //                           fills it with the last numProperties name,value pairs pushed onto the deserialization stack
197     SparseArrayTag = '@', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack;
198                           //                                            fills it with the last numProperties name,value pairs pushed onto the deserialization stack
199     DenseArrayTag = '$', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack;
200                          //                                            fills it with the last length elements and numProperties name,value pairs pushed onto deserialization stack
201     RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref)
202     ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> ArrayBuffer (ref)
203     ArrayBufferTransferTag = 't', // index:uint32_t -> ArrayBuffer. For ArrayBuffer transfer
204     ArrayBufferViewTag = 'V', // subtag:byte, byteOffset:uint32_t, byteLength:uint32_t -> ArrayBufferView (ref). Consumes an ArrayBuffer from the top of the deserialization stack.
205     ObjectReferenceTag = '^', // ref:uint32_t -> reference table[ref]
206     GenerateFreshObjectTag = 'o', // -> empty object allocated an object ID and pushed onto the open stack (ref)
207     GenerateFreshSparseArrayTag = 'a', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref)
208     GenerateFreshDenseArrayTag = 'A', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref)
209     ReferenceCountTag = '?', // refTableSize:uint32_t -> If the reference table is not refTableSize big, fails.
210     StringObjectTag = 's', //  string:RawString -> new String(string) (ref)
211     NumberObjectTag = 'n', // value:double -> new Number(value) (ref)
212     TrueObjectTag = 'y', // new Boolean(true) (ref)
213     FalseObjectTag = 'x', // new Boolean(false) (ref)
214     VersionTag = 0xFF // version:uint32_t -> Uses this as the file version.
215 };
216
217 enum ArrayBufferViewSubTag {
218     ByteArrayTag = 'b',
219     UnsignedByteArrayTag = 'B',
220     UnsignedByteClampedArrayTag = 'C',
221     ShortArrayTag = 'w',
222     UnsignedShortArrayTag = 'W',
223     IntArrayTag = 'd',
224     UnsignedIntArrayTag = 'D',
225     FloatArrayTag = 'f',
226     DoubleArrayTag = 'F',
227     DataViewTag = '?'
228 };
229
230 static bool shouldCheckForCycles(int depth)
231 {
232     ASSERT(depth >= 0);
233     // Since we are not required to spot the cycle as soon as it
234     // happens we can check for cycles only when the current depth
235     // is a power of two.
236     return !(depth & (depth - 1));
237 }
238
239 static const int maxDepth = 20000;
240
241 // VarInt encoding constants.
242 static const int varIntShift = 7;
243 static const int varIntMask = (1 << varIntShift) - 1;
244
245 // ZigZag encoding helps VarInt encoding stay small for negative
246 // numbers with small absolute values.
247 class ZigZag {
248 public:
249     static uint32_t encode(uint32_t value)
250     {
251         if (value & (1U << 31))
252             value = ((~value) << 1) + 1;
253         else
254             value <<= 1;
255         return value;
256     }
257
258     static uint32_t decode(uint32_t value)
259     {
260         if (value & 1)
261             value = ~(value >> 1);
262         else
263             value >>= 1;
264         return value;
265     }
266
267 private:
268     ZigZag();
269 };
270
271 // Writer is responsible for serializing primitive types and storing
272 // information used to reconstruct composite types.
273 class Writer {
274     WTF_MAKE_NONCOPYABLE(Writer);
275 public:
276     explicit Writer(v8::Isolate* isolate)
277         : m_position(0)
278         , m_isolate(isolate)
279     {
280     }
281
282     // Write functions for primitive types.
283
284     void writeUndefined() { append(UndefinedTag); }
285
286     void writeNull() { append(NullTag); }
287
288     void writeTrue() { append(TrueTag); }
289
290     void writeFalse() { append(FalseTag); }
291
292     void writeBooleanObject(bool value)
293     {
294         append(value ? TrueObjectTag : FalseObjectTag);
295     }
296
297     void writeOneByteString(v8::Handle<v8::String>& string)
298     {
299         int stringLength = string->Length();
300         int utf8Length = string->Utf8Length();
301         ASSERT(stringLength >= 0 && utf8Length >= 0);
302
303         append(StringTag);
304         doWriteUint32(static_cast<uint32_t>(utf8Length));
305         ensureSpace(utf8Length);
306
307         // ASCII fast path.
308         if (stringLength == utf8Length)
309             string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOptions());
310         else {
311             char* buffer = reinterpret_cast<char*>(byteAt(m_position));
312             string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions());
313         }
314         m_position += utf8Length;
315     }
316
317     void writeUCharString(v8::Handle<v8::String>& string)
318     {
319         int length = string->Length();
320         ASSERT(length >= 0);
321
322         int size = length * sizeof(UChar);
323         int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size));
324         if ((m_position + 1 + bytes) & 1)
325             append(PaddingTag);
326
327         append(StringUCharTag);
328         doWriteUint32(static_cast<uint32_t>(size));
329         ensureSpace(size);
330
331         ASSERT(!(m_position & 1));
332         uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position));
333         string->Write(buffer, 0, length, v8StringWriteOptions());
334         m_position += size;
335     }
336
337     void writeStringObject(const char* data, int length)
338     {
339         ASSERT(length >= 0);
340         append(StringObjectTag);
341         doWriteString(data, length);
342     }
343
344     void writeWebCoreString(const String& string)
345     {
346         // Uses UTF8 encoding so we can read it back as either V8 or
347         // WebCore string.
348         append(StringTag);
349         doWriteWebCoreString(string);
350     }
351
352     void writeVersion()
353     {
354         append(VersionTag);
355         doWriteUint32(SerializedScriptValue::wireFormatVersion);
356     }
357
358     void writeInt32(int32_t value)
359     {
360         append(Int32Tag);
361         doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
362     }
363
364     void writeUint32(uint32_t value)
365     {
366         append(Uint32Tag);
367         doWriteUint32(value);
368     }
369
370     void writeDate(double numberValue)
371     {
372         append(DateTag);
373         doWriteNumber(numberValue);
374     }
375
376     void writeNumber(double number)
377     {
378         append(NumberTag);
379         doWriteNumber(number);
380     }
381
382     void writeNumberObject(double number)
383     {
384         append(NumberObjectTag);
385         doWriteNumber(number);
386     }
387
388     void writeBlob(const String& uuid, const String& type, unsigned long long size)
389     {
390         append(BlobTag);
391         doWriteWebCoreString(uuid);
392         doWriteWebCoreString(type);
393         doWriteUint64(size);
394     }
395
396     void writeDOMFileSystem(int type, const String& name, const String& url)
397     {
398         append(DOMFileSystemTag);
399         doWriteUint32(type);
400         doWriteWebCoreString(name);
401         doWriteWebCoreString(url);
402     }
403
404     void writeFile(const File& file)
405     {
406         append(FileTag);
407         doWriteFile(file);
408     }
409
410     void writeFileList(const FileList& fileList)
411     {
412         append(FileListTag);
413         uint32_t length = fileList.length();
414         doWriteUint32(length);
415         for (unsigned i = 0; i < length; ++i)
416             doWriteFile(*fileList.item(i));
417     }
418
419     void writeArrayBuffer(const ArrayBuffer& arrayBuffer)
420     {
421         append(ArrayBufferTag);
422         doWriteArrayBuffer(arrayBuffer);
423     }
424
425     void writeArrayBufferView(const ArrayBufferView& arrayBufferView)
426     {
427         append(ArrayBufferViewTag);
428 #ifndef NDEBUG
429         const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer();
430         ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byteOffset() ==
431                static_cast<const uint8_t*>(arrayBufferView.baseAddress()));
432 #endif
433         ArrayBufferView::ViewType type = arrayBufferView.type();
434
435         if (type == ArrayBufferView::TypeInt8)
436             append(ByteArrayTag);
437         else if (type == ArrayBufferView::TypeUint8Clamped)
438             append(UnsignedByteClampedArrayTag);
439         else if (type == ArrayBufferView::TypeUint8)
440             append(UnsignedByteArrayTag);
441         else if (type == ArrayBufferView::TypeInt16)
442             append(ShortArrayTag);
443         else if (type == ArrayBufferView::TypeUint16)
444             append(UnsignedShortArrayTag);
445         else if (type == ArrayBufferView::TypeInt32)
446             append(IntArrayTag);
447         else if (type == ArrayBufferView::TypeUint32)
448             append(UnsignedIntArrayTag);
449         else if (type == ArrayBufferView::TypeFloat32)
450             append(FloatArrayTag);
451         else if (type == ArrayBufferView::TypeFloat64)
452             append(DoubleArrayTag);
453         else if (type == ArrayBufferView::TypeDataView)
454             append(DataViewTag);
455         else
456             ASSERT_NOT_REACHED();
457         doWriteUint32(arrayBufferView.byteOffset());
458         doWriteUint32(arrayBufferView.byteLength());
459     }
460
461     void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
462     {
463         append(ImageDataTag);
464         doWriteUint32(width);
465         doWriteUint32(height);
466         doWriteUint32(pixelDataLength);
467         append(pixelData, pixelDataLength);
468     }
469
470     void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags)
471     {
472         append(RegExpTag);
473         v8::String::Utf8Value patternUtf8Value(pattern);
474         doWriteString(*patternUtf8Value, patternUtf8Value.length());
475         doWriteUint32(static_cast<uint32_t>(flags));
476     }
477
478     void writeTransferredMessagePort(uint32_t index)
479     {
480         append(MessagePortTag);
481         doWriteUint32(index);
482     }
483
484     void writeTransferredArrayBuffer(uint32_t index)
485     {
486         append(ArrayBufferTransferTag);
487         doWriteUint32(index);
488     }
489
490     void writeObjectReference(uint32_t reference)
491     {
492         append(ObjectReferenceTag);
493         doWriteUint32(reference);
494     }
495
496     void writeObject(uint32_t numProperties)
497     {
498         append(ObjectTag);
499         doWriteUint32(numProperties);
500     }
501
502     void writeSparseArray(uint32_t numProperties, uint32_t length)
503     {
504         append(SparseArrayTag);
505         doWriteUint32(numProperties);
506         doWriteUint32(length);
507     }
508
509     void writeDenseArray(uint32_t numProperties, uint32_t length)
510     {
511         append(DenseArrayTag);
512         doWriteUint32(numProperties);
513         doWriteUint32(length);
514     }
515
516     String takeWireString()
517     {
518         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
519         fillHole();
520         String data = String(m_buffer.data(), m_buffer.size());
521         data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueType));
522         return data;
523     }
524
525     void writeReferenceCount(uint32_t numberOfReferences)
526     {
527         append(ReferenceCountTag);
528         doWriteUint32(numberOfReferences);
529     }
530
531     void writeGenerateFreshObject()
532     {
533         append(GenerateFreshObjectTag);
534     }
535
536     void writeGenerateFreshSparseArray(uint32_t length)
537     {
538         append(GenerateFreshSparseArrayTag);
539         doWriteUint32(length);
540     }
541
542     void writeGenerateFreshDenseArray(uint32_t length)
543     {
544         append(GenerateFreshDenseArrayTag);
545         doWriteUint32(length);
546     }
547
548     v8::Isolate* getIsolate() { return m_isolate; }
549
550 private:
551     void doWriteFile(const File& file)
552     {
553         doWriteWebCoreString(file.hasBackingFile() ? file.path() : "");
554         doWriteWebCoreString(file.name());
555         doWriteWebCoreString(file.webkitRelativePath());
556         doWriteWebCoreString(file.uuid());
557         doWriteWebCoreString(file.type());
558
559         // FIXME don't use 4 bytes to encode a flag.
560         if (file.hasValidSnapshotMetadata()) {
561             doWriteUint32(static_cast<uint8_t>(1));
562
563             long long size;
564             double lastModified;
565             file.captureSnapshot(size, lastModified);
566             doWriteUint64(static_cast<uint64_t>(size));
567             doWriteNumber(lastModified);
568         } else {
569             append(static_cast<uint8_t>(0));
570         }
571     }
572
573     void doWriteArrayBuffer(const ArrayBuffer& arrayBuffer)
574     {
575         uint32_t byteLength = arrayBuffer.byteLength();
576         doWriteUint32(byteLength);
577         append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength);
578     }
579
580     void doWriteString(const char* data, int length)
581     {
582         doWriteUint32(static_cast<uint32_t>(length));
583         append(reinterpret_cast<const uint8_t*>(data), length);
584     }
585
586     void doWriteWebCoreString(const String& string)
587     {
588         StringUTF8Adaptor stringUTF8(string);
589         doWriteString(stringUTF8.data(), stringUTF8.length());
590     }
591
592     int bytesNeededToWireEncode(uint32_t value)
593     {
594         int bytes = 1;
595         while (true) {
596             value >>= varIntShift;
597             if (!value)
598                 break;
599             ++bytes;
600         }
601
602         return bytes;
603     }
604
605     template<class T>
606     void doWriteUintHelper(T value)
607     {
608         while (true) {
609             uint8_t b = (value & varIntMask);
610             value >>= varIntShift;
611             if (!value) {
612                 append(b);
613                 break;
614             }
615             append(b | (1 << varIntShift));
616         }
617     }
618
619     void doWriteUint32(uint32_t value)
620     {
621         doWriteUintHelper(value);
622     }
623
624     void doWriteUint64(uint64_t value)
625     {
626         doWriteUintHelper(value);
627     }
628
629     void doWriteNumber(double number)
630     {
631         append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
632     }
633
634     void append(SerializationTag tag)
635     {
636         append(static_cast<uint8_t>(tag));
637     }
638
639     void append(uint8_t b)
640     {
641         ensureSpace(1);
642         *byteAt(m_position++) = b;
643     }
644
645     void append(const uint8_t* data, int length)
646     {
647         ensureSpace(length);
648         memcpy(byteAt(m_position), data, length);
649         m_position += length;
650     }
651
652     void ensureSpace(unsigned extra)
653     {
654         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
655         m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1" to round up.
656     }
657
658     void fillHole()
659     {
660         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
661         // If the writer is at odd position in the buffer, then one of
662         // the bytes in the last UChar is not initialized.
663         if (m_position % 2)
664             *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
665     }
666
667     uint8_t* byteAt(int position)
668     {
669         return reinterpret_cast<uint8_t*>(m_buffer.data()) + position;
670     }
671
672     int v8StringWriteOptions()
673     {
674         return v8::String::NO_NULL_TERMINATION;
675     }
676
677     Vector<BufferValueType> m_buffer;
678     unsigned m_position;
679     v8::Isolate* m_isolate;
680 };
681
682 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Isolate* isolate)
683 {
684     if (!impl)
685         return v8::Handle<v8::Object>();
686     v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
687     ASSERT(wrapper->IsObject());
688     return wrapper.As<v8::Object>();
689 }
690
691 static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Isolate* isolate)
692 {
693     if (!impl)
694         return v8::Handle<v8::ArrayBuffer>();
695     v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
696     ASSERT(wrapper->IsArrayBuffer());
697     return wrapper.As<v8::ArrayBuffer>();
698 }
699
700 class Serializer {
701     class StateBase;
702 public:
703     enum Status {
704         Success,
705         InputError,
706         DataCloneError,
707         JSException
708     };
709
710     Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::Isolate* isolate)
711         : m_writer(writer)
712         , m_tryCatch(tryCatch)
713         , m_depth(0)
714         , m_status(Success)
715         , m_nextObjectReference(0)
716         , m_blobDataHandles(blobDataHandles)
717         , m_isolate(isolate)
718     {
719         ASSERT(!tryCatch.HasCaught());
720         if (messagePorts) {
721             for (size_t i = 0; i < messagePorts->size(); i++)
722                 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), m_writer.getIsolate()), i);
723         }
724         if (arrayBuffers) {
725             for (size_t i = 0; i < arrayBuffers->size(); i++)  {
726                 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), m_writer.getIsolate());
727                 // Coalesce multiple occurences of the same buffer to the first index.
728                 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
729                     m_transferredArrayBuffers.set(v8ArrayBuffer, i);
730             }
731         }
732     }
733
734     Status serialize(v8::Handle<v8::Value> value)
735     {
736         v8::HandleScope scope(m_isolate);
737         m_writer.writeVersion();
738         StateBase* state = doSerialize(value, 0);
739         while (state)
740             state = state->advance(*this);
741         return m_status;
742     }
743
744     String errorMessage() { return m_errorMessage; }
745
746     // Functions used by serialization states.
747     StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next);
748
749     StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBase* next)
750     {
751         return doSerialize(arrayBuffer, next);
752     }
753
754     StateBase* checkException(StateBase* state)
755     {
756         return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0;
757     }
758
759     StateBase* writeObject(uint32_t numProperties, StateBase* state)
760     {
761         m_writer.writeObject(numProperties);
762         return pop(state);
763     }
764
765     StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
766     {
767         m_writer.writeSparseArray(numProperties, length);
768         return pop(state);
769     }
770
771     StateBase* writeDenseArray(uint32_t numProperties, uint32_t length, StateBase* state)
772     {
773         m_writer.writeDenseArray(numProperties, length);
774         return pop(state);
775     }
776
777
778 private:
779     class StateBase {
780         WTF_MAKE_NONCOPYABLE(StateBase);
781     public:
782         virtual ~StateBase() { }
783
784         // Link to the next state to form a stack.
785         StateBase* nextState() { return m_next; }
786
787         // Composite object we're processing in this state.
788         v8::Handle<v8::Value> composite() { return m_composite; }
789
790         // Serializes (a part of) the current composite and returns
791         // the next state to process or null when this is the final
792         // state.
793         virtual StateBase* advance(Serializer&) = 0;
794
795     protected:
796         StateBase(v8::Handle<v8::Value> composite, StateBase* next)
797             : m_composite(composite)
798             , m_next(next)
799         {
800         }
801
802     private:
803         v8::Handle<v8::Value> m_composite;
804         StateBase* m_next;
805     };
806
807     // Dummy state that is used to signal serialization errors.
808     class ErrorState FINAL : public StateBase {
809     public:
810         ErrorState()
811             : StateBase(v8Undefined(), 0)
812         {
813         }
814
815         virtual StateBase* advance(Serializer&) OVERRIDE
816         {
817             delete this;
818             return 0;
819         }
820     };
821
822     template <typename T>
823     class State : public StateBase {
824     public:
825         v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
826
827     protected:
828         State(v8::Handle<T> composite, StateBase* next)
829             : StateBase(composite, next)
830         {
831         }
832     };
833
834     class AbstractObjectState : public State<v8::Object> {
835     public:
836         AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
837             : State<v8::Object>(object, next)
838             , m_index(0)
839             , m_numSerializedProperties(0)
840             , m_nameDone(false)
841         {
842         }
843
844     protected:
845         virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
846
847         StateBase* serializeProperties(bool ignoreIndexed, Serializer& serializer)
848         {
849             while (m_index < m_propertyNames->Length()) {
850                 if (!m_nameDone) {
851                     v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
852                     if (StateBase* newState = serializer.checkException(this))
853                         return newState;
854                     if (propertyName.IsEmpty())
855                         return serializer.handleError(InputError, "Empty property names cannot be cloned.", this);
856                     bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>());
857                     if (StateBase* newState = serializer.checkException(this))
858                         return newState;
859                     bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value());
860                     if (StateBase* newState = serializer.checkException(this))
861                         return newState;
862                     if (hasStringProperty || (hasIndexedProperty && !ignoreIndexed))
863                         m_propertyName = propertyName;
864                     else {
865                         ++m_index;
866                         continue;
867                     }
868                 }
869                 ASSERT(!m_propertyName.IsEmpty());
870                 if (!m_nameDone) {
871                     m_nameDone = true;
872                     if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
873                         return newState;
874                 }
875                 v8::Local<v8::Value> value = composite()->Get(m_propertyName);
876                 if (StateBase* newState = serializer.checkException(this))
877                     return newState;
878                 m_nameDone = false;
879                 m_propertyName.Clear();
880                 ++m_index;
881                 ++m_numSerializedProperties;
882                 // If we return early here, it's either because we have pushed a new state onto the
883                 // serialization state stack or because we have encountered an error (and in both cases
884                 // we are unwinding the native stack).
885                 if (StateBase* newState = serializer.doSerialize(value, this))
886                     return newState;
887             }
888             return objectDone(m_numSerializedProperties, serializer);
889         }
890
891         v8::Local<v8::Array> m_propertyNames;
892
893     private:
894         v8::Local<v8::Value> m_propertyName;
895         unsigned m_index;
896         unsigned m_numSerializedProperties;
897         bool m_nameDone;
898     };
899
900     class ObjectState FINAL : public AbstractObjectState {
901     public:
902         ObjectState(v8::Handle<v8::Object> object, StateBase* next)
903             : AbstractObjectState(object, next)
904         {
905         }
906
907         virtual StateBase* advance(Serializer& serializer) OVERRIDE
908         {
909             if (m_propertyNames.IsEmpty()) {
910                 m_propertyNames = composite()->GetPropertyNames();
911                 if (StateBase* newState = serializer.checkException(this))
912                     return newState;
913                 if (m_propertyNames.IsEmpty())
914                     return serializer.handleError(InputError, "Empty property names cannot be cloned.", nextState());
915             }
916             return serializeProperties(false, serializer);
917         }
918
919     protected:
920         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
921         {
922             return serializer.writeObject(numProperties, this);
923         }
924     };
925
926     class DenseArrayState FINAL : public AbstractObjectState {
927     public:
928         DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
929             : AbstractObjectState(array, next)
930             , m_arrayIndex(0)
931             , m_arrayLength(array->Length())
932         {
933             m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
934         }
935
936         virtual StateBase* advance(Serializer& serializer) OVERRIDE
937         {
938             while (m_arrayIndex < m_arrayLength) {
939                 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIndex);
940                 m_arrayIndex++;
941                 if (StateBase* newState = serializer.checkException(this))
942                     return newState;
943                 if (StateBase* newState = serializer.doSerialize(value, this))
944                     return newState;
945             }
946             return serializeProperties(true, serializer);
947         }
948
949     protected:
950         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
951         {
952             return serializer.writeDenseArray(numProperties, m_arrayLength, this);
953         }
954
955     private:
956         uint32_t m_arrayIndex;
957         uint32_t m_arrayLength;
958     };
959
960     class SparseArrayState FINAL : public AbstractObjectState {
961     public:
962         SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
963             : AbstractObjectState(array, next)
964         {
965             m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
966         }
967
968         virtual StateBase* advance(Serializer& serializer) OVERRIDE
969         {
970             return serializeProperties(false, serializer);
971         }
972
973     protected:
974         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
975         {
976             return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
977         }
978     };
979
980     StateBase* push(StateBase* state)
981     {
982         ASSERT(state);
983         ++m_depth;
984         return checkComposite(state) ? state : handleError(InputError, "Value being cloned is either cyclic or too deeply nested.", state);
985     }
986
987     StateBase* pop(StateBase* state)
988     {
989         ASSERT(state);
990         --m_depth;
991         StateBase* next = state->nextState();
992         delete state;
993         return next;
994     }
995
996     StateBase* handleError(Status errorStatus, const String& message, StateBase* state)
997     {
998         ASSERT(errorStatus != Success);
999         m_status = errorStatus;
1000         m_errorMessage = message;
1001         while (state) {
1002             StateBase* tmp = state->nextState();
1003             delete state;
1004             state = tmp;
1005         }
1006         return new ErrorState;
1007     }
1008
1009     bool checkComposite(StateBase* top)
1010     {
1011         ASSERT(top);
1012         if (m_depth > maxDepth)
1013             return false;
1014         if (!shouldCheckForCycles(m_depth))
1015             return true;
1016         v8::Handle<v8::Value> composite = top->composite();
1017         for (StateBase* state = top->nextState(); state; state = state->nextState()) {
1018             if (state->composite() == composite)
1019                 return false;
1020         }
1021         return true;
1022     }
1023
1024     void writeString(v8::Handle<v8::Value> value)
1025     {
1026         v8::Handle<v8::String> string = value.As<v8::String>();
1027         if (!string->Length() || string->IsOneByte())
1028             m_writer.writeOneByteString(string);
1029         else
1030             m_writer.writeUCharString(string);
1031     }
1032
1033     void writeStringObject(v8::Handle<v8::Value> value)
1034     {
1035         v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>();
1036         v8::String::Utf8Value stringValue(stringObject->ValueOf());
1037         m_writer.writeStringObject(*stringValue, stringValue.length());
1038     }
1039
1040     void writeNumberObject(v8::Handle<v8::Value> value)
1041     {
1042         v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>();
1043         m_writer.writeNumberObject(numberObject->ValueOf());
1044     }
1045
1046     void writeBooleanObject(v8::Handle<v8::Value> value)
1047     {
1048         v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>();
1049         m_writer.writeBooleanObject(booleanObject->ValueOf());
1050     }
1051
1052     void writeBlob(v8::Handle<v8::Value> value)
1053     {
1054         Blob* blob = V8Blob::toNative(value.As<v8::Object>());
1055         if (!blob)
1056             return;
1057         m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
1058         m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle());
1059     }
1060
1061     StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next)
1062     {
1063         DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>());
1064         if (!fs)
1065             return 0;
1066         if (!fs->clonable())
1067             return handleError(DataCloneError, "A FileSystem object could not be cloned.", next);
1068         m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string());
1069         return 0;
1070     }
1071
1072     void writeFile(v8::Handle<v8::Value> value)
1073     {
1074         File* file = V8File::toNative(value.As<v8::Object>());
1075         if (!file)
1076             return;
1077         m_writer.writeFile(*file);
1078         m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
1079     }
1080
1081     void writeFileList(v8::Handle<v8::Value> value)
1082     {
1083         FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
1084         if (!fileList)
1085             return;
1086         m_writer.writeFileList(*fileList);
1087         unsigned length = fileList->length();
1088         for (unsigned i = 0; i < length; ++i)
1089             m_blobDataHandles.add(fileList->item(i)->uuid(), fileList->item(i)->blobDataHandle());
1090     }
1091
1092     void writeImageData(v8::Handle<v8::Value> value)
1093     {
1094         ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
1095         if (!imageData)
1096             return;
1097         Uint8ClampedArray* pixelArray = imageData->data();
1098         m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
1099     }
1100
1101     void writeRegExp(v8::Handle<v8::Value> value)
1102     {
1103         v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>();
1104         m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
1105     }
1106
1107     StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object> object, StateBase* next)
1108     {
1109         ASSERT(!object.IsEmpty());
1110         ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object);
1111         if (!arrayBufferView)
1112             return 0;
1113         if (!arrayBufferView->buffer())
1114             return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
1115         v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate());
1116         if (underlyingBuffer.IsEmpty())
1117             return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
1118         StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1119         if (stateOut)
1120             return stateOut;
1121         m_writer.writeArrayBufferView(*arrayBufferView);
1122         // This should be safe: we serialize something that we know to be a wrapper (see
1123         // the toV8 call above), so the call to doSerializeArrayBuffer should neither
1124         // cause the system stack to overflow nor should it have potential to reach
1125         // this ArrayBufferView again.
1126         //
1127         // We do need to grey the underlying buffer before we grey its view, however;
1128         // ArrayBuffers may be shared, so they need to be given reference IDs, and an
1129         // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer
1130         // (or without an additional tag that would allow us to do two-stage construction
1131         // like we do for Objects and Arrays).
1132         greyObject(object);
1133         return 0;
1134     }
1135
1136     StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next)
1137     {
1138         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>());
1139         if (!arrayBuffer)
1140             return 0;
1141         if (arrayBuffer->isNeutered())
1142             return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1143         ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
1144         m_writer.writeArrayBuffer(*arrayBuffer);
1145         return 0;
1146     }
1147
1148     StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next)
1149     {
1150         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>());
1151         if (!arrayBuffer)
1152             return 0;
1153         if (arrayBuffer->isNeutered())
1154             return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1155         m_writer.writeTransferredArrayBuffer(index);
1156         return 0;
1157     }
1158
1159     static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount)
1160     {
1161         // Let K be the cost of serializing all property values that are there
1162         // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t key)
1163         // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for all properties that are not there)
1164         // so densely is better than sparsly whenever 6*propertyCount > length
1165         return 6 * propertyCount >= length;
1166     }
1167
1168     StateBase* startArrayState(v8::Handle<v8::Array> array, StateBase* next)
1169     {
1170         v8::Handle<v8::Array> propertyNames = array->GetPropertyNames();
1171         if (StateBase* newState = checkException(next))
1172             return newState;
1173         uint32_t length = array->Length();
1174
1175         if (shouldSerializeDensely(length, propertyNames->Length())) {
1176             m_writer.writeGenerateFreshDenseArray(length);
1177             return push(new DenseArrayState(array, propertyNames, next, m_isolate));
1178         }
1179
1180         m_writer.writeGenerateFreshSparseArray(length);
1181         return push(new SparseArrayState(array, propertyNames, next, m_isolate));
1182     }
1183
1184     StateBase* startObjectState(v8::Handle<v8::Object> object, StateBase* next)
1185     {
1186         m_writer.writeGenerateFreshObject();
1187         // FIXME: check not a wrapper
1188         return push(new ObjectState(object, next));
1189     }
1190
1191     // Marks object as having been visited by the serializer and assigns it a unique object reference ID.
1192     // An object may only be greyed once.
1193     void greyObject(const v8::Handle<v8::Object>& object)
1194     {
1195         ASSERT(!m_objectPool.contains(object));
1196         uint32_t objectReference = m_nextObjectReference++;
1197         m_objectPool.set(object, objectReference);
1198     }
1199
1200     Writer& m_writer;
1201     v8::TryCatch& m_tryCatch;
1202     int m_depth;
1203     Status m_status;
1204     String m_errorMessage;
1205     typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool;
1206     ObjectPool m_objectPool;
1207     ObjectPool m_transferredMessagePorts;
1208     ObjectPool m_transferredArrayBuffers;
1209     uint32_t m_nextObjectReference;
1210     BlobDataHandleMap& m_blobDataHandles;
1211     v8::Isolate* m_isolate;
1212 };
1213
1214 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
1215 {
1216     m_writer.writeReferenceCount(m_nextObjectReference);
1217     uint32_t objectReference;
1218     uint32_t arrayBufferIndex;
1219     if ((value->IsObject() || value->IsDate() || value->IsRegExp())
1220         && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
1221         // Note that IsObject() also detects wrappers (eg, it will catch the things
1222         // that we grey and write below).
1223         ASSERT(!value->IsString());
1224         m_writer.writeObjectReference(objectReference);
1225     } else if (value.IsEmpty()) {
1226         return handleError(InputError, "The empty property name cannot be cloned.", next);
1227     } else if (value->IsUndefined())
1228         m_writer.writeUndefined();
1229     else if (value->IsNull())
1230         m_writer.writeNull();
1231     else if (value->IsTrue())
1232         m_writer.writeTrue();
1233     else if (value->IsFalse())
1234         m_writer.writeFalse();
1235     else if (value->IsInt32())
1236         m_writer.writeInt32(value->Int32Value());
1237     else if (value->IsUint32())
1238         m_writer.writeUint32(value->Uint32Value());
1239     else if (value->IsNumber())
1240         m_writer.writeNumber(value.As<v8::Number>()->Value());
1241     else if (V8ArrayBufferView::hasInstance(value, m_isolate))
1242         return writeAndGreyArrayBufferView(value.As<v8::Object>(), next);
1243     else if (value->IsString())
1244         writeString(value);
1245     else if (V8MessagePort::hasInstance(value, m_isolate)) {
1246         uint32_t messagePortIndex;
1247         if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePortIndex))
1248                 m_writer.writeTransferredMessagePort(messagePortIndex);
1249             else
1250                 return handleError(DataCloneError, "A MessagePort could not be cloned.", next);
1251     } else if (V8ArrayBuffer::hasInstance(value, m_isolate) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex))
1252         return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
1253     else {
1254         v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
1255         if (jsObject.IsEmpty())
1256             return handleError(DataCloneError, "An object could not be cloned.", next);
1257         greyObject(jsObject);
1258         if (value->IsDate())
1259             m_writer.writeDate(value->NumberValue());
1260         else if (value->IsStringObject())
1261             writeStringObject(value);
1262         else if (value->IsNumberObject())
1263             writeNumberObject(value);
1264         else if (value->IsBooleanObject())
1265             writeBooleanObject(value);
1266         else if (value->IsArray()) {
1267             return startArrayState(value.As<v8::Array>(), next);
1268         } else if (V8File::hasInstance(value, m_isolate))
1269             writeFile(value);
1270         else if (V8Blob::hasInstance(value, m_isolate))
1271             writeBlob(value);
1272         else if (V8DOMFileSystem::hasInstance(value, m_isolate))
1273             return writeDOMFileSystem(value, next);
1274         else if (V8FileList::hasInstance(value, m_isolate))
1275             writeFileList(value);
1276         else if (V8ImageData::hasInstance(value, m_isolate))
1277             writeImageData(value);
1278         else if (value->IsRegExp())
1279             writeRegExp(value);
1280         else if (V8ArrayBuffer::hasInstance(value, m_isolate))
1281             return writeArrayBuffer(value, next);
1282         else if (value->IsObject()) {
1283             if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNativeError())
1284                 return handleError(DataCloneError, "An object could not be cloned.", next);
1285             return startObjectState(jsObject, next);
1286         } else
1287             return handleError(DataCloneError, "A value could not be cloned.", next);
1288     }
1289     return 0;
1290 }
1291
1292 // Interface used by Reader to create objects of composite types.
1293 class CompositeCreator {
1294 public:
1295     virtual ~CompositeCreator() { }
1296
1297     virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0;
1298     virtual uint32_t objectReferenceCount() = 0;
1299     virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0;
1300     virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) = 0;
1301     virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) = 0;
1302     virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>*) = 0;
1303     virtual bool newSparseArray(uint32_t length) = 0;
1304     virtual bool newDenseArray(uint32_t length) = 0;
1305     virtual bool newObject() = 0;
1306     virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0;
1307     virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0;
1308     virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0;
1309 };
1310
1311 // Reader is responsible for deserializing primitive types and
1312 // restoring information about saved objects of composite types.
1313 class Reader {
1314 public:
1315     Reader(const uint8_t* buffer, int length, v8::Isolate* isolate,  const BlobDataHandleMap& blobDataHandles)
1316         : m_buffer(buffer)
1317         , m_length(length)
1318         , m_position(0)
1319         , m_version(0)
1320         , m_isolate(isolate)
1321         , m_blobDataHandles(blobDataHandles)
1322     {
1323         ASSERT(!(reinterpret_cast<size_t>(buffer) & 1));
1324         ASSERT(length >= 0);
1325     }
1326
1327     bool isEof() const { return m_position >= m_length; }
1328
1329     v8::Isolate* isolate() const { return m_isolate; }
1330
1331     bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
1332     {
1333         SerializationTag tag;
1334         if (!readTag(&tag))
1335             return false;
1336         switch (tag) {
1337         case ReferenceCountTag: {
1338             if (m_version <= 0)
1339                 return false;
1340             uint32_t referenceTableSize;
1341             if (!doReadUint32(&referenceTableSize))
1342                 return false;
1343             // If this test fails, then the serializer and deserializer disagree about the assignment
1344             // of object reference IDs. On the deserialization side, this means there are too many or too few
1345             // calls to pushObjectReference.
1346             if (referenceTableSize != creator.objectReferenceCount())
1347                 return false;
1348             return true;
1349         }
1350         case InvalidTag:
1351             return false;
1352         case PaddingTag:
1353             return true;
1354         case UndefinedTag:
1355             *value = v8::Undefined(m_isolate);
1356             break;
1357         case NullTag:
1358             *value = v8::Null(m_isolate);
1359             break;
1360         case TrueTag:
1361             *value = v8BooleanWithCheck(true, m_isolate);
1362             break;
1363         case FalseTag:
1364             *value = v8BooleanWithCheck(false, m_isolate);
1365             break;
1366         case TrueObjectTag:
1367             *value = v8::BooleanObject::New(true);
1368             creator.pushObjectReference(*value);
1369             break;
1370         case FalseObjectTag:
1371             *value = v8::BooleanObject::New(false);
1372             creator.pushObjectReference(*value);
1373             break;
1374         case StringTag:
1375             if (!readString(value))
1376                 return false;
1377             break;
1378         case StringUCharTag:
1379             if (!readUCharString(value))
1380                 return false;
1381             break;
1382         case StringObjectTag:
1383             if (!readStringObject(value))
1384                 return false;
1385             creator.pushObjectReference(*value);
1386             break;
1387         case Int32Tag:
1388             if (!readInt32(value))
1389                 return false;
1390             break;
1391         case Uint32Tag:
1392             if (!readUint32(value))
1393                 return false;
1394             break;
1395         case DateTag:
1396             if (!readDate(value))
1397                 return false;
1398             creator.pushObjectReference(*value);
1399             break;
1400         case NumberTag:
1401             if (!readNumber(value))
1402                 return false;
1403             break;
1404         case NumberObjectTag:
1405             if (!readNumberObject(value))
1406                 return false;
1407             creator.pushObjectReference(*value);
1408             break;
1409         case BlobTag:
1410             if (!readBlob(value))
1411                 return false;
1412             creator.pushObjectReference(*value);
1413             break;
1414         case FileTag:
1415             if (!readFile(value))
1416                 return false;
1417             creator.pushObjectReference(*value);
1418             break;
1419         case DOMFileSystemTag:
1420             if (!readDOMFileSystem(value))
1421                 return false;
1422             creator.pushObjectReference(*value);
1423             break;
1424         case FileListTag:
1425             if (!readFileList(value))
1426                 return false;
1427             creator.pushObjectReference(*value);
1428             break;
1429         case ImageDataTag:
1430             if (!readImageData(value))
1431                 return false;
1432             creator.pushObjectReference(*value);
1433             break;
1434
1435         case RegExpTag:
1436             if (!readRegExp(value))
1437                 return false;
1438             creator.pushObjectReference(*value);
1439             break;
1440         case ObjectTag: {
1441             uint32_t numProperties;
1442             if (!doReadUint32(&numProperties))
1443                 return false;
1444             if (!creator.completeObject(numProperties, value))
1445                 return false;
1446             break;
1447         }
1448         case SparseArrayTag: {
1449             uint32_t numProperties;
1450             uint32_t length;
1451             if (!doReadUint32(&numProperties))
1452                 return false;
1453             if (!doReadUint32(&length))
1454                 return false;
1455             if (!creator.completeSparseArray(numProperties, length, value))
1456                 return false;
1457             break;
1458         }
1459         case DenseArrayTag: {
1460             uint32_t numProperties;
1461             uint32_t length;
1462             if (!doReadUint32(&numProperties))
1463                 return false;
1464             if (!doReadUint32(&length))
1465                 return false;
1466             if (!creator.completeDenseArray(numProperties, length, value))
1467                 return false;
1468             break;
1469         }
1470         case ArrayBufferViewTag: {
1471             if (m_version <= 0)
1472                 return false;
1473             if (!readArrayBufferView(value, creator))
1474                 return false;
1475             creator.pushObjectReference(*value);
1476             break;
1477         }
1478         case ArrayBufferTag: {
1479             if (m_version <= 0)
1480                 return false;
1481             if (!readArrayBuffer(value))
1482                 return false;
1483             creator.pushObjectReference(*value);
1484             break;
1485         }
1486         case GenerateFreshObjectTag: {
1487             if (m_version <= 0)
1488                 return false;
1489             if (!creator.newObject())
1490                 return false;
1491             return true;
1492         }
1493         case GenerateFreshSparseArrayTag: {
1494             if (m_version <= 0)
1495                 return false;
1496             uint32_t length;
1497             if (!doReadUint32(&length))
1498                 return false;
1499             if (!creator.newSparseArray(length))
1500                 return false;
1501             return true;
1502         }
1503         case GenerateFreshDenseArrayTag: {
1504             if (m_version <= 0)
1505                 return false;
1506             uint32_t length;
1507             if (!doReadUint32(&length))
1508                 return false;
1509             if (!creator.newDenseArray(length))
1510                 return false;
1511             return true;
1512         }
1513         case MessagePortTag: {
1514             if (m_version <= 0)
1515                 return false;
1516             uint32_t index;
1517             if (!doReadUint32(&index))
1518                 return false;
1519             if (!creator.tryGetTransferredMessagePort(index, value))
1520                 return false;
1521             break;
1522         }
1523         case ArrayBufferTransferTag: {
1524             if (m_version <= 0)
1525                 return false;
1526             uint32_t index;
1527             if (!doReadUint32(&index))
1528                 return false;
1529             if (!creator.tryGetTransferredArrayBuffer(index, value))
1530                 return false;
1531             break;
1532         }
1533         case ObjectReferenceTag: {
1534             if (m_version <= 0)
1535                 return false;
1536             uint32_t reference;
1537             if (!doReadUint32(&reference))
1538                 return false;
1539             if (!creator.tryGetObjectFromObjectReference(reference, value))
1540                 return false;
1541             break;
1542         }
1543         default:
1544             return false;
1545         }
1546         return !value->IsEmpty();
1547     }
1548
1549     bool readVersion(uint32_t& version)
1550     {
1551         SerializationTag tag;
1552         if (!readTag(&tag)) {
1553             // This is a nullary buffer. We're still version 0.
1554             version = 0;
1555             return true;
1556         }
1557         if (tag != VersionTag) {
1558             // Versions of the format past 0 start with the version tag.
1559             version = 0;
1560             // Put back the tag.
1561             undoReadTag();
1562             return true;
1563         }
1564         // Version-bearing messages are obligated to finish the version tag.
1565         return doReadUint32(&version);
1566     }
1567
1568     void setVersion(uint32_t version)
1569     {
1570         m_version = version;
1571     }
1572
1573     v8::Isolate* getIsolate() { return m_isolate; }
1574
1575 private:
1576     bool readTag(SerializationTag* tag)
1577     {
1578         if (m_position >= m_length)
1579             return false;
1580         *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
1581         return true;
1582     }
1583
1584     void undoReadTag()
1585     {
1586         if (m_position > 0)
1587             --m_position;
1588     }
1589
1590     bool readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag)
1591     {
1592         if (m_position >= m_length)
1593             return false;
1594         *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]);
1595         return true;
1596     }
1597
1598     bool readString(v8::Handle<v8::Value>* value)
1599     {
1600         uint32_t length;
1601         if (!doReadUint32(&length))
1602             return false;
1603         if (m_position + length > m_length)
1604             return false;
1605         *value = v8::String::NewFromUtf8(m_isolate, reinterpret_cast<const char*>(m_buffer + m_position), v8::String::kNormalString, length);
1606         m_position += length;
1607         return true;
1608     }
1609
1610     bool readUCharString(v8::Handle<v8::Value>* value)
1611     {
1612         uint32_t length;
1613         if (!doReadUint32(&length) || (length & 1))
1614             return false;
1615         if (m_position + length > m_length)
1616             return false;
1617         ASSERT(!(m_position & 1));
1618         *value = v8::String::NewFromTwoByte(m_isolate, reinterpret_cast<const uint16_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar));
1619         m_position += length;
1620         return true;
1621     }
1622
1623     bool readStringObject(v8::Handle<v8::Value>* value)
1624     {
1625         v8::Handle<v8::Value> stringValue;
1626         if (!readString(&stringValue) || !stringValue->IsString())
1627             return false;
1628         *value = v8::StringObject::New(stringValue.As<v8::String>());
1629         return true;
1630     }
1631
1632     bool readWebCoreString(String* string)
1633     {
1634         uint32_t length;
1635         if (!doReadUint32(&length))
1636             return false;
1637         if (m_position + length > m_length)
1638             return false;
1639         *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
1640         m_position += length;
1641         return true;
1642     }
1643
1644     bool readInt32(v8::Handle<v8::Value>* value)
1645     {
1646         uint32_t rawValue;
1647         if (!doReadUint32(&rawValue))
1648             return false;
1649         *value = v8::Integer::New(m_isolate, static_cast<int32_t>(ZigZag::decode(rawValue)));
1650         return true;
1651     }
1652
1653     bool readUint32(v8::Handle<v8::Value>* value)
1654     {
1655         uint32_t rawValue;
1656         if (!doReadUint32(&rawValue))
1657             return false;
1658         *value = v8::Integer::NewFromUnsigned(m_isolate, rawValue);
1659         return true;
1660     }
1661
1662     bool readDate(v8::Handle<v8::Value>* value)
1663     {
1664         double numberValue;
1665         if (!doReadNumber(&numberValue))
1666             return false;
1667         *value = v8DateOrNull(numberValue, m_isolate);
1668         return true;
1669     }
1670
1671     bool readNumber(v8::Handle<v8::Value>* value)
1672     {
1673         double number;
1674         if (!doReadNumber(&number))
1675             return false;
1676         *value = v8::Number::New(m_isolate, number);
1677         return true;
1678     }
1679
1680     bool readNumberObject(v8::Handle<v8::Value>* value)
1681     {
1682         double number;
1683         if (!doReadNumber(&number))
1684             return false;
1685         *value = v8::NumberObject::New(m_isolate, number);
1686         return true;
1687     }
1688
1689     bool readImageData(v8::Handle<v8::Value>* value)
1690     {
1691         uint32_t width;
1692         uint32_t height;
1693         uint32_t pixelDataLength;
1694         if (!doReadUint32(&width))
1695             return false;
1696         if (!doReadUint32(&height))
1697             return false;
1698         if (!doReadUint32(&pixelDataLength))
1699             return false;
1700         if (m_position + pixelDataLength > m_length)
1701             return false;
1702         RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
1703         Uint8ClampedArray* pixelArray = imageData->data();
1704         ASSERT(pixelArray);
1705         ASSERT(pixelArray->length() >= pixelDataLength);
1706         memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
1707         m_position += pixelDataLength;
1708         *value = toV8(imageData.release(), v8::Handle<v8::Object>(), m_isolate);
1709         return true;
1710     }
1711
1712     PassRefPtr<ArrayBuffer> doReadArrayBuffer()
1713     {
1714         uint32_t byteLength;
1715         if (!doReadUint32(&byteLength))
1716             return 0;
1717         if (m_position + byteLength > m_length)
1718             return 0;
1719         const void* bufferStart = m_buffer + m_position;
1720         RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(bufferStart, byteLength);
1721         arrayBuffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
1722         m_position += byteLength;
1723         return arrayBuffer.release();
1724     }
1725
1726     bool readArrayBuffer(v8::Handle<v8::Value>* value)
1727     {
1728         RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer();
1729         if (!arrayBuffer)
1730             return false;
1731         *value = toV8(arrayBuffer.release(), v8::Handle<v8::Object>(), m_isolate);
1732         return true;
1733     }
1734
1735     bool readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator)
1736     {
1737         ArrayBufferViewSubTag subTag;
1738         uint32_t byteOffset;
1739         uint32_t byteLength;
1740         RefPtr<ArrayBuffer> arrayBuffer;
1741         v8::Handle<v8::Value> arrayBufferV8Value;
1742         if (!readArrayBufferViewSubTag(&subTag))
1743             return false;
1744         if (!doReadUint32(&byteOffset))
1745             return false;
1746         if (!doReadUint32(&byteLength))
1747             return false;
1748         if (!creator.consumeTopOfStack(&arrayBufferV8Value))
1749             return false;
1750         if (arrayBufferV8Value.IsEmpty())
1751             return false;
1752         arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>());
1753         if (!arrayBuffer)
1754             return false;
1755         switch (subTag) {
1756         case ByteArrayTag:
1757             *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
1758             break;
1759         case UnsignedByteArrayTag:
1760             *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(),  m_isolate);
1761             break;
1762         case UnsignedByteClampedArrayTag:
1763             *value = toV8(Uint8ClampedArray::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
1764             break;
1765         case ShortArrayTag: {
1766             uint32_t shortLength = byteLength / sizeof(int16_t);
1767             if (shortLength * sizeof(int16_t) != byteLength)
1768                 return false;
1769             *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
1770             break;
1771         }
1772         case UnsignedShortArrayTag: {
1773             uint32_t shortLength = byteLength / sizeof(uint16_t);
1774             if (shortLength * sizeof(uint16_t) != byteLength)
1775                 return false;
1776             *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
1777             break;
1778         }
1779         case IntArrayTag: {
1780             uint32_t intLength = byteLength / sizeof(int32_t);
1781             if (intLength * sizeof(int32_t) != byteLength)
1782                 return false;
1783             *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
1784             break;
1785         }
1786         case UnsignedIntArrayTag: {
1787             uint32_t intLength = byteLength / sizeof(uint32_t);
1788             if (intLength * sizeof(uint32_t) != byteLength)
1789                 return false;
1790             *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
1791             break;
1792         }
1793         case FloatArrayTag: {
1794             uint32_t floatLength = byteLength / sizeof(float);
1795             if (floatLength * sizeof(float) != byteLength)
1796                 return false;
1797             *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
1798             break;
1799         }
1800         case DoubleArrayTag: {
1801             uint32_t floatLength = byteLength / sizeof(double);
1802             if (floatLength * sizeof(double) != byteLength)
1803                 return false;
1804             *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
1805             break;
1806         }
1807         case DataViewTag:
1808             *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
1809             break;
1810         default:
1811             return false;
1812         }
1813         // The various *Array::create() methods will return null if the range the view expects is
1814         // mismatched with the range the buffer can provide or if the byte offset is not aligned
1815         // to the size of the element type.
1816         return !value->IsEmpty();
1817     }
1818
1819     bool readRegExp(v8::Handle<v8::Value>* value)
1820     {
1821         v8::Handle<v8::Value> pattern;
1822         if (!readString(&pattern))
1823             return false;
1824         uint32_t flags;
1825         if (!doReadUint32(&flags))
1826             return false;
1827         *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags));
1828         return true;
1829     }
1830
1831     bool readBlob(v8::Handle<v8::Value>* value)
1832     {
1833         if (m_version < 3)
1834             return false;
1835         String uuid;
1836         String type;
1837         uint64_t size;
1838         if (!readWebCoreString(&uuid))
1839             return false;
1840         if (!readWebCoreString(&type))
1841             return false;
1842         if (!doReadUint64(&size))
1843             return false;
1844         RefPtr<Blob> blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
1845         *value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate);
1846         return true;
1847     }
1848
1849     bool readDOMFileSystem(v8::Handle<v8::Value>* value)
1850     {
1851         uint32_t type;
1852         String name;
1853         String url;
1854         if (!doReadUint32(&type))
1855             return false;
1856         if (!readWebCoreString(&name))
1857             return false;
1858         if (!readWebCoreString(&url))
1859             return false;
1860         RefPtr<DOMFileSystem> fs = DOMFileSystem::create(getExecutionContext(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, url));
1861         *value = toV8(fs.release(), v8::Handle<v8::Object>(), m_isolate);
1862         return true;
1863     }
1864
1865     bool readFile(v8::Handle<v8::Value>* value)
1866     {
1867         RefPtr<File> file = doReadFileHelper();
1868         if (!file)
1869             return false;
1870         *value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate);
1871         return true;
1872     }
1873
1874     bool readFileList(v8::Handle<v8::Value>* value)
1875     {
1876         if (m_version < 3)
1877             return false;
1878         uint32_t length;
1879         if (!doReadUint32(&length))
1880             return false;
1881         RefPtr<FileList> fileList = FileList::create();
1882         for (unsigned i = 0; i < length; ++i) {
1883             RefPtr<File> file = doReadFileHelper();
1884             if (!file)
1885                 return false;
1886             fileList->append(file.release());
1887         }
1888         *value = toV8(fileList.release(), v8::Handle<v8::Object>(), m_isolate);
1889         return true;
1890     }
1891
1892     PassRefPtr<File> doReadFileHelper()
1893     {
1894         if (m_version < 3)
1895             return 0;
1896         String path;
1897         String name;
1898         String relativePath;
1899         String uuid;
1900         String type;
1901         uint32_t hasSnapshot = 0;
1902         uint64_t size = 0;
1903         double lastModified = 0;
1904         if (!readWebCoreString(&path))
1905             return 0;
1906         if (m_version >= 4 && !readWebCoreString(&name))
1907             return 0;
1908         if (m_version >= 4 && !readWebCoreString(&relativePath))
1909             return 0;
1910         if (!readWebCoreString(&uuid))
1911             return 0;
1912         if (!readWebCoreString(&type))
1913             return 0;
1914         if (m_version >= 4 && !doReadUint32(&hasSnapshot))
1915             return 0;
1916         if (hasSnapshot) {
1917             if (!doReadUint64(&size))
1918                 return 0;
1919             if (!doReadNumber(&lastModified))
1920                 return 0;
1921         }
1922         return File::create(path, name, relativePath, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type));
1923     }
1924
1925     template<class T>
1926     bool doReadUintHelper(T* value)
1927     {
1928         *value = 0;
1929         uint8_t currentByte;
1930         int shift = 0;
1931         do {
1932             if (m_position >= m_length)
1933                 return false;
1934             currentByte = m_buffer[m_position++];
1935             *value |= ((currentByte & varIntMask) << shift);
1936             shift += varIntShift;
1937         } while (currentByte & (1 << varIntShift));
1938         return true;
1939     }
1940
1941     bool doReadUint32(uint32_t* value)
1942     {
1943         return doReadUintHelper(value);
1944     }
1945
1946     bool doReadUint64(uint64_t* value)
1947     {
1948         return doReadUintHelper(value);
1949     }
1950
1951     bool doReadNumber(double* number)
1952     {
1953         if (m_position + sizeof(double) > m_length)
1954             return false;
1955         uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
1956         for (unsigned i = 0; i < sizeof(double); ++i)
1957             numberAsByteArray[i] = m_buffer[m_position++];
1958         return true;
1959     }
1960
1961     PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size = -1)
1962     {
1963         // The containing ssv may have a BDH for this uuid if this ssv is just being
1964         // passed from main to worker thread (for example). We use those values when creating
1965         // the new blob instead of cons'ing up a new BDH.
1966         //
1967         // FIXME: Maybe we should require that it work that way where the ssv must have a BDH for any
1968         // blobs it comes across during deserialization. Would require callers to explicitly populate
1969         // the collection of BDH's for blobs to work, which would encourage lifetimes to be considered
1970         // when passing ssv's around cross process. At present, we get 'lucky' in some cases because
1971         // the blob in the src process happens to still exist at the time the dest process is deserializing.
1972         // For example in sharedWorker.postMesssage(...).
1973         BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
1974         if (it != m_blobDataHandles.end()) {
1975             // make assertions about type and size?
1976             return it->value;
1977         }
1978         return BlobDataHandle::create(uuid, type, size);
1979     }
1980
1981     const uint8_t* m_buffer;
1982     const unsigned m_length;
1983     unsigned m_position;
1984     uint32_t m_version;
1985     v8::Isolate* m_isolate;
1986     const BlobDataHandleMap& m_blobDataHandles;
1987 };
1988
1989
1990 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray;
1991
1992 class Deserializer FINAL : public CompositeCreator {
1993 public:
1994     Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents)
1995         : m_reader(reader)
1996         , m_transferredMessagePorts(messagePorts)
1997         , m_arrayBufferContents(arrayBufferContents)
1998         , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0)
1999         , m_version(0)
2000     {
2001     }
2002
2003     v8::Handle<v8::Value> deserialize()
2004     {
2005         if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::wireFormatVersion)
2006             return v8::Null(m_reader.getIsolate());
2007         m_reader.setVersion(m_version);
2008         v8::EscapableHandleScope scope(m_reader.getIsolate());
2009         while (!m_reader.isEof()) {
2010             if (!doDeserialize())
2011                 return v8::Null(m_reader.getIsolate());
2012         }
2013         if (stackDepth() != 1 || m_openCompositeReferenceStack.size())
2014             return v8::Null(m_reader.getIsolate());
2015         v8::Handle<v8::Value> result = scope.Escape(element(0));
2016         return result;
2017     }
2018
2019     virtual bool newSparseArray(uint32_t) OVERRIDE
2020     {
2021         v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), 0);
2022         openComposite(array);
2023         return true;
2024     }
2025
2026     virtual bool newDenseArray(uint32_t length) OVERRIDE
2027     {
2028         v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), length);
2029         openComposite(array);
2030         return true;
2031     }
2032
2033     virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object) OVERRIDE
2034     {
2035         if (stackDepth() < 1)
2036             return false;
2037         *object = element(stackDepth() - 1);
2038         pop(1);
2039         return true;
2040     }
2041
2042     virtual bool newObject() OVERRIDE
2043     {
2044         v8::Local<v8::Object> object = v8::Object::New(m_reader.isolate());
2045         if (object.IsEmpty())
2046             return false;
2047         openComposite(object);
2048         return true;
2049     }
2050
2051     virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value) OVERRIDE
2052     {
2053         v8::Local<v8::Object> object;
2054         if (m_version > 0) {
2055             v8::Local<v8::Value> composite;
2056             if (!closeComposite(&composite))
2057                 return false;
2058             object = composite.As<v8::Object>();
2059         } else {
2060             object = v8::Object::New(m_reader.isolate());
2061         }
2062         if (object.IsEmpty())
2063             return false;
2064         return initializeObject(object, numProperties, value);
2065     }
2066
2067     virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
2068     {
2069         v8::Local<v8::Array> array;
2070         if (m_version > 0) {
2071             v8::Local<v8::Value> composite;
2072             if (!closeComposite(&composite))
2073                 return false;
2074             array = composite.As<v8::Array>();
2075         } else {
2076             array = v8::Array::New(m_reader.isolate());
2077         }
2078         if (array.IsEmpty())
2079             return false;
2080         return initializeObject(array, numProperties, value);
2081     }
2082
2083     virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
2084     {
2085         v8::Local<v8::Array> array;
2086         if (m_version > 0) {
2087             v8::Local<v8::Value> composite;
2088             if (!closeComposite(&composite))
2089                 return false;
2090             array = composite.As<v8::Array>();
2091         }
2092         if (array.IsEmpty())
2093             return false;
2094         if (!initializeObject(array, numProperties, value))
2095             return false;
2096         if (length > stackDepth())
2097             return false;
2098         for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stackPos++) {
2099             v8::Local<v8::Value> elem = element(stackPos);
2100             if (!elem->IsUndefined())
2101                 array->Set(i, elem);
2102         }
2103         pop(length);
2104         return true;
2105     }
2106
2107     virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRIDE
2108     {
2109         m_objectPool.append(object);
2110     }
2111
2112     virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
2113     {
2114         if (!m_transferredMessagePorts)
2115             return false;
2116         if (index >= m_transferredMessagePorts->size())
2117             return false;
2118         *object = toV8(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
2119         return true;
2120     }
2121
2122     virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
2123     {
2124         if (!m_arrayBufferContents)
2125             return false;
2126         if (index >= m_arrayBuffers.size())
2127             return false;
2128         v8::Handle<v8::Object> result = m_arrayBuffers.at(index);
2129         if (result.IsEmpty()) {
2130             RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferContents->at(index));
2131             buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
2132             m_reader.isolate()->AdjustAmountOfExternalAllocatedMemory(buffer->byteLength());
2133             result = toV8Object(buffer.get(), m_reader.getIsolate());
2134             m_arrayBuffers[index] = result;
2135         }
2136         *object = result;
2137         return true;
2138     }
2139
2140     virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object) OVERRIDE
2141     {
2142         if (reference >= m_objectPool.size())
2143             return false;
2144         *object = m_objectPool[reference];
2145         return object;
2146     }
2147
2148     virtual uint32_t objectReferenceCount() OVERRIDE
2149     {
2150         return m_objectPool.size();
2151     }
2152
2153 private:
2154     bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
2155     {
2156         unsigned length = 2 * numProperties;
2157         if (length > stackDepth())
2158             return false;
2159         for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
2160             v8::Local<v8::Value> propertyName = element(i);
2161             v8::Local<v8::Value> propertyValue = element(i + 1);
2162             object->Set(propertyName, propertyValue);
2163         }
2164         pop(length);
2165         *value = object;
2166         return true;
2167     }
2168
2169     bool doDeserialize()
2170     {
2171         v8::Local<v8::Value> value;
2172         if (!m_reader.read(&value, *this))
2173             return false;
2174         if (!value.IsEmpty())
2175             push(value);
2176         return true;
2177     }
2178
2179     void push(v8::Local<v8::Value> value) { m_stack.append(value); }
2180
2181     void pop(unsigned length)
2182     {
2183         ASSERT(length <= m_stack.size());
2184         m_stack.shrink(m_stack.size() - length);
2185     }
2186
2187     unsigned stackDepth() const { return m_stack.size(); }
2188
2189     v8::Local<v8::Value> element(unsigned index)
2190     {
2191         ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size());
2192         return m_stack[index];
2193     }
2194
2195     void openComposite(const v8::Local<v8::Value>& object)
2196     {
2197         uint32_t newObjectReference = m_objectPool.size();
2198         m_openCompositeReferenceStack.append(newObjectReference);
2199         m_objectPool.append(object);
2200     }
2201
2202     bool closeComposite(v8::Handle<v8::Value>* object)
2203     {
2204         if (!m_openCompositeReferenceStack.size())
2205             return false;
2206         uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1];
2207         m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2208         if (objectReference >= m_objectPool.size())
2209             return false;
2210         *object = m_objectPool[objectReference];
2211         return true;
2212     }
2213
2214     Reader& m_reader;
2215     Vector<v8::Local<v8::Value> > m_stack;
2216     Vector<v8::Handle<v8::Value> > m_objectPool;
2217     Vector<uint32_t> m_openCompositeReferenceStack;
2218     MessagePortArray* m_transferredMessagePorts;
2219     ArrayBufferContentsArray* m_arrayBufferContents;
2220     Vector<v8::Handle<v8::Object> > m_arrayBuffers;
2221     uint32_t m_version;
2222 };
2223
2224 } // namespace
2225
2226 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2227 {
2228     return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, exceptionState, isolate));
2229 }
2230
2231 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate)
2232 {
2233     TrackExceptionState exceptionState;
2234     return adoptRef(new SerializedScriptValue(value, 0, 0, exceptionState, isolate));
2235 }
2236
2237 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, ExceptionState& exceptionState, ScriptState* state)
2238 {
2239     ScriptScope scope(state);
2240     return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, exceptionState, state->isolate()));
2241 }
2242
2243 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data)
2244 {
2245     return adoptRef(new SerializedScriptValue(data));
2246 }
2247
2248 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(const Vector<uint8_t>& data)
2249 {
2250     // Decode wire data from big endian to host byte order.
2251     ASSERT(!(data.size() % sizeof(UChar)));
2252     size_t length = data.size() / sizeof(UChar);
2253     StringBuffer<UChar> buffer(length);
2254     const UChar* src = reinterpret_cast<const UChar*>(data.data());
2255     UChar* dst = buffer.characters();
2256     for (size_t i = 0; i < length; i++)
2257         dst[i] = ntohs(src[i]);
2258
2259     return createFromWire(String::adopt(buffer));
2260 }
2261
2262 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data)
2263 {
2264     return create(data, v8::Isolate::GetCurrent());
2265 }
2266
2267 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data, v8::Isolate* isolate)
2268 {
2269     Writer writer(isolate);
2270     writer.writeWebCoreString(data);
2271     String wireData = writer.takeWireString();
2272     return adoptRef(new SerializedScriptValue(wireData));
2273 }
2274
2275 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
2276 {
2277     return adoptRef(new SerializedScriptValue());
2278 }
2279
2280 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue()
2281 {
2282     return nullValue(v8::Isolate::GetCurrent());
2283 }
2284
2285 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue(v8::Isolate* isolate)
2286 {
2287     Writer writer(isolate);
2288     writer.writeNull();
2289     String wireData = writer.takeWireString();
2290     return adoptRef(new SerializedScriptValue(wireData));
2291 }
2292
2293 // Convert serialized string to big endian wire data.
2294 void SerializedScriptValue::toWireBytes(Vector<char>& result) const
2295 {
2296     ASSERT(result.isEmpty());
2297     size_t length = m_data.length();
2298     result.resize(length * sizeof(UChar));
2299     UChar* dst = reinterpret_cast<UChar*>(result.data());
2300
2301     if (m_data.is8Bit()) {
2302         const LChar* src = m_data.characters8();
2303         for (size_t i = 0; i < length; i++)
2304             dst[i] = htons(static_cast<UChar>(src[i]));
2305     } else {
2306         const UChar* src = m_data.characters16();
2307         for (size_t i = 0; i < length; i++)
2308             dst[i] = htons(src[i]);
2309     }
2310 }
2311
2312 SerializedScriptValue::SerializedScriptValue()
2313     : m_externallyAllocatedMemory(0)
2314 {
2315 }
2316
2317 inline void neuterBinding(ArrayBuffer* object)
2318 {
2319     v8::Isolate* isolate = v8::Isolate::GetCurrent();
2320     Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStores();
2321     for (size_t i = 0; i < allStores.size(); i++) {
2322         v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBuffer>(object, isolate);
2323         if (!wrapper.IsEmpty()) {
2324             ASSERT(wrapper->IsArrayBuffer());
2325             v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
2326         }
2327     }
2328 }
2329
2330 inline void neuterBinding(ArrayBufferView* object)
2331 {
2332     v8::Isolate* isolate = v8::Isolate::GetCurrent();
2333     Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStores();
2334     for (size_t i = 0; i < allStores.size(); i++) {
2335         v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(object, isolate);
2336         if (!wrapper.IsEmpty())
2337             wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByteArray, 0);
2338     }
2339 }
2340
2341 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2342 {
2343     ASSERT(arrayBuffers.size());
2344
2345     for (size_t i = 0; i < arrayBuffers.size(); i++) {
2346         if (arrayBuffers[i]->isNeutered()) {
2347             exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered.");
2348             return nullptr;
2349         }
2350     }
2351
2352     OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size()));
2353
2354     HashSet<ArrayBuffer*> visited;
2355     for (size_t i = 0; i < arrayBuffers.size(); i++) {
2356         Vector<RefPtr<ArrayBufferView> > neuteredViews;
2357
2358         if (visited.contains(arrayBuffers[i].get()))
2359             continue;
2360         visited.add(arrayBuffers[i].get());
2361
2362         bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews);
2363         if (!result) {
2364             exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred.");
2365             return nullptr;
2366         }
2367
2368         neuterBinding(arrayBuffers[i].get());
2369         for (size_t j = 0; j < neuteredViews.size(); j++)
2370             neuterBinding(neuteredViews[j].get());
2371     }
2372     return contents.release();
2373 }
2374
2375 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
2376     : m_externallyAllocatedMemory(0)
2377 {
2378     Writer writer(isolate);
2379     Serializer::Status status;
2380     String errorMessage;
2381     {
2382         v8::TryCatch tryCatch;
2383         Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHandles, tryCatch, isolate);
2384         status = serializer.serialize(value);
2385         if (status == Serializer::JSException) {
2386             // If there was a JS exception thrown, re-throw it.
2387             exceptionState.rethrowV8Exception(tryCatch.Exception());
2388             return;
2389         }
2390         errorMessage = serializer.errorMessage();
2391     }
2392     switch (status) {
2393     case Serializer::InputError:
2394     case Serializer::DataCloneError:
2395         exceptionState.throwDOMException(DataCloneError, errorMessage);
2396         return;
2397     case Serializer::Success:
2398         m_data = writer.takeWireString();
2399         ASSERT(m_data.impl()->hasOneRef());
2400         if (arrayBuffers && arrayBuffers->size())
2401             m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, exceptionState, isolate);
2402         return;
2403     case Serializer::JSException:
2404         ASSERT_NOT_REACHED();
2405         break;
2406     }
2407     ASSERT_NOT_REACHED();
2408 }
2409
2410 SerializedScriptValue::SerializedScriptValue(const String& wireData)
2411     : m_externallyAllocatedMemory(0)
2412 {
2413     m_data = wireData.isolatedCopy();
2414 }
2415
2416 v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts)
2417 {
2418     return deserialize(v8::Isolate::GetCurrent(), messagePorts);
2419 }
2420
2421 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts)
2422 {
2423     if (!m_data.impl())
2424         return v8::Null(isolate);
2425     COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
2426     m_data.ensure16Bit();
2427     // FIXME: SerializedScriptValue shouldn't use String for its underlying
2428     // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
2429     // information stored in m_data isn't even encoded in UTF-16. Instead,
2430     // unicode characters are encoded as UTF-8 with two code units per UChar.
2431     Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, m_blobDataHandles);
2432     Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get());
2433
2434     // deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
2435     // Holding a RefPtr ensures we are alive (along with our internal data) throughout the operation.
2436     RefPtr<SerializedScriptValue> protect(this);
2437     return deserializer.deserialize();
2438 }
2439
2440 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext()
2441 {
2442     if (m_externallyAllocatedMemory)
2443         return;
2444     m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length());
2445     v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externallyAllocatedMemory);
2446 }
2447
2448 SerializedScriptValue::~SerializedScriptValue()
2449 {
2450     // If the allocated memory was not registered before, then this class is likely
2451     // used in a context other then Worker's onmessage environment and the presence of
2452     // current v8 context is not guaranteed. Avoid calling v8 then.
2453     if (m_externallyAllocatedMemory) {
2454         ASSERT(v8::Isolate::GetCurrent());
2455         v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
2456     }
2457 }
2458
2459 } // namespace WebCore