maplike should define a set method
https://bugs.webkit.org/show_bug.cgi?id=204877

Reviewed by Chris Dumez.

Source/WebCore:

maplike implementation was defining an add method instead of a set method.
Update implementation to define and use a set method.
Add an InternalsMapLike to allow testing.

Test: js/dom/maplike.html

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Modules/highlight/HighlightMap.cpp:
(WebCore::HighlightMap::addFromMapLike):
* Modules/highlight/HighlightMap.h:
* Modules/highlight/HighlightMap.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMMapLike.h:
(WebCore::DOMMapLike::set):
(WebCore::forwardSetToMapLike):
* bindings/scripts/IDLParser.pm:
(parseMapLikeProperties):
* bindings/scripts/test/JS/JSMapLike.cpp:
(WebCore::jsMapLikePrototypeFunctionSetBody):
(WebCore::jsMapLikePrototypeFunctionSet):
(WebCore::jsMapLikePrototypeFunctionAddBody): Deleted.
(WebCore::jsMapLikePrototypeFunctionAdd): Deleted.
* testing/Internals.cpp:
(WebCore::Internals::createInternalsMapLike):
* testing/Internals.h:
* testing/Internals.idl:
* testing/InternalsMapLike.cpp: Added.
* testing/InternalsMapLike.h: Added.
* testing/InternalsMapLike.idl: Added.

LayoutTests:

* highlight/highlight-interfaces-expected.txt:
* highlight/highlight-interfaces.html:
* js/dom/maplike-expected.txt: Added.
* js/dom/maplike.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253153 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 0b11b7d..0fc6016 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,5 +1,17 @@
 2019-12-05  youenn fablet  <youenn@apple.com>
 
+        maplike should define a set method
+        https://bugs.webkit.org/show_bug.cgi?id=204877
+
+        Reviewed by Chris Dumez.
+
+        * highlight/highlight-interfaces-expected.txt:
+        * highlight/highlight-interfaces.html:
+        * js/dom/maplike-expected.txt: Added.
+        * js/dom/maplike.html: Added.
+
+2019-12-05  youenn fablet  <youenn@apple.com>
+
         inspector/page/overrideSetting-MockCaptureDevicesEnabled.html is failing after removal of internals.setMockMediaCaptureDevicesEnabled API
         https://bugs.webkit.org/show_bug.cgi?id=204849
 
diff --git a/LayoutTests/highlight/highlight-interfaces-expected.txt b/LayoutTests/highlight/highlight-interfaces-expected.txt
index 557de07..b3051c3 100644
--- a/LayoutTests/highlight/highlight-interfaces-expected.txt
+++ b/LayoutTests/highlight/highlight-interfaces-expected.txt
@@ -10,9 +10,9 @@
 PASS HighlightMap instanceof Function is true
 PASS typeof HighlightMap is "function"
 PASS new HighlightMap() instanceof HighlightMap is true
-PASS new HighlightMap().set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2}))) is undefined.
+PASS new HighlightMap().set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2}))) is defined.
 PASS CSS.highlights is defined.
-PASS CSS.highlights.set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2}))) is undefined.
+PASS CSS.highlights.set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2}))) is CSS.highlights
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/highlight/highlight-interfaces.html b/LayoutTests/highlight/highlight-interfaces.html
index 5358fc1..58f494c 100644
--- a/LayoutTests/highlight/highlight-interfaces.html
+++ b/LayoutTests/highlight/highlight-interfaces.html
@@ -13,9 +13,9 @@
 shouldBeTrue("HighlightMap instanceof Function");
 shouldBeEqualToString("typeof HighlightMap", "function");
 shouldBeTrue("new HighlightMap() instanceof HighlightMap");
-shouldBeUndefined('new HighlightMap().set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2})))');
+shouldBeDefined('new HighlightMap().set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2})))');
 shouldBeDefined('CSS.highlights');
-shouldBeUndefined('CSS.highlights.set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2})))');
+shouldBe('CSS.highlights.set("foo-styling",new HighlightRangeGroup(new StaticRange({startContainer: document.body, startOffset: 1, endContainer: document.body, endOffset: 2})))', 'CSS.highlights');
 
 </script>
 </body>
diff --git a/LayoutTests/js/dom/maplike-expected.txt b/LayoutTests/js/dom/maplike-expected.txt
new file mode 100644
index 0000000..54a4095
--- /dev/null
+++ b/LayoutTests/js/dom/maplike-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Basic add/remove/clear functionality 
+
diff --git a/LayoutTests/js/dom/maplike.html b/LayoutTests/js/dom/maplike.html
new file mode 100644
index 0000000..c36e52db
--- /dev/null
+++ b/LayoutTests/js/dom/maplike.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+<head>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="application/javascript">
+test(() => {
+    assert_true(!!window.internals);
+    const maplike = internals.createInternalsMapLike();
+    assert_array_equals(maplike.inspectKeys(), ["init"], "init keys");
+    assert_array_equals(maplike.inspectValues(), [0], "init values");
+    assert_true(maplike.has("init"));
+
+    maplike.set("testA", 1);
+    assert_array_equals(maplike.inspectKeys(), ["init", "testA"]);
+    assert_array_equals(maplike.inspectValues(), [0, 1]);
+    maplike.set("testA", 2);
+    assert_array_equals(maplike.inspectKeys(), ["init", "testA"]);
+    assert_array_equals(maplike.inspectValues(), [0, 2]);
+    maplike.set("testB", 3);
+    assert_array_equals(maplike.inspectKeys(), ["init", "testA", "testB"]);
+    assert_array_equals(maplike.inspectValues(), [0, 2, 3]);
+
+    maplike.delete("init");
+    assert_array_equals(maplike.inspectKeys(), ["testA", "testB"]);
+    assert_array_equals(maplike.inspectValues(), [2, 3]);
+
+    assert_equals(maplike.size, 2, "size");
+
+    let entriesTest = "";
+    for (let entry of maplike.entries()) {
+        entriesTest += entry;
+        entriesTest += ' ';
+    }
+    assert_equals(entriesTest, "testA,2 testB,3 ", "entries test");
+
+    let valuesTest = "";
+    for (let entry of maplike.values()) {
+        valuesTest += entry;
+    }
+    assert_equals(valuesTest, "23", "values test");
+
+    let keysTest = "";
+    for (let entry of maplike.keys()) {
+        keysTest += entry;
+    }
+    assert_equals(keysTest, "testAtestB", "keys test");
+
+    let forEachTest = "";
+    maplike.forEach((value, key, object) => {
+        forEachTest += key;
+        forEachTest += ',';
+        forEachTest += value;
+        forEachTest += ' ';
+        assert_equals(object, maplike);
+    });
+    assert_equals(forEachTest, "testA,2 testB,3 ", "forEach test");
+
+    maplike.clear();
+    assert_array_equals(maplike.inspectKeys(), []);
+    assert_array_equals(maplike.inspectValues(), []);
+}, "Basic add/remove/clear functionality");
+</script>
+</body>
+</html>
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index 4bfb237..5220687 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -1605,6 +1605,7 @@
     testing/GCObservation.idl
     testing/InternalSettings.idl
     testing/Internals.idl
+    testing/InternalsMapLike.idl
     testing/InternalsSetLike.idl
     testing/MallocStatistics.idl
     testing/MemoryInfo.idl
@@ -1626,6 +1627,7 @@
     testing/GCObservation.cpp
     testing/InternalSettings.cpp
     testing/Internals.cpp
+    testing/InternalsMapLike.cpp
     testing/InternalsSetLike.cpp
     testing/MockCDMFactory.cpp
     testing/MockGamepad.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 3cf876b..2638d77 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,43 @@
+2019-12-05  youenn fablet  <youenn@apple.com>
+
+        maplike should define a set method
+        https://bugs.webkit.org/show_bug.cgi?id=204877
+
+        Reviewed by Chris Dumez.
+
+        maplike implementation was defining an add method instead of a set method.
+        Update implementation to define and use a set method.
+        Add an InternalsMapLike to allow testing.
+
+        Test: js/dom/maplike.html
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Modules/highlight/HighlightMap.cpp:
+        (WebCore::HighlightMap::addFromMapLike):
+        * Modules/highlight/HighlightMap.h:
+        * Modules/highlight/HighlightMap.idl:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSDOMMapLike.h:
+        (WebCore::DOMMapLike::set):
+        (WebCore::forwardSetToMapLike):
+        * bindings/scripts/IDLParser.pm:
+        (parseMapLikeProperties):
+        * bindings/scripts/test/JS/JSMapLike.cpp:
+        (WebCore::jsMapLikePrototypeFunctionSetBody):
+        (WebCore::jsMapLikePrototypeFunctionSet):
+        (WebCore::jsMapLikePrototypeFunctionAddBody): Deleted.
+        (WebCore::jsMapLikePrototypeFunctionAdd): Deleted.
+        * testing/Internals.cpp:
+        (WebCore::Internals::createInternalsMapLike):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+        * testing/InternalsMapLike.cpp: Added.
+        * testing/InternalsMapLike.h: Added.
+        * testing/InternalsMapLike.idl: Added.
+
 2019-12-05  Antti Koivisto  <antti@apple.com>
 
         [LFC][Integration] Disable LFC when floats are present for now
diff --git a/Source/WebCore/DerivedSources-input.xcfilelist b/Source/WebCore/DerivedSources-input.xcfilelist
index 37e545d..00bdb95 100644
--- a/Source/WebCore/DerivedSources-input.xcfilelist
+++ b/Source/WebCore/DerivedSources-input.xcfilelist
@@ -1092,6 +1092,7 @@
 $(PROJECT_DIR)/testing/GCObservation.idl
 $(PROJECT_DIR)/testing/InternalSettings.idl
 $(PROJECT_DIR)/testing/Internals.idl
+$(PROJECT_DIR)/testing/InternalsMapLike.idl
 $(PROJECT_DIR)/testing/InternalsSetLike.idl
 $(PROJECT_DIR)/testing/MallocStatistics.idl
 $(PROJECT_DIR)/testing/MemoryInfo.idl
diff --git a/Source/WebCore/DerivedSources-output.xcfilelist b/Source/WebCore/DerivedSources-output.xcfilelist
index e14cd1f..6f51904 100644
--- a/Source/WebCore/DerivedSources-output.xcfilelist
+++ b/Source/WebCore/DerivedSources-output.xcfilelist
@@ -691,10 +691,6 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGlobalEventHandlers.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGlobalPerformance.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGlobalPerformance.h
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightMap.cpp
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightMap.h
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightRangeGroup.cpp
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightRangeGroup.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLAllCollection.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLAllCollection.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLAnchorElement.cpp
@@ -873,6 +869,10 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHashChangeEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHdrMetadataType.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHdrMetadataType.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightMap.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightMap.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightRangeGroup.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHighlightRangeGroup.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHistory.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHistory.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHkdfParams.cpp
@@ -939,6 +939,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternalSettingsGenerated.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternals.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternals.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternalsMapLike.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternalsMapLike.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternalsSetLike.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSInternalsSetLike.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSIntersectionObserver.cpp
diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
index 82d8dc3..0bfabec 100644
--- a/Source/WebCore/DerivedSources.make
+++ b/Source/WebCore/DerivedSources.make
@@ -1082,6 +1082,7 @@
     $(WebCore)/testing/GCObservation.idl \
     $(WebCore)/testing/InternalSettings.idl \
     $(WebCore)/testing/Internals.idl \
+    $(WebCore)/testing/InternalsMapLike.idl \
     $(WebCore)/testing/InternalsSetLike.idl \
     $(WebCore)/testing/MallocStatistics.idl \
     $(WebCore)/testing/MemoryInfo.idl \
diff --git a/Source/WebCore/Modules/highlight/HighlightMap.cpp b/Source/WebCore/Modules/highlight/HighlightMap.cpp
index 7937409..b248ef7 100644
--- a/Source/WebCore/Modules/highlight/HighlightMap.cpp
+++ b/Source/WebCore/Modules/highlight/HighlightMap.cpp
@@ -34,10 +34,8 @@
     UNUSED_PARAM(group);
 }
 
-bool HighlightMap::addFromMapLike(const String& value)
+void HighlightMap::setFromMapLike(String&&, Ref<HighlightRangeGroup>&&)
 {
-    UNUSED_PARAM(value);
-    return false;
 }
 
 bool HighlightMap::remove(const String& value)
@@ -67,12 +65,4 @@
     return false;
 }
 
-ExceptionOr<void> HighlightMap::set(const String& name, const HighlightRangeGroup& value)
-{
-    UNUSED_PARAM(name);
-    UNUSED_PARAM(value);
-    
-    return { };
-}
-
 }
diff --git a/Source/WebCore/Modules/highlight/HighlightMap.h b/Source/WebCore/Modules/highlight/HighlightMap.h
index ecdac08..641e24b 100644
--- a/Source/WebCore/Modules/highlight/HighlightMap.h
+++ b/Source/WebCore/Modules/highlight/HighlightMap.h
@@ -49,9 +49,7 @@
     ExceptionOr<void> setNamedItem(const String& name, const HighlightRangeGroup& value);
     bool deleteNamedProperty(const String& name);
     
-    ExceptionOr<void> set(const String& name, const HighlightRangeGroup& value);
-    
-    bool addFromMapLike(const String& value);
+    void setFromMapLike(String&&, Ref<HighlightRangeGroup>&&);
     void clear() { };
     bool remove(const String& value);
     
diff --git a/Source/WebCore/Modules/highlight/HighlightMap.idl b/Source/WebCore/Modules/highlight/HighlightMap.idl
index a907919..36e5b55 100644
--- a/Source/WebCore/Modules/highlight/HighlightMap.idl
+++ b/Source/WebCore/Modules/highlight/HighlightMap.idl
@@ -30,5 +30,4 @@
 ] interface HighlightMap {
     maplike<DOMString, HighlightRangeGroup>;
     [CEReactions, MayThrowException] setter void (DOMString style, HighlightRangeGroup group);
-    [MayThrowException] void set(DOMString style, HighlightRangeGroup group);
 };
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 6303d7d..7dcc824 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -1048,6 +1048,8 @@
 		4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 4129C9801F5861C7009D7403 /* ReadableStreamSink.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		412DE4B8219285C00075F3A7 /* RTCRtpCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 412DE4B6219285BF0075F3A7 /* RTCRtpCapabilities.h */; };
 		4133CB8B20F80E9900E89B11 /* MediaStreamAudioSourceCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4133CB8920F80E8600E89B11 /* MediaStreamAudioSourceCocoa.cpp */; };
+		4136C57A2398E5BE002497D3 /* InternalsMapLike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4136C5782398E5B5002497D3 /* InternalsMapLike.cpp */; };
+		4136C57C2398ECCF002497D3 /* JSInternalsMapLike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D6F3E921C1F85550061DBD6 /* JSInternalsMapLike.cpp */; };
 		4136EC0C23838870000ADBCE /* InternalsSetLike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4136EC09238387C3000ADBCE /* InternalsSetLike.cpp */; };
 		4136EC0D23838A47000ADBCE /* InternalsSetLike.h in Headers */ = {isa = PBXBuildFile; fileRef = 4136EC0A238387C4000ADBCE /* InternalsSetLike.h */; };
 		41380C271F3436AC00155FDA /* DOMCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 41380C251F34369A00155FDA /* DOMCache.h */; };
@@ -6729,6 +6731,7 @@
 		2D6F3E8C1C1ECB1C0061DBD4 /* MockPageOverlay.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MockPageOverlay.idl; sourceTree = "<group>"; };
 		2D6F3E921C1F85550061DBD4 /* JSMockPageOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMockPageOverlay.cpp; sourceTree = "<group>"; };
 		2D6F3E921C1F85550061DBD5 /* JSInternalsSetLike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternalsSetLike.cpp; sourceTree = "<group>"; };
+		2D6F3E921C1F85550061DBD6 /* JSInternalsMapLike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternalsMapLike.cpp; sourceTree = "<group>"; };
 		2D6F3E931C1F85550061DBD4 /* JSMockPageOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMockPageOverlay.h; sourceTree = "<group>"; };
 		2D70BA1218074DDF0001908A /* PlatformCALayerCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformCALayerCocoa.h; sourceTree = "<group>"; };
 		2D70BA1418074F850001908A /* PlatformCALayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformCALayer.cpp; sourceTree = "<group>"; };
@@ -7291,6 +7294,9 @@
 		4131F3B51F955BC50059995A /* ExtendableEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ExtendableEventInit.idl; sourceTree = "<group>"; };
 		4133CB8920F80E8600E89B11 /* MediaStreamAudioSourceCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamAudioSourceCocoa.cpp; sourceTree = "<group>"; };
 		41369E55218C76E300792E29 /* RTCRtpCapabilities.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCRtpCapabilities.idl; sourceTree = "<group>"; };
+		4136C5762398E5B4002497D3 /* InternalsMapLike.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InternalsMapLike.h; sourceTree = "<group>"; };
+		4136C5782398E5B5002497D3 /* InternalsMapLike.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InternalsMapLike.cpp; sourceTree = "<group>"; };
+		4136C5792398E5B6002497D3 /* InternalsMapLike.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = InternalsMapLike.idl; sourceTree = "<group>"; };
 		4136EC0723838746000ADBCE /* InternalsSetLike.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = InternalsSetLike.idl; sourceTree = "<group>"; };
 		4136EC09238387C3000ADBCE /* InternalsSetLike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InternalsSetLike.cpp; sourceTree = "<group>"; };
 		4136EC0A238387C4000ADBCE /* InternalsSetLike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalsSetLike.h; sourceTree = "<group>"; };
@@ -18069,6 +18075,9 @@
 				A7BF7EDC14C9175A0014489D /* InternalSettings.cpp */,
 				A7BF7EDD14C9175A0014489D /* InternalSettings.h */,
 				A7BF7EDE14C9175A0014489D /* InternalSettings.idl */,
+				4136C5782398E5B5002497D3 /* InternalsMapLike.cpp */,
+				4136C5762398E5B4002497D3 /* InternalsMapLike.h */,
+				4136C5792398E5B6002497D3 /* InternalsMapLike.idl */,
 				4136EC09238387C3000ADBCE /* InternalsSetLike.cpp */,
 				4136EC0A238387C4000ADBCE /* InternalsSetLike.h */,
 				4136EC0723838746000ADBCE /* InternalsSetLike.idl */,
@@ -18135,6 +18144,7 @@
 				A7B4EA7914C9348400C8F5BF /* JSInternalSettings.h */,
 				53ED3FDC167A88E7006762E6 /* JSInternalSettingsGenerated.cpp */,
 				53ED3FDD167A88E7006762E6 /* JSInternalSettingsGenerated.h */,
+				2D6F3E921C1F85550061DBD6 /* JSInternalsMapLike.cpp */,
 				2D6F3E921C1F85550061DBD5 /* JSInternalsSetLike.cpp */,
 				A7B4EA6814C9348400C8F5BF /* JSMallocStatistics.cpp */,
 				A7B4EA6914C9348400C8F5BF /* JSMallocStatistics.h */,
@@ -33391,16 +33401,19 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				2D4150DE1C1F868C000A3BA4 /* (null) in Sources */,
 				51714EAC1CF65951004723C4 /* GCObservation.cpp in Sources */,
 				417DA6D913734E6E007C57FB /* Internals.cpp in Sources */,
 				E179F0DA1B9774FE00ED0A27 /* Internals.mm in Sources */,
 				A7BF7EDF14C9175A0014489D /* InternalSettings.cpp in Sources */,
 				DE5F86111FA239DA006DB63A /* InternalSettingsGenerated.cpp in Sources */,
+				4136C57A2398E5BE002497D3 /* InternalsMapLike.cpp in Sources */,
 				4136EC0C23838870000ADBCE /* InternalsSetLike.cpp in Sources */,
 				DE5F86121FA239E7006DB63A /* JSGCObservation.cpp in Sources */,
 				417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */,
 				A740B5A714C935AF00A77FA4 /* JSInternalSettings.cpp in Sources */,
 				53ED3FDE167A88E7006762E6 /* JSInternalSettingsGenerated.cpp in Sources */,
+				4136C57C2398ECCF002497D3 /* JSInternalsMapLike.cpp in Sources */,
 				2D4150DE1C1F868C000A3BA3 /* JSInternalsSetLike.cpp in Sources */,
 				538EC9321F99B9F7004D22A8 /* JSMallocStatistics.cpp in Sources */,
 				CD5393D3175E018600C07123 /* JSMemoryInfo.cpp in Sources */,
diff --git a/Source/WebCore/bindings/js/JSDOMMapLike.h b/Source/WebCore/bindings/js/JSDOMMapLike.h
index cd62b7f..e8f5e03 100644
--- a/Source/WebCore/bindings/js/JSDOMMapLike.h
+++ b/Source/WebCore/bindings/js/JSDOMMapLike.h
@@ -34,11 +34,11 @@
 
 namespace WebCore {
 
-JSC::JSMap& createBackingMap(JSC::JSGlobalObject&, JSC::JSGlobalObject&, JSC::JSObject&);
-void initializeBackingMap(JSC::VM&, JSC::JSObject&, JSC::JSMap&);
-JSC::JSValue forwardAttributeGetterToBackingMap(JSC::JSGlobalObject&, JSC::JSObject&, const JSC::Identifier&);
-JSC::JSValue forwardFunctionCallToBackingMap(JSC::JSGlobalObject&, JSC::CallFrame&, JSC::JSObject&, const JSC::Identifier&);
-JSC::JSValue forwardForEachCallToBackingMap(JSC::JSGlobalObject&, JSC::CallFrame&, JSDOMGlobalObject&, JSC::JSObject&);
+WEBCORE_EXPORT JSC::JSMap& createBackingMap(JSC::JSGlobalObject&, JSC::JSGlobalObject&, JSC::JSObject&);
+WEBCORE_EXPORT void initializeBackingMap(JSC::VM&, JSC::JSObject&, JSC::JSMap&);
+WEBCORE_EXPORT JSC::JSValue forwardAttributeGetterToBackingMap(JSC::JSGlobalObject&, JSC::JSObject&, const JSC::Identifier&);
+WEBCORE_EXPORT JSC::JSValue forwardFunctionCallToBackingMap(JSC::JSGlobalObject&, JSC::CallFrame&, JSC::JSObject&, const JSC::Identifier&);
+WEBCORE_EXPORT JSC::JSValue forwardForEachCallToBackingMap(JSC::JSGlobalObject&, JSC::CallFrame&, JSDOMGlobalObject&, JSC::JSObject&);
 
 template<typename WrapperClass> void synchronizeBackingMap(JSC::JSGlobalObject&, JSDOMGlobalObject&, WrapperClass&);
 template<typename WrapperClass> JSC::JSValue forwardSizeToMapLike(JSC::JSGlobalObject&, WrapperClass&);
@@ -49,14 +49,14 @@
 template<typename WrapperClass, typename Callback> JSC::JSValue forwardForEachToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, Callback&&);
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardGetToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardHasToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
-template<typename WrapperClass, typename ItemType> JSC::JSValue forwardAddToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
+template<typename WrapperClass, typename ItemType, typename ValueType> JSC::JSValue forwardSetToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&, ValueType&&);
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardDeleteToMapLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
 
 class DOMMapLike final : public DOMGuarded<JSC::JSMap> {
 public:
     static Ref<DOMMapLike> create(JSDOMGlobalObject& globalObject, JSC::JSMap& map) { return adoptRef(*new DOMMapLike(globalObject, map)); }
 
-    template<typename Key, typename Value> void set(typename Key::ParameterType&&, typename Value::ParameterType&&);
+    template<typename Key, typename Value> void set(typename Key::ParameterType, typename Value::ParameterType);
 
     JSC::JSMap* backingMap() { return guarded(); }
 
@@ -64,7 +64,7 @@
     DOMMapLike(JSDOMGlobalObject& globalObject, JSC::JSMap& map) : DOMGuarded<JSC::JSMap>(globalObject, map) { }
 };
 
-template<typename Key, typename Value> inline void DOMMapLike::set(typename Key::ParameterType&& key, typename Value::ParameterType&& value)
+template<typename Key, typename Value> inline void DOMMapLike::set(typename Key::ParameterType key, typename Value::ParameterType value)
 {
     if (isEmpty())
         return;
@@ -134,10 +134,10 @@
     return forwardFunctionCallToBackingMap(lexicalGlobalObject, callFrame, mapLike, vm.propertyNames->builtinNames().hasPublicName());
 }
 
-template<typename WrapperClass, typename ItemType> inline JSC::JSValue forwardAddToMapLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& mapLike, ItemType&& item)
+template<typename WrapperClass, typename KeyType, typename ValueType> inline JSC::JSValue forwardSetToMapLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& mapLike, KeyType&& key, ValueType&& value)
 {
-    if (mapLike.wrapped().addFromMapLike(std::forward<ItemType>(item)))
-        forwardFunctionCallToBackingMap(lexicalGlobalObject, callFrame, mapLike, JSC::getVM(&lexicalGlobalObject).propertyNames->add);
+    mapLike.wrapped().setFromMapLike(std::forward<KeyType>(key), std::forward<ValueType>(value));
+    forwardFunctionCallToBackingMap(lexicalGlobalObject, callFrame, mapLike, JSC::getVM(&lexicalGlobalObject).propertyNames->set);
     return &mapLike;
 }
 
diff --git a/Source/WebCore/bindings/scripts/IDLParser.pm b/Source/WebCore/bindings/scripts/IDLParser.pm
index 34ce719..8e12759 100644
--- a/Source/WebCore/bindings/scripts/IDLParser.pm
+++ b/Source/WebCore/bindings/scripts/IDLParser.pm
@@ -1997,16 +1997,21 @@
 
     return $maplike if $isReadOnly;
 
-    my $addOperation = IDLOperation->new();
-    $addOperation->name("add");
-    $addOperation->isMapLike(1);
-    my $addArgument = IDLArgument->new();
-    $addArgument->name("key");
-    $addArgument->type($maplike->keyType);
-    $addArgument->extendedAttributes($extendedAttributeList);
-    push(@{$addOperation->arguments}, ($addArgument));
-    $addOperation->extendedAttributes($notEnumerableExtendedAttributeList);
-    $addOperation->type(makeSimpleType("any"));
+    my $setOperation = IDLOperation->new();
+    $setOperation->name("set");
+    $setOperation->isMapLike(1);
+    my $setKeyArgument = IDLArgument->new();
+    $setKeyArgument->name("key");
+    $setKeyArgument->type($maplike->keyType);
+    $setKeyArgument->extendedAttributes($extendedAttributeList);
+    my $setValueArgument = IDLArgument->new();
+    $setValueArgument->name("value");
+    $setValueArgument->type($maplike->valueType);
+    $setValueArgument->extendedAttributes($extendedAttributeList);
+    push(@{$setOperation->arguments}, ($setKeyArgument));
+    push(@{$setOperation->arguments}, ($setValueArgument));
+    $setOperation->extendedAttributes($notEnumerableExtendedAttributeList);
+    $setOperation->type(makeSimpleType("any"));
 
     my $clearOperation = IDLOperation->new();
     $clearOperation->name("clear");
@@ -2025,7 +2030,7 @@
     $deleteOperation->extendedAttributes($notEnumerableExtendedAttributeList);
     $deleteOperation->type(makeSimpleType("any"));
 
-    push(@{$maplike->operations}, $addOperation);
+    push(@{$maplike->operations}, $setOperation);
     push(@{$maplike->operations}, $clearOperation);
     push(@{$maplike->operations}, $deleteOperation);
 
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp b/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp
index 3687b83..d10d088 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp
+++ b/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp
@@ -52,7 +52,7 @@
 JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionKeys(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionValues(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionForEach(JSC::JSGlobalObject*, JSC::CallFrame*);
-JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionAdd(JSC::JSGlobalObject*, JSC::CallFrame*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionSet(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionClear(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionDelete(JSC::JSGlobalObject*, JSC::CallFrame*);
 
@@ -116,7 +116,7 @@
     { "keys", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionKeys), (intptr_t) (0) } },
     { "values", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionValues), (intptr_t) (0) } },
     { "forEach", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionForEach), (intptr_t) (1) } },
-    { "add", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionAdd), (intptr_t) (1) } },
+    { "set", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionSet), (intptr_t) (2) } },
     { "clear", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionClear), (intptr_t) (0) } },
     { "delete", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMapLikePrototypeFunctionDelete), (intptr_t) (1) } },
 };
@@ -304,21 +304,23 @@
     return IDLOperation<JSMapLike>::call<jsMapLikePrototypeFunctionForEachBody>(*lexicalGlobalObject, *callFrame, "forEach");
 }
 
-static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionAddBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMapLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionSetBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMapLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
 {
     UNUSED_PARAM(lexicalGlobalObject);
     UNUSED_PARAM(callFrame);
     UNUSED_PARAM(throwScope);
-    if (UNLIKELY(callFrame->argumentCount() < 1))
+    if (UNLIKELY(callFrame->argumentCount() < 2))
         return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
     auto key = convert<IDLDOMString>(*lexicalGlobalObject, callFrame->uncheckedArgument(0));
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    return JSValue::encode(toJS<IDLAny>(forwardAddToMapLike(*lexicalGlobalObject, *callFrame, *castedThis, WTFMove(key))));
+    auto value = convert<IDLDOMString>(*lexicalGlobalObject, callFrame->uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS<IDLAny>(forwardSetToMapLike(*lexicalGlobalObject, *callFrame, *castedThis, WTFMove(key), WTFMove(value))));
 }
 
-EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionAdd(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionSet(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
 {
-    return IDLOperation<JSMapLike>::call<jsMapLikePrototypeFunctionAddBody>(*lexicalGlobalObject, *callFrame, "add");
+    return IDLOperation<JSMapLike>::call<jsMapLikePrototypeFunctionSetBody>(*lexicalGlobalObject, *callFrame, "set");
 }
 
 static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionClearBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMapLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index b84bfff..73de036 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -108,6 +108,7 @@
 #include "InstrumentingAgents.h"
 #include "IntRect.h"
 #include "InternalSettings.h"
+#include "InternalsMapLike.h"
 #include "InternalsSetLike.h"
 #include "JSDOMPromiseDeferred.h"
 #include "JSImageData.h"
@@ -5298,6 +5299,11 @@
     return getCurrentProcessID();
 }
 
+Ref<InternalsMapLike> Internals::createInternalsMapLike()
+{
+    return InternalsMapLike::create();
+}
+
 Ref<InternalsSetLike> Internals::createInternalsSetLike()
 {
     return InternalsSetLike::create();
diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h
index ec32617..25322ed 100644
--- a/Source/WebCore/testing/Internals.h
+++ b/Source/WebCore/testing/Internals.h
@@ -75,6 +75,7 @@
 class HTMLVideoElement;
 class ImageData;
 class InspectorStubFrontend;
+class InternalsMapLike;
 class InternalSettings;
 class InternalsSetLike;
 class MallocStatistics;
@@ -908,6 +909,7 @@
     int processIdentifier() const;
 
     Ref<InternalsSetLike> createInternalsSetLike();
+    Ref<InternalsMapLike> createInternalsMapLike();
 
 private:
     explicit Internals(Document&);
diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl
index 3af7dbe..4529216 100644
--- a/Source/WebCore/testing/Internals.idl
+++ b/Source/WebCore/testing/Internals.idl
@@ -817,5 +817,6 @@
 
     [Conditional=PICTURE_IN_PICTURE_API] void setPictureInPictureAPITestEnabled(HTMLVideoElement videoElement, boolean enabled);
 
+    InternalsMapLike createInternalsMapLike();
     InternalsSetLike createInternalsSetLike();
 };
diff --git a/Source/WebCore/testing/InternalsMapLike.cpp b/Source/WebCore/testing/InternalsMapLike.cpp
new file mode 100644
index 0000000..f1f8e3d
--- /dev/null
+++ b/Source/WebCore/testing/InternalsMapLike.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InternalsMapLike.h"
+
+#include "IDLTypes.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+InternalsMapLike::InternalsMapLike()
+{
+    m_values.add("init", 0);
+}
+
+void InternalsMapLike::synchronizeBackingMap(Ref<DOMMapLike>&& mapLike)
+{
+    m_mapLike = WTFMove(mapLike);
+    for (auto& keyValue : m_values)
+        m_mapLike->set<IDLDOMString, IDLUnsignedLong>(keyValue.key, keyValue.value);
+}
+
+void InternalsMapLike::setFromMapLike(String&& key, unsigned value)
+{
+    m_values.set(WTFMove(key), value);
+}
+
+void InternalsMapLike::clear()
+{
+    m_values.clear();
+}
+
+bool InternalsMapLike::remove(const String& key)
+{
+    return m_values.remove(key);
+}
+
+Vector<String> InternalsMapLike::inspectKeys() const
+{
+    auto result = copyToVector(m_values.keys());
+    std::sort(result.begin(), result.end(), WTF::codePointCompareLessThan);
+    return result;
+}
+
+Vector<unsigned> InternalsMapLike::inspectValues() const
+{
+    auto result = copyToVector(m_values.values());
+    std::sort(result.begin(), result.end(), std::less<unsigned>());
+    return result;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/InternalsMapLike.h b/Source/WebCore/testing/InternalsMapLike.h
new file mode 100644
index 0000000..b733f5c
--- /dev/null
+++ b/Source/WebCore/testing/InternalsMapLike.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSDOMMapLike.h"
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class InternalsMapLike : public RefCounted<InternalsMapLike> {
+public:
+    static Ref<InternalsMapLike> create() { return adoptRef(*new InternalsMapLike); }
+
+    void setFromMapLike(String&&, unsigned);
+    void clear();
+    bool remove(const String&);
+
+    void synchronizeBackingMap(Ref<DOMMapLike>&&);
+    DOMMapLike* backingMap() { return m_mapLike.get(); }
+
+    Vector<String> inspectKeys() const;
+    Vector<unsigned> inspectValues() const;
+
+private:
+    InternalsMapLike();
+    HashMap<String, unsigned> m_values;
+    RefPtr<DOMMapLike> m_mapLike;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/InternalsMapLike.idl b/Source/WebCore/testing/InternalsMapLike.idl
new file mode 100644
index 0000000..97974a1
--- /dev/null
+++ b/Source/WebCore/testing/InternalsMapLike.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    NoInterfaceObject,
+    ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+    SkipVTableValidation,
+] interface InternalsMapLike
+{
+    maplike<DOMString, unsigned long>;
+
+    sequence<DOMString> inspectKeys();
+    sequence<unsigned long> inspectValues();
+};
+