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