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