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