1d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2010 Google Inc. All rights reserved.
3d0825bca7fe65beaee391d30da42e937db621564Steve Block *
4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Redistribution and use in source and binary forms, with or without
5d0825bca7fe65beaee391d30da42e937db621564Steve Block * modification, are permitted provided that the following conditions are
6d0825bca7fe65beaee391d30da42e937db621564Steve Block * met:
7d0825bca7fe65beaee391d30da42e937db621564Steve Block *
8d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Redistributions of source code must retain the above copyright
9d0825bca7fe65beaee391d30da42e937db621564Steve Block * notice, this list of conditions and the following disclaimer.
10d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Redistributions in binary form must reproduce the above
11d0825bca7fe65beaee391d30da42e937db621564Steve Block * copyright notice, this list of conditions and the following disclaimer
12d0825bca7fe65beaee391d30da42e937db621564Steve Block * in the documentation and/or other materials provided with the
13d0825bca7fe65beaee391d30da42e937db621564Steve Block * distribution.
14d0825bca7fe65beaee391d30da42e937db621564Steve Block *     * Neither the name of Google Inc. nor the names of its
15d0825bca7fe65beaee391d30da42e937db621564Steve Block * contributors may be used to endorse or promote products derived from
16d0825bca7fe65beaee391d30da42e937db621564Steve Block * this software without specific prior written permission.
17d0825bca7fe65beaee391d30da42e937db621564Steve Block *
18d0825bca7fe65beaee391d30da42e937db621564Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19d0825bca7fe65beaee391d30da42e937db621564Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21d0825bca7fe65beaee391d30da42e937db621564Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22d0825bca7fe65beaee391d30da42e937db621564Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23d0825bca7fe65beaee391d30da42e937db621564Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25d0825bca7fe65beaee391d30da42e937db621564Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26d0825bca7fe65beaee391d30da42e937db621564Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27d0825bca7fe65beaee391d30da42e937db621564Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28d0825bca7fe65beaee391d30da42e937db621564Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29d0825bca7fe65beaee391d30da42e937db621564Steve Block */
30d0825bca7fe65beaee391d30da42e937db621564Steve Block
31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "config.h"
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SerializedScriptValue.h"
33d0825bca7fe65beaee391d30da42e937db621564Steve Block
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Blob.h"
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ByteArray.h"
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "CanvasPixelArray.h"
37ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "ExceptionCode.h"
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "File.h"
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "FileList.h"
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ImageData.h"
41d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SharedBuffer.h"
42545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "V8Binding.h"
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8Blob.h"
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8File.h"
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8FileList.h"
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8ImageData.h"
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8Proxy.h"
480617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include "V8Utilities.h"
49d0825bca7fe65beaee391d30da42e937db621564Steve Block
50d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Assertions.h>
51d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/RefCounted.h>
52d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Vector.h>
53d0825bca7fe65beaee391d30da42e937db621564Steve Block
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch// FIXME: consider crashing in debug mode on deserialization errors
55d0825bca7fe65beaee391d30da42e937db621564Steve Block
56d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace WebCore {
57d0825bca7fe65beaee391d30da42e937db621564Steve Block
58d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace {
59d0825bca7fe65beaee391d30da42e937db621564Steve Block
60d0825bca7fe65beaee391d30da42e937db621564Steve Blocktypedef UChar BufferValueType;
61d0825bca7fe65beaee391d30da42e937db621564Steve Block
62d0825bca7fe65beaee391d30da42e937db621564Steve Block// Serialization format is a sequence of (tag, optional data)
63d0825bca7fe65beaee391d30da42e937db621564Steve Block// pairs. Tag always takes exactly one byte.
64d0825bca7fe65beaee391d30da42e937db621564Steve Blockenum SerializationTag {
65d0825bca7fe65beaee391d30da42e937db621564Steve Block    InvalidTag = '!',
66d0825bca7fe65beaee391d30da42e937db621564Steve Block    PaddingTag = '\0',
67d0825bca7fe65beaee391d30da42e937db621564Steve Block    UndefinedTag = '_',
68d0825bca7fe65beaee391d30da42e937db621564Steve Block    NullTag = '0',
69d0825bca7fe65beaee391d30da42e937db621564Steve Block    TrueTag = 'T',
70d0825bca7fe65beaee391d30da42e937db621564Steve Block    FalseTag = 'F',
71d0825bca7fe65beaee391d30da42e937db621564Steve Block    StringTag = 'S',
72d0825bca7fe65beaee391d30da42e937db621564Steve Block    Int32Tag = 'I',
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Uint32Tag = 'U',
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    DateTag = 'D',
75d0825bca7fe65beaee391d30da42e937db621564Steve Block    NumberTag = 'N',
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    BlobTag = 'b',
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    FileTag = 'f',
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    FileListTag = 'l',
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ImageDataTag = '#',
80d0825bca7fe65beaee391d30da42e937db621564Steve Block    ArrayTag = '[',
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ObjectTag = '{',
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    SparseArrayTag = '@',
83e14391e94c850b8bd03680c23b38978db68687a8John Reck    RegExpTag = 'R',
84d0825bca7fe65beaee391d30da42e937db621564Steve Block};
85d0825bca7fe65beaee391d30da42e937db621564Steve Block
86d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic bool shouldCheckForCycles(int depth)
87d0825bca7fe65beaee391d30da42e937db621564Steve Block{
88d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(depth >= 0);
89d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Since we are not required to spot the cycle as soon as it
90d0825bca7fe65beaee391d30da42e937db621564Steve Block    // happens we can check for cycles only when the current depth
91d0825bca7fe65beaee391d30da42e937db621564Steve Block    // is a power of two.
92d0825bca7fe65beaee391d30da42e937db621564Steve Block    return !(depth & (depth - 1));
93d0825bca7fe65beaee391d30da42e937db621564Steve Block}
94d0825bca7fe65beaee391d30da42e937db621564Steve Block
95d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int maxDepth = 20000;
96d0825bca7fe65beaee391d30da42e937db621564Steve Block
97d0825bca7fe65beaee391d30da42e937db621564Steve Block// VarInt encoding constants.
98d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int varIntShift = 7;
99d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const int varIntMask = (1 << varIntShift) - 1;
100d0825bca7fe65beaee391d30da42e937db621564Steve Block
101d0825bca7fe65beaee391d30da42e937db621564Steve Block// ZigZag encoding helps VarInt encoding stay small for negative
102d0825bca7fe65beaee391d30da42e937db621564Steve Block// numbers with small absolute values.
103d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass ZigZag {
104d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
105d0825bca7fe65beaee391d30da42e937db621564Steve Block    static uint32_t encode(uint32_t value)
106d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
107d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (value & (1U << 31))
108d0825bca7fe65beaee391d30da42e937db621564Steve Block            value = ((~value) << 1) + 1;
109d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
110d0825bca7fe65beaee391d30da42e937db621564Steve Block            value <<= 1;
111d0825bca7fe65beaee391d30da42e937db621564Steve Block        return value;
112d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
113d0825bca7fe65beaee391d30da42e937db621564Steve Block
114d0825bca7fe65beaee391d30da42e937db621564Steve Block    static uint32_t decode(uint32_t value)
115d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
116d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (value & 1)
117d0825bca7fe65beaee391d30da42e937db621564Steve Block            value = ~(value >> 1);
118d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
119d0825bca7fe65beaee391d30da42e937db621564Steve Block            value >>= 1;
120d0825bca7fe65beaee391d30da42e937db621564Steve Block        return value;
121d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
122d0825bca7fe65beaee391d30da42e937db621564Steve Block
123d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
124d0825bca7fe65beaee391d30da42e937db621564Steve Block    ZigZag();
125d0825bca7fe65beaee391d30da42e937db621564Steve Block};
126d0825bca7fe65beaee391d30da42e937db621564Steve Block
127d0825bca7fe65beaee391d30da42e937db621564Steve Block// Writer is responsible for serializing primitive types and storing
128d0825bca7fe65beaee391d30da42e937db621564Steve Block// information used to reconstruct composite types.
129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass Writer {
130ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(Writer);
131d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Writer()
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : m_position(0)
134d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
135d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
136d0825bca7fe65beaee391d30da42e937db621564Steve Block
137d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Write functions for primitive types.
138d0825bca7fe65beaee391d30da42e937db621564Steve Block
139d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeUndefined() { append(UndefinedTag); }
140d0825bca7fe65beaee391d30da42e937db621564Steve Block
141d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeNull() { append(NullTag); }
142d0825bca7fe65beaee391d30da42e937db621564Steve Block
143d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeTrue() { append(TrueTag); }
144d0825bca7fe65beaee391d30da42e937db621564Steve Block
145d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeFalse() { append(FalseTag); }
146d0825bca7fe65beaee391d30da42e937db621564Steve Block
147d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeString(const char* data, int length)
148d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(length >= 0);
150d0825bca7fe65beaee391d30da42e937db621564Steve Block        append(StringTag);
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteString(data, length);
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeWebCoreString(const String& string)
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Uses UTF8 encoding so we can read it back as either V8 or
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // WebCore string.
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(StringTag);
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteWebCoreString(string);
160d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
161d0825bca7fe65beaee391d30da42e937db621564Steve Block
162d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeInt32(int32_t value)
163d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
164d0825bca7fe65beaee391d30da42e937db621564Steve Block        append(Int32Tag);
165d0825bca7fe65beaee391d30da42e937db621564Steve Block        doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
166d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
167d0825bca7fe65beaee391d30da42e937db621564Steve Block
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeUint32(uint32_t value)
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(Uint32Tag);
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(value);
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeDate(double numberValue)
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(DateTag);
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteNumber(numberValue);
178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
180d0825bca7fe65beaee391d30da42e937db621564Steve Block    void writeNumber(double number)
181d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
182d0825bca7fe65beaee391d30da42e937db621564Steve Block        append(NumberTag);
183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteNumber(number);
184d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
185d0825bca7fe65beaee391d30da42e937db621564Steve Block
186f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void writeBlob(const String& url, const String& type, unsigned long long size)
187d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(BlobTag);
189f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteWebCoreString(url);
190f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteWebCoreString(type);
191f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteUint64(size);
192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
194f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void writeFile(const String& path, const String& url, const String& type)
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(FileTag);
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteWebCoreString(path);
198f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteWebCoreString(url);
199f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteWebCoreString(type);
200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeFileList(const FileList& fileList)
203dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
204dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(FileListTag);
205dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t length = fileList.length();
206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(length);
207f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        for (unsigned i = 0; i < length; ++i) {
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            doWriteWebCoreString(fileList.item(i)->path());
209f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            doWriteWebCoreString(fileList.item(i)->url().string());
210f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            doWriteWebCoreString(fileList.item(i)->type());
211f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
216dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(ImageDataTag);
217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(width);
218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(height);
219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(pixelDataLength);
220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(pixelData, pixelDataLength);
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
22281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
223e14391e94c850b8bd03680c23b38978db68687a8John Reck    void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags)
224e14391e94c850b8bd03680c23b38978db68687a8John Reck    {
225e14391e94c850b8bd03680c23b38978db68687a8John Reck        append(RegExpTag);
226e14391e94c850b8bd03680c23b38978db68687a8John Reck        v8::String::Utf8Value patternUtf8Value(pattern);
227e14391e94c850b8bd03680c23b38978db68687a8John Reck        doWriteString(*patternUtf8Value, patternUtf8Value.length());
228e14391e94c850b8bd03680c23b38978db68687a8John Reck        doWriteUint32(static_cast<uint32_t>(flags));
22981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
230dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeArray(uint32_t length)
232dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
233dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(ArrayTag);
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(length);
235dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
236dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeObject(uint32_t numProperties)
238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(ObjectTag);
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(numProperties);
241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeSparseArray(uint32_t numProperties, uint32_t length)
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(SparseArrayTag);
246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(numProperties);
247dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(length);
248d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
249d0825bca7fe65beaee391d30da42e937db621564Steve Block
250d0825bca7fe65beaee391d30da42e937db621564Steve Block    Vector<BufferValueType>& data()
251d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
252d0825bca7fe65beaee391d30da42e937db621564Steve Block        fillHole();
253d0825bca7fe65beaee391d30da42e937db621564Steve Block        return m_buffer;
254d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
255d0825bca7fe65beaee391d30da42e937db621564Steve Block
256d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void doWriteString(const char* data, int length)
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteUint32(static_cast<uint32_t>(length));
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(reinterpret_cast<const uint8_t*>(data), length);
261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void doWriteWebCoreString(const String& string)
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        RefPtr<SharedBuffer> buffer = utf8Buffer(string);
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        doWriteString(buffer->data(), buffer->size());
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
269f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<class T>
270f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void doWriteUintHelper(T value)
271d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
272d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (true) {
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            uint8_t b = (value & varIntMask);
274d0825bca7fe65beaee391d30da42e937db621564Steve Block            value >>= varIntShift;
275d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!value) {
276d0825bca7fe65beaee391d30da42e937db621564Steve Block                append(b);
277d0825bca7fe65beaee391d30da42e937db621564Steve Block                break;
278d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
279d0825bca7fe65beaee391d30da42e937db621564Steve Block            append(b | (1 << varIntShift));
280d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
281d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
282d0825bca7fe65beaee391d30da42e937db621564Steve Block
283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void doWriteUint32(uint32_t value)
284f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
285f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteUintHelper(value);
286f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
288f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void doWriteUint64(uint64_t value)
289f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
290f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        doWriteUintHelper(value);
291f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
292f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void doWriteNumber(double number)
294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
298d0825bca7fe65beaee391d30da42e937db621564Steve Block    void append(SerializationTag tag)
299d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(static_cast<uint8_t>(tag));
301d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
302d0825bca7fe65beaee391d30da42e937db621564Steve Block
303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(uint8_t b)
304d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
305d0825bca7fe65beaee391d30da42e937db621564Steve Block        ensureSpace(1);
306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *byteAt(m_position++) = b;
307d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
308d0825bca7fe65beaee391d30da42e937db621564Steve Block
309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const uint8_t* data, int length)
310d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
311d0825bca7fe65beaee391d30da42e937db621564Steve Block        ensureSpace(length);
312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        memcpy(byteAt(m_position), data, length);
313d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_position += length;
314d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
315d0825bca7fe65beaee391d30da42e937db621564Steve Block
316d0825bca7fe65beaee391d30da42e937db621564Steve Block    void ensureSpace(int extra)
317d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
318d0825bca7fe65beaee391d30da42e937db621564Steve Block        COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
319d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_buffer.grow((m_position + extra + 1) / 2); // "+ 1" to round up.
320d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
321d0825bca7fe65beaee391d30da42e937db621564Steve Block
322d0825bca7fe65beaee391d30da42e937db621564Steve Block    void fillHole()
323d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
324d0825bca7fe65beaee391d30da42e937db621564Steve Block        COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
325d0825bca7fe65beaee391d30da42e937db621564Steve Block        // If the writer is at odd position in the buffer, then one of
326d0825bca7fe65beaee391d30da42e937db621564Steve Block        // the bytes in the last UChar is not initialized.
327d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_position % 2)
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
329d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
330d0825bca7fe65beaee391d30da42e937db621564Steve Block
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; }
332d0825bca7fe65beaee391d30da42e937db621564Steve Block
333d0825bca7fe65beaee391d30da42e937db621564Steve Block    Vector<BufferValueType> m_buffer;
334d0825bca7fe65beaee391d30da42e937db621564Steve Block    unsigned m_position;
335d0825bca7fe65beaee391d30da42e937db621564Steve Block};
336d0825bca7fe65beaee391d30da42e937db621564Steve Block
337d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass Serializer {
338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class StateBase;
339d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    enum Status {
34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Success,
34281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        InputError,
34381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSException,
34481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSFailure
34581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    };
34681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
34781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Serializer(Writer& writer, v8::TryCatch& tryCatch)
348d0825bca7fe65beaee391d30da42e937db621564Steve Block        : m_writer(writer)
34981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        , m_tryCatch(tryCatch)
350d0825bca7fe65beaee391d30da42e937db621564Steve Block        , m_depth(0)
35181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        , m_status(Success)
352d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
35381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(!tryCatch.HasCaught());
354d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
355d0825bca7fe65beaee391d30da42e937db621564Steve Block
35681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Status serialize(v8::Handle<v8::Value> value)
357d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
358d0825bca7fe65beaee391d30da42e937db621564Steve Block        v8::HandleScope scope;
359dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StateBase* state = doSerialize(value, 0);
360dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        while (state)
361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            state = state->advance(*this);
36281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return m_status;
363dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
364dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Functions used by serialization states.
366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next);
368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
36981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    StateBase* checkException(StateBase* state)
37081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
37181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0;
37281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
37381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
37481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    StateBase* reportFailure(StateBase* state)
37581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
37681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return handleError(JSFailure, state);
37781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
37881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* writeArray(uint32_t length, StateBase* state)
380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeArray(length);
382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return pop(state);
383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* writeObject(uint32_t numProperties, StateBase* state)
386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeObject(numProperties);
388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return pop(state);
389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeSparseArray(numProperties, length);
394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return pop(state);
395d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
396d0825bca7fe65beaee391d30da42e937db621564Steve Block
397d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
398ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    class StateBase {
399ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        WTF_MAKE_NONCOPYABLE(StateBase);
400d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
401d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual ~StateBase() { }
402d0825bca7fe65beaee391d30da42e937db621564Steve Block
403d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Link to the next state to form a stack.
404d0825bca7fe65beaee391d30da42e937db621564Steve Block        StateBase* nextState() { return m_next; }
405d0825bca7fe65beaee391d30da42e937db621564Steve Block
406d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Composite object we're processing in this state.
407d0825bca7fe65beaee391d30da42e937db621564Steve Block        v8::Handle<v8::Value> composite() { return m_composite; }
408d0825bca7fe65beaee391d30da42e937db621564Steve Block
409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Serializes (a part of) the current composite and returns
410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // the next state to process or null when this is the final
411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // state.
412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* advance(Serializer&) = 0;
413d0825bca7fe65beaee391d30da42e937db621564Steve Block
414d0825bca7fe65beaee391d30da42e937db621564Steve Block    protected:
415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StateBase(v8::Handle<v8::Value> composite, StateBase* next)
416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : m_composite(composite)
417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            , m_next(next)
418d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
419d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
420d0825bca7fe65beaee391d30da42e937db621564Steve Block
421d0825bca7fe65beaee391d30da42e937db621564Steve Block    private:
422d0825bca7fe65beaee391d30da42e937db621564Steve Block        v8::Handle<v8::Value> m_composite;
423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StateBase* m_next;
424d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
425d0825bca7fe65beaee391d30da42e937db621564Steve Block
426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Dummy state that is used to signal serialization errors.
427dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class ErrorState : public StateBase {
428d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
429dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ErrorState()
430dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : StateBase(v8::Handle<v8::Value>(), 0)
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
433d0825bca7fe65beaee391d30da42e937db621564Steve Block
434dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* advance(Serializer&)
435dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            delete this;
437dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return 0;
438dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
439dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    };
440dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
441dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    template <typename T>
442dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class State : public StateBase {
443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    public:
444dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
445d0825bca7fe65beaee391d30da42e937db621564Steve Block
446d0825bca7fe65beaee391d30da42e937db621564Steve Block    protected:
447dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        State(v8::Handle<T> composite, StateBase* next)
448dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : StateBase(composite, next)
449d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
450d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
451d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
452d0825bca7fe65beaee391d30da42e937db621564Steve Block
453dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if 0
454dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Currently unused, see comment in newArrayState.
455dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class ArrayState : public State<v8::Array> {
456d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ArrayState(v8::Handle<v8::Array> array, StateBase* next)
458dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : State<v8::Array>(array, next)
459dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            , m_index(-1)
460d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
461d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
462d0825bca7fe65beaee391d30da42e937db621564Steve Block
463dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* advance(Serializer& serializer)
464d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
465dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ++m_index;
466dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            for (; m_index < composite()->Length(); ++m_index) {
46781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                v8::Handle<v8::Value> value = composite()->Get(m_index);
46881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (StateBase* newState = serializer.checkException(this))
46981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return newState;
47081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (StateBase* newState = serializer.doSerialize(value, this))
471dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    return newState;
472d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
473dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return serializer.writeArray(composite()->Length(), this);
474d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
475d0825bca7fe65beaee391d30da42e937db621564Steve Block
476d0825bca7fe65beaee391d30da42e937db621564Steve Block    private:
477dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned m_index;
478d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
480d0825bca7fe65beaee391d30da42e937db621564Steve Block
481dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class AbstractObjectState : public State<v8::Object> {
482d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
484dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : State<v8::Object>(object, next)
48581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            , m_index(0)
486dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            , m_numSerializedProperties(0)
487dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            , m_nameDone(false)
488d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
489d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
490d0825bca7fe65beaee391d30da42e937db621564Steve Block
491dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* advance(Serializer& serializer)
492d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
49381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_index) {
49481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_propertyNames = composite()->GetPropertyNames();
49581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (StateBase* newState = serializer.checkException(this))
49681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return newState;
49781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (m_propertyNames.IsEmpty())
49881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return serializer.reportFailure(this);
49981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
50081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            while (m_index < m_propertyNames->Length()) {
50181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_nameDone) {
502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
50381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (StateBase* newState = serializer.checkException(this))
50481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        return newState;
50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (propertyName.IsEmpty())
50681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        return serializer.reportFailure(this);
50781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>());
50881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (StateBase* newState = serializer.checkException(this))
50981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        return newState;
51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value());
51181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (StateBase* newState = serializer.checkException(this))
51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        return newState;
51381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (hasStringProperty || hasIndexedProperty)
514dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                        m_propertyName = propertyName;
51581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    else {
51681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        ++m_index;
517dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                        continue;
51881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    }
519dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
520dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                ASSERT(!m_propertyName.IsEmpty());
521dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                if (!m_nameDone) {
522dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    m_nameDone = true;
523dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
524dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                        return newState;
525dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
526dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                v8::Local<v8::Value> value = composite()->Get(m_propertyName);
52781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (StateBase* newState = serializer.checkException(this))
52881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return newState;
529dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                m_nameDone = false;
530dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                m_propertyName.Clear();
53181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ++m_index;
532dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                ++m_numSerializedProperties;
533dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                if (StateBase* newState = serializer.doSerialize(value, this))
534dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    return newState;
535dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return objectDone(m_numSerializedProperties, serializer);
537d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
538d0825bca7fe65beaee391d30da42e937db621564Steve Block
539dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    protected:
540dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
541d0825bca7fe65beaee391d30da42e937db621564Steve Block
542d0825bca7fe65beaee391d30da42e937db621564Steve Block    private:
543dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Local<v8::Array> m_propertyNames;
544dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Local<v8::Value> m_propertyName;
545d0825bca7fe65beaee391d30da42e937db621564Steve Block        unsigned m_index;
546dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned m_numSerializedProperties;
547dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        bool m_nameDone;
548d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
549d0825bca7fe65beaee391d30da42e937db621564Steve Block
550dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class ObjectState : public AbstractObjectState {
551d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
552dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ObjectState(v8::Handle<v8::Object> object, StateBase* next)
553dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : AbstractObjectState(object, next)
554d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
555d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
556d0825bca7fe65beaee391d30da42e937db621564Steve Block
557dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    protected:
558dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
559d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
560dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return serializer.writeObject(numProperties, this);
561d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
562dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    };
563d0825bca7fe65beaee391d30da42e937db621564Steve Block
564dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    class SparseArrayState : public AbstractObjectState {
565dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    public:
566dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        SparseArrayState(v8::Handle<v8::Array> array, StateBase* next)
567dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            : AbstractObjectState(array, next)
568d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
569d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
570d0825bca7fe65beaee391d30da42e937db621564Steve Block
571dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    protected:
572dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
573d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
574dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
575d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
576d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
577d0825bca7fe65beaee391d30da42e937db621564Steve Block
578dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* push(StateBase* state)
579d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
580dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(state);
581d0825bca7fe65beaee391d30da42e937db621564Steve Block        ++m_depth;
58281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return checkComposite(state) ? state : handleError(InputError, state);
583d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
584d0825bca7fe65beaee391d30da42e937db621564Steve Block
585dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StateBase* pop(StateBase* state)
586d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
587dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(state);
588d0825bca7fe65beaee391d30da42e937db621564Steve Block        --m_depth;
589dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StateBase* next = state->nextState();
590dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        delete state;
591dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return next;
592dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
593dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
59481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    StateBase* handleError(Status errorStatus, StateBase* state)
595dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
59681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(errorStatus != Success);
59781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_status = errorStatus;
598dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        while (state) {
599dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            StateBase* tmp = state->nextState();
600dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            delete state;
601dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            state = tmp;
602dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
603dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return new ErrorState;
604d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
605d0825bca7fe65beaee391d30da42e937db621564Steve Block
606dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool checkComposite(StateBase* top)
607d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
608dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(top);
609d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_depth > maxDepth)
610d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
611d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!shouldCheckForCycles(m_depth))
612d0825bca7fe65beaee391d30da42e937db621564Steve Block            return true;
613dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Handle<v8::Value> composite = top->composite();
614dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (StateBase* state = top->nextState(); state; state = state->nextState()) {
615d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (state->composite() == composite)
616d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
617d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
618d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
619d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
620d0825bca7fe65beaee391d30da42e937db621564Steve Block
621dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeString(v8::Handle<v8::Value> value)
622dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
623dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::String::Utf8Value stringValue(value);
624dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeString(*stringValue, stringValue.length());
625dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
626dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
627dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeBlob(v8::Handle<v8::Value> value)
628dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
629dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Blob* blob = V8Blob::toNative(value.As<v8::Object>());
630dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!blob)
631dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
632f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_writer.writeBlob(blob->url().string(), blob->type(), blob->size());
633dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
634dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeFile(v8::Handle<v8::Value> value)
636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        File* file = V8File::toNative(value.As<v8::Object>());
638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!file)
639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
640f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_writer.writeFile(file->path(), file->url().string(), file->type());
641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeFileList(v8::Handle<v8::Value> value)
644dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
645dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!fileList)
647dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeFileList(*fileList);
649dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
650dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
651dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void writeImageData(v8::Handle<v8::Value> value)
652dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
653dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
654dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!imageData)
655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
656dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        WTF::ByteArray* pixelArray = imageData->data()->data();
657dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
658dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
65981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
660e14391e94c850b8bd03680c23b38978db68687a8John Reck    void writeRegExp(v8::Handle<v8::Value> value)
661e14391e94c850b8bd03680c23b38978db68687a8John Reck    {
662e14391e94c850b8bd03680c23b38978db68687a8John Reck        v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>();
663e14391e94c850b8bd03680c23b38978db68687a8John Reck        m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
664e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
665dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next)
667dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
668dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // FIXME: use plain Array state when we can quickly check that
669dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // an array is not sparse and has only indexed properties.
670dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return new SparseArrayState(array, next);
671dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
672dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
673dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next)
674dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
67581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // FIXME: check not a wrapper
676dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return new ObjectState(object, next);
677dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
678dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
679d0825bca7fe65beaee391d30da42e937db621564Steve Block    Writer& m_writer;
68081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    v8::TryCatch& m_tryCatch;
681d0825bca7fe65beaee391d30da42e937db621564Steve Block    int m_depth;
68281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Status m_status;
683dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
684dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
685dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockSerializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
686dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
68781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (value.IsEmpty())
68881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return reportFailure(next);
689dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (value->IsUndefined())
690dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeUndefined();
691dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsNull())
692dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeNull();
693dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsTrue())
694dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeTrue();
695dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsFalse())
696dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeFalse();
697dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsInt32())
698dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeInt32(value->Int32Value());
699dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsUint32())
700dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeUint32(value->Uint32Value());
701dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsDate())
702dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeDate(value->NumberValue());
703dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsNumber())
704dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_writer.writeNumber(value.As<v8::Number>()->Value());
705dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsString())
706dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeString(value);
707dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsArray())
708dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return push(newArrayState(value.As<v8::Array>(), next));
709dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (V8File::HasInstance(value))
710dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeFile(value);
711dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (V8Blob::HasInstance(value))
712dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeBlob(value);
713dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (V8FileList::HasInstance(value))
714dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeFileList(value);
715dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (V8ImageData::HasInstance(value))
716dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeImageData(value);
717e14391e94c850b8bd03680c23b38978db68687a8John Reck    else if (value->IsRegExp())
718e14391e94c850b8bd03680c23b38978db68687a8John Reck        writeRegExp(value);
719dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (value->IsObject())
720dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return push(newObjectState(value.As<v8::Object>(), next));
721dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return 0;
722dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
723dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
724dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Interface used by Reader to create objects of composite types.
725dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass CompositeCreator {
726dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockpublic:
727dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual ~CompositeCreator() { }
728dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
729dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0;
730dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0;
731dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0;
732d0825bca7fe65beaee391d30da42e937db621564Steve Block};
733d0825bca7fe65beaee391d30da42e937db621564Steve Block
734d0825bca7fe65beaee391d30da42e937db621564Steve Block// Reader is responsible for deserializing primitive types and
735d0825bca7fe65beaee391d30da42e937db621564Steve Block// restoring information about saved objects of composite types.
736d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass Reader {
737d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
738dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Reader(const uint8_t* buffer, int length)
739d0825bca7fe65beaee391d30da42e937db621564Steve Block        : m_buffer(buffer)
740d0825bca7fe65beaee391d30da42e937db621564Steve Block        , m_length(length)
741d0825bca7fe65beaee391d30da42e937db621564Steve Block        , m_position(0)
742d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
743d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT(length >= 0);
744d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
745d0825bca7fe65beaee391d30da42e937db621564Steve Block
746d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool isEof() const { return m_position >= m_length; }
747d0825bca7fe65beaee391d30da42e937db621564Steve Block
748dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
749d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
750dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        SerializationTag tag;
751dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!readTag(&tag))
752d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
753dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        switch (tag) {
754d0825bca7fe65beaee391d30da42e937db621564Steve Block        case InvalidTag:
755d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
756d0825bca7fe65beaee391d30da42e937db621564Steve Block        case PaddingTag:
757dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return true;
758d0825bca7fe65beaee391d30da42e937db621564Steve Block        case UndefinedTag:
759d0825bca7fe65beaee391d30da42e937db621564Steve Block            *value = v8::Undefined();
760d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
761d0825bca7fe65beaee391d30da42e937db621564Steve Block        case NullTag:
762d0825bca7fe65beaee391d30da42e937db621564Steve Block            *value = v8::Null();
763d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
764d0825bca7fe65beaee391d30da42e937db621564Steve Block        case TrueTag:
765d0825bca7fe65beaee391d30da42e937db621564Steve Block            *value = v8::True();
766d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
767d0825bca7fe65beaee391d30da42e937db621564Steve Block        case FalseTag:
768d0825bca7fe65beaee391d30da42e937db621564Steve Block            *value = v8::False();
769d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
770d0825bca7fe65beaee391d30da42e937db621564Steve Block        case StringTag:
771d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!readString(value))
772d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
773d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
774d0825bca7fe65beaee391d30da42e937db621564Steve Block        case Int32Tag:
775d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!readInt32(value))
776d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
777d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
778dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case Uint32Tag:
779dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readUint32(value))
780dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
781dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
782dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case DateTag:
783dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readDate(value))
784dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
785dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
786d0825bca7fe65beaee391d30da42e937db621564Steve Block        case NumberTag:
787d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!readNumber(value))
788d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
789d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
790dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case BlobTag:
791dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readBlob(value))
792dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
793dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
794dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case FileTag:
795dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readFile(value))
796dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
797dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
798dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case FileListTag:
799dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readFileList(value))
800dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
801dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
802dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case ImageDataTag:
803dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readImageData(value))
804dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
805dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
806dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case ArrayTag: {
807dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            uint32_t length;
808dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!doReadUint32(&length))
809dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
810dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!creator.createArray(length, value))
811d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
812d0825bca7fe65beaee391d30da42e937db621564Steve Block            break;
813d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
814e14391e94c850b8bd03680c23b38978db68687a8John Reck        case RegExpTag:
815e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (!readRegExp(value))
816e14391e94c850b8bd03680c23b38978db68687a8John Reck                return false;
817e14391e94c850b8bd03680c23b38978db68687a8John Reck            break;
818dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case ObjectTag: {
819dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            uint32_t numProperties;
820dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!doReadUint32(&numProperties))
821dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
822dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!creator.createObject(numProperties, value))
823dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
824dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
825dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
826dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        case SparseArrayTag: {
827dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            uint32_t numProperties;
828dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            uint32_t length;
829dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!doReadUint32(&numProperties))
830dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
831dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!doReadUint32(&length))
832dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
833dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!creator.createSparseArray(numProperties, length, value))
834dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
835dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            break;
836dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
837dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        default:
838dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
839dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
840dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return !value->IsEmpty();
841d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
842d0825bca7fe65beaee391d30da42e937db621564Steve Block
843d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
844d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool readTag(SerializationTag* tag)
845d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
846d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_position >= m_length)
847d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
848d0825bca7fe65beaee391d30da42e937db621564Steve Block        *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
849d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
850d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
851d0825bca7fe65beaee391d30da42e937db621564Steve Block
852d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool readString(v8::Handle<v8::Value>* value)
853d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
854d0825bca7fe65beaee391d30da42e937db621564Steve Block        uint32_t length;
855d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!doReadUint32(&length))
856d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
857d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_position + length > m_length)
858d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
859dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length);
860dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_position += length;
861dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
862dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
863dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
864dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readWebCoreString(String* string)
865dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
866dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t length;
867dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&length))
868dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
869dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (m_position + length > m_length)
870dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
871dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
872d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_position += length;
873d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
874d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
875d0825bca7fe65beaee391d30da42e937db621564Steve Block
876d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool readInt32(v8::Handle<v8::Value>* value)
877d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
878d0825bca7fe65beaee391d30da42e937db621564Steve Block        uint32_t rawValue;
879d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!doReadUint32(&rawValue))
880d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
881d0825bca7fe65beaee391d30da42e937db621564Steve Block        *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue)));
882d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
883d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
884d0825bca7fe65beaee391d30da42e937db621564Steve Block
885dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readUint32(v8::Handle<v8::Value>* value)
886d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
887dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t rawValue;
888dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&rawValue))
889dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
890f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        *value = v8::Integer::NewFromUnsigned(rawValue);
891dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
892dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
893dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
894dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readDate(v8::Handle<v8::Value>* value)
895dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
896dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        double numberValue;
897dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadNumber(&numberValue))
898d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
899dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = v8::Date::New(numberValue);
900dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
901dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
902dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
903dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readNumber(v8::Handle<v8::Value>* value)
904dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
905d0825bca7fe65beaee391d30da42e937db621564Steve Block        double number;
906dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadNumber(&number))
907dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
908d0825bca7fe65beaee391d30da42e937db621564Steve Block        *value = v8::Number::New(number);
909d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
910d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
911d0825bca7fe65beaee391d30da42e937db621564Steve Block
912dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readImageData(v8::Handle<v8::Value>* value)
913dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
914dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t width;
915dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t height;
916dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t pixelDataLength;
917dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&width))
918dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
919dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&height))
920dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
921dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&pixelDataLength))
922dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
923dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (m_position + pixelDataLength > m_length)
924dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
925cad810f21b803229eb11403f9209855525a25d57Steve Block        RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
926dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        WTF::ByteArray* pixelArray = imageData->data()->data();
927dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(pixelArray);
928dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(pixelArray->length() >= pixelDataLength);
929dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
930dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_position += pixelDataLength;
931cad810f21b803229eb11403f9209855525a25d57Steve Block        *value = toV8(imageData.release());
932dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
933dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
93481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
935e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool readRegExp(v8::Handle<v8::Value>* value)
936e14391e94c850b8bd03680c23b38978db68687a8John Reck    {
937e14391e94c850b8bd03680c23b38978db68687a8John Reck        v8::Handle<v8::Value> pattern;
938e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (!readString(&pattern))
939e14391e94c850b8bd03680c23b38978db68687a8John Reck            return false;
940e14391e94c850b8bd03680c23b38978db68687a8John Reck        uint32_t flags;
941e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (!doReadUint32(&flags))
942e14391e94c850b8bd03680c23b38978db68687a8John Reck            return false;
943e14391e94c850b8bd03680c23b38978db68687a8John Reck        *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags));
944e14391e94c850b8bd03680c23b38978db68687a8John Reck        return true;
945e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
947dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readBlob(v8::Handle<v8::Value>* value)
948dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
949f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        String url;
950f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        String type;
951f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        uint64_t size;
952f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (!readWebCoreString(&url))
953f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            return false;
954f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (!readWebCoreString(&type))
955dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
956f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (!doReadUint64(&size))
957f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            return false;
95868513a70bcd92384395513322f1b801e7bf9c729Steve Block        PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size);
959dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = toV8(blob);
960dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
961dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
962dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
963dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readFile(v8::Handle<v8::Value>* value)
964dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
965dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        String path;
966f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        String url;
967f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        String type;
968dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!readWebCoreString(&path))
969dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
970f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (!readWebCoreString(&url))
971f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            return false;
972f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (!readWebCoreString(&type))
973f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            return false;
97468513a70bcd92384395513322f1b801e7bf9c729Steve Block        PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), type);
975dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = toV8(file);
976dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
977dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
978dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
979dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool readFileList(v8::Handle<v8::Value>* value)
980dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
981dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint32_t length;
982dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!doReadUint32(&length))
983dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
984dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        PassRefPtr<FileList> fileList = FileList::create();
985dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (unsigned i = 0; i < length; ++i) {
986dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            String path;
987f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            String urlString;
988f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            String type;
989dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!readWebCoreString(&path))
990dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
991f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (!readWebCoreString(&urlString))
992f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                return false;
993f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (!readWebCoreString(&type))
994f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                return false;
99568513a70bcd92384395513322f1b801e7bf9c729Steve Block            fileList->append(File::create(path, KURL(ParsedURLString, urlString), type));
996dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
997dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = toV8(fileList);
998dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
999dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1000dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1001f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<class T>
1002f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    bool doReadUintHelper(T* value)
1003d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1004d0825bca7fe65beaee391d30da42e937db621564Steve Block        *value = 0;
1005dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint8_t currentByte;
1006d0825bca7fe65beaee391d30da42e937db621564Steve Block        int shift = 0;
1007d0825bca7fe65beaee391d30da42e937db621564Steve Block        do {
1008d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (m_position >= m_length)
1009d0825bca7fe65beaee391d30da42e937db621564Steve Block                return false;
1010d0825bca7fe65beaee391d30da42e937db621564Steve Block            currentByte = m_buffer[m_position++];
1011d0825bca7fe65beaee391d30da42e937db621564Steve Block            *value |= ((currentByte & varIntMask) << shift);
1012d0825bca7fe65beaee391d30da42e937db621564Steve Block            shift += varIntShift;
1013d0825bca7fe65beaee391d30da42e937db621564Steve Block        } while (currentByte & (1 << varIntShift));
1014d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
1015d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1016d0825bca7fe65beaee391d30da42e937db621564Steve Block
1017f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    bool doReadUint32(uint32_t* value)
1018f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
1019f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return doReadUintHelper(value);
1020f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
1021f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
1022f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    bool doReadUint64(uint64_t* value)
1023f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
1024f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return doReadUintHelper(value);
1025f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
1026f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
1027dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool doReadNumber(double* number)
1028dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1029dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (m_position + sizeof(double) > m_length)
1030dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1031dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
1032dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (unsigned i = 0; i < sizeof(double); ++i)
1033dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            numberAsByteArray[i] = m_buffer[m_position++];
1034dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
1035dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1036dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1037dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const uint8_t* m_buffer;
1038d0825bca7fe65beaee391d30da42e937db621564Steve Block    const unsigned m_length;
1039d0825bca7fe65beaee391d30da42e937db621564Steve Block    unsigned m_position;
1040d0825bca7fe65beaee391d30da42e937db621564Steve Block};
1041d0825bca7fe65beaee391d30da42e937db621564Steve Block
1042dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass Deserializer : public CompositeCreator {
1043d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
1044dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    explicit Deserializer(Reader& reader)
1045dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : m_reader(reader)
1046d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1047d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1048d0825bca7fe65beaee391d30da42e937db621564Steve Block
1049dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    v8::Handle<v8::Value> deserialize()
1050d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1051d0825bca7fe65beaee391d30da42e937db621564Steve Block        v8::HandleScope scope;
1052d0825bca7fe65beaee391d30da42e937db621564Steve Block        while (!m_reader.isEof()) {
1053d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!doDeserialize())
1054dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return v8::Null();
1055d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
1056d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (stackDepth() != 1)
1057dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return v8::Null();
1058d0825bca7fe65beaee391d30da42e937db621564Steve Block        return scope.Close(element(0));
1059d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1060d0825bca7fe65beaee391d30da42e937db621564Steve Block
1061dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value)
1062dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1063dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (length > stackDepth())
1064dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1065dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Local<v8::Array> array = v8::Array::New(length);
1066dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (array.IsEmpty())
1067dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1068dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        const int depth = stackDepth() - length;
1069dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (unsigned i = 0; i < length; ++i)
1070dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            array->Set(i, element(depth + i));
1071dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        pop(length);
1072dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = array;
1073dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
1074dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1075dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1076dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
1077dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1078dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Local<v8::Object> object = v8::Object::New();
1079dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (object.IsEmpty())
1080dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1081dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return initializeObject(object, numProperties, value);
1082dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1083dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1084dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
1085dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1086dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::Local<v8::Array> array = v8::Array::New(length);
1087dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (array.IsEmpty())
1088dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1089dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return initializeObject(array, numProperties, value);
1090dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1091dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1092d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
1093dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
1094dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1095dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned length = 2 * numProperties;
1096dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (length > stackDepth())
1097dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1098dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
1099dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            v8::Local<v8::Value> propertyName = element(i);
1100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            v8::Local<v8::Value> propertyValue = element(i + 1);
1101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            object->Set(propertyName, propertyValue);
1102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
1103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        pop(length);
1104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *value = object;
1105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
1106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1108d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool doDeserialize()
1109d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1110d0825bca7fe65beaee391d30da42e937db621564Steve Block        v8::Local<v8::Value> value;
1111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!m_reader.read(&value, *this))
1112d0825bca7fe65beaee391d30da42e937db621564Steve Block            return false;
1113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!value.IsEmpty())
1114d0825bca7fe65beaee391d30da42e937db621564Steve Block            push(value);
1115d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
1116d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1117d0825bca7fe65beaee391d30da42e937db621564Steve Block
1118d0825bca7fe65beaee391d30da42e937db621564Steve Block    void push(v8::Local<v8::Value> value) { m_stack.append(value); }
1119d0825bca7fe65beaee391d30da42e937db621564Steve Block
1120d0825bca7fe65beaee391d30da42e937db621564Steve Block    void pop(unsigned length)
1121d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1122d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT(length <= m_stack.size());
1123d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_stack.shrink(m_stack.size() - length);
1124d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1125d0825bca7fe65beaee391d30da42e937db621564Steve Block
1126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    unsigned stackDepth() const { return m_stack.size(); }
1127d0825bca7fe65beaee391d30da42e937db621564Steve Block
1128d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Local<v8::Value> element(unsigned index)
1129d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
1130d0825bca7fe65beaee391d30da42e937db621564Steve Block        ASSERT(index < m_stack.size());
1131d0825bca7fe65beaee391d30da42e937db621564Steve Block        return m_stack[index];
1132d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
1133d0825bca7fe65beaee391d30da42e937db621564Steve Block
1134d0825bca7fe65beaee391d30da42e937db621564Steve Block    Reader& m_reader;
1135d0825bca7fe65beaee391d30da42e937db621564Steve Block    Vector<v8::Local<v8::Value> > m_stack;
1136d0825bca7fe65beaee391d30da42e937db621564Steve Block};
1137d0825bca7fe65beaee391d30da42e937db621564Steve Block
1138d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace
1139d0825bca7fe65beaee391d30da42e937db621564Steve Block
1140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName,
1141545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                                                      v8::PropertyAttribute attribute, SerializedScriptValue* value)
1142545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1143545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!value)
1144545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
1145545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    v8::Handle<v8::Value> deserialized = value->deserialize();
1146545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    object->ForceSet(v8::String::NewSymbol(propertyName), deserialized, attribute);
1147545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1148545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
114981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> object, const char* propertyName,
115081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                      v8::PropertyAttribute attribute, PassRefPtr<SerializedScriptValue> value)
115181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
115281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    deserializeAndSetProperty(object, propertyName, attribute, value.get());
115381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
115481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1155545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, bool& didThrow)
1156545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1157545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return adoptRef(new SerializedScriptValue(value, didThrow));
1158545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1159545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1160545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value)
1161545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1162545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    bool didThrow;
1163545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return adoptRef(new SerializedScriptValue(value, didThrow));
1164545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1165545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1166545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(String data)
1167545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
11682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return adoptRef(new SerializedScriptValue(data));
1169545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1170545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1171545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create(String data)
1172545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
11732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    Writer writer;
11742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    writer.writeWebCoreString(data);
11752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    String wireData = StringImpl::adopt(writer.data());
11762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return adoptRef(new SerializedScriptValue(wireData));
1177545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1178545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1179545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
1180545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1181545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return adoptRef(new SerializedScriptValue());
1182545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1183545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1184ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochSerializedScriptValue* SerializedScriptValue::nullValue()
11855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
11862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, nullValue, (0));
11872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!nullValue) {
11882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Writer writer;
11892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        writer.writeNull();
11902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        String wireData = StringImpl::adopt(writer.data());
11912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        nullValue = adoptRef(new SerializedScriptValue(wireData));
11922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
11935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return nullValue.get();
11945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
11955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1196ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochSerializedScriptValue* SerializedScriptValue::undefinedValue()
1197ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
11982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, undefinedValue, (0));
11992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!undefinedValue) {
12002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Writer writer;
12012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        writer.writeUndefined();
12022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        String wireData = StringImpl::adopt(writer.data());
12032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        undefinedValue = adoptRef(new SerializedScriptValue(wireData));
12042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1205ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return undefinedValue.get();
1206ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
1207ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
1208545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochPassRefPtr<SerializedScriptValue> SerializedScriptValue::release()
1209545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
12102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data));
1211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_data = String().crossThreadString();
1212545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return result.release();
1213545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1214545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1215545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochSerializedScriptValue::SerializedScriptValue()
1216545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1217545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
1218545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockSerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& didThrow)
1220d0825bca7fe65beaee391d30da42e937db621564Steve Block{
1221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    didThrow = false;
1222d0825bca7fe65beaee391d30da42e937db621564Steve Block    Writer writer;
122381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Serializer::Status status;
122481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
122581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        v8::TryCatch tryCatch;
122681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Serializer serializer(writer, tryCatch);
122781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        status = serializer.serialize(value);
122881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (status == Serializer::JSException) {
122981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // If there was a JS exception thrown, re-throw it.
123081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            didThrow = true;
123181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            tryCatch.ReThrow();
123281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
123381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
123481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
123581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (status == Serializer::InputError) {
123681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // If there was an input error, throw a new exception outside
123781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // of the TryCatch scope.
123881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        didThrow = true;
1239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        throwError(NOT_SUPPORTED_ERR);
124081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
124181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
124281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (status == Serializer::JSFailure) {
124381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // If there was a JS failure (but no exception), there's not
124481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // much we can do except for unwinding the C++ stack by
124581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // pretending there was a JS exception.
1246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        didThrow = true;
1247d0825bca7fe65beaee391d30da42e937db621564Steve Block        return;
1248d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
124981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(status == Serializer::Success);
1250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_data = String(StringImpl::adopt(writer.data())).crossThreadString();
1251d0825bca7fe65beaee391d30da42e937db621564Steve Block}
1252d0825bca7fe65beaee391d30da42e937db621564Steve Block
12532fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockSerializedScriptValue::SerializedScriptValue(String wireData)
1254d0825bca7fe65beaee391d30da42e937db621564Steve Block{
12552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_data = wireData.crossThreadString();
1256d0825bca7fe65beaee391d30da42e937db621564Steve Block}
1257d0825bca7fe65beaee391d30da42e937db621564Steve Block
1258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockv8::Handle<v8::Value> SerializedScriptValue::deserialize()
1259d0825bca7fe65beaee391d30da42e937db621564Steve Block{
1260d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!m_data.impl())
1261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return v8::Null();
1262d0825bca7fe65beaee391d30da42e937db621564Steve Block    COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
1263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
1264d0825bca7fe65beaee391d30da42e937db621564Steve Block    Deserializer deserializer(reader);
1265d0825bca7fe65beaee391d30da42e937db621564Steve Block    return deserializer.deserialize();
1266d0825bca7fe65beaee391d30da42e937db621564Steve Block}
1267d0825bca7fe65beaee391d30da42e937db621564Steve Block
1268d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore
1269