1c5e4e718405213a91dabc15d5394b3dd5df3a00
[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 "Blob.h"
35 #include "ByteArray.h"
36 #include "CanvasPixelArray.h"
37 #include "ExceptionCode.h"
38 #include "File.h"
39 #include "FileList.h"
40 #include "ImageData.h"
41 #include "SharedBuffer.h"
42 #include "V8Binding.h"
43 #include "V8Blob.h"
44 #include "V8File.h"
45 #include "V8FileList.h"
46 #include "V8ImageData.h"
47 #include "V8Proxy.h"
48 #include "V8Utilities.h"
49
50 #include <wtf/Assertions.h>
51 #include <wtf/RefCounted.h>
52 #include <wtf/Vector.h>
53
54 // FIXME:
55 // - catch V8 exceptions
56 // - consider crashing in debug mode on deserialization errors
57
58 namespace WebCore {
59
60 namespace {
61
62 typedef UChar BufferValueType;
63
64 // Serialization format is a sequence of (tag, optional data)
65 // pairs. Tag always takes exactly one byte.
66 enum SerializationTag {
67     InvalidTag = '!',
68     PaddingTag = '\0',
69     UndefinedTag = '_',
70     NullTag = '0',
71     TrueTag = 'T',
72     FalseTag = 'F',
73     StringTag = 'S',
74     Int32Tag = 'I',
75     Uint32Tag = 'U',
76     DateTag = 'D',
77     NumberTag = 'N',
78     BlobTag = 'b',
79     FileTag = 'f',
80     FileListTag = 'l',
81     ImageDataTag = '#',
82     ArrayTag = '[',
83     ObjectTag = '{',
84     SparseArrayTag = '@',
85     RegExpTag = 'R',
86 };
87
88 static bool shouldCheckForCycles(int depth)
89 {
90     ASSERT(depth >= 0);
91     // Since we are not required to spot the cycle as soon as it
92     // happens we can check for cycles only when the current depth
93     // is a power of two.
94     return !(depth & (depth - 1));
95 }
96
97 static const int maxDepth = 20000;
98
99 // VarInt encoding constants.
100 static const int varIntShift = 7;
101 static const int varIntMask = (1 << varIntShift) - 1;
102
103 // ZigZag encoding helps VarInt encoding stay small for negative
104 // numbers with small absolute values.
105 class ZigZag {
106 public:
107     static uint32_t encode(uint32_t value)
108     {
109         if (value & (1U << 31))
110             value = ((~value) << 1) + 1;
111         else
112             value <<= 1;
113         return value;
114     }
115
116     static uint32_t decode(uint32_t value)
117     {
118         if (value & 1)
119             value = ~(value >> 1);
120         else
121             value >>= 1;
122         return value;
123     }
124
125 private:
126     ZigZag();
127 };
128
129 // Writer is responsible for serializing primitive types and storing
130 // information used to reconstruct composite types.
131 class Writer {
132     WTF_MAKE_NONCOPYABLE(Writer);
133 public:
134     Writer()
135         : m_position(0)
136     {
137     }
138
139     // Write functions for primitive types.
140
141     void writeUndefined() { append(UndefinedTag); }
142
143     void writeNull() { append(NullTag); }
144
145     void writeTrue() { append(TrueTag); }
146
147     void writeFalse() { append(FalseTag); }
148
149     void writeString(const char* data, int length)
150     {
151         ASSERT(length >= 0);
152         append(StringTag);
153         doWriteString(data, length);
154     }
155
156     void writeWebCoreString(const String& string)
157     {
158         // Uses UTF8 encoding so we can read it back as either V8 or
159         // WebCore string.
160         append(StringTag);
161         doWriteWebCoreString(string);
162     }
163
164     void writeInt32(int32_t value)
165     {
166         append(Int32Tag);
167         doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
168     }
169
170     void writeUint32(uint32_t value)
171     {
172         append(Uint32Tag);
173         doWriteUint32(value);
174     }
175
176     void writeDate(double numberValue)
177     {
178         append(DateTag);
179         doWriteNumber(numberValue);
180     }
181
182     void writeNumber(double number)
183     {
184         append(NumberTag);
185         doWriteNumber(number);
186     }
187
188     void writeBlob(const String& url, const String& type, unsigned long long size)
189     {
190         append(BlobTag);
191         doWriteWebCoreString(url);
192         doWriteWebCoreString(type);
193         doWriteUint64(size);
194     }
195
196     void writeFile(const String& path, const String& url, const String& type)
197     {
198         append(FileTag);
199         doWriteWebCoreString(path);
200         doWriteWebCoreString(url);
201         doWriteWebCoreString(type);
202     }
203
204     void writeFileList(const FileList& fileList)
205     {
206         append(FileListTag);
207         uint32_t length = fileList.length();
208         doWriteUint32(length);
209         for (unsigned i = 0; i < length; ++i) {
210             doWriteWebCoreString(fileList.item(i)->path());
211             doWriteWebCoreString(fileList.item(i)->url().string());
212             doWriteWebCoreString(fileList.item(i)->type());
213         }
214     }
215
216     void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
217     {
218         append(ImageDataTag);
219         doWriteUint32(width);
220         doWriteUint32(height);
221         doWriteUint32(pixelDataLength);
222         append(pixelData, pixelDataLength);
223     }
224     
225     void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags)
226     {
227         append(RegExpTag);
228         v8::String::Utf8Value patternUtf8Value(pattern);
229         doWriteString(*patternUtf8Value, patternUtf8Value.length());
230         doWriteUint32(static_cast<uint32_t>(flags));
231     }    
232
233     void writeArray(uint32_t length)
234     {
235         append(ArrayTag);
236         doWriteUint32(length);
237     }
238
239     void writeObject(uint32_t numProperties)
240     {
241         append(ObjectTag);
242         doWriteUint32(numProperties);
243     }
244
245     void writeSparseArray(uint32_t numProperties, uint32_t length)
246     {
247         append(SparseArrayTag);
248         doWriteUint32(numProperties);
249         doWriteUint32(length);
250     }
251
252     Vector<BufferValueType>& data()
253     {
254         fillHole();
255         return m_buffer;
256     }
257
258 private:
259     void doWriteString(const char* data, int length)
260     {
261         doWriteUint32(static_cast<uint32_t>(length));
262         append(reinterpret_cast<const uint8_t*>(data), length);
263     }
264
265     void doWriteWebCoreString(const String& string)
266     {
267         RefPtr<SharedBuffer> buffer = utf8Buffer(string);
268         doWriteString(buffer->data(), buffer->size());
269     }
270
271     template<class T>
272     void doWriteUintHelper(T value)
273     {
274         while (true) {
275             uint8_t b = (value & varIntMask);
276             value >>= varIntShift;
277             if (!value) {
278                 append(b);
279                 break;
280             }
281             append(b | (1 << varIntShift));
282         }
283     }
284
285     void doWriteUint32(uint32_t value)
286     {
287         doWriteUintHelper(value);
288     }
289
290     void doWriteUint64(uint64_t value)
291     {
292         doWriteUintHelper(value);
293     }
294
295     void doWriteNumber(double number)
296     {
297         append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
298     }
299
300     void append(SerializationTag tag)
301     {
302         append(static_cast<uint8_t>(tag));
303     }
304
305     void append(uint8_t b)
306     {
307         ensureSpace(1);
308         *byteAt(m_position++) = b;
309     }
310
311     void append(const uint8_t* data, int length)
312     {
313         ensureSpace(length);
314         memcpy(byteAt(m_position), data, length);
315         m_position += length;
316     }
317
318     void ensureSpace(int extra)
319     {
320         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
321         m_buffer.grow((m_position + extra + 1) / 2); // "+ 1" to round up.
322     }
323
324     void fillHole()
325     {
326         COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
327         // If the writer is at odd position in the buffer, then one of
328         // the bytes in the last UChar is not initialized.
329         if (m_position % 2)
330             *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
331     }
332
333     uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; }
334
335     Vector<BufferValueType> m_buffer;
336     unsigned m_position;
337 };
338
339 class Serializer {
340     class StateBase;
341 public:
342     explicit Serializer(Writer& writer)
343         : m_writer(writer)
344         , m_depth(0)
345         , m_hasError(false)
346     {
347     }
348
349     bool serialize(v8::Handle<v8::Value> value)
350     {
351         v8::HandleScope scope;
352         StateBase* state = doSerialize(value, 0);
353         while (state)
354             state = state->advance(*this);
355         return !m_hasError;
356     }
357
358     // Functions used by serialization states.
359
360     StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next);
361
362     StateBase* writeArray(uint32_t length, StateBase* state)
363     {
364         m_writer.writeArray(length);
365         return pop(state);
366     }
367
368     StateBase* writeObject(uint32_t numProperties, StateBase* state)
369     {
370         m_writer.writeObject(numProperties);
371         return pop(state);
372     }
373
374     StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
375     {
376         m_writer.writeSparseArray(numProperties, length);
377         return pop(state);
378     }
379
380 private:
381     class StateBase {
382         WTF_MAKE_NONCOPYABLE(StateBase);
383     public:
384         virtual ~StateBase() { }
385
386         // Link to the next state to form a stack.
387         StateBase* nextState() { return m_next; }
388
389         // Composite object we're processing in this state.
390         v8::Handle<v8::Value> composite() { return m_composite; }
391
392         // Serializes (a part of) the current composite and returns
393         // the next state to process or null when this is the final
394         // state.
395         virtual StateBase* advance(Serializer&) = 0;
396
397     protected:
398         StateBase(v8::Handle<v8::Value> composite, StateBase* next)
399             : m_composite(composite)
400             , m_next(next)
401         {
402         }
403
404     private:
405         v8::Handle<v8::Value> m_composite;
406         StateBase* m_next;
407     };
408
409     // Dummy state that is used to signal serialization errors.
410     class ErrorState : public StateBase {
411     public:
412         ErrorState()
413             : StateBase(v8::Handle<v8::Value>(), 0)
414         {
415         }
416
417         virtual StateBase* advance(Serializer&)
418         {
419             delete this;
420             return 0;
421         }
422     };
423
424     template <typename T>
425     class State : public StateBase {
426     public:
427         v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
428
429     protected:
430         State(v8::Handle<T> composite, StateBase* next)
431             : StateBase(composite, next)
432         {
433         }
434     };
435
436 #if 0
437     // Currently unused, see comment in newArrayState.
438     class ArrayState : public State<v8::Array> {
439     public:
440         ArrayState(v8::Handle<v8::Array> array, StateBase* next)
441             : State<v8::Array>(array, next)
442             , m_index(-1)
443         {
444         }
445
446         virtual StateBase* advance(Serializer& serializer)
447         {
448             ++m_index;
449             for (; m_index < composite()->Length(); ++m_index) {
450                 if (StateBase* newState = serializer.doSerialize(composite()->Get(m_index), this))
451                     return newState;
452             }
453             return serializer.writeArray(composite()->Length(), this);
454         }
455
456     private:
457         unsigned m_index;
458     };
459 #endif
460
461     class AbstractObjectState : public State<v8::Object> {
462     public:
463         AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
464             : State<v8::Object>(object, next)
465             , m_propertyNames(object->GetPropertyNames())
466             , m_index(-1)
467             , m_numSerializedProperties(0)
468             , m_nameDone(false)
469         {
470         }
471
472         virtual StateBase* advance(Serializer& serializer)
473         {
474             ++m_index;
475             for (; m_index < m_propertyNames->Length(); ++m_index) {
476                 if (m_propertyName.IsEmpty()) {
477                     v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
478                     if ((propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()))
479                         || (propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
480                         m_propertyName = propertyName;
481                     } else
482                         continue;
483                 }
484                 ASSERT(!m_propertyName.IsEmpty());
485                 if (!m_nameDone) {
486                     m_nameDone = true;
487                     if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
488                         return newState;
489                 }
490                 v8::Local<v8::Value> value = composite()->Get(m_propertyName);
491                 m_nameDone = false;
492                 m_propertyName.Clear();
493                 ++m_numSerializedProperties;
494                 if (StateBase* newState = serializer.doSerialize(value, this))
495                     return newState;
496             }
497             return objectDone(m_numSerializedProperties, serializer);
498         }
499
500     protected:
501         virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
502
503     private:
504         v8::Local<v8::Array> m_propertyNames;
505         v8::Local<v8::Value> m_propertyName;
506         unsigned m_index;
507         unsigned m_numSerializedProperties;
508         bool m_nameDone;
509     };
510
511     class ObjectState : public AbstractObjectState {
512     public:
513         ObjectState(v8::Handle<v8::Object> object, StateBase* next)
514             : AbstractObjectState(object, next)
515         {
516         }
517
518     protected:
519         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
520         {
521             return serializer.writeObject(numProperties, this);
522         }
523     };
524
525     class SparseArrayState : public AbstractObjectState {
526     public:
527         SparseArrayState(v8::Handle<v8::Array> array, StateBase* next)
528             : AbstractObjectState(array, next)
529         {
530         }
531
532     protected:
533         virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
534         {
535             return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
536         }
537     };
538
539     StateBase* push(StateBase* state)
540     {
541         ASSERT(state);
542         ++m_depth;
543         return checkComposite(state) ? state : handleError(state);
544     }
545
546     StateBase* pop(StateBase* state)
547     {
548         ASSERT(state);
549         --m_depth;
550         StateBase* next = state->nextState();
551         delete state;
552         return next;
553     }
554
555     StateBase* handleError(StateBase* state)
556     {
557         m_hasError = true;
558         while (state) {
559             StateBase* tmp = state->nextState();
560             delete state;
561             state = tmp;
562         }
563         return new ErrorState;
564     }
565
566     bool checkComposite(StateBase* top)
567     {
568         ASSERT(top);
569         if (m_depth > maxDepth)
570             return false;
571         if (!shouldCheckForCycles(m_depth))
572             return true;
573         v8::Handle<v8::Value> composite = top->composite();
574         for (StateBase* state = top->nextState(); state; state = state->nextState()) {
575             if (state->composite() == composite)
576                 return false;
577         }
578         return true;
579     }
580
581     void writeString(v8::Handle<v8::Value> value)
582     {
583         v8::String::Utf8Value stringValue(value);
584         m_writer.writeString(*stringValue, stringValue.length());
585     }
586
587     void writeBlob(v8::Handle<v8::Value> value)
588     {
589         Blob* blob = V8Blob::toNative(value.As<v8::Object>());
590         if (!blob)
591             return;
592         m_writer.writeBlob(blob->url().string(), blob->type(), blob->size());
593     }
594
595     void writeFile(v8::Handle<v8::Value> value)
596     {
597         File* file = V8File::toNative(value.As<v8::Object>());
598         if (!file)
599             return;
600         m_writer.writeFile(file->path(), file->url().string(), file->type());
601     }
602
603     void writeFileList(v8::Handle<v8::Value> value)
604     {
605         FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
606         if (!fileList)
607             return;
608         m_writer.writeFileList(*fileList);
609     }
610
611     void writeImageData(v8::Handle<v8::Value> value)
612     {
613         ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
614         if (!imageData)
615             return;
616         WTF::ByteArray* pixelArray = imageData->data()->data();
617         m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
618     }
619     
620     void writeRegExp(v8::Handle<v8::Value> value)
621     {
622         v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>();
623         m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
624     }
625
626     static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next)
627     {
628         // FIXME: use plain Array state when we can quickly check that
629         // an array is not sparse and has only indexed properties.
630         return new SparseArrayState(array, next);
631     }
632
633     static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next)
634     {
635         // FIXME:
636         // - check not a wrapper
637         // - support File, etc.
638         return new ObjectState(object, next);
639     }
640
641     Writer& m_writer;
642     int m_depth;
643     bool m_hasError;
644 };
645
646 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
647 {
648     if (value->IsUndefined())
649         m_writer.writeUndefined();
650     else if (value->IsNull())
651         m_writer.writeNull();
652     else if (value->IsTrue())
653         m_writer.writeTrue();
654     else if (value->IsFalse())
655         m_writer.writeFalse();
656     else if (value->IsInt32())
657         m_writer.writeInt32(value->Int32Value());
658     else if (value->IsUint32())
659         m_writer.writeUint32(value->Uint32Value());
660     else if (value->IsDate())
661         m_writer.writeDate(value->NumberValue());
662     else if (value->IsNumber())
663         m_writer.writeNumber(value.As<v8::Number>()->Value());
664     else if (value->IsString())
665         writeString(value);
666     else if (value->IsArray())
667         return push(newArrayState(value.As<v8::Array>(), next));
668     else if (V8File::HasInstance(value))
669         writeFile(value);
670     else if (V8Blob::HasInstance(value))
671         writeBlob(value);
672     else if (V8FileList::HasInstance(value))
673         writeFileList(value);
674     else if (V8ImageData::HasInstance(value))
675         writeImageData(value);
676     else if (value->IsRegExp())
677         writeRegExp(value);
678     else if (value->IsObject())
679         return push(newObjectState(value.As<v8::Object>(), next));
680     return 0;
681 }
682
683 // Interface used by Reader to create objects of composite types.
684 class CompositeCreator {
685 public:
686     virtual ~CompositeCreator() { }
687
688     virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0;
689     virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0;
690     virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0;
691 };
692
693 // Reader is responsible for deserializing primitive types and
694 // restoring information about saved objects of composite types.
695 class Reader {
696 public:
697     Reader(const uint8_t* buffer, int length)
698         : m_buffer(buffer)
699         , m_length(length)
700         , m_position(0)
701     {
702         ASSERT(length >= 0);
703     }
704
705     bool isEof() const { return m_position >= m_length; }
706
707     bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
708     {
709         SerializationTag tag;
710         if (!readTag(&tag))
711             return false;
712         switch (tag) {
713         case InvalidTag:
714             return false;
715         case PaddingTag:
716             return true;
717         case UndefinedTag:
718             *value = v8::Undefined();
719             break;
720         case NullTag:
721             *value = v8::Null();
722             break;
723         case TrueTag:
724             *value = v8::True();
725             break;
726         case FalseTag:
727             *value = v8::False();
728             break;
729         case StringTag:
730             if (!readString(value))
731                 return false;
732             break;
733         case Int32Tag:
734             if (!readInt32(value))
735                 return false;
736             break;
737         case Uint32Tag:
738             if (!readUint32(value))
739                 return false;
740             break;
741         case DateTag:
742             if (!readDate(value))
743                 return false;
744             break;
745         case NumberTag:
746             if (!readNumber(value))
747                 return false;
748             break;
749         case BlobTag:
750             if (!readBlob(value))
751                 return false;
752             break;
753         case FileTag:
754             if (!readFile(value))
755                 return false;
756             break;
757         case FileListTag:
758             if (!readFileList(value))
759                 return false;
760             break;
761         case ImageDataTag:
762             if (!readImageData(value))
763                 return false;
764             break;
765         case ArrayTag: {
766             uint32_t length;
767             if (!doReadUint32(&length))
768                 return false;
769             if (!creator.createArray(length, value))
770                 return false;
771             break;
772         }
773         case RegExpTag:
774             if (!readRegExp(value))
775                 return false;
776             break;
777         case ObjectTag: {
778             uint32_t numProperties;
779             if (!doReadUint32(&numProperties))
780                 return false;
781             if (!creator.createObject(numProperties, value))
782                 return false;
783             break;
784         }
785         case SparseArrayTag: {
786             uint32_t numProperties;
787             uint32_t length;
788             if (!doReadUint32(&numProperties))
789                 return false;
790             if (!doReadUint32(&length))
791                 return false;
792             if (!creator.createSparseArray(numProperties, length, value))
793                 return false;
794             break;
795         }
796         default:
797             return false;
798         }
799         return !value->IsEmpty();
800     }
801
802 private:
803     bool readTag(SerializationTag* tag)
804     {
805         if (m_position >= m_length)
806             return false;
807         *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
808         return true;
809     }
810
811     bool readString(v8::Handle<v8::Value>* value)
812     {
813         uint32_t length;
814         if (!doReadUint32(&length))
815             return false;
816         if (m_position + length > m_length)
817             return false;
818         *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length);
819         m_position += length;
820         return true;
821     }
822
823     bool readWebCoreString(String* string)
824     {
825         uint32_t length;
826         if (!doReadUint32(&length))
827             return false;
828         if (m_position + length > m_length)
829             return false;
830         *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
831         m_position += length;
832         return true;
833     }
834
835     bool readInt32(v8::Handle<v8::Value>* value)
836     {
837         uint32_t rawValue;
838         if (!doReadUint32(&rawValue))
839             return false;
840         *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue)));
841         return true;
842     }
843
844     bool readUint32(v8::Handle<v8::Value>* value)
845     {
846         uint32_t rawValue;
847         if (!doReadUint32(&rawValue))
848             return false;
849         *value = v8::Integer::NewFromUnsigned(rawValue);
850         return true;
851     }
852
853     bool readDate(v8::Handle<v8::Value>* value)
854     {
855         double numberValue;
856         if (!doReadNumber(&numberValue))
857             return false;
858         *value = v8::Date::New(numberValue);
859         return true;
860     }
861
862     bool readNumber(v8::Handle<v8::Value>* value)
863     {
864         double number;
865         if (!doReadNumber(&number))
866             return false;
867         *value = v8::Number::New(number);
868         return true;
869     }
870
871     bool readImageData(v8::Handle<v8::Value>* value)
872     {
873         uint32_t width;
874         uint32_t height;
875         uint32_t pixelDataLength;
876         if (!doReadUint32(&width))
877             return false;
878         if (!doReadUint32(&height))
879             return false;
880         if (!doReadUint32(&pixelDataLength))
881             return false;
882         if (m_position + pixelDataLength > m_length)
883             return false;
884         RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
885         WTF::ByteArray* pixelArray = imageData->data()->data();
886         ASSERT(pixelArray);
887         ASSERT(pixelArray->length() >= pixelDataLength);
888         memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
889         m_position += pixelDataLength;
890         *value = toV8(imageData.release());
891         return true;
892     }
893     
894     bool readRegExp(v8::Handle<v8::Value>* value)
895     {
896         v8::Handle<v8::Value> pattern;
897         if (!readString(&pattern))
898             return false;
899         uint32_t flags;
900         if (!doReadUint32(&flags))
901             return false;
902         *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags));
903         return true;
904     }
905
906     bool readBlob(v8::Handle<v8::Value>* value)
907     {
908         String url;
909         String type;
910         uint64_t size;
911         if (!readWebCoreString(&url))
912             return false;
913         if (!readWebCoreString(&type))
914             return false;
915         if (!doReadUint64(&size))
916             return false;
917         PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size);
918         *value = toV8(blob);
919         return true;
920     }
921
922     bool readFile(v8::Handle<v8::Value>* value)
923     {
924         String path;
925         String url;
926         String type;
927         if (!readWebCoreString(&path))
928             return false;
929         if (!readWebCoreString(&url))
930             return false;
931         if (!readWebCoreString(&type))
932             return false;
933         PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), type);
934         *value = toV8(file);
935         return true;
936     }
937
938     bool readFileList(v8::Handle<v8::Value>* value)
939     {
940         uint32_t length;
941         if (!doReadUint32(&length))
942             return false;
943         PassRefPtr<FileList> fileList = FileList::create();
944         for (unsigned i = 0; i < length; ++i) {
945             String path;
946             String urlString;
947             String type;
948             if (!readWebCoreString(&path))
949                 return false;
950             if (!readWebCoreString(&urlString))
951                 return false;
952             if (!readWebCoreString(&type))
953                 return false;
954             fileList->append(File::create(path, KURL(ParsedURLString, urlString), type));
955         }
956         *value = toV8(fileList);
957         return true;
958     }
959
960     template<class T>
961     bool doReadUintHelper(T* value)
962     {
963         *value = 0;
964         uint8_t currentByte;
965         int shift = 0;
966         do {
967             if (m_position >= m_length)
968                 return false;
969             currentByte = m_buffer[m_position++];
970             *value |= ((currentByte & varIntMask) << shift);
971             shift += varIntShift;
972         } while (currentByte & (1 << varIntShift));
973         return true;
974     }
975
976     bool doReadUint32(uint32_t* value)
977     {
978         return doReadUintHelper(value);
979     }
980
981     bool doReadUint64(uint64_t* value)
982     {
983         return doReadUintHelper(value);
984     }
985
986     bool doReadNumber(double* number)
987     {
988         if (m_position + sizeof(double) > m_length)
989             return false;
990         uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
991         for (unsigned i = 0; i < sizeof(double); ++i)
992             numberAsByteArray[i] = m_buffer[m_position++];
993         return true;
994     }
995
996     const uint8_t* m_buffer;
997     const unsigned m_length;
998     unsigned m_position;
999 };
1000
1001 class Deserializer : public CompositeCreator {
1002 public:
1003     explicit Deserializer(Reader& reader)
1004         : m_reader(reader)
1005     {
1006     }
1007
1008     v8::Handle<v8::Value> deserialize()
1009     {
1010         v8::HandleScope scope;
1011         while (!m_reader.isEof()) {
1012             if (!doDeserialize())
1013                 return v8::Null();
1014         }
1015         if (stackDepth() != 1)
1016             return v8::Null();
1017         return scope.Close(element(0));
1018     }
1019
1020     virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value)
1021     {
1022         if (length > stackDepth())
1023             return false;
1024         v8::Local<v8::Array> array = v8::Array::New(length);
1025         if (array.IsEmpty())
1026             return false;
1027         const int depth = stackDepth() - length;
1028         for (unsigned i = 0; i < length; ++i)
1029             array->Set(i, element(depth + i));
1030         pop(length);
1031         *value = array;
1032         return true;
1033     }
1034
1035     virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
1036     {
1037         v8::Local<v8::Object> object = v8::Object::New();
1038         if (object.IsEmpty())
1039             return false;
1040         return initializeObject(object, numProperties, value);
1041     }
1042
1043     virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
1044     {
1045         v8::Local<v8::Array> array = v8::Array::New(length);
1046         if (array.IsEmpty())
1047             return false;
1048         return initializeObject(array, numProperties, value);
1049     }
1050
1051 private:
1052     bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
1053     {
1054         unsigned length = 2 * numProperties;
1055         if (length > stackDepth())
1056             return false;
1057         for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
1058             v8::Local<v8::Value> propertyName = element(i);
1059             v8::Local<v8::Value> propertyValue = element(i + 1);
1060             object->Set(propertyName, propertyValue);
1061         }
1062         pop(length);
1063         *value = object;
1064         return true;
1065     }
1066
1067     bool doDeserialize()
1068     {
1069         v8::Local<v8::Value> value;
1070         if (!m_reader.read(&value, *this))
1071             return false;
1072         if (!value.IsEmpty())
1073             push(value);
1074         return true;
1075     }
1076
1077     void push(v8::Local<v8::Value> value) { m_stack.append(value); }
1078
1079     void pop(unsigned length)
1080     {
1081         ASSERT(length <= m_stack.size());
1082         m_stack.shrink(m_stack.size() - length);
1083     }
1084
1085     unsigned stackDepth() const { return m_stack.size(); }
1086
1087     v8::Local<v8::Value> element(unsigned index)
1088     {
1089         ASSERT(index < m_stack.size());
1090         return m_stack[index];
1091     }
1092
1093     Reader& m_reader;
1094     Vector<v8::Local<v8::Value> > m_stack;
1095 };
1096
1097 } // namespace
1098
1099 void SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName,
1100                                                       v8::PropertyAttribute attribute, SerializedScriptValue* value)
1101 {
1102     if (!value)
1103         return;
1104     v8::Handle<v8::Value> deserialized = value->deserialize();
1105     object->ForceSet(v8::String::NewSymbol(propertyName), deserialized, attribute);
1106 }
1107
1108 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, bool& didThrow)
1109 {
1110     return adoptRef(new SerializedScriptValue(value, didThrow));
1111 }
1112
1113 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value)
1114 {
1115     bool didThrow;
1116     return adoptRef(new SerializedScriptValue(value, didThrow));
1117 }
1118
1119 PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(String data)
1120 {
1121     return adoptRef(new SerializedScriptValue(data));
1122 }
1123
1124 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(String data)
1125 {
1126     Writer writer;
1127     writer.writeWebCoreString(data);
1128     String wireData = StringImpl::adopt(writer.data());
1129     return adoptRef(new SerializedScriptValue(wireData));
1130 }
1131
1132 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
1133 {
1134     return adoptRef(new SerializedScriptValue());
1135 }
1136
1137 SerializedScriptValue* SerializedScriptValue::nullValue()
1138 {
1139     DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, nullValue, (0));
1140     if (!nullValue) {
1141         Writer writer;
1142         writer.writeNull();
1143         String wireData = StringImpl::adopt(writer.data());
1144         nullValue = adoptRef(new SerializedScriptValue(wireData));
1145     }
1146     return nullValue.get();
1147 }
1148
1149 SerializedScriptValue* SerializedScriptValue::undefinedValue()
1150 {
1151     DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, undefinedValue, (0));
1152     if (!undefinedValue) {
1153         Writer writer;
1154         writer.writeUndefined();
1155         String wireData = StringImpl::adopt(writer.data());
1156         undefinedValue = adoptRef(new SerializedScriptValue(wireData));
1157     }
1158     return undefinedValue.get();
1159 }
1160
1161 PassRefPtr<SerializedScriptValue> SerializedScriptValue::release()
1162 {
1163     RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data));
1164     m_data = String().crossThreadString();
1165     return result.release();
1166 }
1167
1168 SerializedScriptValue::SerializedScriptValue()
1169 {
1170 }
1171
1172 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& didThrow)
1173 {
1174     didThrow = false;
1175     Writer writer;
1176     Serializer serializer(writer);
1177     if (!serializer.serialize(value)) {
1178         throwError(NOT_SUPPORTED_ERR);
1179         didThrow = true;
1180         return;
1181     }
1182     m_data = String(StringImpl::adopt(writer.data())).crossThreadString();
1183 }
1184
1185 SerializedScriptValue::SerializedScriptValue(String wireData)
1186 {
1187     m_data = wireData.crossThreadString();
1188 }
1189
1190 v8::Handle<v8::Value> SerializedScriptValue::deserialize()
1191 {
1192     if (!m_data.impl())
1193         return v8::Null();
1194     COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
1195     Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
1196     Deserializer deserializer(reader);
1197     return deserializer.deserialize();
1198 }
1199
1200 } // namespace WebCore