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