15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/SerializedScriptValue.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 34f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8Blob.h" 35f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8File.h" 36f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8FileList.h" 37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8ImageData.h" 38f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8MessagePort.h" 39f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8DOMFileSystem.h" 40f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8Key.h" 4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "bindings/v8/ExceptionState.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h" 43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "bindings/v8/WorkerScriptController.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/custom/V8ArrayBufferCustom.h" 453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8ArrayBufferViewCustom.h" 463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8DataViewCustom.h" 473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Float32ArrayCustom.h" 483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Float64ArrayCustom.h" 493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Int16ArrayCustom.h" 503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Int32ArrayCustom.h" 513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Int8ArrayCustom.h" 523c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Uint16ArrayCustom.h" 533c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Uint32ArrayCustom.h" 543c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Uint8ArrayCustom.h" 553c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "bindings/v8/custom/V8Uint8ClampedArrayCustom.h" 5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h" 5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/MessagePort.h" 5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/Blob.h" 5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/File.h" 6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/FileList.h" 6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/ImageData.h" 6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/canvas/DataView.h" 631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/SharedBuffer.h" 64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "platform/heap/Handle.h" 6507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "public/platform/Platform.h" 666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#include "public/platform/WebBlobInfo.h" 6707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "public/platform/WebCrypto.h" 6807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "public/platform/WebCryptoKey.h" 6907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "public/platform/WebCryptoKeyAlgorithm.h" 7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ArrayBuffer.h" 7181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "wtf/ArrayBufferContents.h" 7253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ArrayBufferView.h" 7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Assertions.h" 7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ByteOrder.h" 7553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Float32Array.h" 7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Float64Array.h" 7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Int16Array.h" 7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Int32Array.h" 7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Int8Array.h" 8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/RefCounted.h" 8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Uint16Array.h" 8253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Uint32Array.h" 8353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Uint8Array.h" 8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Uint8ClampedArray.h" 8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Vector.h" 8602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/text/StringBuffer.h" 875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/text/StringUTF8Adaptor.h" 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: consider crashing in debug mode on deserialization errors 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// NOTE: be sure to change wireFormatVersion as necessary! 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This code implements the HTML5 Structured Clone algorithm: 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-passing-of-structured-data 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// V8ObjectMap is a map from V8 objects to arbitrary values of type T. 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// V8 objects (or handles to V8 objects) cannot be used as keys in ordinary wtf::HashMaps; 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// this class should be used instead. GCObject must be a subtype of v8::Object. 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Suggested usage: 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// V8ObjectMap<v8::Object, int> map; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// v8::Handle<v8::Object> obj = ...; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// map.set(obj, 42); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename GCObject, typename T> 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class V8ObjectMap { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool contains(const v8::Handle<GCObject>& handle) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_map.contains(*handle); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool tryGet(const v8::Handle<GCObject>& handle, T* valueOut) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typename HandleToT::iterator result = m_map.find(*handle); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != m_map.end()) { 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *valueOut = result->value; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void set(const v8::Handle<GCObject>& handle, const T& value) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_map.set(*handle, value); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This implementation uses GetIdentityHash(), which sets a hidden property on the object containing 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // a random integer (or returns the one that had been previously set). This ensures that the table 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // never needs to be rebuilt across garbage collections at the expense of doing additional allocation 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and making more round trips into V8. Note that since GetIdentityHash() is defined only on 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // v8::Objects, this V8ObjectMap cannot be used to map v8::Strings to T (because the public V8 API 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // considers a v8::String to be a v8::Primitive). 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If V8 exposes a way to get at the address of the object held by a handle, then we can produce 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // an alternate implementation that does not need to do any V8-side allocation; however, it will 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // need to rehash after every garbage collection because a key object may have been moved. 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) template<typename G> 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct V8HandlePtrHash { 14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) static v8::Handle<G> unsafeHandleFromRawValue(const G* value) 14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const v8::Handle<G>* handle = reinterpret_cast<const v8::Handle<G>*>(&value); 14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return *handle; 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static unsigned hash(const G* key) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdentityHash()); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static bool equal(const G* a, const G* b) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return unsafeHandleFromRawValue(a) == unsafeHandleFromRawValue(b); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For HashArg. 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const bool safeToCompareToEmptyOrDeleted = false; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef WTF::HashMap<GCObject*, T, V8HandlePtrHash<GCObject> > HandleToT; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HandleToT m_map; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef UChar BufferValueType; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Serialization format is a sequence of tags followed by zero or more data arguments. 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Tags always take exactly one byte. A serialized stream first begins with 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// a complete VersionTag. If the stream does not begin with a VersionTag, we assume that 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// the stream is in format 0. 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This format is private to the implementation of SerializedScriptValue. Do not rely on it 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// externally. It is safe to persist a SerializedScriptValue as a binary blob, but this 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// code should always be used to interpret it. 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// WebCoreStrings are read as (length:uint32_t, string:UTF8[length]). 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// RawStrings are read as (length:uint32_t, string:UTF8[length]). 177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// RawUCharStrings are read as (length:uint32_t, string:UChar[length/sizeof(UChar)]). 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// RawFiles are read as (path:WebCoreString, url:WebCoreStrng, type:WebCoreString). 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// There is a reference table that maps object references (uint32_t) to v8::Values. 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Tokens marked with (ref) are inserted into the reference table and given the next object reference ID after decoding. 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// All tags except InvalidTag, PaddingTag, ReferenceCountTag, VersionTag, GenerateFreshObjectTag 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// and GenerateFreshArrayTag push their results to the deserialization stack. 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// There is also an 'open' stack that is used to resolve circular references. Objects or arrays may 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// contain self-references. Before we begin to deserialize the contents of these values, they 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// are first given object reference IDs (by GenerateFreshObjectTag/GenerateFreshArrayTag); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// these reference IDs are then used with ObjectReferenceTag to tie the recursive knot. 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum SerializationTag { 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InvalidTag = '!', // Causes deserialization to fail. 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PaddingTag = '\0', // Is ignored (but consumed). 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UndefinedTag = '_', // -> <undefined> 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NullTag = '0', // -> <null> 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TrueTag = 'T', // -> <true> 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FalseTag = 'F', // -> <false> 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringTag = 'S', // string:RawString -> string 195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) StringUCharTag = 'c', // string:RawUCharString -> string 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Uint32Tag = 'U', // value:uint32_t -> Integer 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DateTag = 'D', // value:double -> Date (ref) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with transferred MessagePort. 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NumberTag = 'N', // value:double -> Number 2016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch BlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref) 2026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch BlobIndexTag = 'i', // index:int32_t -> Blob (ref) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FileTag = 'f', // file:RawFile -> File (ref) 2046f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch FileIndexTag = 'e', // index:int32_t -> File (ref) 2056f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, uuid:WebCoreString -> FileSystem (ref) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FileListTag = 'l', // length:uint32_t, files:RawFile[length] -> FileList (ref) 2076f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch FileListIndexTag = 'L', // length:uint32_t, files:int32_t[length] -> FileList (ref) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint32_t, data:byte[pixelDataLength] -> ImageData (ref) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the open stack; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fills it with the last numProperties name,value pairs pushed onto the deserialization stack 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SparseArrayTag = '@', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fills it with the last numProperties name,value pairs pushed onto the deserialization stack 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DenseArrayTag = '$', // numProperties:uint32_t, length:uint32_t -> pops the last object from the open stack; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fills it with the last length elements and numProperties name,value pairs pushed onto deserialization stack 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> ArrayBuffer (ref) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferTransferTag = 't', // index:uint32_t -> ArrayBuffer. For ArrayBuffer transfer 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferViewTag = 'V', // subtag:byte, byteOffset:uint32_t, byteLength:uint32_t -> ArrayBufferView (ref). Consumes an ArrayBuffer from the top of the deserialization stack. 21907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch CryptoKeyTag = 'K', // subtag:byte, props, usages:uint32_t, keyDataLength:uint32_t, keyData:byte[keyDataLength] 22007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // If subtag=AesKeyTag: 22107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // props = keyLengthBytes:uint32_t, algorithmId:uint32_t 22207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // If subtag=HmacKeyTag: 22307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // props = keyLengthBytes:uint32_t, hashId:uint32_t 22407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // If subtag=RsaHashedKeyTag: 225d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // props = algorithmId:uint32_t, type:uint32_t, modulusLengthBits:uint32_t, publicExponentLength:uint32_t, publicExponent:byte[publicExponentLength], hashId:uint32_t 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectReferenceTag = '^', // ref:uint32_t -> reference table[ref] 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GenerateFreshObjectTag = 'o', // -> empty object allocated an object ID and pushed onto the open stack (ref) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GenerateFreshSparseArrayTag = 'a', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GenerateFreshDenseArrayTag = 'A', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ReferenceCountTag = '?', // refTableSize:uint32_t -> If the reference table is not refTableSize big, fails. 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringObjectTag = 's', // string:RawString -> new String(string) (ref) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NumberObjectTag = 'n', // value:double -> new Number(value) (ref) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TrueObjectTag = 'y', // new Boolean(true) (ref) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FalseObjectTag = 'x', // new Boolean(false) (ref) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VersionTag = 0xFF // version:uint32_t -> Uses this as the file version. 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum ArrayBufferViewSubTag { 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ByteArrayTag = 'b', 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UnsignedByteArrayTag = 'B', 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UnsignedByteClampedArrayTag = 'C', 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShortArrayTag = 'w', 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UnsignedShortArrayTag = 'W', 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntArrayTag = 'd', 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UnsignedIntArrayTag = 'D', 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatArrayTag = 'f', 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DoubleArrayTag = 'F', 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DataViewTag = '?' 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochenum CryptoKeySubTag { 25207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AesKeyTag = 1, 25307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch HmacKeyTag = 2, 254d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // ID 3 was used by RsaKeyTag, while still behind experimental flag. 25507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch RsaHashedKeyTag = 4, 25607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Maximum allowed value is 255 25707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}; 25807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 25907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochenum AssymetricCryptoKeyType { 26007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch PublicKeyType = 1, 26107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch PrivateKeyType = 2, 26207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Maximum allowed value is 2^32-1 26307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}; 26407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 26507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochenum CryptoKeyAlgorithmTag { 26607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AesCbcTag = 1, 26707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch HmacTag = 2, 26807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch RsaSsaPkcs1v1_5Tag = 3, 269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // ID 4 was used by RsaEs, while still behind experimental flag. 27007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Sha1Tag = 5, 27107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Sha256Tag = 6, 27207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Sha384Tag = 7, 27307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Sha512Tag = 8, 27407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AesGcmTag = 9, 27507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch RsaOaepTag = 10, 27607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AesCtrTag = 11, 27707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AesKwTag = 12, 27807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Maximum allowed value is 2^32-1 27907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}; 28007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 28107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochenum CryptoKeyUsage { 28207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Extractability is not a "usage" in the WebCryptoKeyUsages sense, however 28307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // it fits conveniently into this bitfield. 28407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ExtractableUsage = 1 << 0, 28507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 28607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EncryptUsage = 1 << 1, 28707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch DecryptUsage = 1 << 2, 28807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SignUsage = 1 << 3, 28907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch VerifyUsage = 1 << 4, 29007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch DeriveKeyUsage = 1 << 5, 29107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch WrapKeyUsage = 1 << 6, 29207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch UnwrapKeyUsage = 1 << 7, 293f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu DeriveBitsUsage = 1 << 8, 29407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Maximum allowed value is 1 << 31 29507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}; 29607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool shouldCheckForCycles(int depth) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(depth >= 0); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Since we are not required to spot the cycle as soon as it 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // happens we can check for cycles only when the current depth 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is a power of two. 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !(depth & (depth - 1)); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int maxDepth = 20000; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// VarInt encoding constants. 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int varIntShift = 7; 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int varIntMask = (1 << varIntShift) - 1; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ZigZag encoding helps VarInt encoding stay small for negative 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// numbers with small absolute values. 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ZigZag { 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static uint32_t encode(uint32_t value) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value & (1U << 31)) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value = ((~value) << 1) + 1; 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value <<= 1; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static uint32_t decode(uint32_t value) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value & 1) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value = ~(value >> 1); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value >>= 1; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ZigZag(); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Writer is responsible for serializing primitive types and storing 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// information used to reconstruct composite types. 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Writer { 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WTF_MAKE_NONCOPYABLE(Writer); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Writer() 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_position(0) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Write functions for primitive types. 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeUndefined() { append(UndefinedTag); } 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeNull() { append(NullTag); } 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeTrue() { append(TrueTag); } 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeFalse() { append(FalseTag); } 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeBooleanObject(bool value) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(value ? TrueObjectTag : FalseObjectTag); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 363926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void writeOneByteString(v8::Handle<v8::String>& string) 364926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int stringLength = string->Length(); 366926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int utf8Length = string->Utf8Length(); 367926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(stringLength >= 0 && utf8Length >= 0); 368926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 369926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) append(StringTag); 370926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) doWriteUint32(static_cast<uint32_t>(utf8Length)); 371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ensureSpace(utf8Length); 372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // ASCII fast path. 374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (stringLength == utf8Length) 375926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOptions()); 376926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else { 377926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) char* buffer = reinterpret_cast<char*>(byteAt(m_position)); 378926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); 379926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 380926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_position += utf8Length; 381926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 382926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 383926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void writeUCharString(v8::Handle<v8::String>& string) 384926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 385926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int length = string->Length(); 386926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(length >= 0); 387926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 388926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int size = length * sizeof(UChar); 389926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); 390926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if ((m_position + 1 + bytes) & 1) 391926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) append(PaddingTag); 392926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 393926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) append(StringUCharTag); 394926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) doWriteUint32(static_cast<uint32_t>(size)); 395926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ensureSpace(size); 396926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 397926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!(m_position & 1)); 398926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position)); 399926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) string->Write(buffer, 0, length, v8StringWriteOptions()); 400926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_position += size; 401926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 402926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeStringObject(const char* data, int length) 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(length >= 0); 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(StringObjectTag); 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteString(data, length); 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeWebCoreString(const String& string) 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Uses UTF8 encoding so we can read it back as either V8 or 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // WebCore string. 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(StringTag); 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteWebCoreString(string); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeVersion() 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(VersionTag); 4211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteUint32(SerializedScriptValue::wireFormatVersion); 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeInt32(int32_t value) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(Int32Tag); 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeUint32(uint32_t value) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(Uint32Tag); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(value); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeDate(double numberValue) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(DateTag); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteNumber(numberValue); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeNumber(double number) 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(NumberTag); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteNumber(number); 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeNumberObject(double number) 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(NumberObjectTag); 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteNumber(number); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) void writeBlob(const String& uuid, const String& type, unsigned long long size) 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(BlobTag); 4571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteWebCoreString(uuid); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteWebCoreString(type); 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint64(size); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch void writeBlobIndex(int blobIndex) 4636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 4646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(blobIndex >= 0); 4656f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch append(BlobIndexTag); 4666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch doWriteUint32(blobIndex); 4676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 4686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeDOMFileSystem(int type, const String& name, const String& url) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(DOMFileSystemTag); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(type); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteWebCoreString(name); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteWebCoreString(url); 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) void writeFile(const File& file) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(FileTag); 4801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteFile(file); 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4836f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch void writeFileIndex(int blobIndex) 4846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 4856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch append(FileIndexTag); 4866f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch doWriteUint32(blobIndex); 4876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 4886f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeFileList(const FileList& fileList) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(FileListTag); 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length = fileList.length(); 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(length); 4941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) for (unsigned i = 0; i < length; ++i) 4951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteFile(*fileList.item(i)); 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4986f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch void writeFileListIndex(const Vector<int>& blobIndices) 4996f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 5006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch append(FileListIndexTag); 5016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch uint32_t length = blobIndices.size(); 5026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch doWriteUint32(length); 5036f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch for (unsigned i = 0; i < length; ++i) 5046f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch doWriteUint32(blobIndices[i]); 5056f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 5066f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 50707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool writeCryptoKey(const blink::WebCryptoKey& key) 50807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 50907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch append(static_cast<uint8_t>(CryptoKeyTag)); 51007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 51107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (key.algorithm().paramsType()) { 51207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyAlgorithmParamsTypeAes: 51307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteAesKey(key); 51407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 51507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyAlgorithmParamsTypeHmac: 51607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteHmacKey(key); 51707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 51807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: 519d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) doWriteRsaHashedKey(key); 52007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 52107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyAlgorithmParamsTypeNone: 52207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT_NOT_REACHED(); 52307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 52407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 52507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 52607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteKeyUsages(key.usages(), key.extractable()); 52707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 52807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebVector<uint8_t> keyData; 52907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!blink::Platform::current()->crypto()->serializeKeyForClone(key, keyData)) 53007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 53107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 53207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(keyData.size()); 53307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch append(keyData.data(), keyData.size()); 53407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 53507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 53607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeArrayBuffer(const ArrayBuffer& arrayBuffer) 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ArrayBufferTag); 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteArrayBuffer(arrayBuffer); 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeArrayBufferView(const ArrayBufferView& arrayBufferView) 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ArrayBufferViewTag); 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byteOffset() == 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<const uint8_t*>(arrayBufferView.baseAddress())); 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 55109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ArrayBufferView::ViewType type = arrayBufferView.type(); 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == ArrayBufferView::TypeInt8) 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ByteArrayTag); 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeUint8Clamped) 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(UnsignedByteClampedArrayTag); 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeUint8) 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(UnsignedByteArrayTag); 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeInt16) 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ShortArrayTag); 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeUint16) 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(UnsignedShortArrayTag); 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeInt32) 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(IntArrayTag); 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeUint32) 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(UnsignedIntArrayTag); 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeFloat32) 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(FloatArrayTag); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeFloat64) 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(DoubleArrayTag); 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (type == ArrayBufferView::TypeDataView) 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(DataViewTag); 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(arrayBufferView.byteOffset()); 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(arrayBufferView.byteLength()); 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength) 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ImageDataTag); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(width); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(height); 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(pixelDataLength); 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(pixelData, pixelDataLength); 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(RegExpTag); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::String::Utf8Value patternUtf8Value(pattern); 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteString(*patternUtf8Value, patternUtf8Value.length()); 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(static_cast<uint32_t>(flags)); 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeTransferredMessagePort(uint32_t index) 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(MessagePortTag); 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(index); 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeTransferredArrayBuffer(uint32_t index) 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ArrayBufferTransferTag); 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(index); 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeObjectReference(uint32_t reference) 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ObjectReferenceTag); 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(reference); 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeObject(uint32_t numProperties) 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ObjectTag); 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(numProperties); 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeSparseArray(uint32_t numProperties, uint32_t length) 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(SparseArrayTag); 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(numProperties); 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(length); 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeDenseArray(uint32_t numProperties, uint32_t length) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(DenseArrayTag); 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(numProperties); 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(length); 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) String takeWireString() 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fillHole(); 6388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) String data = String(m_buffer.data(), m_buffer.size()); 6398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueType)); 6408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return data; 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeReferenceCount(uint32_t numberOfReferences) 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(ReferenceCountTag); 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(numberOfReferences); 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeGenerateFreshObject() 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(GenerateFreshObjectTag); 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeGenerateFreshSparseArray(uint32_t length) 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(GenerateFreshSparseArrayTag); 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(length); 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeGenerateFreshDenseArray(uint32_t length) 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(GenerateFreshDenseArrayTag); 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(length); 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 6671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) void doWriteFile(const File& file) 6681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) { 66909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); 67009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteWebCoreString(file.name()); 67109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteWebCoreString(file.webkitRelativePath()); 6721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteWebCoreString(file.uuid()); 6731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) doWriteWebCoreString(file.type()); 67409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 67509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME don't use 4 bytes to encode a flag. 67609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (file.hasValidSnapshotMetadata()) { 67709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteUint32(static_cast<uint8_t>(1)); 67809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 67909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) long long size; 68009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) double lastModified; 68109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) file.captureSnapshot(size, lastModified); 68209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteUint64(static_cast<uint64_t>(size)); 68309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) doWriteNumber(lastModified); 68409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 68509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) append(static_cast<uint8_t>(0)); 68609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 6871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 6881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteArrayBuffer(const ArrayBuffer& arrayBuffer) 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t byteLength = arrayBuffer.byteLength(); 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(byteLength); 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteString(const char* data, int length) 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUint32(static_cast<uint32_t>(length)); 6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(reinterpret_cast<const uint8_t*>(data), length); 7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteWebCoreString(const String& string) 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) StringUTF8Adaptor stringUTF8(string); 7055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) doWriteString(stringUTF8.data(), stringUTF8.length()); 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 70807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch void doWriteHmacKey(const blink::WebCryptoKey& key) 70907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 71007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeHmac); 71107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 71207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch append(static_cast<uint8_t>(HmacKeyTag)); 71307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8)); 71407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8); 71507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id()); 71607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 71707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 71807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch void doWriteAesKey(const blink::WebCryptoKey& key) 71907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 72007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeAes); 72107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 72207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch append(static_cast<uint8_t>(AesKeyTag)); 72307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteAlgorithmId(key.algorithm().id()); 72407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Converting the key length from bits to bytes is lossless and makes 72507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // it fit in 1 byte. 72607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8)); 72707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8); 72807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 72907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 730d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) void doWriteRsaHashedKey(const blink::WebCryptoKey& key) 73107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 732d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(key.algorithm().rsaHashedParams()); 733d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) append(static_cast<uint8_t>(RsaHashedKeyTag)); 73407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 73507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteAlgorithmId(key.algorithm().id()); 73607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 73707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (key.type()) { 73807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyTypePublic: 73907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(PublicKeyType); 74007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 74107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyTypePrivate: 74207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(PrivateKeyType); 74307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 74407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoKeyTypeSecret: 74507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT_NOT_REACHED(); 74607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 74707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 748d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const blink::WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHashedParams(); 74907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(params->modulusLengthBits()); 75007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(params->publicExponent().size()); 75107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch append(params->publicExponent().data(), params->publicExponent().size()); 752d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) doWriteAlgorithmId(key.algorithm().rsaHashedParams()->hash().id()); 75307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 75407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 75507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch void doWriteAlgorithmId(blink::WebCryptoAlgorithmId id) 75607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 75707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (id) { 75807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdAesCbc: 75907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(AesCbcTag); 76007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdHmac: 76107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(HmacTag); 76207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: 76307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(RsaSsaPkcs1v1_5Tag); 76407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdSha1: 76507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(Sha1Tag); 76607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdSha256: 76707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(Sha256Tag); 76807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdSha384: 76907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(Sha384Tag); 77007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdSha512: 77107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(Sha512Tag); 77207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdAesGcm: 77307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(AesGcmTag); 77407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdRsaOaep: 77507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(RsaOaepTag); 77607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdAesCtr: 77707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(AesCtrTag); 77807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case blink::WebCryptoAlgorithmIdAesKw: 77907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return doWriteUint32(AesKwTag); 78007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 78107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT_NOT_REACHED(); 78207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 78307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 78407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch void doWriteKeyUsages(const blink::WebCryptoKeyUsageMask usages, bool extractable) 78507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 78607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Reminder to update this when adding new key usages. 787f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); 78807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 78907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t value = 0; 79007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 79107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (extractable) 79207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= ExtractableUsage; 79307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 79407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageEncrypt) 79507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= EncryptUsage; 79607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageDecrypt) 79707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= DecryptUsage; 79807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageSign) 79907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= SignUsage; 80007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageVerify) 80107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= VerifyUsage; 80207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageDeriveKey) 80307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= DeriveKeyUsage; 80407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageWrapKey) 80507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= WrapKeyUsage; 80607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (usages & blink::WebCryptoKeyUsageUnwrapKey) 80707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch value |= UnwrapKeyUsage; 808f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (usages & blink::WebCryptoKeyUsageDeriveBits) 809f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu value |= DeriveBitsUsage; 81007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 81107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch doWriteUint32(value); 81207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 81307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 814926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int bytesNeededToWireEncode(uint32_t value) 815926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 816926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int bytes = 1; 817926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while (true) { 818926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) value >>= varIntShift; 819926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!value) 820926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 821926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ++bytes; 822926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 823926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 824926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return bytes; 825926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 826926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) template<class T> 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteUintHelper(T value) 8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (true) { 8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint8_t b = (value & varIntMask); 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value >>= varIntShift; 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!value) { 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(b); 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(b | (1 << varIntShift)); 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteUint32(uint32_t value) 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUintHelper(value); 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteUint64(uint64_t value) 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doWriteUintHelper(value); 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doWriteNumber(double number) 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); 8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void append(SerializationTag tag) 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) append(static_cast<uint8_t>(tag)); 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void append(uint8_t b) 8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureSpace(1); 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *byteAt(m_position++) = b; 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void append(const uint8_t* data, int length) 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ensureSpace(length); 8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(byteAt(m_position), data, length); 8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_position += length; 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) void ensureSpace(unsigned extra) 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 8778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1" to round up. 8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void fillHole() 8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the writer is at odd position in the buffer, then one of 8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the bytes in the last UChar is not initialized. 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position % 2) 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); 8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 889926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) uint8_t* byteAt(int position) 890926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 8918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; 892926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 893926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 894926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int v8StringWriteOptions() 895926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 896926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return v8::String::NO_NULL_TERMINATION; 897926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) Vector<BufferValueType> m_buffer; 9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned m_position; 9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 903d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 904926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 905926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!impl) 906926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return v8::Handle<v8::Object>(); 907d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); 908926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(wrapper->IsObject()); 909926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return wrapper.As<v8::Object>(); 910926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 911926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 912d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 913926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 914926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!impl) 915e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return v8::Handle<v8::ArrayBuffer>(); 916d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); 917e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(wrapper->IsArrayBuffer()); 918e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return wrapper.As<v8::ArrayBuffer>(); 919926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 920926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Serializer { 9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class StateBase; 9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) enum Status { 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Success, 9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputError, 9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DataCloneError, 92809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) JSException 9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 931d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, ScriptState* scriptState) 932d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) : m_scriptState(scriptState) 933d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_writer(writer) 9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_tryCatch(tryCatch) 9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_depth(0) 9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_status(Success) 9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_nextObjectReference(0) 9386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch , m_blobInfo(blobInfo) 9391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) , m_blobDataHandles(blobDataHandles) 9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!tryCatch.HasCaught()); 942d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); 9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (messagePorts) { 9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < messagePorts->size(); i++) 945d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i); 9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (arrayBuffers) { 9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < arrayBuffers->size(); i++) { 949d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), creationContext, isolate()); 9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Coalesce multiple occurences of the same buffer to the first index. 9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) 9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_transferredArrayBuffers.set(v8ArrayBuffer, i); 9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 957d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Isolate* isolate() { return m_scriptState->isolate(); } 958d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Status serialize(v8::Handle<v8::Value> value) 9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 961d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::HandleScope scope(isolate()); 9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeVersion(); 9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* state = doSerialize(value, 0); 9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (state) 9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = state->advance(*this); 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_status; 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 96909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String errorMessage() { return m_errorMessage; } 97009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Functions used by serialization states. 97251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next); 97351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 97451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBase* next) 97551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) { 976a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return doSerialize(arrayBuffer, next); 97751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* checkException(StateBase* state) 9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 98109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0; 9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeObject(uint32_t numProperties, StateBase* state) 9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeObject(numProperties); 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return pop(state); 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state) 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeSparseArray(numProperties, length); 9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return pop(state); 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeDenseArray(uint32_t numProperties, uint32_t length, StateBase* state) 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeDenseArray(numProperties, length); 9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return pop(state); 10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class StateBase { 10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WTF_MAKE_NONCOPYABLE(StateBase); 10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual ~StateBase() { } 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Link to the next state to form a stack. 10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* nextState() { return m_next; } 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Composite object we're processing in this state. 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> composite() { return m_composite; } 10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Serializes (a part of) the current composite and returns 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the next state to process or null when this is the final 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // state. 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual StateBase* advance(Serializer&) = 0; 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase(v8::Handle<v8::Value> composite, StateBase* next) 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_composite(composite) 10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_next(next) 10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> m_composite; 10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* m_next; 10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Dummy state that is used to signal serialization errors. 103309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) class ErrorState FINAL : public StateBase { 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorState() 10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : StateBase(v8Undefined(), 0) 10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 104009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* advance(Serializer&) OVERRIDE 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete this; 10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) template <typename T> 10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class State : public StateBase { 10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); } 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) State(v8::Handle<T> composite, StateBase* next) 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : StateBase(composite, next) 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class AbstractObjectState : public State<v8::Object> { 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next) 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : State<v8::Object>(object, next) 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_index(0) 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_numSerializedProperties(0) 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_nameDone(false) 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1072e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch StateBase* serializeProperties(bool ignoreIndexed, Serializer& serializer) 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (m_index < m_propertyNames->Length()) { 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_nameDone) { 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (propertyName.IsEmpty()) 108009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return serializer.handleError(InputError, "Empty property names cannot be cloned.", this); 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()); 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()); 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasStringProperty || (hasIndexedProperty && !ignoreIndexed)) 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_propertyName = propertyName; 10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_index; 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_propertyName.IsEmpty()); 10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_nameDone) { 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nameDone = true; 10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.doSerialize(m_propertyName, this)) 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> value = composite()->Get(m_propertyName); 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nameDone = false; 11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_propertyName.Clear(); 11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_index; 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_numSerializedProperties; 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we return early here, it's either because we have pushed a new state onto the 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // serialization state stack or because we have encountered an error (and in both cases 1109a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // we are unwinding the native stack). 11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.doSerialize(value, this)) 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return objectDone(m_numSerializedProperties, serializer); 11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Array> m_propertyNames; 11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> m_propertyName; 11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned m_index; 11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned m_numSerializedProperties; 11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_nameDone; 11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 112509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) class ObjectState FINAL : public AbstractObjectState { 11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectState(v8::Handle<v8::Object> object, StateBase* next) 11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AbstractObjectState(object, next) 11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 113209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* advance(Serializer& serializer) OVERRIDE 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_propertyNames.IsEmpty()) { 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_propertyNames = composite()->GetPropertyNames(); 11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_propertyNames.IsEmpty()) 113909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return serializer.handleError(InputError, "Empty property names cannot be cloned.", nextState()); 11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeProperties(false, serializer); 11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 114509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE 11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializer.writeObject(numProperties, this); 11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 115109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) class DenseArrayState FINAL : public AbstractObjectState { 11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 11539bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate) 11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AbstractObjectState(array, next) 11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_arrayIndex(0) 11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_arrayLength(array->Length()) 11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11589bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); 11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 116109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* advance(Serializer& serializer) OVERRIDE 11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (m_arrayIndex < m_arrayLength) { 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIndex); 11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_arrayIndex++; 11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.checkException(this)) 11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = serializer.doSerialize(value, this)) 11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeProperties(true, serializer); 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 117509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializer.writeDenseArray(numProperties, m_arrayLength, this); 11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t m_arrayIndex; 11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t m_arrayLength; 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 118509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) class SparseArrayState FINAL : public AbstractObjectState { 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 11879bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate) 11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AbstractObjectState(array, next) 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11909bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); 11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 119309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* advance(Serializer& serializer) OVERRIDE 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeProperties(false, serializer); 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected: 119909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this); 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* push(StateBase* state) 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(state); 12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_depth; 120909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return checkComposite(state) ? state : handleError(InputError, "Value being cloned is either cyclic or too deeply nested.", state); 12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* pop(StateBase* state) 12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(state); 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_depth; 12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* next = state->nextState(); 12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete state; 12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return next; 12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 122109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) StateBase* handleError(Status errorStatus, const String& message, StateBase* state) 12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(errorStatus != Success); 12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_status = errorStatus; 122509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_errorMessage = message; 12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (state) { 12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* tmp = state->nextState(); 12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete state; 12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = tmp; 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return new ErrorState; 12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool checkComposite(StateBase* top) 12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(top); 12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_depth > maxDepth) 12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!shouldCheckForCycles(m_depth)) 12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> composite = top->composite(); 12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (StateBase* state = top->nextState(); state; state = state->nextState()) { 12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state->composite() == composite) 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeString(v8::Handle<v8::Value> value) 12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::String> string = value.As<v8::String>(); 1252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!string->Length() || string->IsOneByte()) 1253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_writer.writeOneByteString(string); 1254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 1255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_writer.writeUCharString(string); 12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeStringObject(v8::Handle<v8::Value> value) 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>(); 1261a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) v8::String::Utf8Value stringValue(stringObject->ValueOf()); 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeStringObject(*stringValue, stringValue.length()); 12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeNumberObject(v8::Handle<v8::Value> value) 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); 1268a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_writer.writeNumberObject(numberObject->ValueOf()); 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeBooleanObject(v8::Handle<v8::Value> value) 12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); 1274a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_writer.writeBooleanObject(booleanObject->ValueOf()); 12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1277d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) StateBase* writeBlob(v8::Handle<v8::Value> value, StateBase* next) 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Blob* blob = V8Blob::toNative(value.As<v8::Object>()); 12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!blob) 1281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return 0; 1282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (blob->hasBeenClosed()) 1283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return handleError(DataCloneError, "A Blob object has been closed, and could therefore not be cloned.", next); 12846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch int blobIndex = -1; 1285c4de9692585dd12fa75b760eebef04fa43fc1ae6Bo Liu m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); 12866f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) 12876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeBlobIndex(blobIndex); 12886f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch else 12896f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); 1290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return 0; 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next) 12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>()); 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!fs) 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!fs->clonable()) 129909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "A FileSystem object could not be cloned.", next); 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string()); 13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 13025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) StateBase* writeFile(v8::Handle<v8::Value> value, StateBase* next) 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) File* file = V8File::toNative(value.As<v8::Object>()); 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!file) 1308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return 0; 1309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (file->hasBeenClosed()) 1310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next); 13116f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch int blobIndex = -1; 1312c4de9692585dd12fa75b760eebef04fa43fc1ae6Bo Liu m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); 131376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) if (appendFileInfo(file, &blobIndex)) { 13146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(blobIndex >= 0); 13156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeFileIndex(blobIndex); 13166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } else { 13176f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeFile(*file); 13186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 1319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return 0; 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch StateBase* writeFileList(v8::Handle<v8::Value> value, StateBase* next) 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FileList* fileList = V8FileList::toNative(value.As<v8::Object>()); 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!fileList) 13266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return 0; 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = fileList->length(); 13286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch Vector<int> blobIndices; 13296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch for (unsigned i = 0; i < length; ++i) { 13306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch int blobIndex = -1; 13316f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch const File* file = fileList->item(i); 13326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (file->hasBeenClosed()) 13336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next); 1334c4de9692585dd12fa75b760eebef04fa43fc1ae6Bo Liu m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); 133576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) if (appendFileInfo(file, &blobIndex)) { 13366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!i || blobIndex > 0); 13376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(blobIndex >= 0); 13386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch blobIndices.append(blobIndex); 13396f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 13406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 13416f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!blobIndices.isEmpty()) 13426f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeFileListIndex(blobIndices); 13436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch else 13446f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_writer.writeFileList(*fileList); 13456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return 0; 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 134807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool writeCryptoKey(v8::Handle<v8::Value> value) 134907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 135007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Key* key = V8Key::toNative(value.As<v8::Object>()); 135107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!key) 1352323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return false; 135307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return m_writer.writeCryptoKey(key->key()); 135407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 135507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeImageData(v8::Handle<v8::Value> value) 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>()); 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!imageData) 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Uint8ClampedArray* pixelArray = imageData->data(); 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length()); 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void writeRegExp(v8::Handle<v8::Value> value) 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); 13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object> object, StateBase* next) 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!object.IsEmpty()); 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object); 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBufferView) 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBufferView->buffer()) 137809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next); 1379d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_scriptState->context()->Global(), isolate()); 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (underlyingBuffer.IsEmpty()) 138109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next); 138251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stateOut) 138451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return stateOut; 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeArrayBufferView(*arrayBufferView); 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This should be safe: we serialize something that we know to be a wrapper (see 138751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // the toV8 call above), so the call to doSerializeArrayBuffer should neither 138851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // cause the system stack to overflow nor should it have potential to reach 138951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // this ArrayBufferView again. 139051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // 139151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // We do need to grey the underlying buffer before we grey its view, however; 139251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // ArrayBuffers may be shared, so they need to be given reference IDs, and an 139351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer 13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (or without an additional tag that would allow us to do two-stage construction 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // like we do for Objects and Arrays). 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) greyObject(object); 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) 14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>()); 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBuffer) 14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (arrayBuffer->isNeutered()) 140609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeArrayBuffer(*arrayBuffer); 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value> value, uint32_t index, StateBase* next) 14135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>()); 14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBuffer) 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (arrayBuffer->isNeutered()) 141809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); 14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeTransferredArrayBuffer(index); 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1423e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount) 14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Let K be the cost of serializing all property values that are there 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t key) 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for all properties that are not there) 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // so densely is better than sparsly whenever 6*propertyCount > length 14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 6 * propertyCount >= length; 14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* startArrayState(v8::Handle<v8::Array> array, StateBase* next) 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Array> propertyNames = array->GetPropertyNames(); 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (StateBase* newState = checkException(next)) 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newState; 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length = array->Length(); 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shouldSerializeDensely(length, propertyNames->Length())) { 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeGenerateFreshDenseArray(length); 1441d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return push(new DenseArrayState(array, propertyNames, next, isolate())); 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeGenerateFreshSparseArray(length); 1445d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return push(new SparseArrayState(array, propertyNames, next, isolate())); 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StateBase* startObjectState(v8::Handle<v8::Object> object, StateBase* next) 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeGenerateFreshObject(); 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: check not a wrapper 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return push(new ObjectState(object, next)); 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Marks object as having been visited by the serializer and assigns it a unique object reference ID. 14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // An object may only be greyed once. 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void greyObject(const v8::Handle<v8::Object>& object) 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_objectPool.contains(object)); 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t objectReference = m_nextObjectReference++; 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_objectPool.set(object, objectReference); 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch bool appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index) 14656f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 14666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!m_blobInfo) 14676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 14686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch *index = m_blobInfo->size(); 14696f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_blobInfo->append(blink::WebBlobInfo(uuid, type, size)); 14706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return true; 14716f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 14726f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 147376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) bool appendFileInfo(const File* file, int* index) 14746f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 14756f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!m_blobInfo) 14766f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 147776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) 147876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) long long size = -1; 147976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) double lastModified = invalidFileTime(); 148076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) file->captureSnapshot(size, lastModified); 14816f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch *index = m_blobInfo->size(); 148276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) m_blobInfo->append(blink::WebBlobInfo(file->uuid(), file->path(), file->name(), file->type(), lastModified, size)); 14836f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return true; 14846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 14856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1486d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtr<ScriptState> m_scriptState; 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Writer& m_writer; 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::TryCatch& m_tryCatch; 14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_depth; 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Status m_status; 149109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String m_errorMessage; 14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectPool m_objectPool; 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectPool m_transferredMessagePorts; 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjectPool m_transferredArrayBuffers; 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t m_nextObjectReference; 14976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch WebBlobInfoArray* m_blobInfo; 14981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) BlobDataHandleMap& m_blobDataHandles; 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 150109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Returns true if the provided object is to be considered a 'host object', as used in the 150209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// HTML5 structured clone algorithm. 150309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static bool isHostObject(v8::Handle<v8::Object> object) 150409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 150509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If the object has any internal fields, then we won't be able to serialize or deserialize 150609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // them; conveniently, this is also a quick way to detect DOM wrapper objects, because 150709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // the mechanism for these relies on data stored in these fields. We should 150809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // catch external array data as a special case. 150909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData(); 151009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 151109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1512a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next) 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeReferenceCount(m_nextObjectReference); 15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t objectReference; 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t arrayBufferIndex; 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((value->IsObject() || value->IsDate() || value->IsRegExp()) 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note that IsObject() also detects wrappers (eg, it will catch the things 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that we grey and write below). 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!value->IsString()); 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeObjectReference(objectReference); 152309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else if (value.IsEmpty()) { 152409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(InputError, "The empty property name cannot be cloned.", next); 152509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else if (value->IsUndefined()) 15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeUndefined(); 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsNull()) 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeNull(); 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsTrue()) 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeTrue(); 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsFalse()) 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeFalse(); 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsInt32()) 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeInt32(value->Int32Value()); 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsUint32()) 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeUint32(value->Uint32Value()); 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsNumber()) 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeNumber(value.As<v8::Number>()->Value()); 1539d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8ArrayBufferView::hasInstance(value, isolate())) 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsString()) 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeString(value); 1543d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8MessagePort::hasInstance(value, isolate())) { 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t messagePortIndex; 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePortIndex)) 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeTransferredMessagePort(messagePortIndex); 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 154809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "A MessagePort could not be cloned.", next); 1549d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return writeTransferredArrayBuffer(value, arrayBufferIndex, next); 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Object> jsObject = value.As<v8::Object>(); 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (jsObject.IsEmpty()) 155409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An object could not be cloned.", next); 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) greyObject(jsObject); 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value->IsDate()) 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_writer.writeDate(value->NumberValue()); 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsStringObject()) 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeStringObject(value); 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsNumberObject()) 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeNumberObject(value); 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsBooleanObject()) 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeBooleanObject(value); 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsArray()) { 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return startArrayState(value.As<v8::Array>(), next); 1566d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else if (V8File::hasInstance(value, isolate())) 1567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return writeFile(value, next); 1568d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8Blob::hasInstance(value, isolate())) 1569d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return writeBlob(value, next); 1570d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8DOMFileSystem::hasInstance(value, isolate())) 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return writeDOMFileSystem(value, next); 1572d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8FileList::hasInstance(value, isolate())) 15736f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return writeFileList(value, next); 1574d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8Key::hasInstance(value, isolate())) { 157507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!writeCryptoKey(value)) 157607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return handleError(DataCloneError, "Couldn't serialize key data", next); 1577d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else if (V8ImageData::hasInstance(value, isolate())) 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeImageData(value); 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsRegExp()) 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeRegExp(value); 1581d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else if (V8ArrayBuffer::hasInstance(value, isolate())) 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return writeArrayBuffer(value, next); 15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (value->IsObject()) { 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNativeError()) 158509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "An object could not be cloned.", next); 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return startObjectState(jsObject, next); 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 158809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return handleError(DataCloneError, "A value could not be cloned.", next); 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Interface used by Reader to create objects of composite types. 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class CompositeCreator { 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual ~CompositeCreator() { } 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual uint32_t objectReferenceCount() = 0; 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) = 0; 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) = 0; 16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>*) = 0; 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool newSparseArray(uint32_t length) = 0; 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool newDenseArray(uint32_t length) = 0; 16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool newObject() = 0; 16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0; 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0; 16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0; 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Reader is responsible for deserializing primitive types and 16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// restoring information about saved objects of composite types. 16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Reader { 16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1616d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Reader(const uint8_t* buffer, int length, const WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, ScriptState* scriptState) 1617d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) : m_scriptState(scriptState) 1618d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_buffer(buffer) 16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_length(length) 16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_position(0) 16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_version(0) 16226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch , m_blobInfo(blobInfo) 16231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) , m_blobDataHandles(blobDataHandles) 16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!(reinterpret_cast<size_t>(buffer) & 1)); 16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(length >= 0); 16275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isEof() const { return m_position >= m_length; } 16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1631d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ScriptState* scriptState() const { return m_scriptState.get(); } 1632d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1633d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)private: 1634d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Isolate* isolate() const { return m_scriptState->isolate(); } 1635a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1636d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)public: 16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator) 16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SerializationTag tag; 16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readTag(&tag)) 16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (tag) { 16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ReferenceCountTag: { 164410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t referenceTableSize; 16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&referenceTableSize)) 16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this test fails, then the serializer and deserializer disagree about the assignment 16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of object reference IDs. On the deserialization side, this means there are too many or too few 16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // calls to pushObjectReference. 16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (referenceTableSize != creator.objectReferenceCount()) 16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case InvalidTag: 16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PaddingTag: 16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UndefinedTag: 1661d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::Undefined(isolate()); 16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NullTag: 1664d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::Null(isolate()); 16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TrueTag: 1667d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8Boolean(true, isolate()); 16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FalseTag: 1670d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8Boolean(false, isolate()); 16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TrueObjectTag: 16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = v8::BooleanObject::New(true); 16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FalseObjectTag: 16775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = v8::BooleanObject::New(false); 16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case StringTag: 16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readString(value)) 16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1684926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case StringUCharTag: 1685926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!readUCharString(value)) 1686926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1687926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case StringObjectTag: 16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readStringObject(value)) 16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 16925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Int32Tag: 16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readInt32(value)) 16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Uint32Tag: 16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readUint32(value)) 16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DateTag: 17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readDate(value)) 17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NumberTag: 17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readNumber(value)) 17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NumberObjectTag: 17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readNumberObject(value)) 17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BlobTag: 17166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch case BlobIndexTag: 17176f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!readBlob(value, tag == BlobIndexTag)) 17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FileTag: 17226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch case FileIndexTag: 17236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!readFile(value, tag == FileIndexTag)) 17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DOMFileSystemTag: 17285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readDOMFileSystem(value)) 17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FileListTag: 17336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch case FileListIndexTag: 17346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!readFileList(value, tag == FileListIndexTag)) 17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 173807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case CryptoKeyTag: 173907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!readCryptoKey(value)) 174007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 174107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch creator.pushObjectReference(*value); 174207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ImageDataTag: 17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readImageData(value)) 17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case RegExpTag: 17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readRegExp(value)) 17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ObjectTag: { 17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t numProperties; 17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&numProperties)) 17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.completeObject(numProperties, value)) 17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SparseArrayTag: { 17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t numProperties; 17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&numProperties)) 17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 17685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.completeSparseArray(numProperties, length, value)) 17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DenseArrayTag: { 17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t numProperties; 17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&numProperties)) 17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.completeDenseArray(numProperties, length, value)) 17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ArrayBufferViewTag: { 178510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readArrayBufferView(value, creator)) 17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ArrayBufferTag: { 179310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readArrayBuffer(value)) 17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) creator.pushObjectReference(*value); 17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GenerateFreshObjectTag: { 180110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.newObject()) 18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GenerateFreshSparseArrayTag: { 180810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 18115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.newSparseArray(length)) 18145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GenerateFreshDenseArrayTag: { 181810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 18215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.newDenseArray(length)) 18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MessagePortTag: { 182810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t index; 18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&index)) 18325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.tryGetTransferredMessagePort(index, value)) 18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 18365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ArrayBufferTransferTag: { 183810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t index; 18415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&index)) 18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.tryGetTransferredArrayBuffer(index, value)) 18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ObjectReferenceTag: { 184810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!m_version) 18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t reference; 18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&reference)) 18525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.tryGetObjectFromObjectReference(reference, value)) 18545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 18565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 18585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !value->IsEmpty(); 18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readVersion(uint32_t& version) 18645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 18655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SerializationTag tag; 18665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readTag(&tag)) { 18675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is a nullary buffer. We're still version 0. 18685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) version = 0; 18695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tag != VersionTag) { 18725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Versions of the format past 0 start with the version tag. 18735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) version = 0; 18745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Put back the tag. 18755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) undoReadTag(); 18765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Version-bearing messages are obligated to finish the version tag. 18795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return doReadUint32(&version); 18805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setVersion(uint32_t version) 18835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 18845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_version = version; 18855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 18885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readTag(SerializationTag* tag) 18895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 18905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position >= m_length) 18915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 18925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *tag = static_cast<SerializationTag>(m_buffer[m_position++]); 18935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 18945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void undoReadTag() 18975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 18985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position > 0) 18995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_position; 19005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag) 19035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position >= m_length) 19055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]); 19075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readString(v8::Handle<v8::Value>* value) 19115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 19135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 19145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position + length > m_length) 19165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1917d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_buffer + m_position), v8::String::kNormalString, length); 19185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_position += length; 19195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1922926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool readUCharString(v8::Handle<v8::Value>* value) 1923926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 1924926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) uint32_t length; 1925926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!doReadUint32(&length) || (length & 1)) 1926926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1927926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_position + length > m_length) 1928926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1929926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!(m_position & 1)); 1930d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar)); 1931926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_position += length; 1932926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1933926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1934926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 19355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readStringObject(v8::Handle<v8::Value>* value) 19365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> stringValue; 19385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readString(&stringValue) || !stringValue->IsString()) 19395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = v8::StringObject::New(stringValue.As<v8::String>()); 19415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readWebCoreString(String* string) 19455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 19475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 19485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position + length > m_length) 19505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length); 19525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_position += length; 19535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readInt32(v8::Handle<v8::Value>* value) 19575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t rawValue; 19595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&rawValue)) 19605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1961d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(rawValue))); 19625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readUint32(v8::Handle<v8::Value>* value) 19665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t rawValue; 19685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&rawValue)) 19695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1970d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::Integer::NewFromUnsigned(isolate(), rawValue); 19715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readDate(v8::Handle<v8::Value>* value) 19755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double numberValue; 19775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadNumber(&numberValue)) 19785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1979d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8DateOrNaN(numberValue, isolate()); 19805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readNumber(v8::Handle<v8::Value>* value) 19845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double number; 19865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadNumber(&number)) 19875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1988d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::Number::New(isolate(), number); 19895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1991e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 19925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readNumberObject(v8::Handle<v8::Value>* value) 19935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 19945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double number; 19955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadNumber(&number)) 19965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1997d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = v8::NumberObject::New(isolate(), number); 19985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 19995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readImageData(v8::Handle<v8::Value>* value) 20025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 20035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t width; 20045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t height; 20055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t pixelDataLength; 20065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&width)) 20075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&height)) 20095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&pixelDataLength)) 20115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position + pixelDataLength > m_length) 20135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2014aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); 20155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Uint8ClampedArray* pixelArray = imageData->data(); 20165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(pixelArray); 20175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(pixelArray->length() >= pixelDataLength); 20185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); 20195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_position += pixelDataLength; 2020d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(imageData.release(), m_scriptState->context()->Global(), isolate()); 20215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 20225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PassRefPtr<ArrayBuffer> doReadArrayBuffer() 20255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 20265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t byteLength; 20275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&byteLength)) 2028d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 20295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position + byteLength > m_length) 2030d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 20315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const void* bufferStart = m_buffer + m_position; 20325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(bufferStart, byteLength); 203351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) arrayBuffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate()); 20345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_position += byteLength; 20355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return arrayBuffer.release(); 20365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readArrayBuffer(v8::Handle<v8::Value>* value) 20395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 20405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer(); 20415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBuffer) 20425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2043d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), isolate()); 20445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 20455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator) 20485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 20495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferViewSubTag subTag; 20505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t byteOffset; 20515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t byteLength; 20525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<ArrayBuffer> arrayBuffer; 20535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> arrayBufferV8Value; 20545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readArrayBufferViewSubTag(&subTag)) 20555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&byteOffset)) 20575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&byteLength)) 20595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!creator.consumeTopOfStack(&arrayBufferV8Value)) 20615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2062e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (arrayBufferV8Value.IsEmpty()) 20635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>()); 20655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!arrayBuffer) 20665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2067d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 2068d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); 20695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (subTag) { 20705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ByteArrayTag: 2071d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate()); 20725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UnsignedByteArrayTag: 2074d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate()); 20755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UnsignedByteClampedArrayTag: 2077d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Uint8ClampedArray::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate()); 20785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ShortArrayTag: { 20805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t shortLength = byteLength / sizeof(int16_t); 20815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shortLength * sizeof(int16_t) != byteLength) 20825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2083d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength), creationContext, isolate()); 20845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UnsignedShortArrayTag: { 20875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t shortLength = byteLength / sizeof(uint16_t); 20885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shortLength * sizeof(uint16_t) != byteLength) 20895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2090d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength), creationContext, isolate()); 20915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case IntArrayTag: { 20945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t intLength = byteLength / sizeof(int32_t); 20955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (intLength * sizeof(int32_t) != byteLength) 20965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2097d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength), creationContext, isolate()); 20985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 20995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case UnsignedIntArrayTag: { 21015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t intLength = byteLength / sizeof(uint32_t); 21025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (intLength * sizeof(uint32_t) != byteLength) 21035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength), creationContext, isolate()); 21055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 21065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FloatArrayTag: { 21085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t floatLength = byteLength / sizeof(float); 21095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (floatLength * sizeof(float) != byteLength) 21105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2111d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate()); 21125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 21135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DoubleArrayTag: { 21155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t floatLength = byteLength / sizeof(double); 21165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (floatLength * sizeof(double) != byteLength) 21175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2118d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate()); 21195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 21205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DataViewTag: 2122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate()); 21235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 21245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 21255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The various *Array::create() methods will return null if the range the view expects is 21285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // mismatched with the range the buffer can provide or if the byte offset is not aligned 21295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to the size of the element type. 21305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !value->IsEmpty(); 21315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readRegExp(v8::Handle<v8::Value>* value) 21345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 21355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> pattern; 21365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readString(&pattern)) 21375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t flags; 21395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&flags)) 21405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags)); 21425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 21435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch bool readBlob(v8::Handle<v8::Value>* value, bool isIndexed) 21465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 21471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_version < 3) 21481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return false; 21496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch RefPtrWillBeRawPtr<Blob> blob; 21506f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (isIndexed) { 21516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_version < 6) 21526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21536f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(m_blobInfo); 21546f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch uint32_t index; 21556f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!doReadUint32(&index) || index >= m_blobInfo->size()) 21566f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21576f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch const blink::WebBlobInfo& info = (*m_blobInfo)[index]; 21586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch blob = Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size())); 21596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } else { 21606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!m_blobInfo); 21616f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch String uuid; 21626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch String type; 21636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch uint64_t size; 21646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!m_blobInfo); 21656f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!readWebCoreString(&uuid)) 21666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!readWebCoreString(&type)) 21686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21696f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!doReadUint64(&size)) 21706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21716f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); 21726f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 2173d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(blob.release(), m_scriptState->context()->Global(), isolate()); 21745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 21755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool readDOMFileSystem(v8::Handle<v8::Value>* value) 21785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 21795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t type; 21805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String name; 21815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String url; 21825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&type)) 21835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readWebCoreString(&name)) 21855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!readWebCoreString(&url)) 21875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 21885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) DOMFileSystem* fs = DOMFileSystem::create(m_scriptState->executionContext(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, url)); 21895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) *value = toV8(fs, m_scriptState->context()->Global(), isolate()); 21905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 21915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 21925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21936f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch bool readFile(v8::Handle<v8::Value>* value, bool isIndexed) 21945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 21956f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch RefPtrWillBeRawPtr<File> file; 21966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (isIndexed) { 21976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_version < 6) 21986f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 21996f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch file = readFileIndexHelper(); 22006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } else { 22016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch file = readFileHelper(); 22026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 22031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!file) 22045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2205d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(file.release(), m_scriptState->context()->Global(), isolate()); 22065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 22075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 22085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 22096f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch bool readFileList(v8::Handle<v8::Value>* value, bool isIndexed) 22105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 22111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_version < 3) 22121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return false; 22135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t length; 22145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doReadUint32(&length)) 22155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtrWillBeRawPtr<FileList> fileList = FileList::create(); 22175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 22186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch RefPtrWillBeRawPtr<File> file; 22196f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (isIndexed) { 22206f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_version < 6) 22216f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return false; 22226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch file = readFileIndexHelper(); 22236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } else { 22246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch file = readFileHelper(); 22256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 22261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!file) 22275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 22281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) fileList->append(file.release()); 22295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2230d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(fileList.release(), m_scriptState->context()->Global(), isolate()); 22315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 22325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 22335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 223407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool readCryptoKey(v8::Handle<v8::Value>* value) 223507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 223607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t rawKeyType; 223707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&rawKeyType)) 223807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 223907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 224007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoKeyAlgorithm algorithm; 2241d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) blink::WebCryptoKeyType type = blink::WebCryptoKeyTypeSecret; 224207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 224307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (static_cast<CryptoKeySubTag>(rawKeyType)) { 224407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case AesKeyTag: 224507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadAesKey(algorithm, type)) 224607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 224707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 224807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case HmacKeyTag: 224907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadHmacKey(algorithm, type)) 225007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 225107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 225207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case RsaHashedKeyTag: 2253d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!doReadRsaHashedKey(algorithm, type)) 225407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 225507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 225607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch default: 225707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 225807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 225907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 226007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoKeyUsageMask usages; 226107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool extractable; 226207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadKeyUsages(usages, extractable)) 226307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 226407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 226507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t keyDataLength; 226607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&keyDataLength)) 226707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 226807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 226907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (m_position + keyDataLength > m_length) 227007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 227107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 227207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch const uint8_t* keyData = m_buffer + m_position; 227307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_position += keyDataLength; 227407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 227507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); 227607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!blink::Platform::current()->crypto()->deserializeKeyForClone( 227707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch algorithm, type, extractable, usages, keyData, keyDataLength, key)) { 227807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 227907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 228007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2281d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *value = toV8(Key::create(key), m_scriptState->context()->Global(), isolate()); 228207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 228307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 228407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 22856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch PassRefPtrWillBeRawPtr<File> readFileHelper() 22861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) { 22871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_version < 3) 2288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 22896f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!m_blobInfo); 22901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) String path; 229109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String name; 229209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String relativePath; 22931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) String uuid; 22941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) String type; 229509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) uint32_t hasSnapshot = 0; 229609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) uint64_t size = 0; 229709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) double lastModified = 0; 22981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!readWebCoreString(&path)) 2299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 230009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_version >= 4 && !readWebCoreString(&name)) 2301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 230209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_version >= 4 && !readWebCoreString(&relativePath)) 2303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 23041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!readWebCoreString(&uuid)) 2305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 23061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!readWebCoreString(&type)) 2307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 230809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_version >= 4 && !doReadUint32(&hasSnapshot)) 2309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 231009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (hasSnapshot) { 231109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!doReadUint64(&size)) 2312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 231309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!doReadNumber(&lastModified)) 2314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 231509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 231609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return File::create(path, name, relativePath, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type)); 23171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 23181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 23196f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch PassRefPtrWillBeRawPtr<File> readFileIndexHelper() 23206f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 23216f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_version < 3) 23226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return nullptr; 23236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(m_blobInfo); 23246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch uint32_t index; 23256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!doReadUint32(&index) || index >= m_blobInfo->size()) 23266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return nullptr; 23276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch const blink::WebBlobInfo& info = (*m_blobInfo)[index]; 23286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return File::create(info.filePath(), info.fileName(), info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size())); 23296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 23306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 23315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) template<class T> 23325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool doReadUintHelper(T* value) 23335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 23345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = 0; 23355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint8_t currentByte; 23365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int shift = 0; 23375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) do { 23385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position >= m_length) 23395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 23405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentByte = m_buffer[m_position++]; 23415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value |= ((currentByte & varIntMask) << shift); 23425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shift += varIntShift; 23435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } while (currentByte & (1 << varIntShift)); 23445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 23455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 23465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool doReadUint32(uint32_t* value) 23485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 23495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return doReadUintHelper(value); 23505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 23515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool doReadUint64(uint64_t* value) 23535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 23545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return doReadUintHelper(value); 23555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 23565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool doReadNumber(double* number) 23585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 23595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_position + sizeof(double) > m_length) 23605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 23615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); 23625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < sizeof(double); ++i) 23635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) numberAsByteArray[i] = m_buffer[m_position++]; 23645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 23655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 23665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size = -1) 23681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) { 23691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // The containing ssv may have a BDH for this uuid if this ssv is just being 23701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // passed from main to worker thread (for example). We use those values when creating 23711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // the new blob instead of cons'ing up a new BDH. 23721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // 23731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // FIXME: Maybe we should require that it work that way where the ssv must have a BDH for any 23741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // blobs it comes across during deserialization. Would require callers to explicitly populate 23751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // the collection of BDH's for blobs to work, which would encourage lifetimes to be considered 23761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // when passing ssv's around cross process. At present, we get 'lucky' in some cases because 23771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // the blob in the src process happens to still exist at the time the dest process is deserializing. 23786f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // For example in sharedWorker.postMessage(...). 23791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); 23801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (it != m_blobDataHandles.end()) { 23811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // make assertions about type and size? 23821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return it->value; 23831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 23841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return BlobDataHandle::create(uuid, type, size); 23851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 23861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 238707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool doReadHmacKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type) 238807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 238907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t lengthBytes; 239007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&lengthBytes)) 239107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 239207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoAlgorithmId hash; 239307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadAlgorithmId(hash)) 239407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 239507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch algorithm = blink::WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8); 239607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch type = blink::WebCryptoKeyTypeSecret; 239707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return !algorithm.isNull(); 239807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 239907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 240007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool doReadAesKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type) 240107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 240207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoAlgorithmId id; 240307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadAlgorithmId(id)) 240407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 240507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t lengthBytes; 240607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&lengthBytes)) 240707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 240807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch algorithm = blink::WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8); 240907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch type = blink::WebCryptoKeyTypeSecret; 241007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return !algorithm.isNull(); 241107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 241207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2413d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) bool doReadRsaHashedKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type) 241407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 241507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch blink::WebCryptoAlgorithmId id; 241607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadAlgorithmId(id)) 241707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 241807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 241907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t rawType; 242007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&rawType)) 242107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 242207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 242307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (static_cast<AssymetricCryptoKeyType>(rawType)) { 242407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case PublicKeyType: 242507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch type = blink::WebCryptoKeyTypePublic; 242607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 242707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case PrivateKeyType: 242807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch type = blink::WebCryptoKeyTypePrivate; 242907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 243007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch default: 243107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 243207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 243307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 243407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t modulusLengthBits; 243507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&modulusLengthBits)) 243607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 243707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 243807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t publicExponentSize; 243907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&publicExponentSize)) 244007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 244107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 244207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (m_position + publicExponentSize > m_length) 244307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 244407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 244507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch const uint8_t* publicExponent = m_buffer + m_position; 244607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_position += publicExponentSize; 244707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2448d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) blink::WebCryptoAlgorithmId hash; 2449d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!doReadAlgorithmId(hash)) 2450d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return false; 2451d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, publicExponent, publicExponentSize, hash); 245207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 245307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return !algorithm.isNull(); 245407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 245507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 245607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool doReadAlgorithmId(blink::WebCryptoAlgorithmId& id) 245707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 245807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t rawId; 245907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&rawId)) 246007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 246107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 246207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) { 246307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case AesCbcTag: 246407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdAesCbc; 246507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 246607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case HmacTag: 246707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdHmac; 246807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 246907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case RsaSsaPkcs1v1_5Tag: 247007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; 247107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 247207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case Sha1Tag: 247307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdSha1; 247407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 247507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case Sha256Tag: 247607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdSha256; 247707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 247807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case Sha384Tag: 247907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdSha384; 248007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 248107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case Sha512Tag: 248207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdSha512; 248307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 248407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case AesGcmTag: 248507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdAesGcm; 248607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 248707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case RsaOaepTag: 248807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdRsaOaep; 248907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 249007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case AesCtrTag: 249107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdAesCtr; 249207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 249307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case AesKwTag: 249407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch id = blink::WebCryptoAlgorithmIdAesKw; 249507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 249607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 249707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 249807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 249907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 250007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 250107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool doReadKeyUsages(blink::WebCryptoKeyUsageMask& usages, bool& extractable) 250207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 250307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Reminder to update this when adding new key usages. 2504f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); 2505f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | DecryptUsage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage; 250607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 250707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch uint32_t rawUsages; 250807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!doReadUint32(&rawUsages)) 250907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 251007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 251107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Make sure it doesn't contain an unrecognized usage value. 251207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & ~allPossibleUsages) 251307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 251407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 251507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages = 0; 251607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 251707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch extractable = rawUsages & ExtractableUsage; 251807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 251907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & EncryptUsage) 252007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageEncrypt; 252107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & DecryptUsage) 252207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageDecrypt; 252307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & SignUsage) 252407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageSign; 252507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & VerifyUsage) 252607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageVerify; 252707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & DeriveKeyUsage) 252807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageDeriveKey; 252907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & WrapKeyUsage) 253007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageWrapKey; 253107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (rawUsages & UnwrapKeyUsage) 253207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch usages |= blink::WebCryptoKeyUsageUnwrapKey; 2533f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (rawUsages & DeriveBitsUsage) 2534f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu usages |= blink::WebCryptoKeyUsageDeriveBits; 253507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 253607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return true; 253707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 253807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2539d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtr<ScriptState> m_scriptState; 25405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const uint8_t* m_buffer; 25415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const unsigned m_length; 25425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned m_position; 25435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t m_version; 25446f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch const WebBlobInfoArray* m_blobInfo; 25451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const BlobDataHandleMap& m_blobDataHandles; 25465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 25475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; 25505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class Deserializer FINAL : public CompositeCreator { 25525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 2553926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents) 25545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_reader(reader) 25555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_transferredMessagePorts(messagePorts) 25565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_arrayBufferContents(arrayBufferContents) 25575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) 25585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_version(0) 25595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 25605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> deserialize() 25635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2564d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Isolate* isolate = m_reader.scriptState()->isolate(); 25651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::wireFormatVersion) 2566d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return v8::Null(isolate); 25675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader.setVersion(m_version); 2568d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::EscapableHandleScope scope(isolate); 25695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (!m_reader.isEof()) { 25705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!doDeserialize()) 2571d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return v8::Null(isolate); 25725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stackDepth() != 1 || m_openCompositeReferenceStack.size()) 2574d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return v8::Null(isolate); 2575a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) v8::Handle<v8::Value> result = scope.Escape(element(0)); 25765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 25775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 257909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool newSparseArray(uint32_t) OVERRIDE 25805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2581d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(), 0); 25825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) openComposite(array); 25835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 25845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 258609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool newDenseArray(uint32_t length) OVERRIDE 25875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2588d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(), length); 25895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) openComposite(array); 25905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 25915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 259309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object) OVERRIDE 25945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 25955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stackDepth() < 1) 25965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 25975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *object = element(stackDepth() - 1); 25985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pop(1); 25995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 26005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 260209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool newObject() OVERRIDE 26035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2604d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isolate()); 26055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (object.IsEmpty()) 26065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) openComposite(object); 26085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 26095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 261109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value) OVERRIDE 26125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Object> object; 26145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_version > 0) { 26155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> composite; 26165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!closeComposite(&composite)) 26175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) object = composite.As<v8::Object>(); 261909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 2620d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) object = v8::Object::New(m_reader.scriptState()->isolate()); 262109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 26225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (object.IsEmpty()) 26235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return initializeObject(object, numProperties, value); 26255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 262709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE 26285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Array> array; 26305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_version > 0) { 26315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> composite; 26325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!closeComposite(&composite)) 26335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) array = composite.As<v8::Array>(); 2635a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } else { 2636d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) array = v8::Array::New(m_reader.scriptState()->isolate()); 2637a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 26385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (array.IsEmpty()) 26395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return initializeObject(array, numProperties, value); 26415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 264309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE 26445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Array> array; 26465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_version > 0) { 26475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> composite; 26485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!closeComposite(&composite)) 26495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) array = composite.As<v8::Array>(); 26515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (array.IsEmpty()) 26535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!initializeObject(array, numProperties, value)) 26555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (length > stackDepth()) 26575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stackPos++) { 26595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> elem = element(stackPos); 26605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!elem->IsUndefined()) 26615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) array->Set(i, elem); 26625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pop(length); 26645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 26655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 266709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRIDE 26685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_objectPool.append(object); 26705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 267209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE 26735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_transferredMessagePorts) 26755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index >= m_transferredMessagePorts->size()) 26775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2678d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->Global(); 2679d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext, m_reader.scriptState()->isolate()); 26805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 26815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 268309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE 26845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 26855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_arrayBufferContents) 26865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index >= m_arrayBuffers.size()) 26885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 26895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Object> result = m_arrayBuffers.at(index); 26905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result.IsEmpty()) { 2691926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferContents->at(index)); 269251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate()); 2693d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Isolate* isolate = m_reader.scriptState()->isolate(); 2694d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->Global(); 2695d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) isolate->AdjustAmountOfExternalAllocatedMemory(buffer->byteLength()); 2696d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) result = toV8Object(buffer.get(), creationContext, isolate); 26975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_arrayBuffers[index] = result; 26985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *object = result; 27005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 27015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 270309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object) OVERRIDE 27045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (reference >= m_objectPool.size()) 27065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 27075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *object = m_objectPool[reference]; 27085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return object; 27095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 271109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual uint32_t objectReferenceCount() OVERRIDE 27125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_objectPool.size(); 27145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 27175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value) 27185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = 2 * numProperties; 27205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (length > stackDepth()) 27215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 27225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { 27235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> propertyName = element(i); 27245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> propertyValue = element(i + 1); 27255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) object->Set(propertyName, propertyValue); 27265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pop(length); 27285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *value = object; 27295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 27305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool doDeserialize() 27335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> value; 27355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_reader.read(&value, *this)) 27365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 27375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!value.IsEmpty()) 27385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) push(value); 27395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 27405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void push(v8::Local<v8::Value> value) { m_stack.append(value); } 27435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void pop(unsigned length) 27455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(length <= m_stack.size()); 27475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_stack.shrink(m_stack.size() - length); 27485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned stackDepth() const { return m_stack.size(); } 27515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Value> element(unsigned index) 27535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2754926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size()); 27555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_stack[index]; 27565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void openComposite(const v8::Local<v8::Value>& object) 27595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t newObjectReference = m_objectPool.size(); 27615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_openCompositeReferenceStack.append(newObjectReference); 27625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_objectPool.append(object); 27635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool closeComposite(v8::Handle<v8::Value>* object) 27665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_openCompositeReferenceStack.size()) 27685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 27695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeReferenceStack.size() - 1]; 27705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 27715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (objectReference >= m_objectPool.size()) 27725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 27735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *object = m_objectPool[objectReference]; 27745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 27755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 27765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Reader& m_reader; 27785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<v8::Local<v8::Value> > m_stack; 27795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<v8::Handle<v8::Value> > m_objectPool; 27805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<uint32_t> m_openCompositeReferenceStack; 27815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MessagePortArray* m_transferredMessagePorts; 27825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArrayBufferContentsArray* m_arrayBufferContents; 27835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<v8::Handle<v8::Object> > m_arrayBuffers; 27845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t m_version; 27855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 27865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace 27885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 278909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate) 27905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 27916f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, exceptionState, isolate)); 27925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 27935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 279451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate) 2795926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 279609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) TrackExceptionState exceptionState; 27976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return adoptRef(new SerializedScriptValue(value, 0, 0, 0, exceptionState, isolate)); 2798926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2799926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 280010f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate) 28015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 280210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch ASSERT(isolate->InContext()); 280310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, blobInfo, exceptionState, isolate)); 28045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data) 28075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 28085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new SerializedScriptValue(data)); 28095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2811926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(const Vector<uint8_t>& data) 2812926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 2813926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Decode wire data from big endian to host byte order. 2814926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!(data.size() % sizeof(UChar))); 2815926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) size_t length = data.size() / sizeof(UChar); 281602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch StringBuffer<UChar> buffer(length); 2817926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const UChar* src = reinterpret_cast<const UChar*>(data.data()); 281802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch UChar* dst = buffer.characters(); 2819926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (size_t i = 0; i < length; i++) 2820926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) dst[i] = ntohs(src[i]); 2821926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2822926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return createFromWire(String::adopt(buffer)); 2823926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2824926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2825926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data) 2826926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 2827926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return create(data, v8::Isolate::GetCurrent()); 2828926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2829926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 28305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data, v8::Isolate* isolate) 28315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2832d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Writer writer; 28335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writer.writeWebCoreString(data); 28348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) String wireData = writer.takeWireString(); 28355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new SerializedScriptValue(wireData)); 28365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::create() 28395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 28405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new SerializedScriptValue()); 28415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2843926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() 2844926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 2845d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Writer writer; 28465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writer.writeNull(); 28478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) String wireData = writer.takeWireString(); 28485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new SerializedScriptValue(wireData)); 28495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2851591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch// Convert serialized string to big endian wire data. 2852591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid SerializedScriptValue::toWireBytes(Vector<char>& result) const 2853926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 2854591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(result.isEmpty()); 2855926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) size_t length = m_data.length(); 2856591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch result.resize(length * sizeof(UChar)); 2857926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) UChar* dst = reinterpret_cast<UChar*>(result.data()); 2858926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2859591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (m_data.is8Bit()) { 2860591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const LChar* src = m_data.characters8(); 2861591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < length; i++) 2862591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch dst[i] = htons(static_cast<UChar>(src[i])); 2863591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 2864591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const UChar* src = m_data.characters16(); 2865591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < length; i++) 2866591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch dst[i] = htons(src[i]); 2867591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 2868926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2869926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 28705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SerializedScriptValue::SerializedScriptValue() 28715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_externallyAllocatedMemory(0) 28725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 28735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 28745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2875d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static void neuterArrayBufferInAllWorlds(ArrayBuffer* object) 28765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2877e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 2878d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isMainThread()) { 2879d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<RefPtr<DOMWrapperWorld> > worlds; 2880d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) DOMWrapperWorld::allWorldsInMainThread(worlds); 2881d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (size_t i = 0; i < worlds.size(); i++) { 2882d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Handle<v8::Object> wrapper = worlds[i]->domDataStore().get<V8ArrayBuffer>(object, isolate); 2883d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!wrapper.IsEmpty()) { 2884d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(wrapper->IsArrayBuffer()); 2885d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter(); 2886d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 2887d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 2888d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 2889d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) v8::Handle<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDataStore().get<V8ArrayBuffer>(object, isolate); 2890e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!wrapper.IsEmpty()) { 2891e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(wrapper->IsArrayBuffer()); 2892e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter(); 2893e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 2894e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 2895e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 2896e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 289709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate) 28985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 289981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) ASSERT(arrayBuffers.size()); 290081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) 29015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < arrayBuffers.size(); i++) { 29025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (arrayBuffers[i]->isNeutered()) { 290309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered."); 29045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return nullptr; 29055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size())); 29095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HashSet<ArrayBuffer*> visited; 29115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < arrayBuffers.size(); i++) { 29125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (visited.contains(arrayBuffers[i].get())) 29135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 29145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visited.add(arrayBuffers[i].get()); 29155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 291609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool result = arrayBuffers[i]->transfer(contents->at(i)); 29175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!result) { 291809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred."); 29195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return nullptr; 29205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2922d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) neuterArrayBufferInAllWorlds(arrayBuffers[i].get()); 29235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return contents.release(); 29255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 29265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29276f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochSerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate) 29285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_externallyAllocatedMemory(0) 29295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2930d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Writer writer; 29315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Serializer::Status status; 293209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String errorMessage; 29335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 29345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::TryCatch tryCatch; 2935d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Serializer serializer(writer, messagePorts, arrayBuffers, blobInfo, m_blobDataHandles, tryCatch, ScriptState::current(isolate)); 29365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) status = serializer.serialize(value); 29375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (status == Serializer::JSException) { 29387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // If there was a JS exception thrown, re-throw it. 293909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.rethrowV8Exception(tryCatch.Exception()); 29405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 29415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 294209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) errorMessage = serializer.errorMessage(); 29435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (status) { 29455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Serializer::InputError: 29465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Serializer::DataCloneError: 294709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, errorMessage); 29485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 29495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Serializer::Success: 29508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_data = writer.takeWireString(); 29518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(m_data.impl()->hasOneRef()); 295281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) if (arrayBuffers && arrayBuffers->size()) 295309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, exceptionState, isolate); 29545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 29555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Serializer::JSException: 295609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT_NOT_REACHED(); 29575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 29585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 29605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 29615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SerializedScriptValue::SerializedScriptValue(const String& wireData) 29635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_externallyAllocatedMemory(0) 29645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 29655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_data = wireData.isolatedCopy(); 29665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 29675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2968926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts) 2969926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 29706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); 2971926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2972926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 29736f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochv8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) 29745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 29755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_data.impl()) 2976a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return v8::Null(isolate); 29775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); 29787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_data.ensure16Bit(); 29797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // FIXME: SerializedScriptValue shouldn't use String for its underlying 29807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The 29817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // information stored in m_data isn't even encoded in UTF-16. Instead, 29827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // unicode characters are encoded as UTF-8 with two code units per UChar. 2983d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), blobInfo, m_blobDataHandles, ScriptState::current(isolate)); 29845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get()); 2985e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2986e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed. 2987e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // Holding a RefPtr ensures we are alive (along with our internal data) throughout the operation. 2988e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<SerializedScriptValue> protect(this); 29895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return deserializer.deserialize(); 29905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 29915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2992d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool SerializedScriptValue::extractTransferables(v8::Local<v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate) 2993d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 2994d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isUndefinedOrNull(value)) { 2995d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ports.resize(0); 2996d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) arrayBuffers.resize(0); 2997d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return true; 2998d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 2999d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 3000d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) uint32_t length = 0; 3001d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (value->IsArray()) { 3002d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); 3003d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) length = array->Length(); 3004d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else if (toV8Sequence(value, length, isolate).IsEmpty()) { 3005d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex + 1)); 3006d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3007d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3008d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 3009d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value); 3010d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 3011d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Validate the passed array of transferrables. 3012d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 3013d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Local<v8::Value> transferrable = transferrables->Get(i); 3014d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Validation of non-null objects, per HTML5 spec 10.3.3. 3015d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isUndefinedOrNull(transferrable)) { 3016d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " is an untransferable " + (transferrable->IsUndefined() ? "'undefined'" : "'null'") + " value."); 3017d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3018d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3019d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. 3020d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (V8MessagePort::hasInstance(transferrable, isolate)) { 3021d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtr<MessagePort> port = V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(transferrable)); 3022d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Check for duplicate MessagePorts. 3023d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (ports.contains(port)) { 3024d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "Message port at index " + String::number(i) + " is a duplicate of an earlier port."); 3025d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3026d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3027d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ports.append(port.release()); 3028d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { 3029d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtr<ArrayBuffer> arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(transferrable)); 3030d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (arrayBuffers.contains(arrayBuffer)) { 3031d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); 3032d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3033d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3034d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) arrayBuffers.append(arrayBuffer.release()); 3035d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 3036d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " does not have a transferable type."); 3037d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3038d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3039d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 3040d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return true; 3041d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 3042d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 30435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() 30445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 30455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_externallyAllocatedMemory) 30465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 30475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); 3048a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externallyAllocatedMemory); 30495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 30505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SerializedScriptValue::~SerializedScriptValue() 30525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 30535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the allocated memory was not registered before, then this class is likely 30545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // used in a context other then Worker's onmessage environment and the presence of 30555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // current v8 context is not guaranteed. Avoid calling v8 then. 30565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_externallyAllocatedMemory) { 30575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(v8::Isolate::GetCurrent()); 3058a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory); 30595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 30605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 30615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 3063