[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

eric at webkit.org eric at webkit.org
Thu Feb 4 21:22:27 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit bd17d91825f7c115925d0d3ea3237b805598c37d
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 21 01:35:54 2010 +0000

    2010-01-20  Vitaly Repeshko  <vitalyr at chromium.org>
    
            Reviewed by Pavel Feldman.
    
            [V8] Support SerializedScriptValue.
            https://bugs.webkit.org/show_bug.cgi?id=32920
            http://crbug.com/30620
    
            Initial implementation of SerializedScriptValue which is used to
            to create a serialized representation of JavaScript objects.  This
            representation is needed for structured clones and worker messages.
    
            * WebCore.gypi: Added SerializedScriptValue.cpp.
            * bindings/scripts/CodeGeneratorV8.pm: Removed conversion to string before using SerializedScriptValue.
            * bindings/v8/SerializedScriptValue.cpp: Added.
            (WebCore::):
            (WebCore::ZigZag::encode):
            (WebCore::ZigZag::decode):
            (WebCore::Writer::Writer):
            (WebCore::Writer::writeUndefined):
            (WebCore::Writer::writeNull):
            (WebCore::Writer::writeTrue):
            (WebCore::Writer::writeFalse):
            (WebCore::Writer::writeString):
            (WebCore::Writer::writeInt32):
            (WebCore::Writer::writeNumber):
            (WebCore::Writer::endComposite):
            (WebCore::Writer::data):
            (WebCore::Writer::doWriteUint32):
            (WebCore::Writer::append):
            (WebCore::Writer::ensureSpace):
            (WebCore::Writer::fillHole):
            (WebCore::Writer::charAt):
            (WebCore::Serializer::Serializer):
            (WebCore::Serializer::serialize):
            (WebCore::Serializer::StateBase::~StateBase):
            (WebCore::Serializer::StateBase::nextState):
            (WebCore::Serializer::StateBase::setNextState):
            (WebCore::Serializer::StateBase::composite):
            (WebCore::Serializer::StateBase::StateBase):
            (WebCore::Serializer::State::composite):
            (WebCore::Serializer::State::tag):
            (WebCore::Serializer::State::State):
            (WebCore::Serializer::StackCleaner::StackCleaner):
            (WebCore::Serializer::StackCleaner::~StackCleaner):
            (WebCore::Serializer::ArrayState::ArrayState):
            (WebCore::Serializer::ArrayState::done):
            (WebCore::Serializer::ArrayState::advance):
            (WebCore::Serializer::ObjectState::ObjectState):
            (WebCore::Serializer::ObjectState::done):
            (WebCore::Serializer::ObjectState::advance):
            (WebCore::Serializer::ObjectState::nextProperty):
            (WebCore::Serializer::doSerialize):
            (WebCore::Serializer::push):
            (WebCore::Serializer::top):
            (WebCore::Serializer::pop):
            (WebCore::Serializer::checkComposite):
            (WebCore::Reader::Reader):
            (WebCore::Reader::isEof):
            (WebCore::Reader::read):
            (WebCore::Reader::readTag):
            (WebCore::Reader::readString):
            (WebCore::Reader::readInt32):
            (WebCore::Reader::readNumber):
            (WebCore::Reader::doReadUint32):
            (WebCore::Deserializer::Deserializer):
            (WebCore::Deserializer::deserialize):
            (WebCore::Deserializer::doDeserialize):
            (WebCore::Deserializer::push):
            (WebCore::Deserializer::pop):
            (WebCore::Deserializer::stackDepth):
            (WebCore::Deserializer::element):
            (WebCore::SerializedScriptValue::SerializedScriptValue):
            (WebCore::SerializedScriptValue::deserialize):
            * bindings/v8/SerializedScriptValue.h:
            (WebCore::SerializedScriptValue::create):
            (WebCore::SerializedScriptValue::createFromWire):
            (WebCore::SerializedScriptValue::release):
            (WebCore::SerializedScriptValue::toWireString):
    
            Updated uses of SerializedScriptValue:
            * bindings/v8/custom/V8DOMWindowCustom.cpp:
            (WebCore::V8DOMWindow::postMessageCallback):
            * bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
            (WebCore::V8DedicatedWorkerContext::postMessageCallback):
            * bindings/v8/custom/V8HistoryCustom.cpp:
            (WebCore::V8History::pushStateCallback):
            (WebCore::V8History::replaceStateCallback):
            * bindings/v8/custom/V8MessageEventCustom.cpp:
            (WebCore::V8MessageEvent::initMessageEventCallback):
            * bindings/v8/custom/V8MessagePortCustom.cpp:
            (WebCore::V8MessagePort::postMessageCallback):
            * bindings/v8/custom/V8WorkerCustom.cpp:
            (WebCore::V8Worker::postMessageCallback):
    2010-01-20  Vitaly Repeshko  <vitalyr at chromium.org>
    
            Reviewed by Pavel Feldman.
    
            [V8] Support SerializedScriptValue.
            https://bugs.webkit.org/show_bug.cgi?id=32920
            http://crbug.com/30620
    
            Updated uses of SerializedScriptValue:
            * src/PlatformMessagePortChannel.cpp:
            (WebCore::PlatformMessagePortChannel::postMessageToRemote):
            (WebCore::PlatformMessagePortChannel::tryGetMessageFromRemote):
            * src/WebWorkerBase.cpp:
            (WebKit::WebWorkerBase::postMessageToWorkerObject):
            * src/WebWorkerClientImpl.cpp:
            (WebKit::WebWorkerClientImpl::postMessageToWorkerContext):
            (WebKit::WebWorkerClientImpl::postMessageToWorkerObjectTask):
            * src/WebWorkerImpl.cpp:
            (WebKit::WebWorkerImpl::postMessageToWorkerContextTask):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53586 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3746188..e8d1d4b 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,98 @@
+2010-01-20  Vitaly Repeshko  <vitalyr at chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        [V8] Support SerializedScriptValue.
+        https://bugs.webkit.org/show_bug.cgi?id=32920
+        http://crbug.com/30620
+
+        Initial implementation of SerializedScriptValue which is used to
+        to create a serialized representation of JavaScript objects.  This
+        representation is needed for structured clones and worker messages.
+
+        * WebCore.gypi: Added SerializedScriptValue.cpp.
+        * bindings/scripts/CodeGeneratorV8.pm: Removed conversion to string before using SerializedScriptValue.
+        * bindings/v8/SerializedScriptValue.cpp: Added.
+        (WebCore::):
+        (WebCore::ZigZag::encode):
+        (WebCore::ZigZag::decode):
+        (WebCore::Writer::Writer):
+        (WebCore::Writer::writeUndefined):
+        (WebCore::Writer::writeNull):
+        (WebCore::Writer::writeTrue):
+        (WebCore::Writer::writeFalse):
+        (WebCore::Writer::writeString):
+        (WebCore::Writer::writeInt32):
+        (WebCore::Writer::writeNumber):
+        (WebCore::Writer::endComposite):
+        (WebCore::Writer::data):
+        (WebCore::Writer::doWriteUint32):
+        (WebCore::Writer::append):
+        (WebCore::Writer::ensureSpace):
+        (WebCore::Writer::fillHole):
+        (WebCore::Writer::charAt):
+        (WebCore::Serializer::Serializer):
+        (WebCore::Serializer::serialize):
+        (WebCore::Serializer::StateBase::~StateBase):
+        (WebCore::Serializer::StateBase::nextState):
+        (WebCore::Serializer::StateBase::setNextState):
+        (WebCore::Serializer::StateBase::composite):
+        (WebCore::Serializer::StateBase::StateBase):
+        (WebCore::Serializer::State::composite):
+        (WebCore::Serializer::State::tag):
+        (WebCore::Serializer::State::State):
+        (WebCore::Serializer::StackCleaner::StackCleaner):
+        (WebCore::Serializer::StackCleaner::~StackCleaner):
+        (WebCore::Serializer::ArrayState::ArrayState):
+        (WebCore::Serializer::ArrayState::done):
+        (WebCore::Serializer::ArrayState::advance):
+        (WebCore::Serializer::ObjectState::ObjectState):
+        (WebCore::Serializer::ObjectState::done):
+        (WebCore::Serializer::ObjectState::advance):
+        (WebCore::Serializer::ObjectState::nextProperty):
+        (WebCore::Serializer::doSerialize):
+        (WebCore::Serializer::push):
+        (WebCore::Serializer::top):
+        (WebCore::Serializer::pop):
+        (WebCore::Serializer::checkComposite):
+        (WebCore::Reader::Reader):
+        (WebCore::Reader::isEof):
+        (WebCore::Reader::read):
+        (WebCore::Reader::readTag):
+        (WebCore::Reader::readString):
+        (WebCore::Reader::readInt32):
+        (WebCore::Reader::readNumber):
+        (WebCore::Reader::doReadUint32):
+        (WebCore::Deserializer::Deserializer):
+        (WebCore::Deserializer::deserialize):
+        (WebCore::Deserializer::doDeserialize):
+        (WebCore::Deserializer::push):
+        (WebCore::Deserializer::pop):
+        (WebCore::Deserializer::stackDepth):
+        (WebCore::Deserializer::element):
+        (WebCore::SerializedScriptValue::SerializedScriptValue):
+        (WebCore::SerializedScriptValue::deserialize):
+        * bindings/v8/SerializedScriptValue.h:
+        (WebCore::SerializedScriptValue::create):
+        (WebCore::SerializedScriptValue::createFromWire):
+        (WebCore::SerializedScriptValue::release):
+        (WebCore::SerializedScriptValue::toWireString):
+
+        Updated uses of SerializedScriptValue:
+        * bindings/v8/custom/V8DOMWindowCustom.cpp:
+        (WebCore::V8DOMWindow::postMessageCallback):
+        * bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
+        (WebCore::V8DedicatedWorkerContext::postMessageCallback):
+        * bindings/v8/custom/V8HistoryCustom.cpp:
+        (WebCore::V8History::pushStateCallback):
+        (WebCore::V8History::replaceStateCallback):
+        * bindings/v8/custom/V8MessageEventCustom.cpp:
+        (WebCore::V8MessageEvent::initMessageEventCallback):
+        * bindings/v8/custom/V8MessagePortCustom.cpp:
+        (WebCore::V8MessagePort::postMessageCallback):
+        * bindings/v8/custom/V8WorkerCustom.cpp:
+        (WebCore::V8Worker::postMessageCallback):
+
 2010-01-20  Steve Falkenburg  <sfalken at apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index de6d296..ab55ec6 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -803,6 +803,7 @@
             'bindings/v8/ScriptStringImpl.h',
             'bindings/v8/ScriptValue.cpp',
             'bindings/v8/ScriptValue.h',
+            'bindings/v8/SerializedScriptValue.cpp',
             'bindings/v8/SerializedScriptValue.h',
             'bindings/v8/specialization/V8BindingDOMWindow.h',
             'bindings/v8/specialization/V8BindingState.cpp',
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 8880264..43dac54 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -2570,7 +2570,7 @@ sub ReturnNativeToJSValue
 
     if ($type eq "SerializedScriptValue") {
         $implIncludes{"$type.h"} = 1;
-        return "return v8String($value->toString())";
+        return "return $value->deserialize()";
     }
 
     if ($type eq "DedicatedWorkerContext" or $type eq "WorkerContext" or $type eq "SharedWorkerContext") {
diff --git a/WebCore/bindings/v8/SerializedScriptValue.cpp b/WebCore/bindings/v8/SerializedScriptValue.cpp
new file mode 100644
index 0000000..4af1a3a
--- /dev/null
+++ b/WebCore/bindings/v8/SerializedScriptValue.cpp
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2010 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "SharedBuffer.h"
+
+#include <v8.h>
+#include <wtf/Assertions.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+// FIXME:
+// - catch V8 exceptions
+// - be ready to get empty handles
+// - consider crashing in debug mode on deserialization errors
+
+namespace WebCore {
+
+namespace {
+
+typedef UChar BufferValueType;
+
+// Serialization format is a sequence of (tag, optional data)
+// pairs. Tag always takes exactly one byte.
+enum SerializationTag {
+    InvalidTag = '!',
+    PaddingTag = '\0',
+    UndefinedTag = '_',
+    NullTag = '0',
+    TrueTag = 'T',
+    FalseTag = 'F',
+    StringTag = 'S',
+    Int32Tag = 'I',
+    NumberTag = 'N',
+    ObjectTag = '{',
+    ArrayTag = '[',
+};
+
+// Helpers to do verbose handle casts.
+
+template <typename T, typename U>
+static v8::Handle<T> handleCast(v8::Handle<U> handle) { return v8::Handle<T>::Cast(handle); }
+
+template <typename T, typename U>
+static v8::Local<T> handleCast(v8::Local<U> handle) { return v8::Local<T>::Cast(handle); }
+
+static bool shouldCheckForCycles(int depth)
+{
+    ASSERT(depth >= 0);
+    // Since we are not required to spot the cycle as soon as it
+    // happens we can check for cycles only when the current depth
+    // is a power of two.
+    return !(depth & (depth - 1));
+}
+
+static const int maxDepth = 20000;
+
+// VarInt encoding constants.
+static const int varIntShift = 7;
+static const int varIntMask = (1 << varIntShift) - 1;
+
+// ZigZag encoding helps VarInt encoding stay small for negative
+// numbers with small absolute values.
+class ZigZag {
+public:
+    static uint32_t encode(uint32_t value)
+    {
+        if (value & (1U << 31))
+            value = ((~value) << 1) + 1;
+        else
+            value <<= 1;
+        return value;
+    }
+
+    static uint32_t decode(uint32_t value)
+    {
+        if (value & 1)
+            value = ~(value >> 1);
+        else
+            value >>= 1;
+        return value;
+    }
+
+private:
+    ZigZag();
+};
+
+// Writer is responsible for serializing primitive types and storing
+// information used to reconstruct composite types.
+class Writer : Noncopyable {
+public:
+    Writer() : m_position(0)
+    {
+    }
+
+    // Write functions for primitive types.
+
+    void writeUndefined() { append(UndefinedTag); }
+
+    void writeNull() { append(NullTag); }
+
+    void writeTrue() { append(TrueTag); }
+
+    void writeFalse() { append(FalseTag); }
+
+    void writeString(const char* data, int length)
+    {
+        append(StringTag);
+        doWriteUint32(static_cast<uint32_t>(length));
+        append(data, length);
+    }
+
+    void writeInt32(int32_t value)
+    {
+        append(Int32Tag);
+        doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
+    }
+
+    void writeNumber(double number)
+    {
+        append(NumberTag);
+        append(reinterpret_cast<char*>(&number), sizeof(number));
+    }
+
+    // Records that a composite object can be constructed by using
+    // |length| previously stored values.
+    void endComposite(SerializationTag tag, int32_t length)
+    {
+        ASSERT(tag == ObjectTag || tag == ArrayTag);
+        append(tag);
+        doWriteUint32(static_cast<uint32_t>(length));
+    }
+
+    Vector<BufferValueType>& data()
+    {
+        fillHole();
+        return m_buffer;
+    }
+
+private:
+    void doWriteUint32(uint32_t value)
+    {
+        while (true) {
+            char b = (value & varIntMask);
+            value >>= varIntShift;
+            if (!value) {
+                append(b);
+                break;
+            }
+            append(b | (1 << varIntShift));
+        }
+    }
+
+    void append(SerializationTag tag)
+    {
+        append(static_cast<char>(tag));
+    }
+
+    void append(char b)
+    {
+        ensureSpace(1);
+        *charAt(m_position++) = b;
+    }
+
+    void append(const char* data, int length)
+    {
+        ensureSpace(length);
+        memcpy(charAt(m_position), data, length);
+        m_position += length;
+    }
+
+    void ensureSpace(int extra)
+    {
+        COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
+        m_buffer.grow((m_position + extra + 1) / 2); // "+ 1" to round up.
+    }
+
+    void fillHole()
+    {
+        COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
+        // If the writer is at odd position in the buffer, then one of
+        // the bytes in the last UChar is not initialized.
+        if (m_position % 2)
+            *charAt(m_position) = static_cast<char>(PaddingTag);
+    }
+
+    char* charAt(int position) { return reinterpret_cast<char*>(m_buffer.data()) + position; }
+
+    Vector<BufferValueType> m_buffer;
+    unsigned m_position;
+};
+
+class Serializer {
+public:
+    explicit Serializer(Writer& writer)
+        : m_writer(writer)
+        , m_state(0)
+        , m_depth(0)
+    {
+    }
+
+    bool serialize(v8::Handle<v8::Value> value)
+    {
+        v8::HandleScope scope;
+        StackCleaner cleaner(&m_state);
+        if (!doSerialize(value))
+            return false;
+        while (top()) {
+            int length;
+            while (!top()->isDone(&length)) {
+                // Note that doSerialize() can change current top().
+                if (!doSerialize(top()->advance()))
+                    return false;
+            }
+            m_writer.endComposite(top()->tag(), length);
+            pop();
+        }
+        return true;
+    }
+
+private:
+    class StateBase : public Noncopyable {
+    public:
+        virtual ~StateBase() { }
+
+        // Link to the next state to form a stack.
+        StateBase* nextState() { return m_next; }
+        void setNextState(StateBase* next) { m_next = next; }
+
+        // Composite object we're processing in this state.
+        v8::Handle<v8::Value> composite() { return m_composite; }
+
+        // Serialization tag for the current composite.
+        virtual SerializationTag tag() const = 0;
+
+        // Returns whether iteration over subobjects of the current
+        // composite object is done. If yes, |*length| is set to the
+        // number of subobjects.
+        virtual bool isDone(int* length) = 0;
+
+        // Advances to the next subobject.
+        // Requires: !this->isDone().
+        virtual v8::Local<v8::Value> advance() = 0;
+
+    protected:
+        StateBase(v8::Handle<v8::Value> composite)
+            : m_next(0)
+            , m_composite(composite)
+        {
+        }
+
+    private:
+        StateBase* m_next;
+        v8::Handle<v8::Value> m_composite;
+    };
+
+    template <typename T, SerializationTag compositeTag>
+    class State : public StateBase {
+    public:
+        v8::Handle<T> composite() { return handleCast<T>(StateBase::composite()); }
+
+        virtual SerializationTag tag() const { return compositeTag; }
+
+    protected:
+        explicit State(v8::Handle<T> composite) : StateBase(composite)
+        {
+        }
+    };
+
+    // Helper to clean up the state stack in case of errors.
+    class StackCleaner : Noncopyable {
+    public:
+        explicit StackCleaner(StateBase** stack) : m_stack(stack)
+        {
+        }
+
+        ~StackCleaner()
+        {
+            StateBase* state = *m_stack;
+            while (state) {
+                StateBase* tmp = state->nextState();
+                delete state;
+                state = tmp;
+            }
+            *m_stack = 0;
+        }
+
+    private:
+        StateBase** m_stack;
+    };
+
+    class ArrayState : public State<v8::Array, ArrayTag> {
+    public:
+        ArrayState(v8::Handle<v8::Array> array)
+            : State<v8::Array, ArrayTag>(array)
+            , m_index(0)
+        {
+        }
+
+        virtual bool isDone(int* length)
+        {
+            *length = composite()->Length();
+            return static_cast<int>(m_index) >= *length;
+        }
+
+        virtual v8::Local<v8::Value> advance()
+        {
+            ASSERT(m_index < composite()->Length());
+            v8::HandleScope scope;
+            return scope.Close(composite()->Get(v8::Integer::New(m_index++)));
+        }
+
+    private:
+        unsigned m_index;
+    };
+
+    class ObjectState : public State<v8::Object, ObjectTag> {
+    public:
+        ObjectState(v8::Handle<v8::Object> object)
+            : State<v8::Object, ObjectTag>(object)
+            , m_propertyNames(object->GetPropertyNames())
+            , m_index(-1)
+            , m_length(0)
+        {
+            nextProperty();
+        }
+
+        virtual bool isDone(int* length)
+        {
+            *length = m_length;
+            return m_index >= 2 * m_propertyNames->Length();
+        }
+
+        virtual v8::Local<v8::Value> advance()
+        {
+            ASSERT(m_index < 2 * m_propertyNames->Length());
+            if (!(m_index % 2)) {
+                ++m_index;
+                return m_propertyName;
+            }
+            v8::Local<v8::Value> result = composite()->Get(m_propertyName);
+            nextProperty();
+            return result;
+        }
+
+    private:
+        void nextProperty()
+        {
+            v8::HandleScope scope;
+            ++m_index;
+            ASSERT(!(m_index % 2));
+            for (; m_index < 2 * m_propertyNames->Length(); m_index += 2) {
+                v8::Local<v8::Value> propertyName = m_propertyNames->Get(v8::Integer::New(m_index / 2));
+                if ((propertyName->IsString() && composite()->HasRealNamedProperty(handleCast<v8::String>(propertyName)))
+                    || (propertyName->IsInt32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
+                    m_propertyName = scope.Close(propertyName);
+                    m_length += 2;
+                    return;
+                }
+            }
+        }
+
+        v8::Local<v8::Array> m_propertyNames;
+        v8::Local<v8::Value> m_propertyName;
+        unsigned m_index;
+        unsigned m_length;
+    };
+
+    bool doSerialize(v8::Handle<v8::Value> value)
+    {
+        if (value->IsUndefined())
+            m_writer.writeUndefined();
+        else if (value->IsNull())
+            m_writer.writeNull();
+        else if (value->IsTrue())
+            m_writer.writeTrue();
+        else if (value->IsFalse())
+            m_writer.writeFalse();
+        else if (value->IsInt32())
+            m_writer.writeInt32(value->Int32Value());
+        else if (value->IsNumber())
+            m_writer.writeNumber(handleCast<v8::Number>(value)->Value());
+        else if (value->IsString()) {
+            v8::String::Utf8Value stringValue(value);
+            m_writer.writeString(*stringValue, stringValue.length());
+        } else if (value->IsArray()) {
+            if (!checkComposite(value))
+                return false;
+            push(new ArrayState(handleCast<v8::Array>(value)));
+        } else if (value->IsObject()) {
+            if (!checkComposite(value))
+                return false;
+            push(new ObjectState(handleCast<v8::Object>(value)));
+            // FIXME:
+            // - check not a wrapper
+            // - support File, ImageData, etc.
+        }
+        return true;
+    }
+
+    void push(StateBase* state)
+    {
+        state->setNextState(m_state);
+        m_state = state;
+        ++m_depth;
+    }
+
+    StateBase* top() { return m_state; }
+
+    void pop()
+    {
+        if (!m_state)
+            return;
+        StateBase* top = m_state;
+        m_state = top->nextState();
+        delete top;
+        --m_depth;
+    }
+
+    bool checkComposite(v8::Handle<v8::Value> composite)
+    {
+        if (m_depth > maxDepth)
+            return false;
+        if (!shouldCheckForCycles(m_depth))
+            return true;
+        for (StateBase* state = top(); state; state = state->nextState()) {
+            if (state->composite() == composite)
+                return false;
+        }
+        return true;
+    }
+
+    Writer& m_writer;
+    StateBase* m_state;
+    int m_depth;
+};
+
+// Reader is responsible for deserializing primitive types and
+// restoring information about saved objects of composite types.
+class Reader {
+public:
+    Reader(const char* buffer, int length)
+        : m_buffer(buffer)
+        , m_length(length)
+        , m_position(0)
+    {
+        ASSERT(length >= 0);
+    }
+
+    bool isEof() const { return m_position >= m_length; }
+
+    bool read(SerializationTag* tag, v8::Handle<v8::Value>* value, int* length)
+    {
+        uint32_t rawLength;
+        if (!readTag(tag))
+            return false;
+        switch (*tag) {
+        case InvalidTag:
+            return false;
+        case PaddingTag:
+            break;
+        case UndefinedTag:
+            *value = v8::Undefined();
+            break;
+        case NullTag:
+            *value = v8::Null();
+            break;
+        case TrueTag:
+            *value = v8::True();
+            break;
+        case FalseTag:
+            *value = v8::False();
+            break;
+        case StringTag:
+            if (!readString(value))
+                return false;
+            break;
+        case Int32Tag:
+            if (!readInt32(value))
+                return false;
+            break;
+        case NumberTag:
+            if (!readNumber(value))
+                return false;
+            break;
+        case ObjectTag:
+        case ArrayTag:
+            if (!doReadUint32(&rawLength))
+                return false;
+            *length = rawLength;
+            break;
+        }
+        return true;
+    }
+
+private:
+    bool readTag(SerializationTag* tag)
+    {
+        if (m_position >= m_length)
+            return false;
+        *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
+        return true;
+    }
+
+    bool readString(v8::Handle<v8::Value>* value)
+    {
+        uint32_t length;
+        if (!doReadUint32(&length))
+            return false;
+        if (m_position + length > m_length)
+            return false;
+        *value = v8::String::New(m_buffer + m_position, length);
+        m_position += length;
+        return true;
+    }
+
+    bool readInt32(v8::Handle<v8::Value>* value)
+    {
+        uint32_t rawValue;
+        if (!doReadUint32(&rawValue))
+            return false;
+        *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue)));
+        return true;
+    }
+
+    bool readNumber(v8::Handle<v8::Value>* value)
+    {
+        if (m_position + sizeof(double) > m_length)
+            return false;
+        double number;
+        char* numberAsByteArray = reinterpret_cast<char*>(&number);
+        for (unsigned i = 0; i < sizeof(double); ++i)
+            numberAsByteArray[i] = m_buffer[m_position++];
+        *value = v8::Number::New(number);
+        return true;
+    }
+
+    bool doReadUint32(uint32_t* value)
+    {
+        *value = 0;
+        char currentByte;
+        int shift = 0;
+        do {
+            if (m_position >= m_length)
+                return false;
+            currentByte = m_buffer[m_position++];
+            *value |= ((currentByte & varIntMask) << shift);
+            shift += varIntShift;
+        } while (currentByte & (1 << varIntShift));
+        return true;
+    }
+
+    const char* m_buffer;
+    const unsigned m_length;
+    unsigned m_position;
+};
+
+class Deserializer {
+public:
+    explicit Deserializer(Reader& reader) : m_reader(reader)
+    {
+    }
+
+    v8::Local<v8::Value> deserialize()
+    {
+        v8::HandleScope scope;
+        while (!m_reader.isEof()) {
+            if (!doDeserialize())
+                return v8::Local<v8::Value>();
+        }
+        if (stackDepth() != 1)
+            return v8::Local<v8::Value>();
+        return scope.Close(element(0));
+    }
+
+private:
+    bool doDeserialize()
+    {
+        SerializationTag tag;
+        v8::Local<v8::Value> value;
+        int length;
+        if (!m_reader.read(&tag, &value, &length))
+            return false;
+        if (!value.IsEmpty()) {
+            push(value);
+        } else if (tag == ObjectTag) {
+            if (length > stackDepth())
+                return false;
+            v8::Local<v8::Object> object = v8::Object::New();
+            for (int i = stackDepth() - length; i < stackDepth(); i += 2) {
+                v8::Local<v8::Value> propertyName = element(i);
+                v8::Local<v8::Value> propertyValue = element(i + 1);
+                object->Set(propertyName, propertyValue);
+            }
+            pop(length);
+            push(object);
+        } else if (tag == ArrayTag) {
+            if (length > stackDepth())
+                return false;
+            v8::Local<v8::Array> array = v8::Array::New(length);
+            const int depth = stackDepth() - length;
+            {
+                v8::HandleScope scope;
+                for (int i = 0; i < length; ++i)
+                    array->Set(v8::Integer::New(i), element(depth + i));
+            }
+            pop(length);
+            push(array);
+        } else if (tag != PaddingTag)
+            return false;
+        return true;
+    }
+
+    void push(v8::Local<v8::Value> value) { m_stack.append(value); }
+
+    void pop(unsigned length)
+    {
+        ASSERT(length <= m_stack.size());
+        m_stack.shrink(m_stack.size() - length);
+    }
+
+    int stackDepth() const { return m_stack.size(); }
+
+    v8::Local<v8::Value> element(unsigned index)
+    {
+        ASSERT(index < m_stack.size());
+        return m_stack[index];
+    }
+
+    Reader& m_reader;
+    Vector<v8::Local<v8::Value> > m_stack;
+};
+
+} // namespace
+
+SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value)
+{
+    Writer writer;
+    Serializer serializer(writer);
+    if (!serializer.serialize(value)) {
+        // FIXME: throw exception
+        return;
+    }
+    m_data = StringImpl::adopt(writer.data());
+}
+
+SerializedScriptValue::SerializedScriptValue(String data, StringDataMode mode)
+{
+    if (mode == WireData)
+        m_data = data;
+    else {
+        ASSERT(mode == StringValue);
+        RefPtr<SharedBuffer> buffer = utf8Buffer(data);
+        Writer writer;
+        writer.writeString(buffer->data(), buffer->size());
+        m_data = StringImpl::adopt(writer.data());
+    }
+}
+
+v8::Local<v8::Value> SerializedScriptValue::deserialize()
+{
+    if (!m_data.impl())
+        return v8::Local<v8::Value>();
+    COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
+    Reader reader(reinterpret_cast<const char*>(m_data.impl()->characters()), 2 * m_data.length());
+    Deserializer deserializer(reader);
+    return deserializer.deserialize();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/SerializedScriptValue.h b/WebCore/bindings/v8/SerializedScriptValue.h
index 26a4199..7eb8935 100644
--- a/WebCore/bindings/v8/SerializedScriptValue.h
+++ b/WebCore/bindings/v8/SerializedScriptValue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -40,11 +40,26 @@ namespace WebCore {
 
 class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
 public:
-    static PassRefPtr<SerializedScriptValue> create(String string)
+    // Creates a serialized representation of the given V8 value.
+    static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value> value)
     {
-        return adoptRef(new SerializedScriptValue(string));
+        return adoptRef(new SerializedScriptValue(value));
     }
 
+    // Creates a serialized value with the given data obtained from a
+    // prior call to toWireString().
+    static PassRefPtr<SerializedScriptValue> createFromWire(String data)
+    {
+        return adoptRef(new SerializedScriptValue(data, WireData));
+    }
+
+    // Creates a serialized representation of WebCore string.
+    static PassRefPtr<SerializedScriptValue> create(String data)
+    {
+        return adoptRef(new SerializedScriptValue(data, StringValue));
+    }
+
+    // Creates an empty serialized value.
     static PassRefPtr<SerializedScriptValue> create()
     {
         return adoptRef(new SerializedScriptValue());
@@ -52,23 +67,29 @@ public:
 
     PassRefPtr<SerializedScriptValue> release()
     {
-        RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data));
+        RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data, WireData));
         m_data = String();
         return result.release();
     }
 
-    String toString()
-    {
-        return m_data;
-    }
+    String toWireString() const { return m_data; }
+
+    // Deserializes the value (in the current context). Returns an
+    // empty handle in case of failure.
+    v8::Local<v8::Value> deserialize();
 
 private:
-    SerializedScriptValue(String string)
-        : m_data(string)
-    {
-    }
+    enum StringDataMode {
+        StringValue,
+        WireData
+    };
 
     SerializedScriptValue() { }
+
+    explicit SerializedScriptValue(v8::Handle<v8::Value>);
+
+    SerializedScriptValue(String data, StringDataMode mode);
+
     String m_data;
 };
 
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index dacd4f6..b594518 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -411,7 +411,7 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
     ASSERT(source->frame());
 
     v8::TryCatch tryCatch;
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
     MessagePortArray portArray;
     String targetOrigin;
 
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
index 5ab6218..4486dbe 100644
--- a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -46,7 +46,7 @@ v8::Handle<v8::Value> V8DedicatedWorkerContext::postMessageCallback(const v8::Ar
 {
     INC_STATS(L"DOM.DedicatedWorkerContext.postMessage");
     DedicatedWorkerContext* workerContext = V8DedicatedWorkerContext::toNative(args.Holder());
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(v8ValueToWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
     MessagePortArray portArray;
     if (args.Length() > 1) {
         if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
index 6aa0806..b857d6e 100644
--- a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
 
 v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
 {
-    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
 
     v8::TryCatch tryCatch;
     String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -64,7 +64,7 @@ v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
 
 v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
 {
-    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
 
     v8::TryCatch tryCatch;
     String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
diff --git a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
index b291d1a..2b027dc 100644
--- a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -65,7 +65,7 @@ v8::Handle<v8::Value> V8MessageEvent::initMessageEventCallback(const v8::Argumen
     String typeArg = v8ValueToWebCoreString(args[0]);
     bool canBubbleArg = args[1]->BooleanValue();
     bool cancelableArg = args[2]->BooleanValue();
-    RefPtr<SerializedScriptValue> dataArg = SerializedScriptValue::create(v8ValueToWebCoreString(args[3]));
+    RefPtr<SerializedScriptValue> dataArg = SerializedScriptValue::create(args[3]);
     String originArg = v8ValueToWebCoreString(args[4]);
     String lastEventIdArg = v8ValueToWebCoreString(args[5]);
     DOMWindow* sourceArg = V8DOMWindow::HasInstance(args[6]) ? V8DOMWindow::toNative(v8::Handle<v8::Object>::Cast(args[6])) : 0;
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index 071b1ac..cc70bc5 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -78,7 +78,7 @@ v8::Handle<v8::Value> V8MessagePort::postMessageCallback(const v8::Arguments& ar
 {
     INC_STATS("DOM.MessagePort.postMessage");
     MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
     MessagePortArray portArray;
     if (args.Length() > 1) {
         if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
index 99cc2d1..46e9929 100644
--- a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
@@ -44,7 +44,7 @@ v8::Handle<v8::Value> V8PopStateEvent::initPopStateEventCallback(const v8::Argum
     String typeArg = v8ValueToWebCoreString(args[0]);
     bool canBubbleArg = args[1]->BooleanValue();
     bool cancelableArg = args[2]->BooleanValue();
-    RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(v8ValueToWebCoreString(args[3]));
+    RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(args[3]);
 
     PopStateEvent* event = V8PopStateEvent::toNative(args.Holder());
     event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateArg.release());
@@ -61,7 +61,7 @@ v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String>
     if (!state)
         return v8::Null();
 
-    return v8StringOrNull(state->toString());
+    return state->deserialize();
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 6dec7af..4291f6d 100644
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -92,7 +92,7 @@ v8::Handle<v8::Value> V8Worker::postMessageCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.Worker.postMessage");
     Worker* worker = V8Worker::toNative(args.Holder());
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
     MessagePortArray portArray;
     if (args.Length() > 1) {
         if (!getMessagePortArray(args[1], portArray))
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 8ee1505..b74efd8 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,23 @@
+2010-01-20  Vitaly Repeshko  <vitalyr at chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        [V8] Support SerializedScriptValue.
+        https://bugs.webkit.org/show_bug.cgi?id=32920
+        http://crbug.com/30620
+
+        Updated uses of SerializedScriptValue:
+        * src/PlatformMessagePortChannel.cpp:
+        (WebCore::PlatformMessagePortChannel::postMessageToRemote):
+        (WebCore::PlatformMessagePortChannel::tryGetMessageFromRemote):
+        * src/WebWorkerBase.cpp:
+        (WebKit::WebWorkerBase::postMessageToWorkerObject):
+        * src/WebWorkerClientImpl.cpp:
+        (WebKit::WebWorkerClientImpl::postMessageToWorkerContext):
+        (WebKit::WebWorkerClientImpl::postMessageToWorkerObjectTask):
+        * src/WebWorkerImpl.cpp:
+        (WebKit::WebWorkerImpl::postMessageToWorkerContextTask):
+
 2010-01-20  Shinichiro Hamaji  <hamaji at chromium.org>
 
         Reviewed by Darin Fisher.
diff --git a/WebKit/chromium/src/PlatformMessagePortChannel.cpp b/WebKit/chromium/src/PlatformMessagePortChannel.cpp
index f8c41d3..aa42a10 100644
--- a/WebKit/chromium/src/PlatformMessagePortChannel.cpp
+++ b/WebKit/chromium/src/PlatformMessagePortChannel.cpp
@@ -179,7 +179,7 @@ void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChann
     if (!m_localPort || !m_webChannel)
         return;
 
-    WebString messageString = message->message()->toString();
+    WebString messageString = message->message()->toWireString();
     OwnPtr<WebCore::MessagePortChannelArray> channels = message->channels();
     WebMessagePortChannelArray* webChannels = 0;
     if (channels.get() && channels->size()) {
@@ -211,7 +211,7 @@ bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChann
                 (*channels)[i] = MessagePortChannel::create(platformChannel);
             }
         }
-        RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::create(message);
+        RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::createFromWire(message);
         result = MessagePortChannel::EventData::create(serializedMessage.release(), channels.release());
     }
 
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp
index 0e3aa4e..7fd3749 100644
--- a/WebKit/chromium/src/WebWorkerBase.cpp
+++ b/WebKit/chromium/src/WebWorkerBase.cpp
@@ -157,7 +157,7 @@ void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>
                                               PassOwnPtr<MessagePortChannelArray> channels)
 {
     dispatchTaskToMainThread(createCallbackTask(&postMessageTask, this,
-                                                message->toString(), channels));
+                                                message->toWireString(), channels));
 }
 
 void WebWorkerBase::postMessageTask(ScriptExecutionContext* context,
diff --git a/WebKit/chromium/src/WebWorkerClientImpl.cpp b/WebKit/chromium/src/WebWorkerClientImpl.cpp
index 6be03a7..598a078 100644
--- a/WebKit/chromium/src/WebWorkerClientImpl.cpp
+++ b/WebKit/chromium/src/WebWorkerClientImpl.cpp
@@ -173,7 +173,7 @@ void WebWorkerClientImpl::postMessageToWorkerContext(
     if (!isMainThread()) {
         WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&postMessageToWorkerContextTask,
                                                                    this,
-                                                                   message->toString(),
+                                                                   message->toWireString(),
                                                                    channels));
         return;
     }
@@ -184,7 +184,7 @@ void WebWorkerClientImpl::postMessageToWorkerContext(
         webchannel->setClient(0);
         webChannels[i] = webchannel;
     }
-    m_webWorker->postMessageToWorkerContext(message->toString(), webChannels);
+    m_webWorker->postMessageToWorkerContext(message->toWireString(), webChannels);
 }
 
 bool WebWorkerClientImpl::hasPendingActivity() const
@@ -356,7 +356,7 @@ void WebWorkerClientImpl::postMessageToWorkerObjectTask(
         OwnPtr<MessagePortArray> ports =
             MessagePort::entanglePorts(*context, channels.release());
         RefPtr<SerializedScriptValue> serializedMessage =
-            SerializedScriptValue::create(message);
+            SerializedScriptValue::createFromWire(message);
         thisPtr->m_worker->dispatchEvent(MessageEvent::create(ports.release(),
                                                               serializedMessage.release()));
     }
diff --git a/WebKit/chromium/src/WebWorkerImpl.cpp b/WebKit/chromium/src/WebWorkerImpl.cpp
index 744be30..5b5e053 100644
--- a/WebKit/chromium/src/WebWorkerImpl.cpp
+++ b/WebKit/chromium/src/WebWorkerImpl.cpp
@@ -88,7 +88,7 @@ void WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionConte
     OwnPtr<MessagePortArray> ports =
         MessagePort::entanglePorts(*context, channels.release());
     RefPtr<SerializedScriptValue> serializedMessage =
-        SerializedScriptValue::create(message);
+        SerializedScriptValue::createFromWire(message);
     workerContext->dispatchEvent(MessageEvent::create(
         ports.release(), serializedMessage.release()));
     thisPtr->confirmMessageFromWorkerObject(workerContext->hasPendingActivity());

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list