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