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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "bindings/core/v8/ScriptValueSerializer.h" 6 #include "bindings/core/v8/ScriptValueSerializer.h"
7 7
8 #include "bindings/core/v8/V8ArrayBuffer.h" 8 #include "bindings/core/v8/V8ArrayBuffer.h"
9 #include "bindings/core/v8/V8ArrayBufferView.h" 9 #include "bindings/core/v8/V8ArrayBufferView.h"
10 #include "bindings/core/v8/V8Blob.h" 10 #include "bindings/core/v8/V8Blob.h"
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 append(GenerateFreshSparseArrayTag); 371 append(GenerateFreshSparseArrayTag);
372 doWriteUint32(length); 372 doWriteUint32(length);
373 } 373 }
374 374
375 void SerializedScriptValueWriter::writeGenerateFreshDenseArray(uint32_t length) 375 void SerializedScriptValueWriter::writeGenerateFreshDenseArray(uint32_t length)
376 { 376 {
377 append(GenerateFreshDenseArrayTag); 377 append(GenerateFreshDenseArrayTag);
378 doWriteUint32(length); 378 doWriteUint32(length);
379 } 379 }
380 380
381 void SerializedScriptValueWriter::writeGenerateFreshMap()
382 {
383 append(GenerateFreshMapTag);
384 }
385
386 void SerializedScriptValueWriter::writeGenerateFreshSet()
387 {
388 append(GenerateFreshSetTag);
389 }
390
391 void SerializedScriptValueWriter::writeMap(uint32_t length)
392 {
393 append(MapTag);
394 doWriteUint32(length);
395 }
396
397 void SerializedScriptValueWriter::writeSet(uint32_t length)
398 {
399 append(SetTag);
400 doWriteUint32(length);
401 }
402
381 void SerializedScriptValueWriter::doWriteFile(const File& file) 403 void SerializedScriptValueWriter::doWriteFile(const File& file)
382 { 404 {
383 doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); 405 doWriteWebCoreString(file.hasBackingFile() ? file.path() : "");
384 doWriteWebCoreString(file.name()); 406 doWriteWebCoreString(file.name());
385 doWriteWebCoreString(file.webkitRelativePath()); 407 doWriteWebCoreString(file.webkitRelativePath());
386 doWriteWebCoreString(file.uuid()); 408 doWriteWebCoreString(file.uuid());
387 doWriteWebCoreString(file.type()); 409 doWriteWebCoreString(file.type());
388 410
389 // FIXME don't use 1 byte to encode a flag. 411 // FIXME don't use 1 byte to encode a flag.
390 if (file.hasValidSnapshotMetadata()) { 412 if (file.hasValidSnapshotMetadata()) {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::advan ce(ScriptValueSerializer& serializer) 593 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::advan ce(ScriptValueSerializer& serializer)
572 { 594 {
573 return serializeProperties(false, serializer); 595 return serializeProperties(false, serializer);
574 } 596 }
575 597
576 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::objec tDone(unsigned numProperties, ScriptValueSerializer& serializer) 598 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::objec tDone(unsigned numProperties, ScriptValueSerializer& serializer)
577 { 599 {
578 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>( )->Length(), this); 600 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>( )->Length(), this);
579 } 601 }
580 602
603 template <typename T>
604 ScriptValueSerializer::StateBase* ScriptValueSerializer::CollectionState<T>::adv ance(ScriptValueSerializer& serializer)
605 {
606 while (m_index < m_length) {
607 v8::Local<v8::Value> value;
608 if (!m_entries->Get(serializer.context(), m_index).ToLocal(&value))
609 return serializer.handleError(JSException, "Failed to get an element while cloning a collection.", this);
610 m_index++;
611 if (StateBase* newState = serializer.checkException(this))
612 return newState;
613 if (StateBase* newState = serializer.doSerialize(value, this))
614 return newState;
615 }
616 // FIXME: Need to call writeSet for Sets.
617 return serializer.writeMap(m_length, this);
618 }
619
581 static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) 620 static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
582 { 621 {
583 if (!impl) 622 if (!impl)
584 return v8::Local<v8::Object>(); 623 return v8::Local<v8::Object>();
585 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); 624 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
586 if (wrapper.IsEmpty()) 625 if (wrapper.IsEmpty())
587 return v8::Local<v8::Object>(); 626 return v8::Local<v8::Object>();
588 ASSERT(wrapper->IsObject()); 627 ASSERT(wrapper->IsObject());
589 return wrapper.As<v8::Object>(); 628 return wrapper.As<v8::Object>();
590 } 629 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if (value->IsDate()) { 742 if (value->IsDate()) {
704 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); 743 m_writer.writeDate(value.As<v8::Date>()->ValueOf());
705 } else if (value->IsStringObject()) { 744 } else if (value->IsStringObject()) {
706 writeStringObject(value); 745 writeStringObject(value);
707 } else if (value->IsNumberObject()) { 746 } else if (value->IsNumberObject()) {
708 writeNumberObject(value); 747 writeNumberObject(value);
709 } else if (value->IsBooleanObject()) { 748 } else if (value->IsBooleanObject()) {
710 writeBooleanObject(value); 749 writeBooleanObject(value);
711 } else if (value->IsArray()) { 750 } else if (value->IsArray()) {
712 return startArrayState(value.As<v8::Array>(), next); 751 return startArrayState(value.As<v8::Array>(), next);
752 } else if (value->IsMap()) {
753 return startMapState(value.As<v8::Map>(), next);
754 } else if (value->IsSet()) {
755 return startSetState(value.As<v8::Set>(), next);
713 } else if (V8File::hasInstance(value, isolate())) { 756 } else if (V8File::hasInstance(value, isolate())) {
714 return writeFile(value, next); 757 return writeFile(value, next);
715 } else if (V8Blob::hasInstance(value, isolate())) { 758 } else if (V8Blob::hasInstance(value, isolate())) {
716 return writeBlob(value, next); 759 return writeBlob(value, next);
717 } else if (V8FileList::hasInstance(value, isolate())) { 760 } else if (V8FileList::hasInstance(value, isolate())) {
718 return writeFileList(value, next); 761 return writeFileList(value, next);
719 } else if (V8ImageData::hasInstance(value, isolate())) { 762 } else if (V8ImageData::hasInstance(value, isolate())) {
720 writeImageData(value); 763 writeImageData(value);
721 } else if (value->IsRegExp()) { 764 } else if (value->IsRegExp()) {
722 writeRegExp(value); 765 writeRegExp(value);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 m_writer.writeSparseArray(numProperties, length); 799 m_writer.writeSparseArray(numProperties, length);
757 return pop(state); 800 return pop(state);
758 } 801 }
759 802
760 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) 803 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state)
761 { 804 {
762 m_writer.writeDenseArray(numProperties, length); 805 m_writer.writeDenseArray(numProperties, length);
763 return pop(state); 806 return pop(state);
764 } 807 }
765 808
809 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeMap(uint32_t lengt h, ScriptValueSerializer::StateBase* state)
810 {
811 m_writer.writeMap(length);
812 return pop(state);
813 }
814
815 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSet(uint32_t lengt h, ScriptValueSerializer::StateBase* state)
816 {
817 m_writer.writeSet(length);
818 return pop(state);
819 }
820
766 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state) 821 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state)
767 { 822 {
768 ASSERT(errorStatus != Success); 823 ASSERT(errorStatus != Success);
769 m_status = errorStatus; 824 m_status = errorStatus;
770 m_errorMessage = message; 825 m_errorMessage = message;
771 while (state) { 826 while (state) {
772 StateBase* tmp = state->nextState(); 827 StateBase* tmp = state->nextState();
773 delete state; 828 delete state;
774 state = tmp; 829 state = tmp;
775 } 830 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 1030
976 if (shouldSerializeDensely(length, propertyNames->Length())) { 1031 if (shouldSerializeDensely(length, propertyNames->Length())) {
977 m_writer.writeGenerateFreshDenseArray(length); 1032 m_writer.writeGenerateFreshDenseArray(length);
978 return push(new DenseArrayState(array, propertyNames, next, isolate())); 1033 return push(new DenseArrayState(array, propertyNames, next, isolate()));
979 } 1034 }
980 1035
981 m_writer.writeGenerateFreshSparseArray(length); 1036 m_writer.writeGenerateFreshSparseArray(length);
982 return push(new SparseArrayState(array, propertyNames, next, isolate())); 1037 return push(new SparseArrayState(array, propertyNames, next, isolate()));
983 } 1038 }
984 1039
1040 ScriptValueSerializer::StateBase* ScriptValueSerializer::startMapState(v8::Local <v8::Map> map, ScriptValueSerializer::StateBase* next)
1041 {
1042 m_writer.writeGenerateFreshMap();
1043 return push(new CollectionState<v8::Map>(map, next));
1044 }
1045
1046 ScriptValueSerializer::StateBase* ScriptValueSerializer::startSetState(v8::Local <v8::Set> set, ScriptValueSerializer::StateBase* next)
1047 {
1048 m_writer.writeGenerateFreshSet();
1049 return push(new CollectionState<v8::Set>(set, next));
1050 }
1051
985 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, ScriptValueSerializer::StateBase* next) 1052 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, ScriptValueSerializer::StateBase* next)
986 { 1053 {
987 m_writer.writeGenerateFreshObject(); 1054 m_writer.writeGenerateFreshObject();
988 // FIXME: check not a wrapper 1055 // FIXME: check not a wrapper
989 return push(new ObjectState(object, next)); 1056 return push(new ObjectState(object, next));
990 } 1057 }
991 1058
992 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. 1059 // Marks object as having been visited by the serializer and assigns it a unique object reference ID.
993 // An object may only be greyed once. 1060 // An object may only be greyed once.
994 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object) 1061 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object)
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 uint32_t numProperties; 1230 uint32_t numProperties;
1164 uint32_t length; 1231 uint32_t length;
1165 if (!doReadUint32(&numProperties)) 1232 if (!doReadUint32(&numProperties))
1166 return false; 1233 return false;
1167 if (!doReadUint32(&length)) 1234 if (!doReadUint32(&length))
1168 return false; 1235 return false;
1169 if (!creator.completeDenseArray(numProperties, length, value)) 1236 if (!creator.completeDenseArray(numProperties, length, value))
1170 return false; 1237 return false;
1171 break; 1238 break;
1172 } 1239 }
1240 case MapTag: {
1241 uint32_t length;
1242 if (!doReadUint32(&length))
1243 return false;
1244 if (!creator.completeMap(length, value))
1245 return false;
1246 break;
1247 }
1248 case SetTag: {
1249 uint32_t length;
1250 if (!doReadUint32(&length))
1251 return false;
1252 if (!creator.completeSet(length, value))
1253 return false;
1254 break;
1255 }
1173 case ArrayBufferViewTag: { 1256 case ArrayBufferViewTag: {
1174 if (!m_version) 1257 if (!m_version)
1175 return false; 1258 return false;
1176 if (!readArrayBufferView(value, creator)) 1259 if (!readArrayBufferView(value, creator))
1177 return false; 1260 return false;
1178 creator.pushObjectReference(*value); 1261 creator.pushObjectReference(*value);
1179 break; 1262 break;
1180 } 1263 }
1181 case ArrayBufferTag: { 1264 case ArrayBufferTag: {
1182 if (!m_version) 1265 if (!m_version)
(...skipping 23 matching lines...) Expand all
1206 case GenerateFreshDenseArrayTag: { 1289 case GenerateFreshDenseArrayTag: {
1207 if (!m_version) 1290 if (!m_version)
1208 return false; 1291 return false;
1209 uint32_t length; 1292 uint32_t length;
1210 if (!doReadUint32(&length)) 1293 if (!doReadUint32(&length))
1211 return false; 1294 return false;
1212 if (!creator.newDenseArray(length)) 1295 if (!creator.newDenseArray(length))
1213 return false; 1296 return false;
1214 return true; 1297 return true;
1215 } 1298 }
1299 case GenerateFreshMapTag: {
1300 if (!m_version)
1301 return false;
1302 if (!creator.newMap())
1303 return false;
1304 return true;
1305 }
1306 case GenerateFreshSetTag: {
1307 if (!m_version)
1308 return false;
1309 if (!creator.newSet())
1310 return false;
1311 return true;
1312 }
1216 case MessagePortTag: { 1313 case MessagePortTag: {
1217 if (!m_version) 1314 if (!m_version)
1218 return false; 1315 return false;
1219 uint32_t index; 1316 uint32_t index;
1220 if (!doReadUint32(&index)) 1317 if (!doReadUint32(&index))
1221 return false; 1318 return false;
1222 if (!creator.tryGetTransferredMessagePort(index, value)) 1319 if (!creator.tryGetTransferredMessagePort(index, value))
1223 return false; 1320 return false;
1224 break; 1321 break;
1225 } 1322 }
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 return true; 1850 return true;
1754 } 1851 }
1755 1852
1756 bool ScriptValueDeserializer::newDenseArray(uint32_t length) 1853 bool ScriptValueDeserializer::newDenseArray(uint32_t length)
1757 { 1854 {
1758 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length); 1855 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length);
1759 openComposite(array); 1856 openComposite(array);
1760 return true; 1857 return true;
1761 } 1858 }
1762 1859
1860 bool ScriptValueDeserializer::newMap()
1861 {
1862 v8::Local<v8::Map> map = v8::Map::New(m_reader.scriptState()->isolate());
1863 openComposite(map);
1864 return true;
1865 }
1866
1867 bool ScriptValueDeserializer::newSet()
1868 {
1869 v8::Local<v8::Set> set = v8::Set::New(m_reader.scriptState()->isolate());
1870 openComposite(set);
1871 return true;
1872 }
1873
1763 bool ScriptValueDeserializer::consumeTopOfStack(v8::Local<v8::Value>* object) 1874 bool ScriptValueDeserializer::consumeTopOfStack(v8::Local<v8::Value>* object)
1764 { 1875 {
1765 if (stackDepth() < 1) 1876 if (stackDepth() < 1)
1766 return false; 1877 return false;
1767 *object = element(stackDepth() - 1); 1878 *object = element(stackDepth() - 1);
1768 pop(1); 1879 pop(1);
1769 return true; 1880 return true;
1770 } 1881 }
1771 1882
1772 bool ScriptValueDeserializer::newObject() 1883 bool ScriptValueDeserializer::newObject()
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 if (!elem->IsUndefined()) { 1943 if (!elem->IsUndefined()) {
1833 // TODO(jsbell): Use DefineOwnProperty when exposed by v8. http://cr bug.com/475206 1944 // TODO(jsbell): Use DefineOwnProperty when exposed by v8. http://cr bug.com/475206
1834 if (!v8CallBoolean(array->ForceSet(context, v8::Integer::New(isolate , i), elem))) 1945 if (!v8CallBoolean(array->ForceSet(context, v8::Integer::New(isolate , i), elem)))
1835 return false; 1946 return false;
1836 } 1947 }
1837 } 1948 }
1838 pop(length); 1949 pop(length);
1839 return true; 1950 return true;
1840 } 1951 }
1841 1952
1953 bool ScriptValueDeserializer::completeMap(uint32_t length, v8::Local<v8::Value>* value)
1954 {
1955 ASSERT(m_version > 0);
1956 v8::Local<v8::Object> map;
1957 v8::Local<v8::Value> composite;
1958 if (!closeComposite(&composite))
1959 return false;
1960 map = composite.As<v8::Map>();
1961 if (map.IsEmpty())
1962 return false;
1963 /*
1964 v8::Local<v8::Context> context = m_reader.scriptState()->context();
1965 ASSERT(length % 2 == 0);
1966 for (unsigned i = stackDepth() - length; i + 1 < stackDepth(); i += 2) {
1967 v8::Local<v8::Value> key = element(i);
1968 v8::Local<v8::Value> value = element(i + 1);
1969 if (map->Set(context, key, value).IsEmpty())
1970 return false;
1971 }
1972 */
1973 pop(length);
1974 return true;
1975 }
1976
1977 bool ScriptValueDeserializer::completeSet(uint32_t length, v8::Local<v8::Value>* value)
1978 {
1979 ASSERT(m_version > 0);
1980 v8::Local<v8::Object> set;
1981 v8::Local<v8::Value> composite;
1982 if (!closeComposite(&composite))
1983 return false;
1984 set = composite.As<v8::Set>();
1985 if (set.IsEmpty())
1986 return false;
1987 /*
1988 v8::Local<v8::Context> context = m_reader.scriptState()->context();
1989 for (unsigned i = stackDepth() - length; i < stackDepth(); i++) {
1990 v8::Local<v8::Value> key = element(i);
1991 if (set->Add(context, key).IsEmpty())
1992 return false;
1993 }
1994 */
1995 pop(length);
1996 return true;
1997 }
1998
1842 void ScriptValueDeserializer::pushObjectReference(const v8::Local<v8::Value>& ob ject) 1999 void ScriptValueDeserializer::pushObjectReference(const v8::Local<v8::Value>& ob ject)
1843 { 2000 {
1844 m_objectPool.append(object); 2001 m_objectPool.append(object);
1845 } 2002 }
1846 2003
1847 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::L ocal<v8::Value>* object) 2004 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::L ocal<v8::Value>* object)
1848 { 2005 {
1849 if (!m_transferredMessagePorts) 2006 if (!m_transferredMessagePorts)
1850 return false; 2007 return false;
1851 if (index >= m_transferredMessagePorts->size()) 2008 if (index >= m_transferredMessagePorts->size())
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 return false; 2097 return false;
1941 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; 2098 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
1942 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 2099 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
1943 if (objectReference >= m_objectPool.size()) 2100 if (objectReference >= m_objectPool.size())
1944 return false; 2101 return false;
1945 *object = m_objectPool[objectReference]; 2102 *object = m_objectPool[objectReference];
1946 return true; 2103 return true;
1947 } 2104 }
1948 2105
1949 } // namespace blink 2106 } // namespace blink
OLDNEW
« 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