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