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

Side by Side Diff: Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 1205973002: Support structured cloning of ES'15 Map and Set (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Handled first round of comments 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 return serializer.writeCollection<T>(m_length, this);
617 }
618
581 static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) 619 static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
582 { 620 {
583 if (!impl) 621 if (!impl)
584 return v8::Local<v8::Object>(); 622 return v8::Local<v8::Object>();
585 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); 623 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
586 if (wrapper.IsEmpty()) 624 if (wrapper.IsEmpty())
587 return v8::Local<v8::Object>(); 625 return v8::Local<v8::Object>();
588 ASSERT(wrapper->IsObject()); 626 ASSERT(wrapper->IsObject());
589 return wrapper.As<v8::Object>(); 627 return wrapper.As<v8::Object>();
590 } 628 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if (value->IsDate()) { 741 if (value->IsDate()) {
704 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); 742 m_writer.writeDate(value.As<v8::Date>()->ValueOf());
705 } else if (value->IsStringObject()) { 743 } else if (value->IsStringObject()) {
706 writeStringObject(value); 744 writeStringObject(value);
707 } else if (value->IsNumberObject()) { 745 } else if (value->IsNumberObject()) {
708 writeNumberObject(value); 746 writeNumberObject(value);
709 } else if (value->IsBooleanObject()) { 747 } else if (value->IsBooleanObject()) {
710 writeBooleanObject(value); 748 writeBooleanObject(value);
711 } else if (value->IsArray()) { 749 } else if (value->IsArray()) {
712 return startArrayState(value.As<v8::Array>(), next); 750 return startArrayState(value.As<v8::Array>(), next);
751 } else if (value->IsMap()) {
752 return startMapState(value.As<v8::Map>(), next);
753 } else if (value->IsSet()) {
754 return startSetState(value.As<v8::Set>(), next);
713 } else if (V8File::hasInstance(value, isolate())) { 755 } else if (V8File::hasInstance(value, isolate())) {
714 return writeFile(value, next); 756 return writeFile(value, next);
715 } else if (V8Blob::hasInstance(value, isolate())) { 757 } else if (V8Blob::hasInstance(value, isolate())) {
716 return writeBlob(value, next); 758 return writeBlob(value, next);
717 } else if (V8FileList::hasInstance(value, isolate())) { 759 } else if (V8FileList::hasInstance(value, isolate())) {
718 return writeFileList(value, next); 760 return writeFileList(value, next);
719 } else if (V8ImageData::hasInstance(value, isolate())) { 761 } else if (V8ImageData::hasInstance(value, isolate())) {
720 writeImageData(value); 762 writeImageData(value);
721 } else if (value->IsRegExp()) { 763 } else if (value->IsRegExp()) {
722 writeRegExp(value); 764 writeRegExp(value);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 m_writer.writeSparseArray(numProperties, length); 798 m_writer.writeSparseArray(numProperties, length);
757 return pop(state); 799 return pop(state);
758 } 800 }
759 801
760 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) 802 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state)
761 { 803 {
762 m_writer.writeDenseArray(numProperties, length); 804 m_writer.writeDenseArray(numProperties, length);
763 return pop(state); 805 return pop(state);
764 } 806 }
765 807
808 template <>
809 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Map >(uint32_t length, ScriptValueSerializer::StateBase* state)
810 {
811 m_writer.writeMap(length);
812 return pop(state);
813 }
814
815 template <>
816 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Set >(uint32_t length, ScriptValueSerializer::StateBase* state)
817 {
818 m_writer.writeSet(length);
819 return pop(state);
820 }
821
766 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state) 822 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state)
767 { 823 {
768 ASSERT(errorStatus != Success); 824 ASSERT(errorStatus != Success);
769 m_status = errorStatus; 825 m_status = errorStatus;
770 m_errorMessage = message; 826 m_errorMessage = message;
771 while (state) { 827 while (state) {
772 StateBase* tmp = state->nextState(); 828 StateBase* tmp = state->nextState();
773 delete state; 829 delete state;
774 state = tmp; 830 state = tmp;
775 } 831 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 1031
976 if (shouldSerializeDensely(length, propertyNames->Length())) { 1032 if (shouldSerializeDensely(length, propertyNames->Length())) {
977 m_writer.writeGenerateFreshDenseArray(length); 1033 m_writer.writeGenerateFreshDenseArray(length);
978 return push(new DenseArrayState(array, propertyNames, next, isolate())); 1034 return push(new DenseArrayState(array, propertyNames, next, isolate()));
979 } 1035 }
980 1036
981 m_writer.writeGenerateFreshSparseArray(length); 1037 m_writer.writeGenerateFreshSparseArray(length);
982 return push(new SparseArrayState(array, propertyNames, next, isolate())); 1038 return push(new SparseArrayState(array, propertyNames, next, isolate()));
983 } 1039 }
984 1040
1041 ScriptValueSerializer::StateBase* ScriptValueSerializer::startMapState(v8::Local <v8::Map> map, ScriptValueSerializer::StateBase* next)
1042 {
1043 m_writer.writeGenerateFreshMap();
1044 return push(new MapState(map, next));
1045 }
1046
1047 ScriptValueSerializer::StateBase* ScriptValueSerializer::startSetState(v8::Local <v8::Set> set, ScriptValueSerializer::StateBase* next)
1048 {
1049 m_writer.writeGenerateFreshSet();
1050 return push(new SetState(set, next));
1051 }
1052
985 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, ScriptValueSerializer::StateBase* next) 1053 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, ScriptValueSerializer::StateBase* next)
986 { 1054 {
987 m_writer.writeGenerateFreshObject(); 1055 m_writer.writeGenerateFreshObject();
988 // FIXME: check not a wrapper 1056 // FIXME: check not a wrapper
989 return push(new ObjectState(object, next)); 1057 return push(new ObjectState(object, next));
990 } 1058 }
991 1059
992 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. 1060 // 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. 1061 // An object may only be greyed once.
994 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object) 1062 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; 1231 uint32_t numProperties;
1164 uint32_t length; 1232 uint32_t length;
1165 if (!doReadUint32(&numProperties)) 1233 if (!doReadUint32(&numProperties))
1166 return false; 1234 return false;
1167 if (!doReadUint32(&length)) 1235 if (!doReadUint32(&length))
1168 return false; 1236 return false;
1169 if (!creator.completeDenseArray(numProperties, length, value)) 1237 if (!creator.completeDenseArray(numProperties, length, value))
1170 return false; 1238 return false;
1171 break; 1239 break;
1172 } 1240 }
1241 case MapTag: {
1242 uint32_t length;
1243 if (!doReadUint32(&length))
1244 return false;
1245 if (!creator.completeMap(length, value))
1246 return false;
1247 break;
1248 }
1249 case SetTag: {
1250 uint32_t length;
1251 if (!doReadUint32(&length))
1252 return false;
1253 if (!creator.completeSet(length, value))
1254 return false;
1255 break;
1256 }
1173 case ArrayBufferViewTag: { 1257 case ArrayBufferViewTag: {
1174 if (!m_version) 1258 if (!m_version)
1175 return false; 1259 return false;
1176 if (!readArrayBufferView(value, creator)) 1260 if (!readArrayBufferView(value, creator))
1177 return false; 1261 return false;
1178 creator.pushObjectReference(*value); 1262 creator.pushObjectReference(*value);
1179 break; 1263 break;
1180 } 1264 }
1181 case ArrayBufferTag: { 1265 case ArrayBufferTag: {
1182 if (!m_version) 1266 if (!m_version)
(...skipping 23 matching lines...) Expand all
1206 case GenerateFreshDenseArrayTag: { 1290 case GenerateFreshDenseArrayTag: {
1207 if (!m_version) 1291 if (!m_version)
1208 return false; 1292 return false;
1209 uint32_t length; 1293 uint32_t length;
1210 if (!doReadUint32(&length)) 1294 if (!doReadUint32(&length))
1211 return false; 1295 return false;
1212 if (!creator.newDenseArray(length)) 1296 if (!creator.newDenseArray(length))
1213 return false; 1297 return false;
1214 return true; 1298 return true;
1215 } 1299 }
1300 case GenerateFreshMapTag: {
1301 if (!m_version)
1302 return false;
1303 if (!creator.newMap())
1304 return false;
1305 return true;
1306 }
1307 case GenerateFreshSetTag: {
1308 if (!m_version)
1309 return false;
1310 if (!creator.newSet())
1311 return false;
1312 return true;
1313 }
1216 case MessagePortTag: { 1314 case MessagePortTag: {
1217 if (!m_version) 1315 if (!m_version)
1218 return false; 1316 return false;
1219 uint32_t index; 1317 uint32_t index;
1220 if (!doReadUint32(&index)) 1318 if (!doReadUint32(&index))
1221 return false; 1319 return false;
1222 if (!creator.tryGetTransferredMessagePort(index, value)) 1320 if (!creator.tryGetTransferredMessagePort(index, value))
1223 return false; 1321 return false;
1224 break; 1322 break;
1225 } 1323 }
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 return true; 1851 return true;
1754 } 1852 }
1755 1853
1756 bool ScriptValueDeserializer::newDenseArray(uint32_t length) 1854 bool ScriptValueDeserializer::newDenseArray(uint32_t length)
1757 { 1855 {
1758 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length); 1856 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length);
1759 openComposite(array); 1857 openComposite(array);
1760 return true; 1858 return true;
1761 } 1859 }
1762 1860
1861 bool ScriptValueDeserializer::newMap()
1862 {
1863 v8::Local<v8::Map> map = v8::Map::New(m_reader.scriptState()->isolate());
1864 openComposite(map);
1865 return true;
1866 }
1867
1868 bool ScriptValueDeserializer::newSet()
1869 {
1870 v8::Local<v8::Set> set = v8::Set::New(m_reader.scriptState()->isolate());
1871 openComposite(set);
1872 return true;
1873 }
1874
1763 bool ScriptValueDeserializer::consumeTopOfStack(v8::Local<v8::Value>* object) 1875 bool ScriptValueDeserializer::consumeTopOfStack(v8::Local<v8::Value>* object)
1764 { 1876 {
1765 if (stackDepth() < 1) 1877 if (stackDepth() < 1)
1766 return false; 1878 return false;
1767 *object = element(stackDepth() - 1); 1879 *object = element(stackDepth() - 1);
1768 pop(1); 1880 pop(1);
1769 return true; 1881 return true;
1770 } 1882 }
1771 1883
1772 bool ScriptValueDeserializer::newObject() 1884 bool ScriptValueDeserializer::newObject()
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 v8::Local<v8::Value> elem = element(stackPos); 1942 v8::Local<v8::Value> elem = element(stackPos);
1831 if (!elem->IsUndefined()) { 1943 if (!elem->IsUndefined()) {
1832 if (!v8CallBoolean(array->CreateDataProperty(context, i, elem))) 1944 if (!v8CallBoolean(array->CreateDataProperty(context, i, elem)))
1833 return false; 1945 return false;
1834 } 1946 }
1835 } 1947 }
1836 pop(length); 1948 pop(length);
1837 return true; 1949 return true;
1838 } 1950 }
1839 1951
1952 bool ScriptValueDeserializer::completeMap(uint32_t length, v8::Local<v8::Value>* value)
1953 {
1954 ASSERT(m_version > 0);
1955 v8::Local<v8::Map> map;
jsbell 2015/06/24 21:37:11 Can this be merged with line 1959?
adamk 2015/06/24 22:50:31 Done.
1956 v8::Local<v8::Value> composite;
1957 if (!closeComposite(&composite))
1958 return false;
1959 map = composite.As<v8::Map>();
1960 if (map.IsEmpty())
1961 return false;
1962 v8::Local<v8::Context> context = m_reader.scriptState()->context();
1963 ASSERT(length % 2 == 0);
1964 for (unsigned i = stackDepth() - length; i + 1 < stackDepth(); i += 2) {
1965 v8::Local<v8::Value> key = element(i);
1966 v8::Local<v8::Value> val = element(i + 1);
1967 if (map->Set(context, key, val).IsEmpty())
1968 return false;
1969 }
1970 pop(length);
1971 *value = map;
1972 return true;
1973 }
1974
1975 bool ScriptValueDeserializer::completeSet(uint32_t length, v8::Local<v8::Value>* value)
1976 {
1977 ASSERT(m_version > 0);
1978 v8::Local<v8::Set> set;
jsbell 2015/06/24 21:37:11 Merge w/ line 1982?
adamk 2015/06/24 22:50:31 Done.
1979 v8::Local<v8::Value> composite;
1980 if (!closeComposite(&composite))
1981 return false;
1982 set = composite.As<v8::Set>();
1983 if (set.IsEmpty())
1984 return false;
1985 v8::Local<v8::Context> context = m_reader.scriptState()->context();
1986 for (unsigned i = stackDepth() - length; i < stackDepth(); i++) {
1987 v8::Local<v8::Value> key = element(i);
1988 if (set->Add(context, key).IsEmpty())
1989 return false;
1990 }
1991 pop(length);
1992 *value = set;
1993 return true;
1994 }
1995
1840 void ScriptValueDeserializer::pushObjectReference(const v8::Local<v8::Value>& ob ject) 1996 void ScriptValueDeserializer::pushObjectReference(const v8::Local<v8::Value>& ob ject)
1841 { 1997 {
1842 m_objectPool.append(object); 1998 m_objectPool.append(object);
1843 } 1999 }
1844 2000
1845 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::L ocal<v8::Value>* object) 2001 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::L ocal<v8::Value>* object)
1846 { 2002 {
1847 if (!m_transferredMessagePorts) 2003 if (!m_transferredMessagePorts)
1848 return false; 2004 return false;
1849 if (index >= m_transferredMessagePorts->size()) 2005 if (index >= m_transferredMessagePorts->size())
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 return false; 2100 return false;
1945 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; 2101 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
1946 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 2102 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
1947 if (objectReference >= m_objectPool.size()) 2103 if (objectReference >= m_objectPool.size())
1948 return false; 2104 return false;
1949 *object = m_objectPool[objectReference]; 2105 *object = m_objectPool[objectReference];
1950 return true; 2106 return true;
1951 } 2107 }
1952 2108
1953 } // namespace blink 2109 } // 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