bc9ebe9ed34bf70322b1cd3d75d1f06e4d805bb7
[WebKit-https.git] / Source / WebCore / bindings / js / SerializedScriptValue.cpp
1 /*
2  * Copyright (C) 2009, 2013 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26
27 #include "config.h"
28 #include "SerializedScriptValue.h"
29
30 #include "Blob.h"
31 #include "CryptoKeyAES.h"
32 #include "CryptoKeyDataOctetSequence.h"
33 #include "CryptoKeyDataRSAComponents.h"
34 #include "CryptoKeyHMAC.h"
35 #include "CryptoKeyRSA.h"
36 #include "ExceptionCode.h"
37 #include "File.h"
38 #include "FileList.h"
39 #include "ImageData.h"
40 #include "JSBlob.h"
41 #include "JSCryptoKey.h"
42 #include "JSDOMBinding.h"
43 #include "JSDOMGlobalObject.h"
44 #include "JSFile.h"
45 #include "JSFileList.h"
46 #include "JSImageData.h"
47 #include "JSMessagePort.h"
48 #include "JSNavigator.h"
49 #include "ScriptExecutionContext.h"
50 #include "SharedBuffer.h"
51 #include "WebCoreJSClientData.h"
52 #include <limits>
53 #include <JavaScriptCore/APICast.h>
54 #include <runtime/ArrayBuffer.h>
55 #include <runtime/BooleanObject.h>
56 #include <runtime/DateInstance.h>
57 #include <runtime/Error.h>
58 #include <runtime/ExceptionHelpers.h>
59 #include <runtime/JSArrayBuffer.h>
60 #include <runtime/JSArrayBufferView.h>
61 #include <runtime/JSCInlines.h>
62 #include <runtime/JSDataView.h>
63 #include <runtime/JSMap.h>
64 #include <runtime/JSMapIterator.h>
65 #include <runtime/JSSet.h>
66 #include <runtime/JSSetIterator.h>
67 #include <runtime/JSTypedArrays.h>
68 #include <runtime/MapData.h>
69 #include <runtime/MapDataInlines.h>
70 #include <runtime/ObjectConstructor.h>
71 #include <runtime/PropertyNameArray.h>
72 #include <runtime/RegExp.h>
73 #include <runtime/RegExpObject.h>
74 #include <runtime/TypedArrayInlines.h>
75 #include <runtime/TypedArrays.h>
76 #include <wtf/HashTraits.h>
77 #include <wtf/Vector.h>
78
79 using namespace JSC;
80
81 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) || CPU(NEEDS_ALIGNED_ACCESS)
82 #define ASSUME_LITTLE_ENDIAN 0
83 #else
84 #define ASSUME_LITTLE_ENDIAN 1
85 #endif
86
87 namespace WebCore {
88
89 static const unsigned maximumFilterRecursion = 40000;
90
91 enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
92     ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember,
93     MapDataStartVisitEntry, MapDataEndVisitKey, MapDataEndVisitValue,
94     SetDataStartVisitEntry, SetDataEndVisitKey };
95
96 // These can't be reordered, and any new types must be added to the end of the list
97 enum SerializationTag {
98     ArrayTag = 1,
99     ObjectTag = 2,
100     UndefinedTag = 3,
101     NullTag = 4,
102     IntTag = 5,
103     ZeroTag = 6,
104     OneTag = 7,
105     FalseTag = 8,
106     TrueTag = 9,
107     DoubleTag = 10,
108     DateTag = 11,
109     FileTag = 12,
110     FileListTag = 13,
111     ImageDataTag = 14,
112     BlobTag = 15,
113     StringTag = 16,
114     EmptyStringTag = 17,
115     RegExpTag = 18,
116     ObjectReferenceTag = 19,
117     MessagePortReferenceTag = 20,
118     ArrayBufferTag = 21,
119     ArrayBufferViewTag = 22,
120     ArrayBufferTransferTag = 23,
121     TrueObjectTag = 24,
122     FalseObjectTag = 25,
123     StringObjectTag = 26,
124     EmptyStringObjectTag = 27,
125     NumberObjectTag = 28,
126     SetObjectTag = 29,
127     MapObjectTag = 30,
128     NonMapPropertiesTag = 31,
129     NonSetPropertiesTag = 32,
130 #if ENABLE(SUBTLE_CRYPTO)
131     CryptoKeyTag = 33,
132 #endif
133     ErrorTag = 255
134 };
135
136 enum ArrayBufferViewSubtag {
137     DataViewTag = 0,
138     Int8ArrayTag = 1,
139     Uint8ArrayTag = 2,
140     Uint8ClampedArrayTag = 3,
141     Int16ArrayTag = 4,
142     Uint16ArrayTag = 5,
143     Int32ArrayTag = 6,
144     Uint32ArrayTag = 7,
145     Float32ArrayTag = 8,
146     Float64ArrayTag = 9
147 };
148
149 static unsigned typedArrayElementSize(ArrayBufferViewSubtag tag)
150 {
151     switch (tag) {
152     case DataViewTag:
153     case Int8ArrayTag:
154     case Uint8ArrayTag:
155     case Uint8ClampedArrayTag:
156         return 1;
157     case Int16ArrayTag:
158     case Uint16ArrayTag:
159         return 2;
160     case Int32ArrayTag:
161     case Uint32ArrayTag:
162     case Float32ArrayTag:
163         return 4;
164     case Float64ArrayTag:
165         return 8;
166     default:
167         return 0;
168     }
169
170 }
171
172 #if ENABLE(SUBTLE_CRYPTO)
173
174 const uint32_t currentKeyFormatVersion = 1;
175
176 enum class CryptoKeyClassSubtag {
177     HMAC = 0,
178     AES = 1,
179     RSA = 2
180 };
181 const uint8_t cryptoKeyClassSubtagMaximumValue = 2;
182
183 enum class CryptoKeyAsymmetricTypeSubtag {
184     Public = 0,
185     Private = 1
186 };
187 const uint8_t cryptoKeyAsymmetricTypeSubtagMaximumValue = 1;
188
189 enum class CryptoKeyUsageTag {
190     Encrypt = 0,
191     Decrypt = 1,
192     Sign = 2,
193     Verify = 3,
194     DeriveKey = 4,
195     DeriveBits = 5,
196     WrapKey = 6,
197     UnwrapKey = 7
198 };
199 const uint8_t cryptoKeyUsageTagMaximumValue = 7;
200
201 enum class CryptoAlgorithmIdentifierTag {
202     RSAES_PKCS1_v1_5 = 0,
203     RSASSA_PKCS1_v1_5 = 1,
204     RSA_PSS = 2,
205     RSA_OAEP = 3,
206     ECDSA = 4,
207     ECDH = 5,
208     AES_CTR = 6,
209     AES_CBC = 7,
210     AES_CMAC = 8,
211     AES_GCM = 9,
212     AES_CFB = 10,
213     AES_KW = 11,
214     HMAC = 12,
215     DH = 13,
216     SHA_1 = 14,
217     SHA_224 = 15,
218     SHA_256 = 16,
219     SHA_384 = 17,
220     SHA_512 = 18,
221     CONCAT = 19,
222     HKDF_CTR = 20,
223     PBKDF2 = 21,
224 };
225 const uint8_t cryptoAlgorithmIdentifierTagMaximumValue = 21;
226
227 static unsigned countUsages(CryptoKeyUsage usages)
228 {
229     // Fast bit count algorithm for sparse bit maps.
230     unsigned count = 0;
231     while (usages) {
232         usages = usages & (usages - 1);
233         ++count;
234     }
235     return count;
236 }
237
238 #endif
239
240 /* CurrentVersion tracks the serialization version so that persistent stores
241  * are able to correctly bail out in the case of encountering newer formats.
242  *
243  * Initial version was 1.
244  * Version 2. added the ObjectReferenceTag and support for serialization of cyclic graphs.
245  * Version 3. added the FalseObjectTag, TrueObjectTag, NumberObjectTag, StringObjectTag
246  * and EmptyStringObjectTag for serialization of Boolean, Number and String objects.
247  * Version 4. added support for serializing non-index properties of arrays.
248  * Version 5. added support for Map and Set types.
249  */
250 static const unsigned CurrentVersion = 5;
251 static const unsigned TerminatorTag = 0xFFFFFFFF;
252 static const unsigned StringPoolTag = 0xFFFFFFFE;
253 static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD;
254
255 /*
256  * Object serialization is performed according to the following grammar, all tags
257  * are recorded as a single uint8_t.
258  *
259  * IndexType (used for the object pool and StringData's constant pool) is the
260  * minimum sized unsigned integer type required to represent the maximum index
261  * in the constant pool.
262  *
263  * SerializedValue :- <CurrentVersion:uint32_t> Value
264  * Value :- Array | Object | Map | Set | Terminal
265  *
266  * Array :-
267  *     ArrayTag <length:uint32_t>(<index:uint32_t><value:Value>)* TerminatorTag
268  *
269  * Object :-
270  *     ObjectTag (<name:StringData><value:Value>)* TerminatorTag
271  *
272  * Map :- MapObjectTag MapData
273  *
274  * Set :- SetObjectTag SetData
275  *
276  * MapData :- (<key:Value><value:Value>)* NonMapPropertiesTag (<name:StringData><value:Value>)* TerminatorTag
277  * SetData :- (<key:Value>)* NonSetPropertiesTag (<name:StringData><value:Value>)* TerminatorTag
278  *
279  * Terminal :-
280  *      UndefinedTag
281  *    | NullTag
282  *    | IntTag <value:int32_t>
283  *    | ZeroTag
284  *    | OneTag
285  *    | FalseTag
286  *    | TrueTag
287  *    | FalseObjectTag
288  *    | TrueObjectTag
289  *    | DoubleTag <value:double>
290  *    | NumberObjectTag <value:double>
291  *    | DateTag <value:double>
292  *    | String
293  *    | EmptyStringTag
294  *    | EmptyStringObjectTag
295  *    | File
296  *    | FileList
297  *    | ImageData
298  *    | Blob
299  *    | ObjectReference
300  *    | MessagePortReferenceTag <value:uint32_t>
301  *    | ArrayBuffer
302  *    | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLength:uint32_t> (ArrayBuffer | ObjectReference)
303  *    | ArrayBufferTransferTag <value:uint32_t>
304  *    | CryptoKeyTag <wrappedKeyLength:uint32_t> <factor:byte{wrappedKeyLength}>
305  *
306  * Inside wrapped crypto key, data is serialized in this format:
307  *
308  * <keyFormatVersion:uint32_t> <extractable:int32_t> <usagesCount:uint32_t> <usages:byte{usagesCount}> CryptoKeyClassSubtag (CryptoKeyHMAC | CryptoKeyAES | CryptoKeyRSA)
309  *
310  * String :-
311  *      EmptyStringTag
312  *      StringTag StringData
313  *
314  * StringObject:
315  *      EmptyStringObjectTag
316  *      StringObjectTag StringData
317  *
318  * StringData :-
319  *      StringPoolTag <cpIndex:IndexType>
320  *      (not (TerminatorTag | StringPoolTag))<length:uint32_t><characters:UChar{length}> // Added to constant pool when seen, string length 0xFFFFFFFF is disallowed
321  *
322  * File :-
323  *    FileTag FileData
324  *
325  * FileData :-
326  *    <path:StringData> <url:StringData> <type:StringData> <name:StringData>
327  *
328  * FileList :-
329  *    FileListTag <length:uint32_t>(<file:FileData>){length}
330  *
331  * ImageData :-
332  *    ImageDataTag <width:int32_t><height:int32_t><length:uint32_t><data:uint8_t{length}>
333  *
334  * Blob :-
335  *    BlobTag <url:StringData><type:StringData><size:long long>
336  *
337  * RegExp :-
338  *    RegExpTag <pattern:StringData><flags:StringData>
339  *
340  * ObjectReference :-
341  *    ObjectReferenceTag <opIndex:IndexType>
342  *
343  * ArrayBuffer :-
344  *    ArrayBufferTag <length:uint32_t> <contents:byte{length}>
345  *
346  * CryptoKeyHMAC :-
347  *    <keySize:uint32_t> <keyData:byte{keySize}> CryptoAlgorithmIdentifierTag // Algorithm tag inner hash function.
348  *
349  * CryptoKeyAES :-
350  *    CryptoAlgorithmIdentifierTag <keySize:uint32_t> <keyData:byte{keySize}>
351  *
352  * CryptoKeyRSA :-
353  *    CryptoAlgorithmIdentifierTag <isRestrictedToHash:int32_t> CryptoAlgorithmIdentifierTag? CryptoKeyAsymmetricTypeSubtag CryptoKeyRSAPublicComponents CryptoKeyRSAPrivateComponents?
354  *
355  * CryptoKeyRSAPublicComponents :-
356  *    <modulusSize:uint32_t> <modulus:byte{modulusSize}> <exponentSize:uint32_t> <exponent:byte{exponentSize}>
357  *
358  * CryptoKeyRSAPrivateComponents :-
359  *    <privateExponentSize:uint32_t> <privateExponent:byte{privateExponentSize}> <primeCount:uint32_t> FirstPrimeInfo? PrimeInfo{primeCount - 1}
360  *
361  * // CRT data could be computed from prime factors. It is only serialized to reuse a code path that's needed for JWK.
362  * FirstPrimeInfo :-
363  *    <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}>
364  *
365  * PrimeInfo :-
366  *    <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}> <crtCoefficientSize:uint32_t> <crtCoefficient:byte{crtCoefficientSize}>
367  */
368
369 typedef std::pair<JSC::JSValue, SerializationReturnCode> DeserializationResult;
370
371 class CloneBase {
372 protected:
373     CloneBase(ExecState* exec)
374         : m_exec(exec)
375         , m_failed(false)
376     {
377     }
378
379     bool shouldTerminate()
380     {
381         return m_exec->hadException();
382     }
383
384     void throwStackOverflow()
385     {
386         m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));
387     }
388
389     void fail()
390     {
391         m_failed = true;
392     }
393
394     ExecState* m_exec;
395     bool m_failed;
396     MarkedArgumentBuffer m_gcBuffer;
397 };
398
399 #if ENABLE(SUBTLE_CRYPTO)
400 static bool wrapCryptoKey(ExecState* exec, const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey)
401 {
402     ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec);
403     if (!scriptExecutionContext)
404         return false;
405     return scriptExecutionContext->wrapCryptoKey(key, wrappedKey);
406 }
407
408 static bool unwrapCryptoKey(ExecState* exec, const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
409 {
410     ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec);
411     if (!scriptExecutionContext)
412         return false;
413     return scriptExecutionContext->unwrapCryptoKey(wrappedKey, key);
414 }
415 #endif
416
417 #if ASSUME_LITTLE_ENDIAN
418 template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
419 {
420     buffer.append(reinterpret_cast<uint8_t*>(&value), sizeof(value));
421 }
422 #else
423 template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
424 {
425     for (unsigned i = 0; i < sizeof(T); i++) {
426         buffer.append(value & 0xFF);
427         value >>= 8;
428     }
429 }
430 #endif
431
432 template <> void writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, uint8_t value)
433 {
434     buffer.append(value);
435 }
436
437 template <typename T> static bool writeLittleEndian(Vector<uint8_t>& buffer, const T* values, uint32_t length)
438 {
439     if (length > std::numeric_limits<uint32_t>::max() / sizeof(T))
440         return false;
441
442 #if ASSUME_LITTLE_ENDIAN
443     buffer.append(reinterpret_cast<const uint8_t*>(values), length * sizeof(T));
444 #else
445     for (unsigned i = 0; i < length; i++) {
446         T value = values[i];
447         for (unsigned j = 0; j < sizeof(T); j++) {
448             buffer.append(static_cast<uint8_t>(value & 0xFF));
449             value >>= 8;
450         }
451     }
452 #endif
453     return true;
454 }
455
456 static bool writeLittleEndianUInt16(Vector<uint8_t>& buffer, const LChar* values, uint32_t length)
457 {
458     if (length > std::numeric_limits<uint32_t>::max() / 2)
459         return false;
460
461     for (unsigned i = 0; i < length; ++i) {
462         buffer.append(values[i]);
463         buffer.append(0);
464     }
465
466     return true;
467 }
468
469 template <> bool writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, const uint8_t* values, uint32_t length)
470 {
471     buffer.append(values, length);
472     return true;
473 }
474
475 class CloneSerializer : CloneBase {
476 public:
477     static SerializationReturnCode serialize(ExecState* exec, JSValue value,
478                                              MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
479                                              Vector<String>& blobURLs, Vector<uint8_t>& out)
480     {
481         CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out);
482         return serializer.serialize(value);
483     }
484
485     static bool serialize(const String& s, Vector<uint8_t>& out)
486     {
487         writeLittleEndian(out, CurrentVersion);
488         if (s.isEmpty()) {
489             writeLittleEndian<uint8_t>(out, EmptyStringTag);
490             return true;
491         }
492         writeLittleEndian<uint8_t>(out, StringTag);
493         writeLittleEndian(out, s.length());
494         if (s.is8Bit())
495             return writeLittleEndianUInt16(out, s.characters8(), s.length());
496         return writeLittleEndian(out, s.characters16(), s.length());
497     }
498
499     static void serializeUndefined(Vector<uint8_t>& out)
500     {
501         writeLittleEndian(out, CurrentVersion);
502         writeLittleEndian<uint8_t>(out, UndefinedTag);
503     }
504
505     static void serializeBoolean(bool value, Vector<uint8_t>& out)
506     {
507         writeLittleEndian(out, CurrentVersion);
508         writeLittleEndian<uint8_t>(out, value ? TrueTag : FalseTag);
509     }
510
511     static void serializeNumber(double value, Vector<uint8_t>& out)
512     {
513         writeLittleEndian(out, CurrentVersion);
514         writeLittleEndian<uint8_t>(out, DoubleTag);
515         union {
516             double d;
517             int64_t i;
518         } u;
519         u.d = value;
520         writeLittleEndian(out, u.i);
521     }
522
523 private:
524     typedef HashMap<JSObject*, uint32_t> ObjectPool;
525
526     CloneSerializer(ExecState* exec, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out)
527         : CloneBase(exec)
528         , m_buffer(out)
529         , m_blobURLs(blobURLs)
530         , m_emptyIdentifier(Identifier::fromString(exec, emptyString()))
531     {
532         write(CurrentVersion);
533         fillTransferMap(messagePorts, m_transferredMessagePorts);
534         fillTransferMap(arrayBuffers, m_transferredArrayBuffers);
535     }
536
537     template <class T>
538     void fillTransferMap(Vector<RefPtr<T>, 1>* input, ObjectPool& result)
539     {
540         if (!input)
541             return;
542         JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject());
543         for (size_t i = 0; i < input->size(); i++) {
544             JSC::JSValue value = toJS(m_exec, globalObject, input->at(i).get());
545             JSC::JSObject* obj = value.getObject();
546             if (obj && !result.contains(obj))
547                 result.add(obj, i);
548         }
549     }
550
551     SerializationReturnCode serialize(JSValue in);
552
553     bool isArray(JSValue value)
554     {
555         if (!value.isObject())
556             return false;
557         JSObject* object = asObject(value);
558         return isJSArray(object) || object->inherits(JSArray::info());
559     }
560
561     bool isMap(JSValue value)
562     {
563         if (!value.isObject())
564             return false;
565         JSObject* object = asObject(value);
566         return object->inherits(JSMap::info());
567     }
568     bool isSet(JSValue value)
569     {
570         if (!value.isObject())
571             return false;
572         JSObject* object = asObject(value);
573         return object->inherits(JSSet::info());
574     }
575
576     bool checkForDuplicate(JSObject* object)
577     {
578         // Record object for graph reconstruction
579         ObjectPool::const_iterator found = m_objectPool.find(object);
580
581         // Handle duplicate references
582         if (found != m_objectPool.end()) {
583             write(ObjectReferenceTag);
584             ASSERT(found->value < m_objectPool.size());
585             writeObjectIndex(found->value);
586             return true;
587         }
588
589         return false;
590     }
591
592     void recordObject(JSObject* object)
593     {
594         m_objectPool.add(object, m_objectPool.size());
595         m_gcBuffer.append(object);
596     }
597
598     bool startObjectInternal(JSObject* object)
599     {
600         if (checkForDuplicate(object))
601             return false;
602         recordObject(object);
603         return true;
604     }
605
606     bool startObject(JSObject* object)
607     {
608         if (!startObjectInternal(object))
609             return false;
610         write(ObjectTag);
611         return true;
612     }
613
614     bool startArray(JSArray* array)
615     {
616         if (!startObjectInternal(array))
617             return false;
618
619         unsigned length = array->length();
620         write(ArrayTag);
621         write(length);
622         return true;
623     }
624
625     bool startSet(JSSet* set)
626     {
627         if (!startObjectInternal(set))
628             return false;
629
630         write(SetObjectTag);
631         return true;
632     }
633
634     bool startMap(JSMap* map)
635     {
636         if (!startObjectInternal(map))
637             return false;
638
639         write(MapObjectTag);
640         return true;
641     }
642
643     void endObject()
644     {
645         write(TerminatorTag);
646     }
647
648     JSValue getProperty(JSObject* object, const Identifier& propertyName)
649     {
650         PropertySlot slot(object);
651         if (object->methodTable()->getOwnPropertySlot(object, m_exec, propertyName, slot))
652             return slot.getValue(m_exec, propertyName);
653         return JSValue();
654     }
655
656     void dumpImmediate(JSValue value)
657     {
658         if (value.isNull())
659             write(NullTag);
660         else if (value.isUndefined())
661             write(UndefinedTag);
662         else if (value.isNumber()) {
663             if (value.isInt32()) {
664                 if (!value.asInt32())
665                     write(ZeroTag);
666                 else if (value.asInt32() == 1)
667                     write(OneTag);
668                 else {
669                     write(IntTag);
670                     write(static_cast<uint32_t>(value.asInt32()));
671                 }
672             } else {
673                 write(DoubleTag);
674                 write(value.asDouble());
675             }
676         } else if (value.isBoolean()) {
677             if (value.isTrue())
678                 write(TrueTag);
679             else
680                 write(FalseTag);
681         }
682     }
683
684     void dumpString(const String& string)
685     {
686         if (string.isEmpty())
687             write(EmptyStringTag);
688         else {
689             write(StringTag);
690             write(string);
691         }
692     }
693
694     void dumpStringObject(const String& string)
695     {
696         if (string.isEmpty())
697             write(EmptyStringObjectTag);
698         else {
699             write(StringObjectTag);
700             write(string);
701         }
702     }
703
704     bool dumpArrayBufferView(JSObject* obj, SerializationReturnCode& code)
705     {
706         write(ArrayBufferViewTag);
707         if (obj->inherits(JSDataView::info()))
708             write(DataViewTag);
709         else if (obj->inherits(JSUint8ClampedArray::info()))
710             write(Uint8ClampedArrayTag);
711         else if (obj->inherits(JSInt8Array::info()))
712             write(Int8ArrayTag);
713         else if (obj->inherits(JSUint8Array::info()))
714             write(Uint8ArrayTag);
715         else if (obj->inherits(JSInt16Array::info()))
716             write(Int16ArrayTag);
717         else if (obj->inherits(JSUint16Array::info()))
718             write(Uint16ArrayTag);
719         else if (obj->inherits(JSInt32Array::info()))
720             write(Int32ArrayTag);
721         else if (obj->inherits(JSUint32Array::info()))
722             write(Uint32ArrayTag);
723         else if (obj->inherits(JSFloat32Array::info()))
724             write(Float32ArrayTag);
725         else if (obj->inherits(JSFloat64Array::info()))
726             write(Float64ArrayTag);
727         else
728             return false;
729
730         RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(obj);
731         write(static_cast<uint32_t>(arrayBufferView->byteOffset()));
732         write(static_cast<uint32_t>(arrayBufferView->byteLength()));
733         RefPtr<ArrayBuffer> arrayBuffer = arrayBufferView->buffer();
734         if (!arrayBuffer) {
735             code = ValidationError;
736             return true;
737         }
738         JSValue bufferObj = toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), arrayBuffer.get());
739         return dumpIfTerminal(bufferObj, code);
740     }
741
742     bool dumpIfTerminal(JSValue value, SerializationReturnCode& code)
743     {
744         if (!value.isCell()) {
745             dumpImmediate(value);
746             return true;
747         }
748
749         if (value.isString()) {
750             String str = asString(value)->value(m_exec);
751             dumpString(str);
752             return true;
753         }
754
755         if (value.isNumber()) {
756             write(DoubleTag);
757             write(value.asNumber());
758             return true;
759         }
760
761         if (value.isObject() && asObject(value)->inherits(DateInstance::info())) {
762             write(DateTag);
763             write(asDateInstance(value)->internalNumber());
764             return true;
765         }
766
767         if (isArray(value))
768             return false;
769
770         if (value.isObject()) {
771             JSObject* obj = asObject(value);
772             if (obj->inherits(BooleanObject::info())) {
773                 if (!startObjectInternal(obj)) // handle duplicates
774                     return true;
775                 write(asBooleanObject(value)->internalValue().toBoolean(m_exec) ? TrueObjectTag : FalseObjectTag);
776                 return true;
777             }
778             if (obj->inherits(StringObject::info())) {
779                 if (!startObjectInternal(obj)) // handle duplicates
780                     return true;
781                 String str = asString(asStringObject(value)->internalValue())->value(m_exec);
782                 dumpStringObject(str);
783                 return true;
784             }
785             if (obj->inherits(NumberObject::info())) {
786                 if (!startObjectInternal(obj)) // handle duplicates
787                     return true;
788                 write(NumberObjectTag);
789                 NumberObject* obj = static_cast<NumberObject*>(asObject(value));
790                 write(obj->internalValue().asNumber());
791                 return true;
792             }
793             if (File* file = JSFile::toWrapped(obj)) {
794                 write(FileTag);
795                 write(file);
796                 return true;
797             }
798             if (FileList* list = JSFileList::toWrapped(obj)) {
799                 write(FileListTag);
800                 unsigned length = list->length();
801                 write(length);
802                 for (unsigned i = 0; i < length; i++)
803                     write(list->item(i));
804                 return true;
805             }
806             if (Blob* blob = JSBlob::toWrapped(obj)) {
807                 write(BlobTag);
808                 m_blobURLs.append(blob->url());
809                 write(blob->url());
810                 write(blob->type());
811                 write(blob->size());
812                 return true;
813             }
814             if (ImageData* data = JSImageData::toWrapped(obj)) {
815                 write(ImageDataTag);
816                 write(data->width());
817                 write(data->height());
818                 write(data->data()->length());
819                 write(data->data()->data(), data->data()->length());
820                 return true;
821             }
822             if (obj->inherits(RegExpObject::info())) {
823                 RegExpObject* regExp = asRegExpObject(obj);
824                 char flags[3];
825                 int flagCount = 0;
826                 if (regExp->regExp()->global())
827                     flags[flagCount++] = 'g';
828                 if (regExp->regExp()->ignoreCase())
829                     flags[flagCount++] = 'i';
830                 if (regExp->regExp()->multiline())
831                     flags[flagCount++] = 'm';
832                 write(RegExpTag);
833                 write(regExp->regExp()->pattern());
834                 write(String(flags, flagCount));
835                 return true;
836             }
837             if (obj->inherits(JSMessagePort::info())) {
838                 ObjectPool::iterator index = m_transferredMessagePorts.find(obj);
839                 if (index != m_transferredMessagePorts.end()) {
840                     write(MessagePortReferenceTag);
841                     write(index->value);
842                     return true;
843                 }
844                 // MessagePort object could not be found in transferred message ports
845                 code = ValidationError;
846                 return true;
847             }
848             if (ArrayBuffer* arrayBuffer = toArrayBuffer(obj)) {
849                 if (arrayBuffer->isNeutered()) {
850                     code = ValidationError;
851                     return true;
852                 }
853                 ObjectPool::iterator index = m_transferredArrayBuffers.find(obj);
854                 if (index != m_transferredArrayBuffers.end()) {
855                     write(ArrayBufferTransferTag);
856                     write(index->value);
857                     return true;
858                 }
859                 if (!startObjectInternal(obj)) // handle duplicates
860                     return true;
861                 write(ArrayBufferTag);
862                 write(arrayBuffer->byteLength());
863                 write(static_cast<const uint8_t*>(arrayBuffer->data()), arrayBuffer->byteLength());
864                 return true;
865             }
866             if (obj->inherits(JSArrayBufferView::info())) {
867                 if (checkForDuplicate(obj))
868                     return true;
869                 bool success = dumpArrayBufferView(obj, code);
870                 recordObject(obj);
871                 return success;
872             }
873 #if ENABLE(SUBTLE_CRYPTO)
874             if (CryptoKey* key = JSCryptoKey::toWrapped(obj)) {
875                 write(CryptoKeyTag);
876                 Vector<uint8_t> serializedKey;
877                 Vector<String> dummyBlobURLs;
878                 CloneSerializer rawKeySerializer(m_exec, nullptr, nullptr, dummyBlobURLs, serializedKey);
879                 rawKeySerializer.write(key);
880                 Vector<uint8_t> wrappedKey;
881                 if (!wrapCryptoKey(m_exec, serializedKey, wrappedKey))
882                     return false;
883                 write(wrappedKey);
884                 return true;
885             }
886 #endif
887
888             return false;
889         }
890         // Any other types are expected to serialize as null.
891         write(NullTag);
892         return true;
893     }
894
895     void write(SerializationTag tag)
896     {
897         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
898     }
899
900     void write(ArrayBufferViewSubtag tag)
901     {
902         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
903     }
904
905 #if ENABLE(SUBTLE_CRYPTO)
906     void write(CryptoKeyClassSubtag tag)
907     {
908         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
909     }
910
911     void write(CryptoKeyAsymmetricTypeSubtag tag)
912     {
913         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
914     }
915
916     void write(CryptoKeyUsageTag tag)
917     {
918         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
919     }
920
921     void write(CryptoAlgorithmIdentifierTag tag)
922     {
923         writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
924     }
925 #endif
926
927     void write(uint8_t c)
928     {
929         writeLittleEndian(m_buffer, c);
930     }
931
932     void write(uint32_t i)
933     {
934         writeLittleEndian(m_buffer, i);
935     }
936
937     void write(double d)
938     {
939         union {
940             double d;
941             int64_t i;
942         } u;
943         u.d = d;
944         writeLittleEndian(m_buffer, u.i);
945     }
946
947     void write(int32_t i)
948     {
949         writeLittleEndian(m_buffer, i);
950     }
951
952     void write(unsigned long long i)
953     {
954         writeLittleEndian(m_buffer, i);
955     }
956     
957     void write(uint16_t ch)
958     {
959         writeLittleEndian(m_buffer, ch);
960     }
961
962     void writeStringIndex(unsigned i)
963     {
964         writeConstantPoolIndex(m_constantPool, i);
965     }
966     
967     void writeObjectIndex(unsigned i)
968     {
969         writeConstantPoolIndex(m_objectPool, i);
970     }
971
972     template <class T> void writeConstantPoolIndex(const T& constantPool, unsigned i)
973     {
974         ASSERT(i < constantPool.size());
975         if (constantPool.size() <= 0xFF)
976             write(static_cast<uint8_t>(i));
977         else if (constantPool.size() <= 0xFFFF)
978             write(static_cast<uint16_t>(i));
979         else
980             write(static_cast<uint32_t>(i));
981     }
982
983     void write(const Identifier& ident)
984     {
985         const String& str = ident.string();
986         StringConstantPool::AddResult addResult = m_constantPool.add(ident.impl(), m_constantPool.size());
987         if (!addResult.isNewEntry) {
988             write(StringPoolTag);
989             writeStringIndex(addResult.iterator->value);
990             return;
991         }
992
993         unsigned length = str.length();
994
995         // This condition is unlikely to happen as they would imply an ~8gb
996         // string but we should guard against it anyway
997         if (length >= StringPoolTag) {
998             fail();
999             return;
1000         }
1001
1002         // Guard against overflow
1003         if (length > (std::numeric_limits<uint32_t>::max() - sizeof(uint32_t)) / sizeof(UChar)) {
1004             fail();
1005             return;
1006         }
1007
1008         writeLittleEndian<uint32_t>(m_buffer, length);
1009         if (!length || str.is8Bit()) {
1010             if (!writeLittleEndianUInt16(m_buffer, str.characters8(), length))
1011                 fail();
1012             return;
1013         }
1014         if (!writeLittleEndian(m_buffer, str.characters16(), length))
1015             fail();
1016     }
1017
1018     void write(const String& str)
1019     {
1020         if (str.isNull())
1021             write(m_emptyIdentifier);
1022         else
1023             write(Identifier::fromString(m_exec, str));
1024     }
1025
1026     void write(const Vector<uint8_t>& vector)
1027     {
1028         uint32_t size = vector.size();
1029         write(size);
1030         writeLittleEndian(m_buffer, vector.data(), size);
1031     }
1032
1033     void write(const File* file)
1034     {
1035         m_blobURLs.append(file->url());
1036         write(file->path());
1037         write(file->url());
1038         write(file->type());
1039         write(file->name());
1040     }
1041
1042 #if ENABLE(SUBTLE_CRYPTO)
1043     void write(CryptoAlgorithmIdentifier algorithm)
1044     {
1045         switch (algorithm) {
1046         case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
1047             write(CryptoAlgorithmIdentifierTag::RSAES_PKCS1_v1_5);
1048             break;
1049         case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
1050             write(CryptoAlgorithmIdentifierTag::RSASSA_PKCS1_v1_5);
1051             break;
1052         case CryptoAlgorithmIdentifier::RSA_PSS:
1053             write(CryptoAlgorithmIdentifierTag::RSA_PSS);
1054             break;
1055         case CryptoAlgorithmIdentifier::RSA_OAEP:
1056             write(CryptoAlgorithmIdentifierTag::RSA_OAEP);
1057             break;
1058         case CryptoAlgorithmIdentifier::ECDSA:
1059             write(CryptoAlgorithmIdentifierTag::ECDSA);
1060             break;
1061         case CryptoAlgorithmIdentifier::ECDH:
1062             write(CryptoAlgorithmIdentifierTag::ECDH);
1063             break;
1064         case CryptoAlgorithmIdentifier::AES_CTR:
1065             write(CryptoAlgorithmIdentifierTag::AES_CTR);
1066             break;
1067         case CryptoAlgorithmIdentifier::AES_CBC:
1068             write(CryptoAlgorithmIdentifierTag::AES_CBC);
1069             break;
1070         case CryptoAlgorithmIdentifier::AES_CMAC:
1071             write(CryptoAlgorithmIdentifierTag::AES_CMAC);
1072             break;
1073         case CryptoAlgorithmIdentifier::AES_GCM:
1074             write(CryptoAlgorithmIdentifierTag::AES_GCM);
1075             break;
1076         case CryptoAlgorithmIdentifier::AES_CFB:
1077             write(CryptoAlgorithmIdentifierTag::AES_CFB);
1078             break;
1079         case CryptoAlgorithmIdentifier::AES_KW:
1080             write(CryptoAlgorithmIdentifierTag::AES_KW);
1081             break;
1082         case CryptoAlgorithmIdentifier::HMAC:
1083             write(CryptoAlgorithmIdentifierTag::HMAC);
1084             break;
1085         case CryptoAlgorithmIdentifier::DH:
1086             write(CryptoAlgorithmIdentifierTag::DH);
1087             break;
1088         case CryptoAlgorithmIdentifier::SHA_1:
1089             write(CryptoAlgorithmIdentifierTag::SHA_1);
1090             break;
1091         case CryptoAlgorithmIdentifier::SHA_224:
1092             write(CryptoAlgorithmIdentifierTag::SHA_224);
1093             break;
1094         case CryptoAlgorithmIdentifier::SHA_256:
1095             write(CryptoAlgorithmIdentifierTag::SHA_256);
1096             break;
1097         case CryptoAlgorithmIdentifier::SHA_384:
1098             write(CryptoAlgorithmIdentifierTag::SHA_384);
1099             break;
1100         case CryptoAlgorithmIdentifier::SHA_512:
1101             write(CryptoAlgorithmIdentifierTag::SHA_512);
1102             break;
1103         case CryptoAlgorithmIdentifier::CONCAT:
1104             write(CryptoAlgorithmIdentifierTag::CONCAT);
1105             break;
1106         case CryptoAlgorithmIdentifier::HKDF_CTR:
1107             write(CryptoAlgorithmIdentifierTag::HKDF_CTR);
1108             break;
1109         case CryptoAlgorithmIdentifier::PBKDF2:
1110             write(CryptoAlgorithmIdentifierTag::PBKDF2);
1111             break;
1112         }
1113     }
1114
1115     void write(CryptoKeyDataRSAComponents::Type type)
1116     {
1117         switch (type) {
1118         case CryptoKeyDataRSAComponents::Type::Public:
1119             write(CryptoKeyAsymmetricTypeSubtag::Public);
1120             return;
1121         case CryptoKeyDataRSAComponents::Type::Private:
1122             write(CryptoKeyAsymmetricTypeSubtag::Private);
1123             return;
1124         }
1125     }
1126
1127     void write(const CryptoKeyDataRSAComponents& key)
1128     {
1129         write(key.type());
1130         write(key.modulus());
1131         write(key.exponent());
1132         if (key.type() == CryptoKeyDataRSAComponents::Type::Public)
1133             return;
1134
1135         write(key.privateExponent());
1136
1137         unsigned primeCount = key.hasAdditionalPrivateKeyParameters() ? key.otherPrimeInfos().size() + 2 : 0;
1138         write(primeCount);
1139         if (!primeCount)
1140             return;
1141
1142         write(key.firstPrimeInfo().primeFactor);
1143         write(key.firstPrimeInfo().factorCRTExponent);
1144         write(key.secondPrimeInfo().primeFactor);
1145         write(key.secondPrimeInfo().factorCRTExponent);
1146         write(key.secondPrimeInfo().factorCRTCoefficient);
1147         for (unsigned i = 2; i < primeCount; ++i) {
1148             write(key.otherPrimeInfos()[i].primeFactor);
1149             write(key.otherPrimeInfos()[i].factorCRTExponent);
1150             write(key.otherPrimeInfos()[i].factorCRTCoefficient);
1151         }
1152     }
1153
1154     void write(const CryptoKey* key)
1155     {
1156         write(currentKeyFormatVersion);
1157
1158         write(key->extractable());
1159
1160         CryptoKeyUsage usages = key->usagesBitmap();
1161         write(countUsages(usages));
1162         if (usages & CryptoKeyUsageEncrypt)
1163             write(CryptoKeyUsageTag::Encrypt);
1164         if (usages & CryptoKeyUsageDecrypt)
1165             write(CryptoKeyUsageTag::Decrypt);
1166         if (usages & CryptoKeyUsageSign)
1167             write(CryptoKeyUsageTag::Sign);
1168         if (usages & CryptoKeyUsageVerify)
1169             write(CryptoKeyUsageTag::Verify);
1170         if (usages & CryptoKeyUsageDeriveKey)
1171             write(CryptoKeyUsageTag::DeriveKey);
1172         if (usages & CryptoKeyUsageDeriveBits)
1173             write(CryptoKeyUsageTag::DeriveBits);
1174         if (usages & CryptoKeyUsageWrapKey)
1175             write(CryptoKeyUsageTag::WrapKey);
1176         if (usages & CryptoKeyUsageUnwrapKey)
1177             write(CryptoKeyUsageTag::UnwrapKey);
1178
1179         switch (key->keyClass()) {
1180         case CryptoKeyClass::HMAC:
1181             write(CryptoKeyClassSubtag::HMAC);
1182             write(downcast<CryptoKeyHMAC>(*key).key());
1183             write(downcast<CryptoKeyHMAC>(*key).hashAlgorithmIdentifier());
1184             break;
1185         case CryptoKeyClass::AES:
1186             write(CryptoKeyClassSubtag::AES);
1187             write(key->algorithmIdentifier());
1188             write(downcast<CryptoKeyAES>(*key).key());
1189             break;
1190         case CryptoKeyClass::RSA:
1191             write(CryptoKeyClassSubtag::RSA);
1192             write(key->algorithmIdentifier());
1193             CryptoAlgorithmIdentifier hash;
1194             bool isRestrictedToHash = downcast<CryptoKeyRSA>(*key).isRestrictedToHash(hash);
1195             write(isRestrictedToHash);
1196             if (isRestrictedToHash)
1197                 write(hash);
1198             write(downcast<CryptoKeyDataRSAComponents>(*key->exportData()));
1199             break;
1200         }
1201     }
1202 #endif
1203
1204     void write(const uint8_t* data, unsigned length)
1205     {
1206         m_buffer.append(data, length);
1207     }
1208
1209     Vector<uint8_t>& m_buffer;
1210     Vector<String>& m_blobURLs;
1211     ObjectPool m_objectPool;
1212     ObjectPool m_transferredMessagePorts;
1213     ObjectPool m_transferredArrayBuffers;
1214     typedef HashMap<RefPtr<UniquedStringImpl>, uint32_t, IdentifierRepHash> StringConstantPool;
1215     StringConstantPool m_constantPool;
1216     Identifier m_emptyIdentifier;
1217 };
1218
1219 SerializationReturnCode CloneSerializer::serialize(JSValue in)
1220 {
1221     Vector<uint32_t, 16> indexStack;
1222     Vector<uint32_t, 16> lengthStack;
1223     Vector<PropertyNameArray, 16> propertyStack;
1224     Vector<JSObject*, 32> inputObjectStack;
1225     Vector<JSMapIterator*, 4> mapIteratorStack;
1226     Vector<JSSetIterator*, 4> setIteratorStack;
1227     Vector<JSValue, 4> mapIteratorValueStack;
1228     Vector<WalkerState, 16> stateStack;
1229     WalkerState state = StateUnknown;
1230     JSValue inValue = in;
1231     while (1) {
1232         switch (state) {
1233             arrayStartState:
1234             case ArrayStartState: {
1235                 ASSERT(isArray(inValue));
1236                 if (inputObjectStack.size() > maximumFilterRecursion)
1237                     return StackOverflowError;
1238
1239                 JSArray* inArray = asArray(inValue);
1240                 unsigned length = inArray->length();
1241                 if (!startArray(inArray))
1242                     break;
1243                 inputObjectStack.append(inArray);
1244                 indexStack.append(0);
1245                 lengthStack.append(length);
1246             }
1247             arrayStartVisitMember:
1248             FALLTHROUGH;
1249             case ArrayStartVisitMember: {
1250                 JSObject* array = inputObjectStack.last();
1251                 uint32_t index = indexStack.last();
1252                 if (index == lengthStack.last()) {
1253                     indexStack.removeLast();
1254                     lengthStack.removeLast();
1255
1256                     propertyStack.append(PropertyNameArray(m_exec));
1257                     array->methodTable()->getOwnNonIndexPropertyNames(array, m_exec, propertyStack.last(), EnumerationMode());
1258                     if (propertyStack.last().size()) {
1259                         write(NonIndexPropertiesTag);
1260                         indexStack.append(0);
1261                         goto objectStartVisitMember;
1262                     }
1263                     propertyStack.removeLast();
1264
1265                     endObject();
1266                     inputObjectStack.removeLast();
1267                     break;
1268                 }
1269                 inValue = array->getDirectIndex(m_exec, index);
1270                 if (!inValue) {
1271                     indexStack.last()++;
1272                     goto arrayStartVisitMember;
1273                 }
1274
1275                 write(index);
1276                 SerializationReturnCode terminalCode = SuccessfullyCompleted;
1277                 if (dumpIfTerminal(inValue, terminalCode)) {
1278                     if (terminalCode != SuccessfullyCompleted)
1279                         return terminalCode;
1280                     indexStack.last()++;
1281                     goto arrayStartVisitMember;
1282                 }
1283                 stateStack.append(ArrayEndVisitMember);
1284                 goto stateUnknown;
1285             }
1286             case ArrayEndVisitMember: {
1287                 indexStack.last()++;
1288                 goto arrayStartVisitMember;
1289             }
1290             objectStartState:
1291             case ObjectStartState: {
1292                 ASSERT(inValue.isObject());
1293                 if (inputObjectStack.size() > maximumFilterRecursion)
1294                     return StackOverflowError;
1295                 JSObject* inObject = asObject(inValue);
1296                 if (!startObject(inObject))
1297                     break;
1298                 // At this point, all supported objects other than Object
1299                 // objects have been handled. If we reach this point and
1300                 // the input is not an Object object then we should throw
1301                 // a DataCloneError.
1302                 if (inObject->classInfo() != JSFinalObject::info())
1303                     return DataCloneError;
1304                 inputObjectStack.append(inObject);
1305                 indexStack.append(0);
1306                 propertyStack.append(PropertyNameArray(m_exec));
1307                 inObject->methodTable()->getOwnPropertyNames(inObject, m_exec, propertyStack.last(), EnumerationMode());
1308             }
1309             objectStartVisitMember:
1310             FALLTHROUGH;
1311             case ObjectStartVisitMember: {
1312                 JSObject* object = inputObjectStack.last();
1313                 uint32_t index = indexStack.last();
1314                 PropertyNameArray& properties = propertyStack.last();
1315                 if (index == properties.size()) {
1316                     endObject();
1317                     inputObjectStack.removeLast();
1318                     indexStack.removeLast();
1319                     propertyStack.removeLast();
1320                     break;
1321                 }
1322                 inValue = getProperty(object, properties[index]);
1323                 if (shouldTerminate())
1324                     return ExistingExceptionError;
1325
1326                 if (!inValue) {
1327                     // Property was removed during serialisation
1328                     indexStack.last()++;
1329                     goto objectStartVisitMember;
1330                 }
1331                 write(properties[index]);
1332
1333                 if (shouldTerminate())
1334                     return ExistingExceptionError;
1335
1336                 SerializationReturnCode terminalCode = SuccessfullyCompleted;
1337                 if (!dumpIfTerminal(inValue, terminalCode)) {
1338                     stateStack.append(ObjectEndVisitMember);
1339                     goto stateUnknown;
1340                 }
1341                 if (terminalCode != SuccessfullyCompleted)
1342                     return terminalCode;
1343                 FALLTHROUGH;
1344             }
1345             case ObjectEndVisitMember: {
1346                 if (shouldTerminate())
1347                     return ExistingExceptionError;
1348
1349                 indexStack.last()++;
1350                 goto objectStartVisitMember;
1351             }
1352             mapStartState: {
1353                 ASSERT(inValue.isObject());
1354                 if (inputObjectStack.size() > maximumFilterRecursion)
1355                     return StackOverflowError;
1356                 JSMap* inMap = jsCast<JSMap*>(inValue);
1357                 if (!startMap(inMap))
1358                     break;
1359                 JSMapIterator* iterator = JSMapIterator::create(m_exec->vm(), m_exec->lexicalGlobalObject()->mapIteratorStructure(), inMap, MapIterateKeyValue);
1360                 m_gcBuffer.append(inMap);
1361                 m_gcBuffer.append(iterator);
1362                 mapIteratorStack.append(iterator);
1363                 inputObjectStack.append(inMap);
1364                 goto mapDataStartVisitEntry;
1365             }
1366             mapDataStartVisitEntry:
1367             case MapDataStartVisitEntry: {
1368                 JSMapIterator* iterator = mapIteratorStack.last();
1369                 JSValue key, value;
1370                 if (!iterator->nextKeyValue(key, value)) {
1371                     mapIteratorStack.removeLast();
1372                     JSObject* object = inputObjectStack.last();
1373                     ASSERT(jsDynamicCast<JSMap*>(object));
1374                     propertyStack.append(PropertyNameArray(m_exec));
1375                     object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), EnumerationMode());
1376                     write(NonMapPropertiesTag);
1377                     indexStack.append(0);
1378                     goto objectStartVisitMember;
1379                 }
1380                 inValue = key;
1381                 m_gcBuffer.append(value);
1382                 mapIteratorValueStack.append(value);
1383                 stateStack.append(MapDataEndVisitKey);
1384                 goto stateUnknown;
1385             }
1386             case MapDataEndVisitKey: {
1387                 inValue = mapIteratorValueStack.last();
1388                 mapIteratorValueStack.removeLast();
1389                 stateStack.append(MapDataEndVisitValue);
1390                 goto stateUnknown;
1391             }
1392             case MapDataEndVisitValue: {
1393                 goto mapDataStartVisitEntry;
1394             }
1395
1396             setStartState: {
1397                 ASSERT(inValue.isObject());
1398                 if (inputObjectStack.size() > maximumFilterRecursion)
1399                     return StackOverflowError;
1400                 JSSet* inSet = jsCast<JSSet*>(inValue);
1401                 if (!startSet(inSet))
1402                     break;
1403                 JSSetIterator* iterator = JSSetIterator::create(m_exec->vm(), m_exec->lexicalGlobalObject()->setIteratorStructure(), inSet, SetIterateKey);
1404                 m_gcBuffer.append(inSet);
1405                 m_gcBuffer.append(iterator);
1406                 setIteratorStack.append(iterator);
1407                 inputObjectStack.append(inSet);
1408                 goto setDataStartVisitEntry;
1409             }
1410             setDataStartVisitEntry:
1411             case SetDataStartVisitEntry: {
1412                 JSSetIterator* iterator = setIteratorStack.last();
1413                 JSValue key;
1414                 if (!iterator->next(m_exec, key)) {
1415                     setIteratorStack.removeLast();
1416                     JSObject* object = inputObjectStack.last();
1417                     ASSERT(jsDynamicCast<JSSet*>(object));
1418                     propertyStack.append(PropertyNameArray(m_exec));
1419                     object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), EnumerationMode());
1420                     write(NonSetPropertiesTag);
1421                     indexStack.append(0);
1422                     goto objectStartVisitMember;
1423                 }
1424                 inValue = key;
1425                 stateStack.append(SetDataEndVisitKey);
1426                 goto stateUnknown;
1427             }
1428             case SetDataEndVisitKey: {
1429                 goto setDataStartVisitEntry;
1430             }
1431
1432             stateUnknown:
1433             case StateUnknown: {
1434                 SerializationReturnCode terminalCode = SuccessfullyCompleted;
1435                 if (dumpIfTerminal(inValue, terminalCode)) {
1436                     if (terminalCode != SuccessfullyCompleted)
1437                         return terminalCode;
1438                     break;
1439                 }
1440
1441                 if (isArray(inValue))
1442                     goto arrayStartState;
1443                 if (isMap(inValue))
1444                     goto mapStartState;
1445                 if (isSet(inValue))
1446                     goto setStartState;
1447                 goto objectStartState;
1448             }
1449         }
1450         if (stateStack.isEmpty())
1451             break;
1452
1453         state = stateStack.last();
1454         stateStack.removeLast();
1455     }
1456     if (m_failed)
1457         return UnspecifiedError;
1458
1459     return SuccessfullyCompleted;
1460 }
1461
1462 typedef Vector<JSC::ArrayBufferContents> ArrayBufferContentsArray;
1463
1464 class CloneDeserializer : CloneBase {
1465 public:
1466     static String deserializeString(const Vector<uint8_t>& buffer)
1467     {
1468         if (buffer.isEmpty())
1469             return String();
1470         const uint8_t* ptr = buffer.begin();
1471         const uint8_t* end = buffer.end();
1472         uint32_t version;
1473         if (!readLittleEndian(ptr, end, version) || version > CurrentVersion)
1474             return String();
1475         uint8_t tag;
1476         if (!readLittleEndian(ptr, end, tag) || tag != StringTag)
1477             return String();
1478         uint32_t length;
1479         if (!readLittleEndian(ptr, end, length) || length >= StringPoolTag)
1480             return String();
1481         String str;
1482         if (!readString(ptr, end, str, length))
1483             return String();
1484         return String(str.impl());
1485     }
1486
1487     static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject,
1488                                              MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray,
1489                                              const Vector<uint8_t>& buffer)
1490     {
1491         if (!buffer.size())
1492             return std::make_pair(jsNull(), UnspecifiedError);
1493         CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer);
1494         if (!deserializer.isValid())
1495             return std::make_pair(JSValue(), ValidationError);
1496         return deserializer.deserialize();
1497     }
1498
1499 private:
1500     struct CachedString {
1501         CachedString(const String& string)
1502             : m_string(string)
1503         {
1504         }
1505
1506         JSValue jsString(ExecState* exec)
1507         {
1508             if (!m_jsString)
1509                 m_jsString = JSC::jsString(exec, m_string);
1510             return m_jsString;
1511         }
1512         const String& string() { return m_string; }
1513
1514     private:
1515         String m_string;
1516         JSValue m_jsString;
1517     };
1518
1519     struct CachedStringRef {
1520         CachedStringRef()
1521             : m_base(0)
1522             , m_index(0)
1523         {
1524         }
1525         CachedStringRef(Vector<CachedString>* base, size_t index)
1526             : m_base(base)
1527             , m_index(index)
1528         {
1529         }
1530         
1531         CachedString* operator->() { ASSERT(m_base); return &m_base->at(m_index); }
1532         
1533     private:
1534         Vector<CachedString>* m_base;
1535         size_t m_index;
1536     };
1537
1538     CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, 
1539                       MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents,
1540                       const Vector<uint8_t>& buffer)
1541         : CloneBase(exec)
1542         , m_globalObject(globalObject)
1543         , m_isDOMGlobalObject(globalObject->inherits(JSDOMGlobalObject::info()))
1544         , m_ptr(buffer.data())
1545         , m_end(buffer.data() + buffer.size())
1546         , m_version(0xFFFFFFFF)
1547         , m_messagePorts(messagePorts)
1548         , m_arrayBufferContents(arrayBufferContents)
1549         , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0)
1550     {
1551         if (!read(m_version))
1552             m_version = 0xFFFFFFFF;
1553     }
1554
1555     DeserializationResult deserialize();
1556
1557     void throwValidationError()
1558     {
1559         m_exec->vm().throwException(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
1560     }
1561
1562     bool isValid() const { return m_version <= CurrentVersion; }
1563
1564     template <typename T> bool readLittleEndian(T& value)
1565     {
1566         if (m_failed || !readLittleEndian(m_ptr, m_end, value)) {
1567             fail();
1568             return false;
1569         }
1570         return true;
1571     }
1572 #if ASSUME_LITTLE_ENDIAN
1573     template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
1574     {
1575         if (ptr > end - sizeof(value))
1576             return false;
1577
1578         if (sizeof(T) == 1)
1579             value = *ptr++;
1580         else {
1581             value = *reinterpret_cast<const T*>(ptr);
1582             ptr += sizeof(T);
1583         }
1584         return true;
1585     }
1586 #else
1587     template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
1588     {
1589         if (ptr > end - sizeof(value))
1590             return false;
1591
1592         if (sizeof(T) == 1)
1593             value = *ptr++;
1594         else {
1595             value = 0;
1596             for (unsigned i = 0; i < sizeof(T); i++)
1597                 value += ((T)*ptr++) << (i * 8);
1598         }
1599         return true;
1600     }
1601 #endif
1602
1603     bool read(uint32_t& i)
1604     {
1605         return readLittleEndian(i);
1606     }
1607
1608     bool read(int32_t& i)
1609     {
1610         return readLittleEndian(*reinterpret_cast<uint32_t*>(&i));
1611     }
1612
1613     bool read(uint16_t& i)
1614     {
1615         return readLittleEndian(i);
1616     }
1617
1618     bool read(uint8_t& i)
1619     {
1620         return readLittleEndian(i);
1621     }
1622
1623     bool read(double& d)
1624     {
1625         union {
1626             double d;
1627             uint64_t i64;
1628         } u;
1629         if (!readLittleEndian(u.i64))
1630             return false;
1631         d = u.d;
1632         return true;
1633     }
1634
1635     bool read(unsigned long long& i)
1636     {
1637         return readLittleEndian(i);
1638     }
1639
1640     bool readStringIndex(uint32_t& i)
1641     {
1642         return readConstantPoolIndex(m_constantPool, i);
1643     }
1644
1645     template <class T> bool readConstantPoolIndex(const T& constantPool, uint32_t& i)
1646     {
1647         if (constantPool.size() <= 0xFF) {
1648             uint8_t i8;
1649             if (!read(i8))
1650                 return false;
1651             i = i8;
1652             return true;
1653         }
1654         if (constantPool.size() <= 0xFFFF) {
1655             uint16_t i16;
1656             if (!read(i16))
1657                 return false;
1658             i = i16;
1659             return true;
1660         }
1661         return read(i);
1662     }
1663
1664     static bool readString(const uint8_t*& ptr, const uint8_t* end, String& str, unsigned length)
1665     {
1666         if (length >= std::numeric_limits<int32_t>::max() / sizeof(UChar))
1667             return false;
1668
1669         unsigned size = length * sizeof(UChar);
1670         if ((end - ptr) < static_cast<int>(size))
1671             return false;
1672
1673 #if ASSUME_LITTLE_ENDIAN
1674         str = String(reinterpret_cast<const UChar*>(ptr), length);
1675         ptr += length * sizeof(UChar);
1676 #else
1677         Vector<UChar> buffer;
1678         buffer.reserveCapacity(length);
1679         for (unsigned i = 0; i < length; i++) {
1680             uint16_t ch;
1681             readLittleEndian(ptr, end, ch);
1682             buffer.append(ch);
1683         }
1684         str = String::adopt(buffer);
1685 #endif
1686         return true;
1687     }
1688
1689     bool readStringData(CachedStringRef& cachedString)
1690     {
1691         bool scratch;
1692         return readStringData(cachedString, scratch);
1693     }
1694
1695     bool readStringData(CachedStringRef& cachedString, bool& wasTerminator)
1696     {
1697         if (m_failed)
1698             return false;
1699         uint32_t length = 0;
1700         if (!read(length))
1701             return false;
1702         if (length == TerminatorTag) {
1703             wasTerminator = true;
1704             return false;
1705         }
1706         if (length == StringPoolTag) {
1707             unsigned index = 0;
1708             if (!readStringIndex(index)) {
1709                 fail();
1710                 return false;
1711             }
1712             if (index >= m_constantPool.size()) {
1713                 fail();
1714                 return false;
1715             }
1716             cachedString = CachedStringRef(&m_constantPool, index);
1717             return true;
1718         }
1719         String str;
1720         if (!readString(m_ptr, m_end, str, length)) {
1721             fail();
1722             return false;
1723         }
1724         m_constantPool.append(str);
1725         cachedString = CachedStringRef(&m_constantPool, m_constantPool.size() - 1);
1726         return true;
1727     }
1728
1729     SerializationTag readTag()
1730     {
1731         if (m_ptr >= m_end)
1732             return ErrorTag;
1733         return static_cast<SerializationTag>(*m_ptr++);
1734     }
1735
1736     bool readArrayBufferViewSubtag(ArrayBufferViewSubtag& tag)
1737     {
1738         if (m_ptr >= m_end)
1739             return false;
1740         tag = static_cast<ArrayBufferViewSubtag>(*m_ptr++);
1741         return true;
1742     }
1743
1744     void putProperty(JSObject* object, unsigned index, JSValue value)
1745     {
1746         object->putDirectIndex(m_exec, index, value);
1747     }
1748
1749     void putProperty(JSObject* object, const Identifier& property, JSValue value)
1750     {
1751         object->putDirectMayBeIndex(m_exec, property, value);
1752     }
1753
1754     bool readFile(RefPtr<File>& file)
1755     {
1756         CachedStringRef path;
1757         if (!readStringData(path))
1758             return 0;
1759         CachedStringRef url;
1760         if (!readStringData(url))
1761             return 0;
1762         CachedStringRef type;
1763         if (!readStringData(type))
1764             return 0;
1765         CachedStringRef name;
1766         if (!readStringData(name))
1767             return 0;
1768         if (m_isDOMGlobalObject)
1769             file = File::deserialize(path->string(), URL(URL(), url->string()), type->string(), name->string());
1770         return true;
1771     }
1772
1773     bool readArrayBuffer(RefPtr<ArrayBuffer>& arrayBuffer)
1774     {
1775         uint32_t length;
1776         if (!read(length))
1777             return false;
1778         if (m_ptr + length > m_end)
1779             return false;
1780         arrayBuffer = ArrayBuffer::create(m_ptr, length);
1781         m_ptr += length;
1782         return true;
1783     }
1784
1785     bool readArrayBufferView(JSValue& arrayBufferView)
1786     {
1787         ArrayBufferViewSubtag arrayBufferViewSubtag;
1788         if (!readArrayBufferViewSubtag(arrayBufferViewSubtag))
1789             return false;
1790         uint32_t byteOffset;
1791         if (!read(byteOffset))
1792             return false;
1793         uint32_t byteLength;
1794         if (!read(byteLength))
1795             return false;
1796         JSObject* arrayBufferObj = asObject(readTerminal());
1797         if (!arrayBufferObj || !arrayBufferObj->inherits(JSArrayBuffer::info()))
1798             return false;
1799
1800         unsigned elementSize = typedArrayElementSize(arrayBufferViewSubtag);
1801         if (!elementSize)
1802             return false;
1803         unsigned length = byteLength / elementSize;
1804         if (length * elementSize != byteLength)
1805             return false;
1806
1807         RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(arrayBufferObj);
1808         switch (arrayBufferViewSubtag) {
1809         case DataViewTag:
1810             arrayBufferView = getJSValue(DataView::create(arrayBuffer, byteOffset, length).get());
1811             return true;
1812         case Int8ArrayTag:
1813             arrayBufferView = getJSValue(Int8Array::create(arrayBuffer, byteOffset, length).get());
1814             return true;
1815         case Uint8ArrayTag:
1816             arrayBufferView = getJSValue(Uint8Array::create(arrayBuffer, byteOffset, length).get());
1817             return true;
1818         case Uint8ClampedArrayTag:
1819             arrayBufferView = getJSValue(Uint8ClampedArray::create(arrayBuffer, byteOffset, length).get());
1820             return true;
1821         case Int16ArrayTag:
1822             arrayBufferView = getJSValue(Int16Array::create(arrayBuffer, byteOffset, length).get());
1823             return true;
1824         case Uint16ArrayTag:
1825             arrayBufferView = getJSValue(Uint16Array::create(arrayBuffer, byteOffset, length).get());
1826             return true;
1827         case Int32ArrayTag:
1828             arrayBufferView = getJSValue(Int32Array::create(arrayBuffer, byteOffset, length).get());
1829             return true;
1830         case Uint32ArrayTag:
1831             arrayBufferView = getJSValue(Uint32Array::create(arrayBuffer, byteOffset, length).get());
1832             return true;
1833         case Float32ArrayTag:
1834             arrayBufferView = getJSValue(Float32Array::create(arrayBuffer, byteOffset, length).get());
1835             return true;
1836         case Float64ArrayTag:
1837             arrayBufferView = getJSValue(Float64Array::create(arrayBuffer, byteOffset, length).get());
1838             return true;
1839         default:
1840             return false;
1841         }
1842     }
1843
1844     bool read(Vector<uint8_t>& result)
1845     {
1846         ASSERT(result.isEmpty());
1847         uint32_t size;
1848         if (!read(size))
1849             return false;
1850         if (m_ptr + size > m_end)
1851             return false;
1852         result.append(m_ptr, size);
1853         m_ptr += size;
1854         return true;
1855     }
1856
1857 #if ENABLE(SUBTLE_CRYPTO)
1858     bool read(CryptoAlgorithmIdentifier& result)
1859     {
1860         uint8_t algorithmTag;
1861         if (!read(algorithmTag))
1862             return false;
1863         if (algorithmTag > cryptoAlgorithmIdentifierTagMaximumValue)
1864             return false;
1865         switch (static_cast<CryptoAlgorithmIdentifierTag>(algorithmTag)) {
1866         case CryptoAlgorithmIdentifierTag::RSAES_PKCS1_v1_5:
1867             result = CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5;
1868             break;
1869         case CryptoAlgorithmIdentifierTag::RSASSA_PKCS1_v1_5:
1870             result = CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5;
1871             break;
1872         case CryptoAlgorithmIdentifierTag::RSA_PSS:
1873             result = CryptoAlgorithmIdentifier::RSA_PSS;
1874             break;
1875         case CryptoAlgorithmIdentifierTag::RSA_OAEP:
1876             result = CryptoAlgorithmIdentifier::RSA_OAEP;
1877             break;
1878         case CryptoAlgorithmIdentifierTag::ECDSA:
1879             result = CryptoAlgorithmIdentifier::ECDSA;
1880             break;
1881         case CryptoAlgorithmIdentifierTag::ECDH:
1882             result = CryptoAlgorithmIdentifier::ECDH;
1883             break;
1884         case CryptoAlgorithmIdentifierTag::AES_CTR:
1885             result = CryptoAlgorithmIdentifier::AES_CTR;
1886             break;
1887         case CryptoAlgorithmIdentifierTag::AES_CBC:
1888             result = CryptoAlgorithmIdentifier::AES_CBC;
1889             break;
1890         case CryptoAlgorithmIdentifierTag::AES_CMAC:
1891             result = CryptoAlgorithmIdentifier::AES_CMAC;
1892             break;
1893         case CryptoAlgorithmIdentifierTag::AES_GCM:
1894             result = CryptoAlgorithmIdentifier::AES_GCM;
1895             break;
1896         case CryptoAlgorithmIdentifierTag::AES_CFB:
1897             result = CryptoAlgorithmIdentifier::AES_CFB;
1898             break;
1899         case CryptoAlgorithmIdentifierTag::AES_KW:
1900             result = CryptoAlgorithmIdentifier::AES_KW;
1901             break;
1902         case CryptoAlgorithmIdentifierTag::HMAC:
1903             result = CryptoAlgorithmIdentifier::HMAC;
1904             break;
1905         case CryptoAlgorithmIdentifierTag::DH:
1906             result = CryptoAlgorithmIdentifier::DH;
1907             break;
1908         case CryptoAlgorithmIdentifierTag::SHA_1:
1909             result = CryptoAlgorithmIdentifier::SHA_1;
1910             break;
1911         case CryptoAlgorithmIdentifierTag::SHA_224:
1912             result = CryptoAlgorithmIdentifier::SHA_224;
1913             break;
1914         case CryptoAlgorithmIdentifierTag::SHA_256:
1915             result = CryptoAlgorithmIdentifier::SHA_256;
1916             break;
1917         case CryptoAlgorithmIdentifierTag::SHA_384:
1918             result = CryptoAlgorithmIdentifier::SHA_384;
1919             break;
1920         case CryptoAlgorithmIdentifierTag::SHA_512:
1921             result = CryptoAlgorithmIdentifier::SHA_512;
1922             break;
1923         case CryptoAlgorithmIdentifierTag::CONCAT:
1924             result = CryptoAlgorithmIdentifier::CONCAT;
1925             break;
1926         case CryptoAlgorithmIdentifierTag::HKDF_CTR:
1927             result = CryptoAlgorithmIdentifier::HKDF_CTR;
1928             break;
1929         case CryptoAlgorithmIdentifierTag::PBKDF2:
1930             result = CryptoAlgorithmIdentifier::PBKDF2;
1931             break;
1932         }
1933         return true;
1934     }
1935
1936     bool read(CryptoKeyClassSubtag& result)
1937     {
1938         uint8_t tag;
1939         if (!read(tag))
1940             return false;
1941         if (tag > cryptoKeyClassSubtagMaximumValue)
1942             return false;
1943         result = static_cast<CryptoKeyClassSubtag>(tag);
1944         return true;
1945     }
1946
1947     bool read(CryptoKeyUsageTag& result)
1948     {
1949         uint8_t tag;
1950         if (!read(tag))
1951             return false;
1952         if (tag > cryptoKeyUsageTagMaximumValue)
1953             return false;
1954         result = static_cast<CryptoKeyUsageTag>(tag);
1955         return true;
1956     }
1957
1958     bool read(CryptoKeyAsymmetricTypeSubtag& result)
1959     {
1960         uint8_t tag;
1961         if (!read(tag))
1962             return false;
1963         if (tag > cryptoKeyAsymmetricTypeSubtagMaximumValue)
1964             return false;
1965         result = static_cast<CryptoKeyAsymmetricTypeSubtag>(tag);
1966         return true;
1967     }
1968
1969     bool readHMACKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result)
1970     {
1971         Vector<uint8_t> keyData;
1972         if (!read(keyData))
1973             return false;
1974         CryptoAlgorithmIdentifier hash;
1975         if (!read(hash))
1976             return false;
1977         result = CryptoKeyHMAC::create(keyData, hash, extractable, usages);
1978         return true;
1979     }
1980
1981     bool readAESKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result)
1982     {
1983         CryptoAlgorithmIdentifier algorithm;
1984         if (!read(algorithm))
1985             return false;
1986         if (!CryptoKeyAES::isValidAESAlgorithm(algorithm))
1987             return false;
1988         Vector<uint8_t> keyData;
1989         if (!read(keyData))
1990             return false;
1991         result = CryptoKeyAES::create(algorithm, keyData, extractable, usages);
1992         return true;
1993     }
1994
1995     bool readRSAKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result)
1996     {
1997         CryptoAlgorithmIdentifier algorithm;
1998         if (!read(algorithm))
1999             return false;
2000
2001         int32_t isRestrictedToHash;
2002         CryptoAlgorithmIdentifier hash;
2003         if (!read(isRestrictedToHash))
2004             return false;
2005         if (isRestrictedToHash && !read(hash))
2006             return false;
2007
2008         CryptoKeyAsymmetricTypeSubtag type;
2009         if (!read(type))
2010             return false;
2011
2012         Vector<uint8_t> modulus;
2013         if (!read(modulus))
2014             return false;
2015         Vector<uint8_t> exponent;
2016         if (!read(exponent))
2017             return false;
2018
2019         if (type == CryptoKeyAsymmetricTypeSubtag::Public) {
2020             auto keyData = CryptoKeyDataRSAComponents::createPublic(modulus, exponent);
2021             auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
2022             if (isRestrictedToHash)
2023                 key->restrictToHash(hash);
2024             result = WTF::move(key);
2025             return true;
2026         }
2027
2028         Vector<uint8_t> privateExponent;
2029         if (!read(privateExponent))
2030             return false;
2031
2032         uint32_t primeCount;
2033         if (!read(primeCount))
2034             return false;
2035
2036         if (!primeCount) {
2037             auto keyData = CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
2038             auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
2039             if (isRestrictedToHash)
2040                 key->restrictToHash(hash);
2041             result = WTF::move(key);
2042             return true;
2043         }
2044
2045         if (primeCount < 2)
2046             return false;
2047
2048         CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo;
2049         CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo;
2050         Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos(primeCount - 2);
2051
2052         if (!read(firstPrimeInfo.primeFactor))
2053             return false;
2054         if (!read(firstPrimeInfo.factorCRTExponent))
2055             return false;
2056         if (!read(secondPrimeInfo.primeFactor))
2057             return false;
2058         if (!read(secondPrimeInfo.factorCRTExponent))
2059             return false;
2060         if (!read(secondPrimeInfo.factorCRTCoefficient))
2061             return false;
2062         for (unsigned i = 2; i < primeCount; ++i) {
2063             if (!read(otherPrimeInfos[i].primeFactor))
2064                 return false;
2065             if (!read(otherPrimeInfos[i].factorCRTExponent))
2066                 return false;
2067             if (!read(otherPrimeInfos[i].factorCRTCoefficient))
2068                 return false;
2069         }
2070
2071         auto keyData = CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
2072         auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
2073         if (isRestrictedToHash)
2074             key->restrictToHash(hash);
2075         result = WTF::move(key);
2076         return true;
2077     }
2078
2079     bool readCryptoKey(JSValue& cryptoKey)
2080     {
2081         uint32_t keyFormatVersion;
2082         if (!read(keyFormatVersion) || keyFormatVersion > currentKeyFormatVersion)
2083             return false;
2084
2085         int32_t extractable;
2086         if (!read(extractable))
2087             return false;
2088
2089         uint32_t usagesCount;
2090         if (!read(usagesCount))
2091             return false;
2092
2093         CryptoKeyUsage usages = 0;
2094         for (uint32_t i = 0; i < usagesCount; ++i) {
2095             CryptoKeyUsageTag usage;
2096             if (!read(usage))
2097                 return false;
2098             switch (usage) {
2099             case CryptoKeyUsageTag::Encrypt:
2100                 usages |= CryptoKeyUsageEncrypt;
2101                 break;
2102             case CryptoKeyUsageTag::Decrypt:
2103                 usages |= CryptoKeyUsageDecrypt;
2104                 break;
2105             case CryptoKeyUsageTag::Sign:
2106                 usages |= CryptoKeyUsageSign;
2107                 break;
2108             case CryptoKeyUsageTag::Verify:
2109                 usages |= CryptoKeyUsageVerify;
2110                 break;
2111             case CryptoKeyUsageTag::DeriveKey:
2112                 usages |= CryptoKeyUsageDeriveKey;
2113                 break;
2114             case CryptoKeyUsageTag::DeriveBits:
2115                 usages |= CryptoKeyUsageDeriveBits;
2116                 break;
2117             case CryptoKeyUsageTag::WrapKey:
2118                 usages |= CryptoKeyUsageWrapKey;
2119                 break;
2120             case CryptoKeyUsageTag::UnwrapKey:
2121                 usages |= CryptoKeyUsageUnwrapKey;
2122                 break;
2123             }
2124         }
2125
2126         CryptoKeyClassSubtag cryptoKeyClass;
2127         if (!read(cryptoKeyClass))
2128             return false;
2129         RefPtr<CryptoKey> result;
2130         switch (cryptoKeyClass) {
2131         case CryptoKeyClassSubtag::HMAC:
2132             if (!readHMACKey(extractable, usages, result))
2133                 return false;
2134             break;
2135         case CryptoKeyClassSubtag::AES:
2136             if (!readAESKey(extractable, usages, result))
2137                 return false;
2138             break;
2139         case CryptoKeyClassSubtag::RSA:
2140             if (!readRSAKey(extractable, usages, result))
2141                 return false;
2142             break;
2143         }
2144         cryptoKey = getJSValue(result.get());
2145         return true;
2146     }
2147 #endif
2148
2149     template<class T>
2150     JSValue getJSValue(T* nativeObj)
2151     {
2152         return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), nativeObj);
2153     }
2154
2155     template<class T>
2156     JSValue getJSValue(T& nativeObj)
2157     {
2158         return getJSValue(&nativeObj);
2159     }
2160
2161     JSValue readTerminal()
2162     {
2163         SerializationTag tag = readTag();
2164         switch (tag) {
2165         case UndefinedTag:
2166             return jsUndefined();
2167         case NullTag:
2168             return jsNull();
2169         case IntTag: {
2170             int32_t i;
2171             if (!read(i))
2172                 return JSValue();
2173             return jsNumber(i);
2174         }
2175         case ZeroTag:
2176             return jsNumber(0);
2177         case OneTag:
2178             return jsNumber(1);
2179         case FalseTag:
2180             return jsBoolean(false);
2181         case TrueTag:
2182             return jsBoolean(true);
2183         case FalseObjectTag: {
2184             BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure());
2185             obj->setInternalValue(m_exec->vm(), jsBoolean(false));
2186             m_gcBuffer.append(obj);
2187             return obj;
2188         }
2189         case TrueObjectTag: {
2190             BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure());
2191             obj->setInternalValue(m_exec->vm(), jsBoolean(true));
2192              m_gcBuffer.append(obj);
2193             return obj;
2194         }
2195         case DoubleTag: {
2196             double d;
2197             if (!read(d))
2198                 return JSValue();
2199             return jsNumber(d);
2200         }
2201         case NumberObjectTag: {
2202             double d;
2203             if (!read(d))
2204                 return JSValue();
2205             NumberObject* obj = constructNumber(m_exec, m_globalObject, jsNumber(d));
2206             m_gcBuffer.append(obj);
2207             return obj;
2208         }
2209         case DateTag: {
2210             double d;
2211             if (!read(d))
2212                 return JSValue();
2213             return DateInstance::create(m_exec->vm(), m_globalObject->dateStructure(), d);
2214         }
2215         case FileTag: {
2216             RefPtr<File> file;
2217             if (!readFile(file))
2218                 return JSValue();
2219             if (!m_isDOMGlobalObject)
2220                 return jsNull();
2221             return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), file.get());
2222         }
2223         case FileListTag: {
2224             unsigned length = 0;
2225             if (!read(length))
2226                 return JSValue();
2227             Vector<RefPtr<File>> files;
2228             for (unsigned i = 0; i < length; i++) {
2229                 RefPtr<File> file;
2230                 if (!readFile(file))
2231                     return JSValue();
2232                 if (m_isDOMGlobalObject)
2233                     files.append(WTF::move(file));
2234             }
2235             if (!m_isDOMGlobalObject)
2236                 return jsNull();
2237             return getJSValue(FileList::create(WTF::move(files)).get());
2238         }
2239         case ImageDataTag: {
2240             int32_t width;
2241             if (!read(width))
2242                 return JSValue();
2243             int32_t height;
2244             if (!read(height))
2245                 return JSValue();
2246             uint32_t length;
2247             if (!read(length))
2248                 return JSValue();
2249             if (m_end < ((uint8_t*)0) + length || m_ptr > m_end - length) {
2250                 fail();
2251                 return JSValue();
2252             }
2253             if (!m_isDOMGlobalObject) {
2254                 m_ptr += length;
2255                 return jsNull();
2256             }
2257             RefPtr<ImageData> result = ImageData::create(IntSize(width, height));
2258             memcpy(result->data()->data(), m_ptr, length);
2259             m_ptr += length;
2260             return getJSValue(result.get());
2261         }
2262         case BlobTag: {
2263             CachedStringRef url;
2264             if (!readStringData(url))
2265                 return JSValue();
2266             CachedStringRef type;
2267             if (!readStringData(type))
2268                 return JSValue();
2269             unsigned long long size = 0;
2270             if (!read(size))
2271                 return JSValue();
2272             if (!m_isDOMGlobalObject)
2273                 return jsNull();
2274             return getJSValue(Blob::deserialize(URL(URL(), url->string()), type->string(), size).get());
2275         }
2276         case StringTag: {
2277             CachedStringRef cachedString;
2278             if (!readStringData(cachedString))
2279                 return JSValue();
2280             return cachedString->jsString(m_exec);
2281         }
2282         case EmptyStringTag:
2283             return jsEmptyString(&m_exec->vm());
2284         case StringObjectTag: {
2285             CachedStringRef cachedString;
2286             if (!readStringData(cachedString))
2287                 return JSValue();
2288             StringObject* obj = constructString(m_exec->vm(), m_globalObject, cachedString->jsString(m_exec));
2289             m_gcBuffer.append(obj);
2290             return obj;
2291         }
2292         case EmptyStringObjectTag: {
2293             VM& vm = m_exec->vm();
2294             StringObject* obj = constructString(vm, m_globalObject, jsEmptyString(&vm));
2295             m_gcBuffer.append(obj);
2296             return obj;
2297         }
2298         case RegExpTag: {
2299             CachedStringRef pattern;
2300             if (!readStringData(pattern))
2301                 return JSValue();
2302             CachedStringRef flags;
2303             if (!readStringData(flags))
2304                 return JSValue();
2305             RegExpFlags reFlags = regExpFlags(flags->string());
2306             ASSERT(reFlags != InvalidFlags);
2307             VM& vm = m_exec->vm();
2308             RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags);
2309             return RegExpObject::create(vm, m_globalObject->regExpStructure(), regExp);
2310         }
2311         case ObjectReferenceTag: {
2312             unsigned index = 0;
2313             if (!readConstantPoolIndex(m_gcBuffer, index)) {
2314                 fail();
2315                 return JSValue();
2316             }
2317             return m_gcBuffer.at(index);
2318         }
2319         case MessagePortReferenceTag: {
2320             uint32_t index;
2321             bool indexSuccessfullyRead = read(index);
2322             if (!indexSuccessfullyRead || !m_messagePorts || index >= m_messagePorts->size()) {
2323                 fail();
2324                 return JSValue();
2325             }
2326             return getJSValue(m_messagePorts->at(index).get());
2327         }
2328         case ArrayBufferTag: {
2329             RefPtr<ArrayBuffer> arrayBuffer;
2330             if (!readArrayBuffer(arrayBuffer)) {
2331                 fail();
2332                 return JSValue();
2333             }
2334             JSValue result = getJSValue(arrayBuffer.get());
2335             m_gcBuffer.append(result);
2336             return result;
2337         }
2338         case ArrayBufferTransferTag: {
2339             uint32_t index;
2340             bool indexSuccessfullyRead = read(index);
2341             if (!indexSuccessfullyRead || index >= m_arrayBuffers.size()) {
2342                 fail();
2343                 return JSValue();
2344             }
2345
2346             if (!m_arrayBuffers[index])
2347                 m_arrayBuffers[index] = ArrayBuffer::create(m_arrayBufferContents->at(index));
2348
2349             return getJSValue(m_arrayBuffers[index].get());
2350         }
2351         case ArrayBufferViewTag: {
2352             JSValue arrayBufferView;
2353             if (!readArrayBufferView(arrayBufferView)) {
2354                 fail();
2355                 return JSValue();
2356             }
2357             m_gcBuffer.append(arrayBufferView);
2358             return arrayBufferView;
2359         }
2360 #if ENABLE(SUBTLE_CRYPTO)
2361         case CryptoKeyTag: {
2362             Vector<uint8_t> wrappedKey;
2363             if (!read(wrappedKey)) {
2364                 fail();
2365                 return JSValue();
2366             }
2367             Vector<uint8_t> serializedKey;
2368             if (!unwrapCryptoKey(m_exec, wrappedKey, serializedKey)) {
2369                 fail();
2370                 return JSValue();
2371             }
2372             JSValue cryptoKey;
2373             CloneDeserializer rawKeyDeserializer(m_exec, m_globalObject, nullptr, nullptr, serializedKey);
2374             if (!rawKeyDeserializer.readCryptoKey(cryptoKey)) {
2375                 fail();
2376                 return JSValue();
2377             }
2378             m_gcBuffer.append(cryptoKey);
2379             return cryptoKey;
2380         }
2381 #endif
2382         default:
2383             m_ptr--; // Push the tag back
2384             return JSValue();
2385         }
2386     }
2387
2388     template<SerializationTag Tag>
2389     bool consumeCollectionDataTerminationIfPossible()
2390     {
2391         if (readTag() == Tag)
2392             return true;
2393         m_ptr--;
2394         return false;
2395     }
2396
2397     JSGlobalObject* m_globalObject;
2398     bool m_isDOMGlobalObject;
2399     const uint8_t* m_ptr;
2400     const uint8_t* m_end;
2401     unsigned m_version;
2402     Vector<CachedString> m_constantPool;
2403     MessagePortArray* m_messagePorts;
2404     ArrayBufferContentsArray* m_arrayBufferContents;
2405     ArrayBufferArray m_arrayBuffers;
2406 };
2407
2408 DeserializationResult CloneDeserializer::deserialize()
2409 {
2410     Vector<uint32_t, 16> indexStack;
2411     Vector<Identifier, 16> propertyNameStack;
2412     Vector<JSObject*, 32> outputObjectStack;
2413     Vector<JSValue, 4> mapKeyStack;
2414     Vector<JSMap*, 4> mapStack;
2415     Vector<JSSet*, 4> setStack;
2416     Vector<WalkerState, 16> stateStack;
2417     WalkerState state = StateUnknown;
2418     JSValue outValue;
2419
2420     while (1) {
2421         switch (state) {
2422         arrayStartState:
2423         case ArrayStartState: {
2424             uint32_t length;
2425             if (!read(length)) {
2426                 fail();
2427                 goto error;
2428             }
2429             JSArray* outArray = constructEmptyArray(m_exec, 0, m_globalObject, length);
2430             m_gcBuffer.append(outArray);
2431             outputObjectStack.append(outArray);
2432         }
2433         arrayStartVisitMember:
2434         FALLTHROUGH;
2435         case ArrayStartVisitMember: {
2436             uint32_t index;
2437             if (!read(index)) {
2438                 fail();
2439                 goto error;
2440             }
2441             if (index == TerminatorTag) {
2442                 JSObject* outArray = outputObjectStack.last();
2443                 outValue = outArray;
2444                 outputObjectStack.removeLast();
2445                 break;
2446             } else if (index == NonIndexPropertiesTag) {
2447                 goto objectStartVisitMember;
2448             }
2449
2450             if (JSValue terminal = readTerminal()) {
2451                 putProperty(outputObjectStack.last(), index, terminal);
2452                 goto arrayStartVisitMember;
2453             }
2454             if (m_failed)
2455                 goto error;
2456             indexStack.append(index);
2457             stateStack.append(ArrayEndVisitMember);
2458             goto stateUnknown;
2459         }
2460         case ArrayEndVisitMember: {
2461             JSObject* outArray = outputObjectStack.last();
2462             putProperty(outArray, indexStack.last(), outValue);
2463             indexStack.removeLast();
2464             goto arrayStartVisitMember;
2465         }
2466         objectStartState:
2467         case ObjectStartState: {
2468             if (outputObjectStack.size() > maximumFilterRecursion)
2469                 return std::make_pair(JSValue(), StackOverflowError);
2470             JSObject* outObject = constructEmptyObject(m_exec, m_globalObject->objectPrototype());
2471             m_gcBuffer.append(outObject);
2472             outputObjectStack.append(outObject);
2473         }
2474         objectStartVisitMember:
2475         FALLTHROUGH;
2476         case ObjectStartVisitMember: {
2477             CachedStringRef cachedString;
2478             bool wasTerminator = false;
2479             if (!readStringData(cachedString, wasTerminator)) {
2480                 if (!wasTerminator)
2481                     goto error;
2482
2483                 JSObject* outObject = outputObjectStack.last();
2484                 outValue = outObject;
2485                 outputObjectStack.removeLast();
2486                 break;
2487             }
2488
2489             if (JSValue terminal = readTerminal()) {
2490                 putProperty(outputObjectStack.last(), Identifier::fromString(m_exec, cachedString->string()), terminal);
2491                 goto objectStartVisitMember;
2492             }
2493             stateStack.append(ObjectEndVisitMember);
2494             propertyNameStack.append(Identifier::fromString(m_exec, cachedString->string()));
2495             goto stateUnknown;
2496         }
2497         case ObjectEndVisitMember: {
2498             putProperty(outputObjectStack.last(), propertyNameStack.last(), outValue);
2499             propertyNameStack.removeLast();
2500             goto objectStartVisitMember;
2501         }
2502         mapObjectStartState: {
2503             if (outputObjectStack.size() > maximumFilterRecursion)
2504                 return std::make_pair(JSValue(), StackOverflowError);
2505             JSMap* map = JSMap::create(m_exec->vm(), m_globalObject->mapStructure());
2506             m_gcBuffer.append(map);
2507             outputObjectStack.append(map);
2508             mapStack.append(map);
2509             goto mapDataStartVisitEntry;
2510         }
2511         mapDataStartVisitEntry:
2512         case MapDataStartVisitEntry: {
2513             if (consumeCollectionDataTerminationIfPossible<NonMapPropertiesTag>()) {
2514                 mapStack.removeLast();
2515                 goto objectStartVisitMember;
2516             }
2517             stateStack.append(MapDataEndVisitKey);
2518             goto stateUnknown;
2519         }
2520         case MapDataEndVisitKey: {
2521             mapKeyStack.append(outValue);
2522             stateStack.append(MapDataEndVisitValue);
2523             goto stateUnknown;
2524         }
2525         case MapDataEndVisitValue: {
2526             mapStack.last()->set(m_exec, mapKeyStack.last(), outValue);
2527             mapKeyStack.removeLast();
2528             goto mapDataStartVisitEntry;
2529         }
2530
2531         setObjectStartState: {
2532             if (outputObjectStack.size() > maximumFilterRecursion)
2533                 return std::make_pair(JSValue(), StackOverflowError);
2534             JSSet* set = JSSet::create(m_exec->vm(), m_globalObject->setStructure());
2535             m_gcBuffer.append(set);
2536             outputObjectStack.append(set);
2537             setStack.append(set);
2538             goto setDataStartVisitEntry;
2539         }
2540         setDataStartVisitEntry:
2541         case SetDataStartVisitEntry: {
2542             if (consumeCollectionDataTerminationIfPossible<NonSetPropertiesTag>()) {
2543                 setStack.removeLast();
2544                 goto objectStartVisitMember;
2545             }
2546             stateStack.append(SetDataEndVisitKey);
2547             goto stateUnknown;
2548         }
2549         case SetDataEndVisitKey: {
2550             JSSet* set = setStack.last();
2551             set->add(m_exec, outValue);
2552             goto setDataStartVisitEntry;
2553         }
2554
2555         stateUnknown:
2556         case StateUnknown:
2557             if (JSValue terminal = readTerminal()) {
2558                 outValue = terminal;
2559                 break;
2560             }
2561             SerializationTag tag = readTag();
2562             if (tag == ArrayTag)
2563                 goto arrayStartState;
2564             if (tag == ObjectTag)
2565                 goto objectStartState;
2566             if (tag == MapObjectTag)
2567                 goto mapObjectStartState;
2568             if (tag == SetObjectTag)
2569                 goto setObjectStartState;
2570             goto error;
2571         }
2572         if (stateStack.isEmpty())
2573             break;
2574
2575         state = stateStack.last();
2576         stateStack.removeLast();
2577     }
2578     ASSERT(outValue);
2579     ASSERT(!m_failed);
2580     return std::make_pair(outValue, SuccessfullyCompleted);
2581 error:
2582     fail();
2583     return std::make_pair(JSValue(), ValidationError);
2584 }
2585
2586 void SerializedScriptValue::addBlobURL(const String& string)
2587 {
2588     m_blobURLs.append(Vector<uint16_t>());
2589     m_blobURLs.last().reserveCapacity(string.length());
2590     for (size_t i = 0; i < string.length(); i++)
2591         m_blobURLs.last().append(string.characterAt(i));
2592     m_blobURLs.last().resize(m_blobURLs.last().size());
2593 }
2594
2595 SerializedScriptValue::~SerializedScriptValue()
2596 {
2597 }
2598
2599 SerializedScriptValue::SerializedScriptValue(const Vector<uint8_t>& buffer)
2600     : m_data(buffer)
2601 {
2602 }
2603
2604 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer)
2605 {
2606     m_data.swap(buffer);
2607 }
2608
2609 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs)
2610 {
2611     m_data.swap(buffer);
2612     for (auto& string : blobURLs)
2613         addBlobURL(string);
2614 }
2615
2616 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray)
2617     : m_arrayBufferContentsArray(WTF::move(arrayBufferContentsArray))
2618 {
2619     m_data.swap(buffer);
2620     for (auto& string : blobURLs)
2621         addBlobURL(string);
2622 }
2623
2624 std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(
2625     ExecState* exec, ArrayBufferArray& arrayBuffers, SerializationReturnCode& code)
2626 {
2627     for (size_t i = 0; i < arrayBuffers.size(); i++) {
2628         if (arrayBuffers[i]->isNeutered()) {
2629             code = ValidationError;
2630             return nullptr;
2631         }
2632     }
2633
2634     auto contents = std::make_unique<ArrayBufferContentsArray>(arrayBuffers.size());
2635     Vector<Ref<DOMWrapperWorld>> worlds;
2636     static_cast<WebCoreJSClientData*>(exec->vm().clientData)->getAllWorlds(worlds);
2637
2638     HashSet<JSC::ArrayBuffer*> visited;
2639     for (size_t arrayBufferIndex = 0; arrayBufferIndex < arrayBuffers.size(); arrayBufferIndex++) {
2640         if (visited.contains(arrayBuffers[arrayBufferIndex].get()))
2641             continue;
2642         visited.add(arrayBuffers[arrayBufferIndex].get());
2643
2644         bool result = arrayBuffers[arrayBufferIndex]->transfer(contents->at(arrayBufferIndex));
2645         if (!result) {
2646             code = ValidationError;
2647             return nullptr;
2648         }
2649     }
2650     return contents;
2651 }
2652
2653 RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState* exec, JSValue value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, SerializationErrorMode throwExceptions)
2654 {
2655     Vector<uint8_t> buffer;
2656     Vector<String> blobURLs;
2657     SerializationReturnCode code = CloneSerializer::serialize(exec, value, messagePorts, arrayBuffers, blobURLs, buffer);
2658
2659     std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray;
2660
2661     if (arrayBuffers && serializationDidCompleteSuccessfully(code))
2662         arrayBufferContentsArray = transferArrayBuffers(exec, *arrayBuffers, code);
2663
2664     if (throwExceptions == Throwing)
2665         maybeThrowExceptionIfSerializationFailed(exec, code);
2666
2667     if (!serializationDidCompleteSuccessfully(code))
2668         return nullptr;
2669
2670     return adoptRef(*new SerializedScriptValue(buffer, blobURLs, WTF::move(arrayBufferContentsArray)));
2671 }
2672
2673 RefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& string)
2674 {
2675     Vector<uint8_t> buffer;
2676     if (!CloneSerializer::serialize(string, buffer))
2677         return nullptr;
2678     return adoptRef(*new SerializedScriptValue(buffer));
2679 }
2680
2681 #if ENABLE(INDEXED_DATABASE)
2682 Ref<SerializedScriptValue> SerializedScriptValue::numberValue(double value)
2683 {
2684     Vector<uint8_t> buffer;
2685     CloneSerializer::serializeNumber(value, buffer);
2686     return adoptRef(*new SerializedScriptValue(buffer));
2687 }
2688
2689 Ref<SerializedScriptValue> SerializedScriptValue::undefinedValue()
2690 {
2691     Vector<uint8_t> buffer;
2692     CloneSerializer::serializeUndefined(buffer);
2693     return adoptRef(*new SerializedScriptValue(buffer));
2694 }
2695 #endif
2696
2697 PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception)
2698 {
2699     ExecState* exec = toJS(originContext);
2700     JSLockHolder locker(exec);
2701     JSValue value = toJS(exec, apiValue);
2702     RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value, nullptr, nullptr);
2703     if (exec->hadException()) {
2704         if (exception)
2705             *exception = toRef(exec, exec->exception());
2706         exec->clearException();
2707         return 0;
2708     }
2709     ASSERT(serializedValue);
2710     return serializedValue.release();
2711 }
2712
2713 String SerializedScriptValue::toString()
2714 {
2715     return CloneDeserializer::deserializeString(m_data);
2716 }
2717
2718 JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject,
2719                                            MessagePortArray* messagePorts, SerializationErrorMode throwExceptions)
2720 {
2721     DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts,
2722                                                                   m_arrayBufferContentsArray.get(), m_data);
2723     if (throwExceptions == Throwing)
2724         maybeThrowExceptionIfSerializationFailed(exec, result.second);
2725     return result.first ? result.first : jsNull();
2726 }
2727
2728 JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception)
2729 {
2730     ExecState* exec = toJS(destinationContext);
2731     JSLockHolder locker(exec);
2732     JSValue value = deserialize(exec, exec->lexicalGlobalObject(), nullptr);
2733     if (exec->hadException()) {
2734         if (exception)
2735             *exception = toRef(exec, exec->exception());
2736         exec->clearException();
2737         return nullptr;
2738     }
2739     ASSERT(value);
2740     return toRef(exec, value);
2741 }
2742
2743 Ref<SerializedScriptValue> SerializedScriptValue::nullValue()
2744 {
2745     Vector<uint8_t> buffer;
2746     return adoptRef(*new SerializedScriptValue(buffer));
2747 }
2748
2749 void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code)
2750 {
2751     if (code == SuccessfullyCompleted)
2752         return;
2753     
2754     switch (code) {
2755     case StackOverflowError:
2756         exec->vm().throwException(exec, createStackOverflowError(exec));
2757         break;
2758     case ValidationError:
2759         exec->vm().throwException(exec, createTypeError(exec, "Unable to deserialize data."));
2760         break;
2761     case DataCloneError:
2762         setDOMException(exec, DATA_CLONE_ERR);
2763         break;
2764     case ExistingExceptionError:
2765         break;
2766     case UnspecifiedError:
2767         break;
2768     default:
2769         ASSERT_NOT_REACHED();
2770     }
2771 }
2772
2773 bool SerializedScriptValue::serializationDidCompleteSuccessfully(SerializationReturnCode code)
2774 {
2775     return (code == SuccessfullyCompleted);
2776 }
2777
2778 uint32_t SerializedScriptValue::wireFormatVersion()
2779 {
2780     return CurrentVersion;
2781 }
2782
2783 }