Changeset 155008 in webkit
- Timestamp:
- Sep 3, 2013 4:21:10 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r155002 r155008 1 2013-09-03 Oliver Hunt <oliver@apple.com> 2 3 Support structured clone of Map and Set 4 https://bugs.webkit.org/show_bug.cgi?id=120654 5 6 Reviewed by Simon Fraser. 7 8 Tests! 9 10 * fast/dom/Window/script-tests/postmessage-clone.js: 11 (set new): 12 (set add.set add): 13 1 14 2013-09-03 Bear Travis <betravis@adobe.com> 2 15 -
trunk/LayoutTests/fast/dom/Window/script-tests/postmessage-clone.js
r114992 r155008 44 44 tryPostMessage('({get a() { throw "x" }})', true); 45 45 46 var map = new Map; 47 var set = new Set; 48 map.expando1 = {}; 49 map.expando2 = {}; 50 map.aSet = set; 51 map.set(1, 2.5) 52 map.set("entry", map.expando1); 53 map.set(true, set); 54 map.set(map.expando2, map); 55 set.add(false) 56 set.add(map) 57 tryPostMessage("map", false, "evalThunk", function (v) { 58 newMap = v 59 doPassFail(newMap.get("entry") === newMap.expando1, "String keyed entry was cloned correctly"); 60 doPassFail(newMap.get(newMap.expando2) === newMap, "Object key entry was cloned correctly"); 61 shouldBe("newMap.get(true)", "newMap.aSet") 62 shouldBe("newMap.aSet.has(newMap)", "true") 63 newMap.forEach(function (value, key) { 64 console.innerHTML += "LOG: " + value + " => " + key + "<br>" 65 }) 66 }) 67 46 68 if (window.eventSender) { 47 69 var fileInput = document.getElementById("fileInput"); -
trunk/LayoutTests/fast/dom/Window/window-postmessage-clone-expected.txt
r135168 r155008 38 38 PASS: eventData.graph1 is === to eventData.graph2 39 39 PASS: eventData[0] is === to eventData[1] 40 PASS: String keyed entry was cloned correctly 41 PASS: Object key entry was cloned correctly 42 PASS: newMap.get(true) is [object Set] of type object 43 PASS: newMap.aSet.has(newMap) is true of type boolean 44 LOG: 2.5 => 1 45 LOG: [object Object] => entry 46 LOG: [object Set] => true 47 LOG: [object Map] => [object Object] 40 48 PASS: eventData is [object ImageData] of type object 41 49 PASS: eventData is [object Uint8ClampedArray] of type object -
trunk/Source/JavaScriptCore/ChangeLog
r154992 r155008 1 2013-09-03 Oliver Hunt <oliver@apple.com> 2 3 Support structured clone of Map and Set 4 https://bugs.webkit.org/show_bug.cgi?id=120654 5 6 Reviewed by Simon Fraser. 7 8 Make xcode copy the required headers, and add appropriate export attributes 9 10 * JavaScriptCore.xcodeproj/project.pbxproj: 11 * runtime/JSMap.h: 12 * runtime/JSSet.h: 13 * runtime/MapData.h: 14 1 15 2013-09-02 Ryosuke Niwa <rniwa@webkit.org> 2 16 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r154992 r155008 816 816 A700873E17CBE8D300C3E643 /* MapPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A700873C17CBE8D300C3E643 /* MapPrototype.h */; }; 817 817 A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A700873F17CBE8EB00C3E643 /* JSMap.cpp */; }; 818 A700874217CBE8EB00C3E643 /* JSMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A700874017CBE8EB00C3E643 /* JSMap.h */; };818 A700874217CBE8EB00C3E643 /* JSMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A700874017CBE8EB00C3E643 /* JSMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 819 819 A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A70447E917A0BD4600F5898E /* OperandsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 820 820 A70447ED17A0BD7000F5898E /* DumpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A70447EB17A0BD7000F5898E /* DumpContext.cpp */; }; … … 839 839 A729009C17976C6000317298 /* MacroAssemblerARMv7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */; }; 840 840 A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7299D9B17D12837005F5FF9 /* JSSet.cpp */; }; 841 A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299D9C17D12837005F5FF9 /* JSSet.h */; };841 A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299D9C17D12837005F5FF9 /* JSSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 842 842 A7299DA117D12848005F5FF9 /* SetPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7299D9F17D12848005F5FF9 /* SetPrototype.cpp */; }; 843 843 A7299DA217D12848005F5FF9 /* SetPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299DA017D12848005F5FF9 /* SetPrototype.h */; }; … … 883 883 A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; }; 884 884 A78507D617CBC6FD0011F6E7 /* MapData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78507D417CBC6FD0011F6E7 /* MapData.cpp */; }; 885 A78507D717CBC6FD0011F6E7 /* MapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A78507D517CBC6FD0011F6E7 /* MapData.h */; };885 A78507D717CBC6FD0011F6E7 /* MapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A78507D517CBC6FD0011F6E7 /* MapData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 886 886 A78853F917972629001440E4 /* IntendedStructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78853F717972629001440E4 /* IntendedStructureChain.cpp */; }; 887 887 A78853FA17972629001440E4 /* IntendedStructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = A78853F817972629001440E4 /* IntendedStructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; }; -
trunk/Source/JavaScriptCore/runtime/JSMap.h
r154861 r155008 37 37 typedef JSNonFinalObject Base; 38 38 39 DECLARE_ INFO;39 DECLARE_EXPORT_INFO; 40 40 41 41 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) … … 67 67 } 68 68 69 void finishCreation(VM&, JSGlobalObject*);69 JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*); 70 70 71 71 static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/JSSet.h
r154916 r155008 37 37 typedef JSNonFinalObject Base; 38 38 39 DECLARE_ INFO;39 DECLARE_EXPORT_INFO; 40 40 41 41 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) … … 67 67 } 68 68 69 void finishCreation(VM&, JSGlobalObject*);69 JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*); 70 70 71 71 static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/MapData.h
r154864 r155008 81 81 } 82 82 83 void set(CallFrame*, KeyType, JSValue);83 JS_EXPORT_PRIVATE void set(CallFrame*, KeyType, JSValue); 84 84 JSValue get(CallFrame*, KeyType); 85 85 bool remove(CallFrame*, KeyType); -
trunk/Source/WebCore/ChangeLog
r155002 r155008 1 2013-09-03 Oliver Hunt <oliver@apple.com> 2 3 Support structured clone of Map and Set 4 https://bugs.webkit.org/show_bug.cgi?id=120654 5 6 Reviewed by Simon Fraser. 7 8 Add support for cloning Map and Set. Fairly self explanatory change. 9 Needed to add Forwarding headers for the JSMap, JSSet and MapData classes. 10 11 * ForwardingHeaders/runtime/JSMap.h: Added. 12 * ForwardingHeaders/runtime/JSSet.h: Added. 13 * ForwardingHeaders/runtime/MapData.h: Added. 14 * bindings/js/SerializedScriptValue.cpp: 15 (WebCore::CloneSerializer::isMap): 16 (WebCore::CloneSerializer::isSet): 17 (WebCore::CloneSerializer::startSet): 18 (WebCore::CloneSerializer::startMap): 19 (WebCore::CloneSerializer::serialize): 20 (WebCore::CloneDeserializer::consumeMapDataTerminationIfPossible): 21 (WebCore::CloneDeserializer::deserialize): 22 1 23 2013-09-03 Bear Travis <betravis@adobe.com> 2 24 -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp
r154797 r155008 55 55 #include <runtime/JSArrayBufferView.h> 56 56 #include <runtime/JSDataView.h> 57 #include <runtime/JSMap.h> 58 #include <runtime/JSSet.h> 57 59 #include <runtime/JSTypedArrays.h> 60 #include <runtime/MapData.h> 58 61 #include <runtime/ObjectConstructor.h> 59 62 #include <runtime/Operations.h> … … 80 83 81 84 enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, 82 ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember }; 85 ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember, 86 MapDataStartVisitEntry, MapDataEndVisitKey, MapDataEndVisitValue }; 83 87 84 88 // These can't be reordered, and any new types must be added to the end of the list … … 112 116 EmptyStringObjectTag = 27, 113 117 NumberObjectTag = 28, 118 SetObjectTag = 29, 119 MapObjectTag = 30, 120 NonMapPropertiesTag = 31, 114 121 ErrorTag = 255 115 122 }; … … 159 166 * and EmptyStringObjectTag for serialization of Boolean, Number and String objects. 160 167 * Version 4. added support for serializing non-index properties of arrays. 168 * Version 5. added support for Map and Set types. 161 169 */ 162 static const unsigned CurrentVersion = 4;170 static const unsigned CurrentVersion = 5; 163 171 static const unsigned TerminatorTag = 0xFFFFFFFF; 164 172 static const unsigned StringPoolTag = 0xFFFFFFFE; … … 174 182 * 175 183 * SerializedValue :- <CurrentVersion:uint32_t> Value 176 * Value :- Array | Object | Terminal184 * Value :- Array | Object | Map | Set | Terminal 177 185 * 178 186 * Array :- … … 181 189 * Object :- 182 190 * ObjectTag (<name:StringData><value:Value>)* TerminatorTag 191 * 192 * Map :- MapObjectTag MapData 193 * 194 * Set :- SetObjectTag MapData 195 * 196 * MapData :- (<key:Value><value:Value>) NonMapPropertiesTag (<name:StringData><value:Value>)* TerminatorTag 183 197 * 184 198 * Terminal :- … … 400 414 } 401 415 416 bool isMap(JSValue value) 417 { 418 if (!value.isObject()) 419 return false; 420 JSObject* object = asObject(value); 421 return object->inherits(JSMap::info()); 422 } 423 bool isSet(JSValue value) 424 { 425 if (!value.isObject()) 426 return false; 427 JSObject* object = asObject(value); 428 return object->inherits(JSSet::info()); 429 } 430 402 431 bool checkForDuplicate(JSObject* object) 403 432 { … … 446 475 write(ArrayTag); 447 476 write(length); 477 return true; 478 } 479 480 bool startSet(JSSet* set) 481 { 482 if (!startObjectInternal(set)) 483 return false; 484 485 write(SetObjectTag); 486 return true; 487 } 488 489 bool startMap(JSMap* map) 490 { 491 if (!startObjectInternal(map)) 492 return false; 493 494 write(MapObjectTag); 448 495 return true; 449 496 } … … 822 869 Vector<PropertyNameArray, 16> propertyStack; 823 870 Vector<JSObject*, 32> inputObjectStack; 871 Vector<MapData*, 4> mapDataStack; 872 Vector<MapData::const_iterator, 4> iteratorStack; 824 873 Vector<WalkerState, 16> stateStack; 825 874 WalkerState state = StateUnknown; … … 946 995 goto objectStartVisitMember; 947 996 } 997 mapStartState: { 998 ASSERT(inValue.isObject()); 999 if (inputObjectStack.size() > maximumFilterRecursion) 1000 return StackOverflowError; 1001 JSMap* inMap = jsCast<JSMap*>(inValue); 1002 if (!startMap(inMap)) 1003 break; 1004 MapData* mapData = inMap->mapData(); 1005 m_gcBuffer.append(mapData); 1006 mapDataStack.append(mapData); 1007 iteratorStack.append(mapData->begin()); 1008 inputObjectStack.append(inMap); 1009 goto mapDataStartVisitEntry; 1010 } 1011 setStartState: { 1012 ASSERT(inValue.isObject()); 1013 if (inputObjectStack.size() > maximumFilterRecursion) 1014 return StackOverflowError; 1015 JSSet* inSet = jsCast<JSSet*>(inValue); 1016 if (!startSet(inSet)) 1017 break; 1018 MapData* mapData = inSet->mapData(); 1019 m_gcBuffer.append(mapData); 1020 mapDataStack.append(mapData); 1021 iteratorStack.append(mapData->begin()); 1022 inputObjectStack.append(inSet); 1023 goto mapDataStartVisitEntry; 1024 } 1025 mapDataStartVisitEntry: 1026 case MapDataStartVisitEntry: { 1027 MapData::const_iterator& ptr = iteratorStack.last(); 1028 MapData* mapData = mapDataStack.last(); 1029 if (ptr == mapData->end()) { 1030 iteratorStack.removeLast(); 1031 mapDataStack.removeLast(); 1032 JSObject* object = inputObjectStack.last(); 1033 ASSERT(jsDynamicCast<JSSet*>(object) || jsDynamicCast<JSMap*>(object)); 1034 propertyStack.append(PropertyNameArray(m_exec)); 1035 object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), ExcludeDontEnumProperties); 1036 write(NonMapPropertiesTag); 1037 indexStack.append(0); 1038 goto objectStartVisitMember; 1039 } 1040 inValue = ptr.key(); 1041 stateStack.append(MapDataEndVisitKey); 1042 goto stateUnknown; 1043 } 1044 case MapDataEndVisitKey: { 1045 inValue = iteratorStack.last().value(); 1046 stateStack.append(MapDataEndVisitValue); 1047 goto stateUnknown; 1048 } 1049 case MapDataEndVisitValue: { 1050 ++iteratorStack.last(); 1051 goto mapDataStartVisitEntry; 1052 } 1053 948 1054 stateUnknown: 949 1055 case StateUnknown: { … … 957 1063 if (isArray(inValue)) 958 1064 goto arrayStartState; 1065 if (isMap(inValue)) 1066 goto mapStartState; 1067 if (isSet(inValue)) 1068 goto setStartState; 959 1069 goto objectStartState; 960 1070 } … … 1558 1668 } 1559 1669 1670 bool consumeMapDataTerminationIfPossible() 1671 { 1672 if (readTag() == NonMapPropertiesTag) 1673 return true; 1674 m_ptr--; 1675 return false; 1676 } 1677 1560 1678 JSGlobalObject* m_globalObject; 1561 1679 bool m_isDOMGlobalObject; … … 1574 1692 Vector<Identifier, 16> propertyNameStack; 1575 1693 Vector<JSObject*, 32> outputObjectStack; 1694 Vector<JSValue, 4> keyStack; 1695 Vector<MapData*, 4> mapDataStack; 1576 1696 Vector<WalkerState, 16> stateStack; 1577 1697 WalkerState state = StateUnknown; … … 1660 1780 goto objectStartVisitMember; 1661 1781 } 1782 mapObjectStartState: { 1783 if (outputObjectStack.size() > maximumFilterRecursion) 1784 return make_pair(JSValue(), StackOverflowError); 1785 JSMap* map = JSMap::create(m_exec->vm(), m_globalObject->mapStructure()); 1786 m_gcBuffer.append(map); 1787 outputObjectStack.append(map); 1788 MapData* mapData = map->mapData(); 1789 mapDataStack.append(mapData); 1790 goto mapDataStartVisitEntry; 1791 } 1792 setObjectStartState: { 1793 if (outputObjectStack.size() > maximumFilterRecursion) 1794 return make_pair(JSValue(), StackOverflowError); 1795 JSSet* set = JSSet::create(m_exec->vm(), m_globalObject->setStructure()); 1796 m_gcBuffer.append(set); 1797 outputObjectStack.append(set); 1798 MapData* mapData = set->mapData(); 1799 mapDataStack.append(mapData); 1800 goto mapDataStartVisitEntry; 1801 } 1802 mapDataStartVisitEntry: 1803 case MapDataStartVisitEntry: { 1804 if (consumeMapDataTerminationIfPossible()) { 1805 mapDataStack.removeLast(); 1806 goto objectStartVisitMember; 1807 } 1808 stateStack.append(MapDataEndVisitKey); 1809 goto stateUnknown; 1810 } 1811 1812 case MapDataEndVisitKey: { 1813 keyStack.append(outValue); 1814 stateStack.append(MapDataEndVisitValue); 1815 goto stateUnknown; 1816 } 1817 1818 case MapDataEndVisitValue: { 1819 mapDataStack.last()->set(m_exec, keyStack.last(), outValue); 1820 keyStack.removeLast(); 1821 goto mapDataStartVisitEntry; 1822 } 1662 1823 stateUnknown: 1663 1824 case StateUnknown: … … 1671 1832 if (tag == ObjectTag) 1672 1833 goto objectStartState; 1834 if (tag == MapObjectTag) 1835 goto mapObjectStartState; 1836 if (tag == SetObjectTag) 1837 goto setObjectStartState; 1673 1838 goto error; 1674 1839 }
Note: See TracChangeset
for help on using the changeset viewer.