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