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