diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 6a66a4d2..47339d4 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -79,6 +79,7 @@
 #include "RegisteredEventListener.h"
 #include "ScheduledAction.h"
 #include "ScriptController.h"
+#include "SerializedScriptValue.h"
 #include "Settings.h"
 #include "SharedWorkerRepository.h"
 #include "WindowFeatures.h"
@@ -952,7 +953,7 @@
     DOMWindow* window = impl();
 
     DOMWindow* source = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
-    String message = args.at(0).toString(exec);
+    PassRefPtr<SerializedScriptValue> message = SerializedScriptValue::create(exec, args.at(0));
 
     if (exec->hadException())
         return jsUndefined();
diff --git a/WebCore/bindings/js/JSMessageEventCustom.cpp b/WebCore/bindings/js/JSMessageEventCustom.cpp
index 4c61c04..2e7b2d06 100644
--- a/WebCore/bindings/js/JSMessageEventCustom.cpp
+++ b/WebCore/bindings/js/JSMessageEventCustom.cpp
@@ -59,7 +59,7 @@
     const UString& typeArg = args.at(0).toString(exec);
     bool canBubbleArg = args.at(1).toBoolean(exec);
     bool cancelableArg = args.at(2).toBoolean(exec);
-    const UString& dataArg = args.at(3).toString(exec);
+    PassRefPtr<SerializedScriptValue> dataArg = SerializedScriptValue::create(exec, args.at(3));
     const UString& originArg = args.at(4).toString(exec);
     const UString& lastEventIdArg = args.at(5).toString(exec);
     DOMWindow* sourceArg = toDOMWindow(args.at(6));
diff --git a/WebCore/bindings/js/JSMessagePortCustom.h b/WebCore/bindings/js/JSMessagePortCustom.h
index 7e90943..17b1eae 100644
--- a/WebCore/bindings/js/JSMessagePortCustom.h
+++ b/WebCore/bindings/js/JSMessagePortCustom.h
@@ -49,7 +49,7 @@
     template <typename T>
     inline JSC::JSValue handlePostMessage(JSC::ExecState* exec, const JSC::ArgList& args, T* impl)
     {
-        String message = args.at(0).toString(exec);
+        PassRefPtr<SerializedScriptValue> message = SerializedScriptValue::create(exec, args.at(0));
         MessagePortArray portArray;
         fillMessagePortArray(exec, args.at(1), portArray);
         if (exec->hadException())
diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp
new file mode 100644
index 0000000..ab97f2f
--- /dev/null
+++ b/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include "SerializedScriptValue.h"
+
+#include <runtime/DateInstance.h>
+#include <runtime/ExceptionHelpers.h>
+#include <runtime/PropertyNameArray.h>
+#include <wtf/HashTraits.h>
+#include <wtf/Vector.h>
+
+using namespace JSC;
+
+namespace WebCore
+{
+
+class SerializedObject : public SharedSerializedData
+{
+public:
+    typedef Vector<RefPtr<StringImpl> > PropertyNameList;
+    typedef Vector<SerializedScriptValueData> ValueList;
+    void set(const Identifier& propertyName, const SerializedScriptValueData& value)
+    {
+        ASSERT(m_names.size() == m_values.size());
+        m_names.append(String(propertyName.ustring()).crossThreadString().impl());
+        m_values.append(value);
+    }
+    PropertyNameList& names() { return m_names; }
+    ValueList& values() { return m_values; }
+    static PassRefPtr<SerializedObject> create()
+    {
+        return adoptRef(new SerializedObject);
+    }
+    void clear()
+    {
+        m_names.clear();
+        m_values.clear();
+    }
+private:
+    SerializedObject() { }
+    PropertyNameList m_names;
+    ValueList m_values;
+};
+
+class SerializedArray : public SharedSerializedData
+{
+    typedef HashMap<unsigned, SerializedScriptValueData, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > SparseMap;
+public:
+    void setIndex(unsigned index, const SerializedScriptValueData& value)
+    {
+        ASSERT(index < m_length);
+        if (index == m_compactStorage.size())
+            m_compactStorage.append(value);
+        else
+            m_sparseStorage.set(index, value);
+    }
+
+    bool canDoFastRead(unsigned index) const
+    {
+        ASSERT(index < m_length);
+        return index < m_compactStorage.size();
+    }
+
+    const SerializedScriptValueData& getIndex(unsigned index)
+    {
+        ASSERT(index < m_compactStorage.size());
+        return m_compactStorage[index];
+    }
+
+    SerializedScriptValueData getSparseIndex(unsigned index, bool& hasIndex)
+    {
+        ASSERT(index >= m_compactStorage.size());
+        ASSERT(index < m_length);
+        SparseMap::iterator iter = m_sparseStorage.find(index);
+        if (iter == m_sparseStorage.end()) {
+            hasIndex = false;
+            return SerializedScriptValueData();
+        }
+        hasIndex = true;
+        return iter->second;
+    }
+
+    unsigned length() const
+    {
+        return m_length;
+    }
+
+    static PassRefPtr<SerializedArray> create(unsigned length)
+    {
+        return adoptRef(new SerializedArray(length));
+    }
+
+    void clear()
+    {
+        m_compactStorage.clear();
+        m_sparseStorage.clear();
+        m_length = 0;
+    }
+private:
+    SerializedArray(unsigned length)
+        : m_length(length)
+    {
+    }
+
+    Vector<SerializedScriptValueData> m_compactStorage;
+    SparseMap m_sparseStorage;
+    unsigned m_length;
+};
+
+SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedObject> data)
+    : m_type(ObjectType)
+    , m_sharedData(data)
+{
+}
+
+SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedArray> data)
+    : m_type(ArrayType)
+    , m_sharedData(data)
+{
+}
+
+SerializedArray* SharedSerializedData::asArray()
+{
+    return static_cast<SerializedArray*>(this);
+}
+
+SerializedObject* SharedSerializedData::asObject()
+{
+    return static_cast<SerializedObject*>(this);
+}
+
+static const unsigned maximumFilterRecursion = 40000;
+enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
+    ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
+template <typename TreeWalker> typename TreeWalker::OutputType walk(TreeWalker& context, typename TreeWalker::InputType in)
+{
+    typedef typename TreeWalker::InputObject InputObject;
+    typedef typename TreeWalker::InputArray InputArray;
+    typedef typename TreeWalker::OutputObject OutputObject;
+    typedef typename TreeWalker::OutputArray OutputArray;
+    typedef typename TreeWalker::InputType InputType;
+    typedef typename TreeWalker::OutputType OutputType;
+    typedef typename TreeWalker::PropertyList PropertyList;
+
+    Vector<uint32_t, 16> indexStack;
+    Vector<uint32_t, 16> lengthStack;
+    Vector<PropertyList, 16> propertyStack;
+    Vector<InputObject, 16> inputObjectStack;
+    Vector<InputArray, 16> inputArrayStack;
+    Vector<OutputObject, 16> outputObjectStack;
+    Vector<OutputArray, 16> outputArrayStack;
+    Vector<WalkerState, 16> stateStack;
+    WalkerState state = StateUnknown;
+    InputType inValue = in;
+    OutputType outValue = context.null();
+
+    unsigned tickCount = context.ticksUntilNextCheck();
+    while (1) {
+        switch (state) {
+            arrayStartState:
+            case ArrayStartState: {
+                ASSERT(context.isArray(inValue));
+                if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) {
+                    context.throwStackOverflow();
+                    return context.null();
+                }
+
+                InputArray inArray = context.asInputArray(inValue);
+                unsigned length = context.length(inArray);
+                OutputArray outArray = context.createOutputArray(length);
+                if (!context.startArray(inArray, outArray))
+                    return context.null();
+                inputArrayStack.append(inArray);
+                outputArrayStack.append(outArray);
+                indexStack.append(0);
+                lengthStack.append(length);
+                // fallthrough
+            }
+            arrayStartVisitMember:
+            case ArrayStartVisitMember: {
+                if (!--tickCount) {
+                    if (context.didTimeOut()) {
+                        context.throwInterruptedException();
+                        return context.null();
+                    }
+                    tickCount = context.ticksUntilNextCheck();
+                }
+
+                InputArray array = inputArrayStack.last();
+                uint32_t index = indexStack.last();
+                if (index == lengthStack.last()) {
+                    InputArray inArray = inputArrayStack.last();
+                    OutputArray outArray = outputArrayStack.last();
+                    context.endArray(inArray, outArray);
+                    outValue = outArray;
+                    inputArrayStack.removeLast();
+                    outputArrayStack.removeLast();
+                    indexStack.removeLast();
+                    lengthStack.removeLast();
+                    break;
+                }
+                if (context.canDoFastRead(array, index))
+                    inValue = context.getIndex(array, index);
+                else {
+                    bool hasIndex = false;
+                    inValue = context.getSparseIndex(array, index, hasIndex);
+                    if (!hasIndex) {
+                        indexStack.last()++;
+                        goto arrayStartVisitMember;
+                    }
+                }
+
+                if (OutputType transformed = context.convertIfTerminal(inValue))
+                    outValue = transformed;
+                else {
+                    stateStack.append(ArrayEndVisitMember);
+                    goto stateUnknown;
+                }
+                // fallthrough
+            }
+            case ArrayEndVisitMember: {
+                OutputArray outArray = outputArrayStack.last();
+                context.putProperty(outArray, indexStack.last(), outValue);
+                indexStack.last()++;
+                goto arrayStartVisitMember;
+            }
+            objectStartState:
+            case ObjectStartState: {
+                ASSERT(context.isObject(inValue));
+                if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) {
+                    context.throwStackOverflow();
+                    return context.null();
+                }
+                InputObject inObject = context.asInputObject(inValue);
+                OutputObject outObject = context.createOutputObject();
+                if (!context.startObject(inObject, outObject))
+                    return context.null();
+                inputObjectStack.append(inObject);
+                outputObjectStack.append(outObject);
+                indexStack.append(0);
+                context.getPropertyNames(inObject, propertyStack);
+                // fallthrough
+            }
+            objectStartVisitMember:
+            case ObjectStartVisitMember: {
+                if (!--tickCount) {
+                    if (context.didTimeOut()) {
+                        context.throwInterruptedException();
+                        return context.null();
+                    }
+                    tickCount = context.ticksUntilNextCheck();
+                }
+
+                InputObject object = inputObjectStack.last();
+                uint32_t index = indexStack.last();
+                PropertyList& properties = propertyStack.last();
+                if (index == properties.size()) {
+                    InputObject inObject = inputObjectStack.last();
+                    OutputObject outObject = outputObjectStack.last();
+                    context.endObject(inObject, outObject);
+                    outValue = outObject;
+                    inputObjectStack.removeLast();
+                    outputObjectStack.removeLast();
+                    indexStack.removeLast();
+                    propertyStack.removeLast();
+                    break;
+                }
+                inValue = context.getProperty(object, properties[index], index);
+
+                if (context.shouldTerminate())
+                    return context.null();
+
+                if (OutputType transformed = context.convertIfTerminal(inValue))
+                    outValue = transformed;
+                else {
+                    stateStack.append(ObjectEndVisitMember);
+                    goto stateUnknown;
+                }
+                // fallthrough
+            }
+            case ObjectEndVisitMember: {
+                context.putProperty(outputObjectStack.last(), propertyStack.last()[indexStack.last()], outValue);
+                if (context.shouldTerminate())
+                    return context.null();
+
+                indexStack.last()++;
+                goto objectStartVisitMember;
+            }
+            stateUnknown:
+            case StateUnknown:
+                if (OutputType transformed = context.convertIfTerminal(inValue)) {
+                    outValue = transformed;
+                    break;
+                }
+                if (context.isArray(inValue))
+                    goto arrayStartState;
+                goto objectStartState;
+        }
+        if (stateStack.isEmpty())
+            break;
+
+        state = stateStack.last();
+        stateStack.removeLast();
+
+        if (!--tickCount) {
+            if (context.didTimeOut()) {
+                context.throwInterruptedException();
+                return context.null();
+            }
+            tickCount = context.ticksUntilNextCheck();
+        }
+    }
+    return outValue;
+}
+
+struct BaseWalker {
+    BaseWalker(ExecState* exec)
+        : m_exec(exec)
+        , m_timeoutChecker(exec->globalData().timeoutChecker)
+    {
+        m_timeoutChecker.reset();
+    }
+    ExecState* m_exec;
+    TimeoutChecker m_timeoutChecker;
+    MarkedArgumentBuffer m_gcBuffer;
+
+    bool shouldTerminate()
+    {
+        return m_exec->hadException();
+    }
+
+    unsigned ticksUntilNextCheck()
+    {
+        return m_timeoutChecker.ticksUntilNextCheck();
+    }
+
+    bool didTimeOut()
+    {
+        return m_timeoutChecker.didTimeOut(m_exec);
+    }
+
+    void throwStackOverflow()
+    {
+        m_exec->setException(createStackOverflowError(m_exec));
+    }
+
+    void throwInterruptedException()
+    {
+        m_exec->setException(createInterruptedExecutionException(&m_exec->globalData()));
+    }
+};
+
+struct SerializingTreeWalker : public BaseWalker {
+    typedef JSValue InputType;
+    typedef JSArray* InputArray;
+    typedef JSObject* InputObject;
+    typedef SerializedScriptValueData OutputType;
+    typedef RefPtr<SerializedArray> OutputArray;
+    typedef RefPtr<SerializedObject> OutputObject;
+    typedef PropertyNameArray PropertyList;
+
+    SerializingTreeWalker(ExecState* exec)
+        : BaseWalker(exec)
+    {
+    }
+
+    OutputType null() { return SerializedScriptValueData(); }
+
+    bool isArray(JSValue value)
+    {
+        if (!value.isObject())
+            return false;
+        JSObject* object = asObject(value);
+        return isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::info);
+    }
+
+    bool isObject(JSValue value)
+    {
+        return value.isObject();
+    }
+
+    JSArray* asInputArray(JSValue value)
+    {
+        return asArray(value);
+    }
+
+    JSObject* asInputObject(JSValue value)
+    {
+        return asObject(value);
+    }
+
+    PassRefPtr<SerializedArray> createOutputArray(unsigned length)
+    {
+        return SerializedArray::create(length);
+    }
+
+    PassRefPtr<SerializedObject> createOutputObject()
+    {
+        return SerializedObject::create();
+    }
+
+    uint32_t length(JSValue array)
+    {
+        ASSERT(array.isObject());
+        JSObject* object = asObject(array);
+        return object->get(m_exec, m_exec->propertyNames().length).toUInt32(m_exec);
+    }
+
+    bool canDoFastRead(JSArray* array, unsigned index)
+    {
+        return isJSArray(&m_exec->globalData(), array) && array->canGetIndex(index);
+    }
+
+    JSValue getIndex(JSArray* array, unsigned index)
+    {
+        return array->getIndex(index);
+    }
+
+    JSValue getSparseIndex(JSObject* object, unsigned propertyName, bool& hasIndex)
+    {
+        PropertySlot slot(object);
+        if (object->getOwnPropertySlot(m_exec, propertyName, slot)) {
+            hasIndex = true;
+            return slot.getValue(m_exec, propertyName);
+        }
+        hasIndex = false;
+        return jsNull();
+    }
+
+    JSValue getProperty(JSObject* object, const Identifier& propertyName, unsigned)
+    {
+        PropertySlot slot(object);
+        if (object->getOwnPropertySlot(m_exec, propertyName, slot))
+            return slot.getValue(m_exec, propertyName);
+        return jsNull();
+    }
+
+    SerializedScriptValueData convertIfTerminal(JSValue value)
+    {
+        if (!value.isCell())
+            return SerializedScriptValueData(value);
+
+        if (value.isString())
+            return SerializedScriptValueData(asString(value)->value());
+
+        if (value.isNumber())
+            return SerializedScriptValueData(SerializedScriptValueData::NumberType, value.uncheckedGetNumber());
+
+        if (value.isObject() && asObject(value)->inherits(&DateInstance::info))
+            return SerializedScriptValueData(SerializedScriptValueData::DateType, asDateInstance(value)->internalNumber());
+
+        if (isArray(value))
+            return SerializedScriptValueData();
+
+        CallData unusedData;
+        if (value.isObject() && value.getCallData(unusedData) == CallTypeNone)
+            return SerializedScriptValueData();
+
+        // Any other types are expected to serialize as null.
+        return SerializedScriptValueData(jsNull());
+    }
+
+    void getPropertyNames(JSObject* object, Vector<PropertyNameArray, 16>& propertyStack)
+    {
+        propertyStack.append(PropertyNameArray(m_exec));
+        object->getOwnPropertyNames(m_exec, propertyStack.last());
+    }
+
+    void putProperty(RefPtr<SerializedArray> array, unsigned propertyName, const SerializedScriptValueData& value)
+    {
+        array->setIndex(propertyName, value);
+    }
+
+    void putProperty(RefPtr<SerializedObject> object, const Identifier& propertyName, const SerializedScriptValueData& value)
+    {
+        object->set(propertyName, value);
+    }
+
+    bool startArray(JSArray* inArray, RefPtr<SerializedArray>)
+    {
+        // Cycle detection
+        if (!m_cycleDetector.add(inArray).second) {
+            m_exec->setException(createTypeError(m_exec, "Cannot post cyclic structures."));
+            return false;
+        }
+        m_gcBuffer.append(inArray);
+        return true;
+    }
+
+    void endArray(JSArray* inArray, RefPtr<SerializedArray>)
+    {
+        m_cycleDetector.remove(inArray);
+        m_gcBuffer.removeLast();
+    }
+
+    bool startObject(JSObject* inObject, RefPtr<SerializedObject>)
+    {
+        // Cycle detection
+        if (!m_cycleDetector.add(inObject).second) {
+            m_exec->setException(createTypeError(m_exec, "Cannot post cyclic structures."));
+            return false;
+        }
+        m_gcBuffer.append(inObject);
+        return true;
+    }
+
+    void endObject(JSObject* inObject, RefPtr<SerializedObject>)
+    {
+        m_cycleDetector.remove(inObject);
+        m_gcBuffer.removeLast();
+    }
+
+private:
+    HashSet<JSObject*> m_cycleDetector;
+};
+
+SerializedScriptValueData SerializedScriptValueData::serialize(ExecState* exec, JSValue inValue)
+{
+    SerializingTreeWalker context(exec);
+    return walk<SerializingTreeWalker>(context, inValue);
+}
+
+
+struct DeserializingTreeWalker : public BaseWalker {
+    typedef SerializedScriptValueData InputType;
+    typedef RefPtr<SerializedArray> InputArray;
+    typedef RefPtr<SerializedObject> InputObject;
+    typedef JSValue OutputType;
+    typedef JSArray* OutputArray;
+    typedef JSObject* OutputObject;
+    typedef SerializedObject::PropertyNameList PropertyList;
+
+    DeserializingTreeWalker(ExecState* exec, bool mustCopy)
+        : BaseWalker(exec)
+        , m_mustCopy(mustCopy)
+    {
+    }
+
+    OutputType null() { return jsNull(); }
+
+    bool isArray(const SerializedScriptValueData& value)
+    {
+        return value.type() == SerializedScriptValueData::ArrayType;
+    }
+
+    bool isObject(const SerializedScriptValueData& value)
+    {
+        return value.type() == SerializedScriptValueData::ObjectType;
+    }
+
+    SerializedArray* asInputArray(const SerializedScriptValueData& value)
+    {
+        return value.asArray();
+    }
+
+    SerializedObject* asInputObject(const SerializedScriptValueData& value)
+    {
+        return value.asObject();
+    }
+
+    JSArray* createOutputArray(unsigned length)
+    {
+        JSArray* array = constructEmptyArray(m_exec);
+        array->setLength(length);
+        return array;
+    }
+
+    JSObject* createOutputObject()
+    {
+        return constructEmptyObject(m_exec);
+    }
+
+    uint32_t length(RefPtr<SerializedArray> array)
+    {
+        return array->length();
+    }
+
+    bool canDoFastRead(RefPtr<SerializedArray> array, unsigned index)
+    {
+        return array->canDoFastRead(index);
+    }
+
+    SerializedScriptValueData getIndex(RefPtr<SerializedArray> array, unsigned index)
+    {
+        return array->getIndex(index);
+    }
+
+    SerializedScriptValueData getSparseIndex(RefPtr<SerializedArray> array, unsigned propertyName, bool& hasIndex)
+    {
+        return array->getSparseIndex(propertyName, hasIndex);
+    }
+
+    SerializedScriptValueData getProperty(RefPtr<SerializedObject> object, const RefPtr<StringImpl>& propertyName, unsigned propertyIndex)
+    {
+        ASSERT(object->names()[propertyIndex] == propertyName);
+        return object->values()[propertyIndex];
+    }
+
+    JSValue convertIfTerminal(SerializedScriptValueData& value)
+    {
+        switch (value.type()) {
+            case SerializedScriptValueData::ArrayType:
+            case SerializedScriptValueData::ObjectType:
+                return JSValue();
+            case SerializedScriptValueData::StringType:
+                return jsString(m_exec, value.asString().crossThreadString());
+            case SerializedScriptValueData::ImmediateType:
+                return value.asImmediate();
+            case SerializedScriptValueData::NumberType:
+                return jsNumber(m_exec, value.asDouble());
+            case SerializedScriptValueData::DateType:
+                return new (m_exec) DateInstance(m_exec, value.asDouble());
+            default:
+                ASSERT_NOT_REACHED();
+                return JSValue();
+        }
+    }
+
+    void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)
+    {
+        properties.append(object->names());
+    }
+
+    void putProperty(JSArray* array, unsigned propertyName, JSValue value)
+    {
+        array->put(m_exec, propertyName, value);
+    }
+
+    void putProperty(JSObject* object, const RefPtr<StringImpl> propertyName, JSValue value)
+    {
+        object->putDirect(Identifier(m_exec, String(propertyName)), value);
+    }
+
+    bool startArray(RefPtr<SerializedArray>, JSArray* outArray)
+    {
+        m_gcBuffer.append(outArray);
+        return true;
+    }
+    void endArray(RefPtr<SerializedArray>, JSArray*)
+    {
+        m_gcBuffer.removeLast();
+    }
+    bool startObject(RefPtr<SerializedObject>, JSObject* outObject)
+    {
+        m_gcBuffer.append(outObject);
+        return true;
+    }
+    void endObject(RefPtr<SerializedObject>, JSObject*)
+    {
+        m_gcBuffer.removeLast();
+    }
+
+private:
+    bool m_mustCopy;
+};
+
+JSValue SerializedScriptValueData::deserialize(ExecState* exec, bool mustCopy) const
+{
+    DeserializingTreeWalker context(exec, mustCopy);
+    return walk<DeserializingTreeWalker>(context, *this);
+}
+
+struct TeardownTreeWalker {
+    typedef SerializedScriptValueData InputType;
+    typedef RefPtr<SerializedArray> InputArray;
+    typedef RefPtr<SerializedObject> InputObject;
+    typedef bool OutputType;
+    typedef bool OutputArray;
+    typedef bool OutputObject;
+    typedef SerializedObject::PropertyNameList PropertyList;
+
+    bool shouldTerminate()
+    {
+        return false;
+    }
+
+    unsigned ticksUntilNextCheck()
+    {
+        return 0xFFFFFFFF;
+    }
+
+    bool didTimeOut()
+    {
+        return false;
+    }
+
+    void throwStackOverflow()
+    {
+    }
+
+    void throwInterruptedException()
+    {
+    }
+
+    bool null() { return false; }
+
+    bool isArray(const SerializedScriptValueData& value)
+    {
+        return value.type() == SerializedScriptValueData::ArrayType;
+    }
+
+    bool isObject(const SerializedScriptValueData& value)
+    {
+        return value.type() == SerializedScriptValueData::ObjectType;
+    }
+
+    SerializedArray* asInputArray(const SerializedScriptValueData& value)
+    {
+        return value.asArray();
+    }
+
+    SerializedObject* asInputObject(const SerializedScriptValueData& value)
+    {
+        return value.asObject();
+    }
+
+    bool createOutputArray(unsigned)
+    {
+        return false;
+    }
+
+    bool createOutputObject()
+    {
+        return false;
+    }
+
+    uint32_t length(RefPtr<SerializedArray> array)
+    {
+        return array->length();
+    }
+
+    bool canDoFastRead(RefPtr<SerializedArray> array, unsigned index)
+    {
+        return array->canDoFastRead(index);
+    }
+
+    SerializedScriptValueData getIndex(RefPtr<SerializedArray> array, unsigned index)
+    {
+        return array->getIndex(index);
+    }
+
+    SerializedScriptValueData getSparseIndex(RefPtr<SerializedArray> array, unsigned propertyName, bool& hasIndex)
+    {
+        return array->getSparseIndex(propertyName, hasIndex);
+    }
+
+    SerializedScriptValueData getProperty(RefPtr<SerializedObject> object, const RefPtr<StringImpl>& propertyName, unsigned propertyIndex)
+    {
+        ASSERT(object->names()[propertyIndex] == propertyName);
+        return object->values()[propertyIndex];
+    }
+
+    bool convertIfTerminal(SerializedScriptValueData& value)
+    {
+        switch (value.type()) {
+            case SerializedScriptValueData::ArrayType:
+            case SerializedScriptValueData::ObjectType:
+                return false;
+            case SerializedScriptValueData::StringType:
+            case SerializedScriptValueData::ImmediateType:
+            case SerializedScriptValueData::NumberType:
+                return true;
+            default:
+                ASSERT_NOT_REACHED();
+                return JSValue();
+        }
+    }
+
+    void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)
+    {
+        properties.append(object->names());
+    }
+
+    void putProperty(bool, unsigned, bool)
+    {
+    }
+
+    void putProperty(bool, const RefPtr<StringImpl>&, bool)
+    {
+    }
+
+    bool startArray(RefPtr<SerializedArray>, bool)
+    {
+        return true;
+    }
+    void endArray(RefPtr<SerializedArray> array, bool)
+    {
+        array->clear();
+    }
+    bool startObject(RefPtr<SerializedObject>, bool)
+    {
+        return true;
+    }
+    void endObject(RefPtr<SerializedObject> object, bool)
+    {
+        object->clear();
+    }
+};
+
+void SerializedScriptValueData::tearDownSerializedData()
+{
+    if (m_sharedData && m_sharedData->refCount() > 1)
+        return;
+    TeardownTreeWalker context;
+    walk<TeardownTreeWalker>(context, *this);
+}
+
+}
diff --git a/WebCore/bindings/js/SerializedScriptValue.h b/WebCore/bindings/js/SerializedScriptValue.h
new file mode 100644
index 0000000..74c5962
--- /dev/null
+++ b/WebCore/bindings/js/SerializedScriptValue.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef SerializedScriptValue_h
+#define SerializedScriptValue_h
+
+#include "ScriptValue.h"
+
+namespace WebCore {
+    class SerializedObject;
+    class SerializedArray;
+
+    class SharedSerializedData : public RefCounted<SharedSerializedData>
+    {
+    public:
+        virtual ~SharedSerializedData() { }
+        SerializedArray* asArray();
+        SerializedObject* asObject();
+    };
+
+    class SerializedScriptValue;
+
+    class SerializedScriptValueData
+    {
+    public:
+        enum SerializedType {
+            EmptyType,
+            DateType,
+            NumberType,
+            ImmediateType,
+            ObjectType,
+            ArrayType,
+            StringType
+        };
+
+        SerializedType type() const { return m_type; }
+        static SerializedScriptValueData serialize(JSC::ExecState*, JSC::JSValue);
+        JSC::JSValue deserialize(JSC::ExecState*, bool mustCopy) const;
+
+        ~SerializedScriptValueData()
+        {
+            if (m_sharedData)
+                tearDownSerializedData();
+        }
+
+        SerializedScriptValueData()
+            : m_type(EmptyType)
+        {
+        }
+
+        explicit SerializedScriptValueData(const String& string)
+            : m_type(StringType)
+            , m_string(string.crossThreadString()) // FIXME: Should be able to just share the Rep
+        {
+        }
+
+        explicit SerializedScriptValueData(JSC::JSValue value)
+            : m_type(ImmediateType)
+        {
+            ASSERT(!value.isCell());
+            m_data.m_immediate = JSC::JSValue::encode(value);
+        }
+
+        SerializedScriptValueData(SerializedType type, double value)
+            : m_type(type)
+        {
+            m_data.m_double = value;
+        }
+
+        SerializedScriptValueData(RefPtr<SerializedObject>);
+        SerializedScriptValueData(RefPtr<SerializedArray>);
+
+        JSC::JSValue asImmediate() const
+        {
+            ASSERT(m_type == ImmediateType);
+            return JSC::JSValue::decode(m_data.m_immediate);
+        }
+
+        double asDouble() const
+        {
+            ASSERT(m_type == NumberType || m_type == DateType);
+            return m_data.m_double;
+        }
+
+        String asString() const
+        {
+            ASSERT(m_type == StringType);
+            return m_string;
+        }
+
+        SerializedObject* asObject() const
+        {
+            ASSERT(m_type == ObjectType);
+            ASSERT(m_sharedData);
+            return m_sharedData->asObject();
+        }
+
+        SerializedArray* asArray() const
+        {
+            ASSERT(m_type == ArrayType);
+            ASSERT(m_sharedData);
+            return m_sharedData->asArray();
+        }
+
+        operator bool () const { return m_type != EmptyType; }
+
+        SerializedScriptValueData release() {
+            SerializedScriptValueData result = *this;
+            *this = SerializedScriptValueData();
+            return result;
+        }
+
+    private:
+        void tearDownSerializedData();
+        SerializedType m_type;
+        RefPtr<SharedSerializedData> m_sharedData;
+        String m_string;
+        union {
+            double m_double;
+            JSC::EncodedJSValue m_immediate;
+        } m_data;
+    };
+
+    class SerializedScriptValue : public RefCounted<SerializedScriptValue>
+    {
+    public:
+        static PassRefPtr<SerializedScriptValue> create(JSC::ExecState* exec, JSC::JSValue value)
+        {
+            return adoptRef(new SerializedScriptValue(SerializedScriptValueData::serialize(exec, value)));
+        }
+
+        static PassRefPtr<SerializedScriptValue> create(String string)
+        {
+            return adoptRef(new SerializedScriptValue(SerializedScriptValueData(string)));
+        }
+
+        static PassRefPtr<SerializedScriptValue> create()
+        {
+            return adoptRef(new SerializedScriptValue(SerializedScriptValueData()));
+        }
+
+        PassRefPtr<SerializedScriptValue> release() {
+            PassRefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_value));
+            m_value = SerializedScriptValueData();
+            result->m_mustCopy = true;
+            return result;
+        }
+
+        String toString() {
+            if (m_value.type() != SerializedScriptValueData::StringType)
+                return "";
+            return m_value.asString();
+        }
+
+        JSC::JSValue deserialize(JSC::ExecState* exec)
+        {
+            if (!m_value)
+                return JSC::jsNull();
+            return m_value.deserialize(exec, m_mustCopy);
+        }
+
+        ~SerializedScriptValue()
+        {
+        }
+    private:
+        SerializedScriptValue(SerializedScriptValueData value)
+            : m_value(value)
+            , m_mustCopy(false)
+        {
+        }
+        SerializedScriptValueData m_value;
+        bool m_mustCopy;
+    };
+}
+
+#endif
