| Index: Source/bindings/core/v8/ScriptValueSerializer.cpp
|
| diff --git a/Source/bindings/core/v8/ScriptValueSerializer.cpp b/Source/bindings/core/v8/ScriptValueSerializer.cpp
|
| index 11fb2d37d51ae2af107bfe62c812cfd6931397ac..3cc2ca973c55c7b6ab2937d02ecf27dd8da24155 100644
|
| --- a/Source/bindings/core/v8/ScriptValueSerializer.cpp
|
| +++ b/Source/bindings/core/v8/ScriptValueSerializer.cpp
|
| @@ -378,6 +378,28 @@ void SerializedScriptValueWriter::writeGenerateFreshDenseArray(uint32_t length)
|
| doWriteUint32(length);
|
| }
|
|
|
| +void SerializedScriptValueWriter::writeGenerateFreshMap()
|
| +{
|
| + append(GenerateFreshMapTag);
|
| +}
|
| +
|
| +void SerializedScriptValueWriter::writeGenerateFreshSet()
|
| +{
|
| + append(GenerateFreshSetTag);
|
| +}
|
| +
|
| +void SerializedScriptValueWriter::writeMap(uint32_t length)
|
| +{
|
| + append(MapTag);
|
| + doWriteUint32(length);
|
| +}
|
| +
|
| +void SerializedScriptValueWriter::writeSet(uint32_t length)
|
| +{
|
| + append(SetTag);
|
| + doWriteUint32(length);
|
| +}
|
| +
|
| void SerializedScriptValueWriter::doWriteFile(const File& file)
|
| {
|
| doWriteWebCoreString(file.hasBackingFile() ? file.path() : "");
|
| @@ -578,6 +600,23 @@ ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::objec
|
| return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
|
| }
|
|
|
| +template <typename T>
|
| +ScriptValueSerializer::StateBase* ScriptValueSerializer::CollectionState<T>::advance(ScriptValueSerializer& serializer)
|
| +{
|
| + while (m_index < m_length) {
|
| + v8::Local<v8::Value> value;
|
| + if (!m_entries->Get(serializer.context(), m_index).ToLocal(&value))
|
| + return serializer.handleError(JSException, "Failed to get an element while cloning a collection.", this);
|
| + m_index++;
|
| + if (StateBase* newState = serializer.checkException(this))
|
| + return newState;
|
| + if (StateBase* newState = serializer.doSerialize(value, this))
|
| + return newState;
|
| + }
|
| + // FIXME: Need to call writeSet for Sets.
|
| + return serializer.writeMap(m_length, this);
|
| +}
|
| +
|
| static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
|
| {
|
| if (!impl)
|
| @@ -710,6 +749,10 @@ ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeValue(v8::Lo
|
| writeBooleanObject(value);
|
| } else if (value->IsArray()) {
|
| return startArrayState(value.As<v8::Array>(), next);
|
| + } else if (value->IsMap()) {
|
| + return startMapState(value.As<v8::Map>(), next);
|
| + } else if (value->IsSet()) {
|
| + return startSetState(value.As<v8::Set>(), next);
|
| } else if (V8File::hasInstance(value, isolate())) {
|
| return writeFile(value, next);
|
| } else if (V8Blob::hasInstance(value, isolate())) {
|
| @@ -763,6 +806,18 @@ ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_
|
| return pop(state);
|
| }
|
|
|
| +ScriptValueSerializer::StateBase* ScriptValueSerializer::writeMap(uint32_t length, ScriptValueSerializer::StateBase* state)
|
| +{
|
| + m_writer.writeMap(length);
|
| + return pop(state);
|
| +}
|
| +
|
| +ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSet(uint32_t length, ScriptValueSerializer::StateBase* state)
|
| +{
|
| + m_writer.writeSet(length);
|
| + return pop(state);
|
| +}
|
| +
|
| ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValueSerializer::Status errorStatus, const String& message, ScriptValueSerializer::StateBase* state)
|
| {
|
| ASSERT(errorStatus != Success);
|
| @@ -982,6 +1037,18 @@ ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Loc
|
| return push(new SparseArrayState(array, propertyNames, next, isolate()));
|
| }
|
|
|
| +ScriptValueSerializer::StateBase* ScriptValueSerializer::startMapState(v8::Local<v8::Map> map, ScriptValueSerializer::StateBase* next)
|
| +{
|
| + m_writer.writeGenerateFreshMap();
|
| + return push(new CollectionState<v8::Map>(map, next));
|
| +}
|
| +
|
| +ScriptValueSerializer::StateBase* ScriptValueSerializer::startSetState(v8::Local<v8::Set> set, ScriptValueSerializer::StateBase* next)
|
| +{
|
| + m_writer.writeGenerateFreshSet();
|
| + return push(new CollectionState<v8::Set>(set, next));
|
| +}
|
| +
|
| ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next)
|
| {
|
| m_writer.writeGenerateFreshObject();
|
| @@ -1170,6 +1237,22 @@ bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Local<v8
|
| return false;
|
| break;
|
| }
|
| + case MapTag: {
|
| + uint32_t length;
|
| + if (!doReadUint32(&length))
|
| + return false;
|
| + if (!creator.completeMap(length, value))
|
| + return false;
|
| + break;
|
| + }
|
| + case SetTag: {
|
| + uint32_t length;
|
| + if (!doReadUint32(&length))
|
| + return false;
|
| + if (!creator.completeSet(length, value))
|
| + return false;
|
| + break;
|
| + }
|
| case ArrayBufferViewTag: {
|
| if (!m_version)
|
| return false;
|
| @@ -1213,6 +1296,20 @@ bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Local<v8
|
| return false;
|
| return true;
|
| }
|
| + case GenerateFreshMapTag: {
|
| + if (!m_version)
|
| + return false;
|
| + if (!creator.newMap())
|
| + return false;
|
| + return true;
|
| + }
|
| + case GenerateFreshSetTag: {
|
| + if (!m_version)
|
| + return false;
|
| + if (!creator.newSet())
|
| + return false;
|
| + return true;
|
| + }
|
| case MessagePortTag: {
|
| if (!m_version)
|
| return false;
|
| @@ -1760,6 +1857,20 @@ bool ScriptValueDeserializer::newDenseArray(uint32_t length)
|
| return true;
|
| }
|
|
|
| +bool ScriptValueDeserializer::newMap()
|
| +{
|
| + v8::Local<v8::Map> map = v8::Map::New(m_reader.scriptState()->isolate());
|
| + openComposite(map);
|
| + return true;
|
| +}
|
| +
|
| +bool ScriptValueDeserializer::newSet()
|
| +{
|
| + v8::Local<v8::Set> set = v8::Set::New(m_reader.scriptState()->isolate());
|
| + openComposite(set);
|
| + return true;
|
| +}
|
| +
|
| bool ScriptValueDeserializer::consumeTopOfStack(v8::Local<v8::Value>* object)
|
| {
|
| if (stackDepth() < 1)
|
| @@ -1839,6 +1950,52 @@ bool ScriptValueDeserializer::completeDenseArray(uint32_t numProperties, uint32_
|
| return true;
|
| }
|
|
|
| +bool ScriptValueDeserializer::completeMap(uint32_t length, v8::Local<v8::Value>* value)
|
| +{
|
| + ASSERT(m_version > 0);
|
| + v8::Local<v8::Object> map;
|
| + v8::Local<v8::Value> composite;
|
| + if (!closeComposite(&composite))
|
| + return false;
|
| + map = composite.As<v8::Map>();
|
| + if (map.IsEmpty())
|
| + return false;
|
| + /*
|
| + v8::Local<v8::Context> context = m_reader.scriptState()->context();
|
| + ASSERT(length % 2 == 0);
|
| + for (unsigned i = stackDepth() - length; i + 1 < stackDepth(); i += 2) {
|
| + v8::Local<v8::Value> key = element(i);
|
| + v8::Local<v8::Value> value = element(i + 1);
|
| + if (map->Set(context, key, value).IsEmpty())
|
| + return false;
|
| + }
|
| + */
|
| + pop(length);
|
| + return true;
|
| +}
|
| +
|
| +bool ScriptValueDeserializer::completeSet(uint32_t length, v8::Local<v8::Value>* value)
|
| +{
|
| + ASSERT(m_version > 0);
|
| + v8::Local<v8::Object> set;
|
| + v8::Local<v8::Value> composite;
|
| + if (!closeComposite(&composite))
|
| + return false;
|
| + set = composite.As<v8::Set>();
|
| + if (set.IsEmpty())
|
| + return false;
|
| + /*
|
| + v8::Local<v8::Context> context = m_reader.scriptState()->context();
|
| + for (unsigned i = stackDepth() - length; i < stackDepth(); i++) {
|
| + v8::Local<v8::Value> key = element(i);
|
| + if (set->Add(context, key).IsEmpty())
|
| + return false;
|
| + }
|
| + */
|
| + pop(length);
|
| + return true;
|
| +}
|
| +
|
| void ScriptValueDeserializer::pushObjectReference(const v8::Local<v8::Value>& object)
|
| {
|
| m_objectPool.append(object);
|
|
|