Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Unified Diff: Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 1185703009: Work In Progress: Handle Maps and Sets in Structured Clone (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/core/v8/ScriptValueSerializer.h ('k') | Source/bindings/core/v8/SerializationTag.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « Source/bindings/core/v8/ScriptValueSerializer.h ('k') | Source/bindings/core/v8/SerializationTag.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698