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