<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[213108] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/213108">213108</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-02-27 17:34:35 -0800 (Mon, 27 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebRTC] Support modern RTCStatsReport
https://bugs.webkit.org/show_bug.cgi?id=166916
&lt;rdar://problem/30293780&gt;

Patch by Youenn Fablet &lt;youenn@apple.com&gt; on 2017-02-27
Reviewed by Alex Christensen.

Updating binding generator and IDL parser to handle maplike.
Covered by binding tests.

Added support for maplike binding from JS wrapper to DOM class.
The principle is to have the JSXX wrapper having a @backingMap slot containing a Map.
All maplike methods are forwarded to the corresponding Map methods.
The XX object is responsible to add key/value pairs using a helper routine.
The creation of the Map is done at creation of the JSXX wrapper.

DOM class is interacting with the map through DOMMapLike.
Extracted DOMGuarded from DOM promise implementation.
This allows reusing this code for DOMMapLike.

Covered by binding tests and manual tests.

* CMakeLists.txt:
* DerivedSources.make:
* Modules/mediastream/RTCStatsReport.h:
(WebCore::RTCStatsReport::InboundRTPStreamStats::InboundRTPStreamStats):
(WebCore::RTCStatsReport::OutboundRTPStreamStats::OutboundRTPStreamStats):
(WebCore::RTCStatsReport::create):
(WebCore::RTCStatsReport::synchronizeBackingMap):
(WebCore::RTCStatsReport::backingMap):
(WebCore::RTCStatsReport::addStats):
* Modules/mediastream/RTCStatsReport.idl:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::fromStdString):
(WebCore::fillRTCStats):
(WebCore::fillRTCRTPStreamStats):
(WebCore::fillInboundRTPStreamStats):
(WebCore::fillOutboundRTPStreamStats):
(WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered):
* Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMBindingInternals.js: Added.
(mapLikeForEach):
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::visitChildren):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMGuardedObject.cpp: Added.
(WebCore::DOMGuardedObject::DOMGuardedObject):
(WebCore::DOMGuardedObject::~DOMGuardedObject):
(WebCore::DOMGuardedObject::clear):
(WebCore::DOMGuardedObject::contextDestroyed):
* bindings/js/JSDOMGuardedObject.h: Added.
(WebCore::DOMGuardedObject::isSuspended):
(WebCore::DOMGuardedObject::visitAggregate):
(WebCore::DOMGuardedObject::guardedObject):
(WebCore::DOMGuardedObject::globalObject):
(WebCore::DOMGuardedObject::isEmpty):
(WebCore::DOMGuarded::DOMGuarded):
(WebCore::DOMGuarded::guarded):
* bindings/js/JSDOMMapLike.cpp: Added.
(WebCore::getBackingMap):
(WebCore::initializeBackingMap):
(WebCore::createBackingMap):
(WebCore::forwardAttributeGetterToBackingMap):
(WebCore::forwardFunctionCallToBackingMap):
(WebCore::forwardForEachCallToBackingMap):
* bindings/js/JSDOMMapLike.h: Added.
(WebCore::DOMMapLike::set):
(WebCore::synchronizeBackingMap):
(WebCore::forwardSizeToMapLike):
(WebCore::forwardEntriesToMapLike):
(WebCore::forwardKeysToMapLike):
(WebCore::forwardValuesToMapLike):
(WebCore::forwardClearToMapLike):
(WebCore::forwardForEachToMapLike):
(WebCore::forwardHasToMapLike):
(WebCore::forwardAddToMapLike):
(WebCore::forwardDeleteToMapLike):
* bindings/js/JSDOMPromise.cpp:
(WebCore::DeferredPromise::promise):
(WebCore::DeferredPromise::reject):
* bindings/js/JSDOMPromise.h:
(WebCore::DeferredPromise::resolve):
(WebCore::DeferredPromise::resolveWithNewlyCreated):
(WebCore::DeferredPromise::reject):
(WebCore::DeferredPromise::resolveWithCallback):
(WebCore::DeferredPromise::rejectWithCallback):
(WebCore::DeferredPromise::DeferredPromise):
(WebCore::DeferredPromise::deferred):
* bindings/js/WebCoreBuiltinNames.h:
* bindings/scripts/CodeGeneratorJS.pm:
(PrototypeFunctionCount):
(GeneratePropertiesHashTable):
(InterfaceNeedsIterator):
(GenerateImplementation):
(GenerateParametersCheck):
* bindings/scripts/IDLParser.pm:
(assert):
(parseAttributeOrOperationOrIterator):
(parseSerializer):
(parseAttributeOrOperationRest):
(parseAttribute):
(parseAttributeRest):
(parseOperationOrIterator):
(parseOptionalIterableInterface):
(parseMapLikeRest):
(parseMapLikeProperties):
(parseOperationRest):
(applyMemberList):
* bindings/scripts/test/JS/JSMapLike.cpp: Added.
* bindings/scripts/test/JS/JSMapLike.h: Added.
* bindings/scripts/test/JS/JSReadOnlyMapLike.cpp: Added.
* bindings/scripts/test/JS/JSReadOnlyMapLike.h: Added.
* bindings/scripts/test/TestMapLike.idl: Added.
* bindings/scripts/test/TestReadOnlyMapLike.idl: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceThirdPartylibwebrtcSourcewebrtcapistatsrtcstats_objectsh">trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstats_objects.h</a></li>
<li><a href="#trunkSourceThirdPartylibwebrtcSourcewebrtcapistatsrtcstatsreporth">trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstatsreport.h</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCStatsReporth">trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCStatsReportidl">trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendh">trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMGlobalObjectcpp">trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMGlobalObjecth">trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMPromisecpp">trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMPromiseh">trunk/Source/WebCore/bindings/js/JSDOMPromise.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh">trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsIDLParserpm">trunk/Source/WebCore/bindings/scripts/IDLParser.pm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingInternalsjs">trunk/Source/WebCore/bindings/js/JSDOMBindingInternals.js</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMGuardedObjectcpp">trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMGuardedObjecth">trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMMapLikecpp">trunk/Source/WebCore/bindings/js/JSDOMMapLike.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMMapLikeh">trunk/Source/WebCore/bindings/js/JSDOMMapLike.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSMapLikecpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSMapLikeh">trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSReadOnlyMapLikecpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSReadOnlyMapLikeh">trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestTestMapLikeidl">trunk/Source/WebCore/bindings/scripts/test/TestMapLike.idl</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestTestReadOnlyMapLikeidl">trunk/Source/WebCore/bindings/scripts/test/TestReadOnlyMapLike.idl</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCStatsReportcpp">trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceThirdPartylibwebrtcSourcewebrtcapistatsrtcstats_objectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstats_objects.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstats_objects.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstats_objects.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -14,6 +14,7 @@
</span><span class="cx"> #include &lt;string&gt;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;webrtc/api/stats/rtcstats.h&quot;
</span><ins>+#include &quot;webrtc/base/export.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace webrtc {
</span><span class="cx"> 
</span><span class="lines">@@ -301,7 +302,7 @@
</span><span class="cx"> // https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
</span><span class="cx"> // TODO(hbos): Finish implementation and support the remote case
</span><span class="cx"> // |is_remote = true|. Tracking bug crbug.com/657855
</span><del>-class RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
</del><ins>+class WEBRTC_EXPORT RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
</ins><span class="cx">  public:
</span><span class="cx">   WEBRTC_RTCSTATS_DECL();
</span><span class="cx"> 
</span><span class="lines">@@ -343,7 +344,7 @@
</span><span class="cx"> // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*
</span><span class="cx"> // TODO(hbos): Finish implementation and support the remote case
</span><span class="cx"> // |is_remote = true|. Tracking bug crbug.com/657856
</span><del>-class RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
</del><ins>+class WEBRTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
</ins><span class="cx">  public:
</span><span class="cx">   WEBRTC_RTCSTATS_DECL();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartylibwebrtcSourcewebrtcapistatsrtcstatsreporth"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstatsreport.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstatsreport.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/stats/rtcstatsreport.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -17,6 +17,7 @@
</span><span class="cx"> #include &lt;vector&gt;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;webrtc/api/stats/rtcstats.h&quot;
</span><ins>+#include &quot;webrtc/base/export.h&quot;
</ins><span class="cx"> #include &quot;webrtc/base/refcount.h&quot;
</span><span class="cx"> #include &quot;webrtc/base/scoped_ref_ptr.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -24,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> // A collection of stats.
</span><span class="cx"> // This is accessible as a map from |RTCStats::id| to |RTCStats|.
</span><del>-class RTCStatsReport : public rtc::RefCountInterface {
</del><ins>+class WEBRTC_EXPORT RTCStatsReport : public rtc::RefCountInterface {
</ins><span class="cx">  public:
</span><span class="cx">   typedef std::map&lt;std::string, std::unique_ptr&lt;const RTCStats&gt;&gt; StatsMap;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/CMakeLists.txt        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -935,7 +935,6 @@
</span><span class="cx">     Modules/mediastream/RTCRtpSender.cpp
</span><span class="cx">     Modules/mediastream/RTCRtpTransceiver.cpp
</span><span class="cx">     Modules/mediastream/RTCSessionDescription.cpp
</span><del>-    Modules/mediastream/RTCStatsReport.cpp
</del><span class="cx">     Modules/mediastream/RTCTrackEvent.cpp
</span><span class="cx">     Modules/mediastream/SDPProcessor.cpp
</span><span class="cx">     Modules/mediastream/UserMediaController.cpp
</span><span class="lines">@@ -1121,6 +1120,8 @@
</span><span class="cx">     bindings/js/JSDOMExceptionHandling.cpp
</span><span class="cx">     bindings/js/JSDOMGlobalObject.cpp
</span><span class="cx">     bindings/js/JSDOMGlobalObjectTask.cpp
</span><ins>+    bindings/js/JSDOMGuardedObject.cpp
+    bindings/js/JSDOMMapLike.cpp
</ins><span class="cx">     bindings/js/JSDOMPromise.cpp
</span><span class="cx">     bindings/js/JSDOMStringMapCustom.cpp
</span><span class="cx">     bindings/js/JSDOMWindowBase.cpp
</span><span class="lines">@@ -3700,6 +3701,7 @@
</span><span class="cx">     ${WEBCORE_DIR}/Modules/streams/StreamInternals.js
</span><span class="cx">     ${WEBCORE_DIR}/Modules/streams/WritableStream.js
</span><span class="cx">     ${WEBCORE_DIR}/Modules/streams/WritableStreamInternals.js
</span><ins>+    ${WEBCORE_DIR}/bindings/js/JSDOMBindingInternals.js
</ins><span class="cx">     ${WEBCORE_DIR}/xml/XMLHttpRequest.js
</span><span class="cx"> )
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/ChangeLog        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -1,3 +1,120 @@
</span><ins>+2017-02-27  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        [WebRTC] Support modern RTCStatsReport
+        https://bugs.webkit.org/show_bug.cgi?id=166916
+        &lt;rdar://problem/30293780&gt;
+
+        Reviewed by Alex Christensen.
+
+        Updating binding generator and IDL parser to handle maplike.
+        Covered by binding tests.
+
+        Added support for maplike binding from JS wrapper to DOM class.
+        The principle is to have the JSXX wrapper having a @backingMap slot containing a Map.
+        All maplike methods are forwarded to the corresponding Map methods.
+        The XX object is responsible to add key/value pairs using a helper routine.
+        The creation of the Map is done at creation of the JSXX wrapper.
+
+        DOM class is interacting with the map through DOMMapLike.
+        Extracted DOMGuarded from DOM promise implementation.
+        This allows reusing this code for DOMMapLike.
+
+        Covered by binding tests and manual tests.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * Modules/mediastream/RTCStatsReport.h:
+        (WebCore::RTCStatsReport::InboundRTPStreamStats::InboundRTPStreamStats):
+        (WebCore::RTCStatsReport::OutboundRTPStreamStats::OutboundRTPStreamStats):
+        (WebCore::RTCStatsReport::create):
+        (WebCore::RTCStatsReport::synchronizeBackingMap):
+        (WebCore::RTCStatsReport::backingMap):
+        (WebCore::RTCStatsReport::addStats):
+        * Modules/mediastream/RTCStatsReport.idl:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::fromStdString):
+        (WebCore::fillRTCStats):
+        (WebCore::fillRTCRTPStreamStats):
+        (WebCore::fillInboundRTPStreamStats):
+        (WebCore::fillOutboundRTPStreamStats):
+        (WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered):
+        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSDOMBindingInternals.js: Added.
+        (mapLikeForEach):
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::visitChildren):
+        * bindings/js/JSDOMGlobalObject.h:
+        * bindings/js/JSDOMGuardedObject.cpp: Added.
+        (WebCore::DOMGuardedObject::DOMGuardedObject):
+        (WebCore::DOMGuardedObject::~DOMGuardedObject):
+        (WebCore::DOMGuardedObject::clear):
+        (WebCore::DOMGuardedObject::contextDestroyed):
+        * bindings/js/JSDOMGuardedObject.h: Added.
+        (WebCore::DOMGuardedObject::isSuspended):
+        (WebCore::DOMGuardedObject::visitAggregate):
+        (WebCore::DOMGuardedObject::guardedObject):
+        (WebCore::DOMGuardedObject::globalObject):
+        (WebCore::DOMGuardedObject::isEmpty):
+        (WebCore::DOMGuarded::DOMGuarded):
+        (WebCore::DOMGuarded::guarded):
+        * bindings/js/JSDOMMapLike.cpp: Added.
+        (WebCore::getBackingMap):
+        (WebCore::initializeBackingMap):
+        (WebCore::createBackingMap):
+        (WebCore::forwardAttributeGetterToBackingMap):
+        (WebCore::forwardFunctionCallToBackingMap):
+        (WebCore::forwardForEachCallToBackingMap):
+        * bindings/js/JSDOMMapLike.h: Added.
+        (WebCore::DOMMapLike::set):
+        (WebCore::synchronizeBackingMap):
+        (WebCore::forwardSizeToMapLike):
+        (WebCore::forwardEntriesToMapLike):
+        (WebCore::forwardKeysToMapLike):
+        (WebCore::forwardValuesToMapLike):
+        (WebCore::forwardClearToMapLike):
+        (WebCore::forwardForEachToMapLike):
+        (WebCore::forwardHasToMapLike):
+        (WebCore::forwardAddToMapLike):
+        (WebCore::forwardDeleteToMapLike):
+        * bindings/js/JSDOMPromise.cpp:
+        (WebCore::DeferredPromise::promise):
+        (WebCore::DeferredPromise::reject):
+        * bindings/js/JSDOMPromise.h:
+        (WebCore::DeferredPromise::resolve):
+        (WebCore::DeferredPromise::resolveWithNewlyCreated):
+        (WebCore::DeferredPromise::reject):
+        (WebCore::DeferredPromise::resolveWithCallback):
+        (WebCore::DeferredPromise::rejectWithCallback):
+        (WebCore::DeferredPromise::DeferredPromise):
+        (WebCore::DeferredPromise::deferred):
+        * bindings/js/WebCoreBuiltinNames.h:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (PrototypeFunctionCount):
+        (GeneratePropertiesHashTable):
+        (InterfaceNeedsIterator):
+        (GenerateImplementation):
+        (GenerateParametersCheck):
+        * bindings/scripts/IDLParser.pm:
+        (assert):
+        (parseAttributeOrOperationOrIterator):
+        (parseSerializer):
+        (parseAttributeOrOperationRest):
+        (parseAttribute):
+        (parseAttributeRest):
+        (parseOperationOrIterator):
+        (parseOptionalIterableInterface):
+        (parseMapLikeRest):
+        (parseMapLikeProperties):
+        (parseOperationRest):
+        (applyMemberList):
+        * bindings/scripts/test/JS/JSMapLike.cpp: Added.
+        * bindings/scripts/test/JS/JSMapLike.h: Added.
+        * bindings/scripts/test/JS/JSReadOnlyMapLike.cpp: Added.
+        * bindings/scripts/test/JS/JSReadOnlyMapLike.h: Added.
+        * bindings/scripts/test/TestMapLike.idl: Added.
+        * bindings/scripts/test/TestReadOnlyMapLike.idl: Added.
+
</ins><span class="cx"> 2017-02-27  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Introduce a VM Traps mechanism and refactor Watchdog to use it.
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/DerivedSources.make        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -1363,6 +1363,7 @@
</span><span class="cx">     $(WebCore)/Modules/streams/StreamInternals.js \
</span><span class="cx">     $(WebCore)/Modules/streams/WritableStream.js \
</span><span class="cx">     $(WebCore)/Modules/streams/WritableStreamInternals.js \
</span><ins>+    $(WebCore)/bindings/js/JSDOMBindingInternals.js \
</ins><span class="cx">     $(WebCore)/xml/XMLHttpRequest.js \
</span><span class="cx"> #
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCStatsReportcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -1,35 +0,0 @@
</span><del>-
-/*
- * Copyright (C) 2012 Google 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 &quot;config.h&quot;
-#include &quot;RTCStatsReport.h&quot;
-
-#if ENABLE(WEB_RTC)
-
-namespace WebCore {
-
-} // namespace WebCore
-
-#endif // ENABLE(WEB_RTC)
</del></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCStatsReporth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2012 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -24,8 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &lt;wtf/Ref.h&gt;
-#include &lt;wtf/RefCounted.h&gt;
</del><ins>+#include &quot;JSDOMMapLike.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -33,8 +33,95 @@
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;RTCStatsReport&gt; create() { return adoptRef(*new RTCStatsReport); }
</span><span class="cx"> 
</span><ins>+    void synchronizeBackingMap(Ref&lt;DOMMapLike&gt;&amp;&amp; mapLike) { m_mapLike = WTFMove(mapLike); }
+    DOMMapLike* backingMap() { return m_mapLike.get(); }
+
+    template&lt;typename Value&gt; void addStats(typename Value::ParameterType&amp;&amp; value) { m_mapLike-&gt;set&lt;IDLDOMString, Value&gt;(value.id, std::forward&lt;typename Value::ParameterType&gt;(value)); }
+
+
+    enum class Type {
+        Codec,
+        InboundRtp,
+        OutboundRtp,
+        PeerConnection,
+        DataChannel,
+        Track,
+        Transport,
+        CandidatePair,
+        LocalCandidate,
+        RemoteCandidate,
+        Certificate
+    };
+    struct Stats {
+        unsigned long long timestamp;
+        Type type;
+        String id;
+    };
+
+    struct RTCRTPStreamStats : Stats {
+        String ssrc;
+        String associateStatsId;
+        bool isRemote { false };
+        String mediaType;
+
+        String mediaTrackId;
+        String transportId;
+        String codecId;
+        unsigned long firCount { 0 };
+        unsigned long pliCount { 0 };
+        unsigned long nackCount { 0 };
+        unsigned long sliCount { 0 };
+        unsigned long long qpSum { 0 };
+    };
+
+    struct InboundRTPStreamStats : RTCRTPStreamStats {
+        InboundRTPStreamStats() { type = RTCStatsReport::Type::InboundRtp; }
+
+        String ssrc;
+        String associateStatsId;
+        bool isRemote { false };
+        String mediaType;
+        String mediaTrackId;
+        String transportId;
+        String codecId;
+        unsigned long firCount { 0 };
+        unsigned long pliCount { 0 };
+        unsigned long nackCount { 0 };
+        unsigned long sliCount { 0 };
+        unsigned long long qpSum { 0 };
+        unsigned long packetsReceived { 0 };
+        unsigned long long bytesReceived { 0 };
+        unsigned long packetsLost { 0 };
+        double jitter { 0 };
+        double fractionLost { 0 };
+        unsigned long packetsDiscarded { 0 };
+        unsigned long packetsRepaired { 0 };
+        unsigned long burstPacketsLost { 0 };
+        unsigned long burstPacketsDiscarded { 0 };
+        unsigned long burstLossCount { 0 };
+        unsigned long burstDiscardCount { 0 };
+        double burstLossRate { 0 };
+        double burstDiscardRate { 0 };
+        double gapLossRate { 0 };
+        double gapDiscardRate { 0 };
+        unsigned long framesDecoded { 0 };
+    };
+
+    struct OutboundRTPStreamStats : RTCRTPStreamStats {
+        OutboundRTPStreamStats() { type = RTCStatsReport::Type::OutboundRtp; }
+
+        unsigned long packetsSent { 0 };
+        unsigned long long bytesSent { 0 };
+        double targetBitrate { 0 };
+        double roundTripTime { 0 };
+        unsigned long framesEncoded { 0 };
+    };
+
</ins><span class="cx"> private:
</span><span class="cx">     RTCStatsReport() = default;
</span><ins>+
+private:
+    RefPtr&lt;DOMMapLike&gt; m_mapLike;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCStatsReportidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -27,6 +27,70 @@
</span><span class="cx">     Conditional=WEB_RTC,
</span><span class="cx">     ImplementationLacksVTable,
</span><span class="cx"> ] interface RTCStatsReport {
</span><del>-    // FIXME: Make it setlike
-    //readonly maplike&lt;DOMString, object&gt;;
</del><ins>+    readonly maplike&lt;DOMString, object&gt;;
</ins><span class="cx"> };
</span><ins>+
+enum RTCStatsType {
+    &quot;codec&quot;,
+    &quot;inbound-rtp&quot;,
+    &quot;outbound-rtp&quot;,
+    &quot;peer-connection&quot;,
+    &quot;data-channel&quot;,
+    &quot;track&quot;,
+    &quot;transport&quot;,
+    &quot;candidate-pair&quot;,
+    &quot;local-candidate&quot;,
+    &quot;remote-candidate&quot;,
+    &quot;certificate&quot;
+};
+
+dictionary RTCStats {
+    unsigned long long timestamp;
+    RTCStatsType type;
+    DOMString id;
+
+};
+
+dictionary RTCRTPStreamStats : RTCStats {
+    DOMString ssrc;
+    DOMString associateStatsId;
+    boolean isRemote = false;
+    DOMString mediaType;
+    DOMString mediaTrackId;
+    DOMString transportId;
+    DOMString codecId;
+    unsigned long firCount;
+    unsigned long pliCount;
+    unsigned long nackCount;
+    unsigned long sliCount;
+    unsigned long long qpSum;
+};
+
+[ JSGenerateToJSObject ]
+dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
+    unsigned long packetsReceived;
+    unsigned long long bytesReceived;
+    unsigned long packetsLost;
+    double jitter;
+    double fractionLost;
+    unsigned long packetsDiscarded;
+    unsigned long packetsRepaired;
+    unsigned long burstPacketsLost;
+    unsigned long burstPacketsDiscarded;
+    unsigned long burstLossCount;
+    unsigned long burstDiscardCount;
+    double burstLossRate;
+    double burstDiscardRate;
+    double gapLossRate;
+    double gapDiscardRate;
+    unsigned long framesDecoded;
+};
+
+[ JSGenerateToJSObject ]
+dictionary RTCOutboundRTPStreamStats : RTCRTPStreamStats {
+    unsigned long packetsSent;
+    unsigned long long bytesSent;
+    double targetBitrate;
+    double roundTripTime;
+    unsigned long framesEncoded;
+};
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCMediaEndpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> #if USE(LIBWEBRTC)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;EventNames.h&quot;
</span><ins>+#include &quot;JSDOMConvert.h&quot;
+#include &quot;JSRTCStatsReport.h&quot;
</ins><span class="cx"> #include &quot;LibWebRTCDataChannelHandler.h&quot;
</span><span class="cx"> #include &quot;LibWebRTCPeerConnectionBackend.h&quot;
</span><span class="cx"> #include &quot;LibWebRTCProvider.h&quot;
</span><span class="lines">@@ -38,6 +40,7 @@
</span><span class="cx"> #include &quot;RTCDataChannelEvent.h&quot;
</span><span class="cx"> #include &quot;RTCPeerConnection.h&quot;
</span><span class="cx"> #include &quot;RTCSessionDescription.h&quot;
</span><ins>+#include &quot;RTCStatsReport.h&quot;
</ins><span class="cx"> #include &quot;RTCTrackEvent.h&quot;
</span><span class="cx"> #include &quot;RealtimeIncomingAudioSource.h&quot;
</span><span class="cx"> #include &quot;RealtimeIncomingVideoSource.h&quot;
</span><span class="lines">@@ -226,16 +229,123 @@
</span><span class="cx">         m_id = track-&gt;id();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr&lt;const webrtc::RTCStatsReport&gt;&amp; report)
</del><ins>+static inline String fromStdString(const std::string&amp; value)
</ins><span class="cx"> {
</span><del>-    callOnMainThread([protectedThis = rtc::scoped_refptr&lt;LibWebRTCMediaEndpoint::StatsCollector&gt;(this), report] {
</del><ins>+    return String(value.data(), value.length());
+}
+
+static inline void fillRTCStats(RTCStatsReport::Stats&amp; stats, const webrtc::RTCStats&amp; rtcStats)
+{
+    stats.timestamp = rtcStats.timestamp_us();
+    stats.id = fromStdString(rtcStats.id());
+}
+
+static inline void fillRTCRTPStreamStats(RTCStatsReport::RTCRTPStreamStats&amp; stats, const webrtc::RTCRTPStreamStats&amp; rtcStats)
+{
+    fillRTCStats(stats, rtcStats);
+    if (rtcStats.ssrc.is_defined())
+        stats.ssrc = fromStdString(*rtcStats.ssrc);
+    if (rtcStats.associate_stats_id.is_defined())
+        stats.associateStatsId = fromStdString(*rtcStats.associate_stats_id);
+    if (rtcStats.is_remote.is_defined())
+        stats.isRemote = *rtcStats.is_remote;
+    if (rtcStats.media_type.is_defined())
+        stats.mediaType = fromStdString(*rtcStats.media_type);
+    if (rtcStats.media_track_id.is_defined())
+        stats.mediaTrackId = fromStdString(*rtcStats.media_track_id);
+    if (rtcStats.transport_id.is_defined())
+        stats.transportId = fromStdString(*rtcStats.transport_id);
+    if (rtcStats.codec_id.is_defined())
+        stats.codecId = fromStdString(*rtcStats.codec_id);
+    if (rtcStats.fir_count.is_defined())
+        stats.firCount = *rtcStats.fir_count;
+    if (rtcStats.pli_count.is_defined())
+        stats.pliCount = *rtcStats.pli_count;
+    if (rtcStats.nack_count.is_defined())
+        stats.nackCount = *rtcStats.nack_count;
+    if (rtcStats.sli_count.is_defined())
+        stats.sliCount = *rtcStats.sli_count;
+    // FIXME: Set qpSum
+    stats.qpSum = 0;
+}
+
+static inline void fillInboundRTPStreamStats(RTCStatsReport::InboundRTPStreamStats&amp; stats, const webrtc::RTCInboundRTPStreamStats&amp; rtcStats)
+{
+    fillRTCRTPStreamStats(stats, rtcStats);
+    if (rtcStats.packets_received.is_defined())
+        stats.packetsReceived = *rtcStats.packets_received;
+    if (rtcStats.bytes_received.is_defined())
+        stats.bytesReceived = *rtcStats.bytes_received;
+    if (rtcStats.packets_lost.is_defined())
+        stats.packetsLost = *rtcStats.packets_lost;
+    if (rtcStats.jitter.is_defined())
+        stats.jitter = *rtcStats.jitter;
+    if (rtcStats.fraction_lost.is_defined())
+        stats.fractionLost = *rtcStats.fraction_lost;
+    if (rtcStats.packets_discarded.is_defined())
+        stats.packetsDiscarded = *rtcStats.packets_discarded;
+    if (rtcStats.packets_repaired.is_defined())
+        stats.packetsRepaired = *rtcStats.packets_repaired;
+    if (rtcStats.burst_packets_lost.is_defined())
+        stats.burstPacketsLost = *rtcStats.burst_packets_lost;
+    if (rtcStats.burst_packets_discarded.is_defined())
+        stats.burstPacketsDiscarded = *rtcStats.burst_packets_discarded;
+    if (rtcStats.burst_loss_count.is_defined())
+        stats.burstLossCount = *rtcStats.burst_loss_count;
+    if (rtcStats.burst_discard_count.is_defined())
+        stats.burstDiscardCount = *rtcStats.burst_discard_count;
+    if (rtcStats.burst_loss_rate.is_defined())
+        stats.burstLossRate = *rtcStats.burst_loss_rate;
+    if (rtcStats.burst_discard_rate.is_defined())
+        stats.burstDiscardRate = *rtcStats.burst_discard_rate;
+    if (rtcStats.gap_loss_rate.is_defined())
+        stats.gapLossRate = *rtcStats.gap_loss_rate;
+    if (rtcStats.gap_discard_rate.is_defined())
+        stats.gapDiscardRate = *rtcStats.gap_discard_rate;
+    // FIXME: Set framesDecoded
+    stats.framesDecoded = 0;
+}
+
+static inline void fillOutboundRTPStreamStats(RTCStatsReport::OutboundRTPStreamStats&amp; stats, const webrtc::RTCOutboundRTPStreamStats&amp; rtcStats)
+{
+    fillRTCRTPStreamStats(stats, rtcStats);
+
+    if (rtcStats.packets_sent.is_defined())
+        stats.packetsSent = *rtcStats.packets_sent;
+    if (rtcStats.bytes_sent.is_defined())
+        stats.bytesSent = *rtcStats.bytes_sent;
+    if (rtcStats.target_bitrate.is_defined())
+        stats.targetBitrate = *rtcStats.target_bitrate;
+    if (rtcStats.round_trip_time.is_defined())
+        stats.roundTripTime = *rtcStats.round_trip_time;
+    // FIXME: Set framesEncoded
+    stats.framesEncoded = 0;
+}
+
+void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr&lt;const webrtc::RTCStatsReport&gt;&amp; rtcReport)
+{
+    callOnMainThread([protectedThis = rtc::scoped_refptr&lt;LibWebRTCMediaEndpoint::StatsCollector&gt;(this), rtcReport] {
</ins><span class="cx">         if (protectedThis-&gt;m_endpoint-&gt;isStopped())
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // FIXME: Fulfill promise with the report
-        UNUSED_PARAM(report);
</del><ins>+        auto report = RTCStatsReport::create();
+        protectedThis-&gt;m_endpoint-&gt;m_peerConnectionBackend.getStatsSucceeded(protectedThis-&gt;m_promise, report.copyRef());
+        ASSERT(report-&gt;backingMap());
</ins><span class="cx"> 
</span><del>-        protectedThis-&gt;m_endpoint-&gt;m_peerConnectionBackend.getStatsFailed(protectedThis-&gt;m_promise, Exception { TypeError, ASCIILiteral(&quot;Stats API is not yet implemented&quot;) });
</del><ins>+        for (const auto&amp; rtcStats : *rtcReport) {
+            if (rtcStats.type() == webrtc::RTCInboundRTPStreamStats::kType) {
+                RTCStatsReport::InboundRTPStreamStats stats;
+                fillInboundRTPStreamStats(stats, static_cast&lt;const webrtc::RTCInboundRTPStreamStats&amp;&gt;(rtcStats));
+                report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::InboundRTPStreamStats&gt;&gt;(WTFMove(stats));
+                return;
+            }
+            if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
+                RTCStatsReport::OutboundRTPStreamStats stats;
+                fillOutboundRTPStreamStats(stats, static_cast&lt;const webrtc::RTCOutboundRTPStreamStats&amp;&gt;(rtcStats));
+                report-&gt;addStats&lt;IDLDictionary&lt;RTCStatsReport::OutboundRTPStreamStats&gt;&gt;(WTFMove(stats));
+                return;
+            }
+        }
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamlibwebrtcLibWebRTCPeerConnectionBackendh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> class LibWebRTCMediaEndpoint;
</span><span class="cx"> class RTCRtpReceiver;
</span><span class="cx"> class RTCSessionDescription;
</span><del>-class RTCstatsReport;
</del><ins>+class RTCStatsReport;
</ins><span class="cx"> class RealtimeOutgoingAudioSource;
</span><span class="cx"> class RealtimeOutgoingVideoSource;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -192,7 +192,6 @@
</span><span class="cx">                 078E090A17D14CEE00420AA1 /* RTCIceCandidateEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B7417CEC32700848E51 /* RTCIceCandidateEvent.cpp */; };
</span><span class="cx">                 078E090B17D14CEE00420AA1 /* RTCPeerConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B7717CEC32700848E51 /* RTCPeerConnection.cpp */; };
</span><span class="cx">                 078E090C17D14CEE00420AA1 /* RTCSessionDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B7A17CEC32700848E51 /* RTCSessionDescription.cpp */; };
</span><del>-                078E090E17D14CEE00420AA1 /* RTCStatsReport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B8317CEC32700848E51 /* RTCStatsReport.cpp */; };
</del><span class="cx">                 078E091217D14CEE00420AA1 /* UserMediaController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B8E17CEC32700848E51 /* UserMediaController.cpp */; };
</span><span class="cx">                 078E091317D14CEE00420AA1 /* UserMediaRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07221B9017CEC32700848E51 /* UserMediaRequest.cpp */; };
</span><span class="cx">                 078E091417D14D1C00420AA1 /* MediaConstraintsImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221B4B17CEC32700848E51 /* MediaConstraintsImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1566,6 +1565,7 @@
</span><span class="cx">                 4162A4581011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */; };
</span><span class="cx">                 416E29A6102FA962007FC14E /* WorkerReportingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E29A5102FA962007FC14E /* WorkerReportingProxy.h */; };
</span><span class="cx">                 416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B764D9 /* ReadableStreamInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                416E6FE81BBD12DF000A3F65 /* JSDOMBindingInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B764DA /* JSDOMBindingInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 416E6FE81BBD12DF000A6023 /* FetchInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B764B9 /* FetchInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 416E6FE81BBD12DF000A6033 /* StreamInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B764C9 /* StreamInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 416E6FE81BBD12DF000A6043 /* ReadableByteStreamInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B73F64 /* ReadableByteStreamInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1601,6 +1601,8 @@
</span><span class="cx">                 419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
</span><span class="cx">                 419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */; };
</span><span class="cx">                 41A1B00E1E526579007F3769 /* LibWebRTCProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A1B00D1E52656E007F3769 /* LibWebRTCProvider.cpp */; };
</span><ins>+                41A1B01C1E54239B007F3769 /* JSDOMGuardedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A1B01A1E542396007F3769 /* JSDOMGuardedObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                41A1B01D1E54239E007F3769 /* JSDOMGuardedObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A1B01B1E542396007F3769 /* JSDOMGuardedObject.cpp */; };
</ins><span class="cx">                 41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */; };
</span><span class="cx">                 41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; };
</span><span class="cx">                 41ABE67B1D0580DB006D862D /* CrossOriginPreflightChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */; };
</span><span class="lines">@@ -1613,6 +1615,8 @@
</span><span class="cx">                 41CF8BE71D46226700707DC9 /* FetchBodyConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41CF8BE41D46222000707DC9 /* FetchBodyConsumer.cpp */; };
</span><span class="cx">                 41D015CA0F4B5C71004A662F /* ContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D015C80F4B5C71004A662F /* ContentType.h */; };
</span><span class="cx">                 41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D015C90F4B5C71004A662F /* ContentType.cpp */; };
</span><ins>+                41DEFCB51E56C1BD000D9E5F /* JSDOMMapLike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41DEFCB31E56C1B9000D9E5F /* JSDOMMapLike.cpp */; };
+                41DEFCB61E56C1BD000D9E5F /* JSDOMMapLike.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */; };
</ins><span class="cx">                 41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */; };
</span><span class="cx">                 41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */; };
</span><span class="cx">                 41E408391DCB748900EFCE19 /* PeerConnectionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E408381DCB747900EFCE19 /* PeerConnectionBackend.cpp */; };
</span><span class="lines">@@ -7242,7 +7246,6 @@
</span><span class="cx">                 07221B7A17CEC32700848E51 /* RTCSessionDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCSessionDescription.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B7B17CEC32700848E51 /* RTCSessionDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCSessionDescription.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B7C17CEC32700848E51 /* RTCSessionDescription.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCSessionDescription.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                07221B8317CEC32700848E51 /* RTCStatsReport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCStatsReport.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 07221B8417CEC32700848E51 /* RTCStatsReport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCStatsReport.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B8517CEC32700848E51 /* RTCStatsReport.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCStatsReport.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07221B8D17CEC32700848E51 /* UserMediaClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -8901,6 +8904,8 @@
</span><span class="cx">                 41A023ED1A39DB7900F722CF /* ReadableStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStream.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41A023ED1A39DB7900F722DF /* WritableStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WritableStream.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41A1B00D1E52656E007F3769 /* LibWebRTCProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCProvider.cpp; path = libwebrtc/LibWebRTCProvider.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                41A1B01A1E542396007F3769 /* JSDOMGuardedObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMGuardedObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                41A1B01B1E542396007F3769 /* JSDOMGuardedObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMGuardedObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DedicatedWorkerThread.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DedicatedWorkerThread.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossOriginPreflightChecker.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -8916,6 +8921,9 @@
</span><span class="cx">                 41D015C80F4B5C71004A662F /* ContentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41D015C90F4B5C71004A662F /* ContentType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentType.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41D51BB21E4E2E8100131A5B /* LibWebRTCAudioFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCAudioFormat.h; path = libwebrtc/LibWebRTCAudioFormat.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                41DEFCB21E56C1B9000D9E5F /* JSDOMBindingInternals.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSDOMBindingInternals.js; sourceTree = &quot;&lt;group&gt;&quot;; };
+                41DEFCB31E56C1B9000D9E5F /* JSDOMMapLike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMMapLike.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMMapLike.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractWorker.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractWorker.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41E1B1CC0FF5986900576B3B /* AbstractWorker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AbstractWorker.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -11702,6 +11710,7 @@
</span><span class="cx">                 9908B0FD1BCAD07D00ED0F45 /* FetchInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9908B0FD1BCAD07D00ED0F55 /* StreamInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9908B0FD1BCAD07D00ED0F65 /* ReadableStreamInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableStreamInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                9908B0FD1BCAD07D00ED0F66 /* JSDOMBindingInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMBindingInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 9908B0FD1BCAD07D00ED0F75 /* WritableStreamInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WritableStreamInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9908B0FD1BCAD07D00ED3F64 /* ReadableByteStreamInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableByteStreamInternalsBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9908B0FE1BCAD07D00ED0F65 /* ReadableStreamDefaultReaderBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableStreamDefaultReaderBuiltins.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -11749,6 +11758,7 @@
</span><span class="cx">                 9B03D8061BB3110D00B764C9 /* StreamInternalsBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamInternalsBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B03D8061BB3110D00B764D8 /* ReadableStreamBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B03D8061BB3110D00B764D9 /* ReadableStreamInternalsBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamInternalsBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                9B03D8061BB3110D00B764DA /* JSDOMBindingInternalsBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMBindingInternalsBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 9B03D8061BB3110D00B764E8 /* WritableStreamBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WritableStreamBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B03D8061BB3110D00B764E9 /* WritableStreamInternalsBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WritableStreamInternalsBuiltins.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9B0FE8731D9E02DF004A8ACB /* DocumentOrShadowRoot.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DocumentOrShadowRoot.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -15472,7 +15482,6 @@
</span><span class="cx">                                 07221B7A17CEC32700848E51 /* RTCSessionDescription.cpp */,
</span><span class="cx">                                 07221B7B17CEC32700848E51 /* RTCSessionDescription.h */,
</span><span class="cx">                                 07221B7C17CEC32700848E51 /* RTCSessionDescription.idl */,
</span><del>-                                07221B8317CEC32700848E51 /* RTCStatsReport.cpp */,
</del><span class="cx">                                 07221B8417CEC32700848E51 /* RTCStatsReport.h */,
</span><span class="cx">                                 07221B8517CEC32700848E51 /* RTCStatsReport.idl */,
</span><span class="cx">                                 5E2C43641BCEE3720001E2BC /* RTCTrackEvent.cpp */,
</span><span class="lines">@@ -18007,6 +18016,8 @@
</span><span class="cx">                                 9908B0FF1BCAD07D00ED0F65 /* ReadableStreamDefaultReaderBuiltins.h */,
</span><span class="cx">                                 9908B0FD1BCAD07D00ED0F65 /* ReadableStreamInternalsBuiltins.cpp */,
</span><span class="cx">                                 9B03D8061BB3110D00B764D9 /* ReadableStreamInternalsBuiltins.h */,
</span><ins>+                                9908B0FD1BCAD07D00ED0F66 /* JSDOMBindingInternalsBuiltins.cpp */,
+                                9B03D8061BB3110D00B764DA /* JSDOMBindingInternalsBuiltins.h */,
</ins><span class="cx">                                 5E2C43751BCF9A0B0001E2BC /* RTCPeerConnectionBuiltins.cpp */,
</span><span class="cx">                                 5E2C43761BCF9A0B0001E2BC /* RTCPeerConnectionBuiltins.h */,
</span><span class="cx">                                 5E2C43781BCF9A0B0001E2BC /* RTCPeerConnectionInternalsBuiltins.cpp */,
</span><span class="lines">@@ -22525,6 +22536,7 @@
</span><span class="cx">                                 9BD4E9151C462872005065BC /* JSCustomElementInterface.h */,
</span><span class="cx">                                 93B70D4809EB0C7C009D8468 /* JSDOMBinding.h */,
</span><span class="cx">                                 7C45C9C61E3E8ABA00AAB558 /* JSDOMBindingCaller.h */,
</span><ins>+                                41DEFCB21E56C1B9000D9E5F /* JSDOMBindingInternals.js */,
</ins><span class="cx">                                 7C45C9CA1E3E8D2E00AAB558 /* JSDOMBindingSecurity.cpp */,
</span><span class="cx">                                 7C45C9C91E3E8CD700AAB558 /* JSDOMBindingSecurity.h */,
</span><span class="cx">                                 7C45C9CC1E3E8F0800AAB558 /* JSDOMExceptionHandling.cpp */,
</span><span class="lines">@@ -22533,8 +22545,12 @@
</span><span class="cx">                                 E1C36C020EB076D6007410BC /* JSDOMGlobalObject.h */,
</span><span class="cx">                                 7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */,
</span><span class="cx">                                 7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */,
</span><ins>+                                41A1B01A1E542396007F3769 /* JSDOMGuardedObject.h */,
+                                41A1B01B1E542396007F3769 /* JSDOMGuardedObject.cpp */,
</ins><span class="cx">                                 4138F8551D253EEE001CB61E /* JSDOMIterator.cpp */,
</span><span class="cx">                                 4138F8561D253EEE001CB61E /* JSDOMIterator.h */,
</span><ins>+                                41DEFCB31E56C1B9000D9E5F /* JSDOMMapLike.cpp */,
+                                41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */,
</ins><span class="cx">                                 E172AF8D1811BC3700FBADB9 /* JSDOMPromise.cpp */,
</span><span class="cx">                                 E172AF8E1811BC3700FBADB9 /* JSDOMPromise.h */,
</span><span class="cx">                                 BC6932710D7E293900AE44D1 /* JSDOMWindowBase.cpp */,
</span><span class="lines">@@ -25667,6 +25683,7 @@
</span><span class="cx">                                 43EDD67F1B485DBF00640E75 /* CombinedFiltersAlphabet.h in Headers */,
</span><span class="cx">                                 26E944D91AC4B2DD007B85B5 /* CombinedURLFilters.h in Headers */,
</span><span class="cx">                                 A584FE351864D5AF00843B10 /* CommandLineAPIHost.h in Headers */,
</span><ins>+                                41DEFCB61E56C1BD000D9E5F /* JSDOMMapLike.h in Headers */,
</ins><span class="cx">                                 A584FE2C1863870F00843B10 /* CommandLineAPIModule.h in Headers */,
</span><span class="cx">                                 A584FE2618637DAB00843B10 /* CommandLineAPIModuleSource.h in Headers */,
</span><span class="cx">                                 6550B6A2099DF0270090D781 /* Comment.h in Headers */,
</span><span class="lines">@@ -27343,6 +27360,7 @@
</span><span class="cx">                                 89B5EAA211E8003D00F2367E /* LineEnding.h in Headers */,
</span><span class="cx">                                 FFEFAB2A18380DA000514534 /* LineLayoutState.h in Headers */,
</span><span class="cx">                                 FFDBC047183D27B700407109 /* LineWidth.h in Headers */,
</span><ins>+                                41A1B01C1E54239B007F3769 /* JSDOMGuardedObject.h in Headers */,
</ins><span class="cx">                                 A7AD2F880EC89D07008AB002 /* LinkHash.h in Headers */,
</span><span class="cx">                                 CBA9DC0B1DF44DF40005675C /* LinkHeader.h in Headers */,
</span><span class="cx">                                 5143B2631DDD15200014FAC6 /* LinkIcon.h in Headers */,
</span><span class="lines">@@ -27829,6 +27847,7 @@
</span><span class="cx">                                 416E6FE81BBD12DF000A6043 /* ReadableByteStreamInternalsBuiltins.h in Headers */,
</span><span class="cx">                                 416E6FE91BBD12E5000A6043 /* ReadableStreamBuiltins.h in Headers */,
</span><span class="cx">                                 416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */,
</span><ins>+                                416E6FE81BBD12DF000A3F65 /* JSDOMBindingInternalsBuiltins.h in Headers */,
</ins><span class="cx">                                 FD31603C12B0267600C1A359 /* RealtimeAnalyser.h in Headers */,
</span><span class="cx">                                 41103AAD1E39791000769F03 /* RealtimeIncomingAudioSource.h in Headers */,
</span><span class="cx">                                 4A4F65711AA997F100E38CDD /* RealtimeMediaSource.h in Headers */,
</span><span class="lines">@@ -29752,6 +29771,7 @@
</span><span class="cx">                                 31288E720E3005D6003619AE /* CSSKeyframeRule.cpp in Sources */,
</span><span class="cx">                                 31288E740E3005D6003619AE /* CSSKeyframesRule.cpp in Sources */,
</span><span class="cx">                                 BC772E16133162C2001EC9CE /* CSSLineBoxContainValue.cpp in Sources */,
</span><ins>+                                41DEFCB51E56C1BD000D9E5F /* JSDOMMapLike.cpp in Sources */,
</ins><span class="cx">                                 946D37491D6D06280077084F /* CSSMarkup.cpp in Sources */,
</span><span class="cx">                                 A80E6CFC0A1989CA007FB8C5 /* CSSMediaRule.cpp in Sources */,
</span><span class="cx">                                 314BE3A31B30F6D100141982 /* CSSNamedImageValue.cpp in Sources */,
</span><span class="lines">@@ -31777,7 +31797,6 @@
</span><span class="cx">                                 5E5E2B131CFC3E70000C0D85 /* RTCRtpTransceiver.cpp in Sources */,
</span><span class="cx">                                 078E090C17D14CEE00420AA1 /* RTCSessionDescription.cpp in Sources */,
</span><span class="cx">                                 073BE34E17D180B2002BD431 /* RTCSessionDescriptionDescriptor.cpp in Sources */,
</span><del>-                                078E090E17D14CEE00420AA1 /* RTCStatsReport.cpp in Sources */,
</del><span class="cx">                                 5E2C43671BCEE3770001E2BC /* RTCTrackEvent.cpp in Sources */,
</span><span class="cx">                                 5824ABA21AE81116009074B7 /* RubyElement.cpp in Sources */,
</span><span class="cx">                                 5824ABA61AE81384009074B7 /* RubyTextElement.cpp in Sources */,
</span><span class="lines">@@ -31911,6 +31930,7 @@
</span><span class="cx">                                 9444CBD31D860C8B0073A074 /* SizesCalcParser.cpp in Sources */,
</span><span class="cx">                                 49E911CC0EF86D47009D0CAF /* SkewTransformOperation.cpp in Sources */,
</span><span class="cx">                                 4150F9F212B6E0E70008C860 /* SliderThumbElement.cpp in Sources */,
</span><ins>+                                41A1B01D1E54239E007F3769 /* JSDOMGuardedObject.cpp in Sources */,
</ins><span class="cx">                                 9B532EA31BA928570038A827 /* SlotAssignment.cpp in Sources */,
</span><span class="cx">                                 4B6FA6F70C39E4A100087011 /* SmartReplaceCF.cpp in Sources */,
</span><span class="cx">                                 E4AFD00B0DAF335400F5F55C /* SMILTime.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingInternalsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSDOMBindingInternals.js (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBindingInternals.js                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMBindingInternals.js        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * 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. ``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
+ * 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.
+ */
+
+// @internal
+
+function mapLikeForEach(callback)
+{
+    &quot;use strict&quot;;
+    this.@backingMap.forEach((value, key, map) =&gt; {
+        callback(value, key, this);
+    });
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -205,8 +205,8 @@
</span><span class="cx">         for (auto&amp; constructor : thisObject-&gt;constructors(locker).values())
</span><span class="cx">             visitor.append(constructor);
</span><span class="cx"> 
</span><del>-        for (auto&amp; deferredPromise : thisObject-&gt;deferredPromises(locker))
-            deferredPromise-&gt;visitAggregate(visitor);
</del><ins>+        for (auto&amp; guarded : thisObject-&gt;guardedObjects(locker))
+            guarded-&gt;visitAggregate(visitor);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     thisObject-&gt;m_builtinInternalFunctions.visit(visitor);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-    class DeferredPromise;
</del><ins>+    class DOMGuardedObject;
</ins><span class="cx">     class Document;
</span><span class="cx">     class Event;
</span><span class="cx">     class DOMWrapperWorld;
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx">     typedef HashMap&lt;const JSC::ClassInfo*, JSC::WriteBarrier&lt;JSC::Structure&gt;&gt; JSDOMStructureMap;
</span><span class="cx">     typedef HashMap&lt;const JSC::ClassInfo*, JSC::WriteBarrier&lt;JSC::JSObject&gt;&gt; JSDOMConstructorMap;
</span><del>-    typedef HashSet&lt;DeferredPromise*&gt; DeferredPromiseSet;
</del><ins>+    typedef HashSet&lt;DOMGuardedObject*&gt; DOMGuardedObjectSet;
</ins><span class="cx"> 
</span><span class="cx">     class WEBCORE_EXPORT JSDOMGlobalObject : public JSC::JSGlobalObject {
</span><span class="cx">         typedef JSC::JSGlobalObject Base;
</span><span class="lines">@@ -56,11 +56,11 @@
</span><span class="cx"> 
</span><span class="cx">     public:
</span><span class="cx">         Lock&amp; gcLock() { return m_gcLock; }
</span><del>-        
</del><ins>+
</ins><span class="cx">         JSDOMStructureMap&amp; structures(const AbstractLocker&amp;) { return m_structures; }
</span><span class="cx">         JSDOMConstructorMap&amp; constructors(const AbstractLocker&amp;) { return m_constructors; }
</span><span class="cx"> 
</span><del>-        DeferredPromiseSet&amp; deferredPromises(const AbstractLocker&amp;) { return m_deferredPromises; }
</del><ins>+        DOMGuardedObjectSet&amp; guardedObjects(const AbstractLocker&amp;) { return m_guardedObjects; }
</ins><span class="cx"> 
</span><span class="cx">         ScriptExecutionContext* scriptExecutionContext() const;
</span><span class="cx"> 
</span><span class="lines">@@ -94,7 +94,7 @@
</span><span class="cx">     protected:
</span><span class="cx">         JSDOMStructureMap m_structures;
</span><span class="cx">         JSDOMConstructorMap m_constructors;
</span><del>-        DeferredPromiseSet m_deferredPromises;
</del><ins>+        DOMGuardedObjectSet m_guardedObjects;
</ins><span class="cx"> 
</span><span class="cx">         Event* m_currentEvent;
</span><span class="cx">         Ref&lt;DOMWrapperWorld&gt; m_world;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMGuardedObjectcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.cpp (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2017 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 &quot;config.h&quot;
+#include &quot;JSDOMGuardedObject.h&quot;
+
+using namespace JSC;
+
+namespace WebCore {
+
+DOMGuardedObject::DOMGuardedObject(JSDOMGlobalObject&amp; globalObject, JSCell&amp; guarded)
+    : ActiveDOMCallback(globalObject.scriptExecutionContext())
+    , m_guarded(&amp;guarded)
+    , m_globalObject(&amp;globalObject)
+{
+    auto locker = lockDuringMarking(globalObject.vm().heap, globalObject.gcLock());
+    globalObject.vm().heap.writeBarrier(&amp;globalObject, &amp;guarded);
+    globalObject.guardedObjects(locker).add(this);
+}
+
+DOMGuardedObject::~DOMGuardedObject()
+{
+    clear();
+}
+
+void DOMGuardedObject::clear()
+{
+    ASSERT(!m_guarded || m_globalObject);
+    if (m_guarded &amp;&amp; m_globalObject) {
+        auto locker = lockDuringMarking(m_globalObject-&gt;vm().heap, m_globalObject-&gt;gcLock());
+        m_globalObject-&gt;guardedObjects(locker).remove(this);
+    }
+    m_guarded.clear();
+}
+
+void DOMGuardedObject::contextDestroyed()
+{
+    ActiveDOMCallback::contextDestroyed();
+    clear();
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMGuardedObjecth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include &quot;ActiveDOMCallback.h&quot;
+#include &quot;JSDOMGlobalObject.h&quot;
+#include &lt;heap/HeapInlines.h&gt;
+#include &lt;heap/StrongInlines.h&gt;
+#include &lt;runtime/JSCell.h&gt;
+
+namespace WebCore {
+
+class DOMGuardedObject : public RefCounted&lt;DOMGuardedObject&gt;, public ActiveDOMCallback {
+public:
+    ~DOMGuardedObject();
+
+    bool isSuspended() { return !m_guarded || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended.
+
+    void visitAggregate(JSC::SlotVisitor&amp; visitor) { visitor.append(m_guarded); }
+
+    JSC::JSValue guardedObject() const { return m_guarded.get(); }
+    JSDOMGlobalObject* globalObject() const { return m_globalObject.get(); }
+
+protected:
+    DOMGuardedObject(JSDOMGlobalObject&amp;, JSC::JSCell&amp;);
+
+    void clear();
+    void contextDestroyed() override;
+    bool isEmpty() { return !m_guarded; }
+
+    JSC::Weak&lt;JSC::JSCell&gt; m_guarded;
+    JSC::Weak&lt;JSDOMGlobalObject&gt; m_globalObject;
+};
+
+template &lt;typename T&gt; class DOMGuarded : public DOMGuardedObject {
+protected:
+    DOMGuarded(JSDOMGlobalObject&amp; globalObject, T&amp; guarded) : DOMGuardedObject(globalObject, guarded) { }
+    T* guarded() const { return JSC::jsDynamicCast&lt;T*&gt;(globalObject()-&gt;vm(), guardedObject()); }
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMMapLikecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSDOMMapLike.cpp (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMMapLike.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMMapLike.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+/*
+ * Copyright (C) 2017 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 CANON INC. ``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 CANON INC. OR
+ * 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 &quot;config.h&quot;
+#include &quot;JSDOMMapLike.h&quot;
+
+#include &quot;WebCoreJSClientData.h&quot;
+
+namespace WebCore {
+
+static inline JSC::JSObject&amp; getBackingMap(JSC::ExecState&amp; state, JSC::JSObject&amp; mapLike)
+{
+    auto&amp; vm = state.vm();
+    auto backingMap = mapLike.get(&amp;state, static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;builtinNames().backingMapPrivateName());
+    return *JSC::asObject(backingMap);
+}
+
+void initializeBackingMap(JSC::VM&amp; vm, JSC::JSObject&amp; mapLike, JSC::JSMap&amp; backingMap)
+{
+    mapLike.putDirect(vm, static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;builtinNames().backingMapPrivateName(), &amp;backingMap, JSC::DontEnum);
+}
+
+JSC::JSMap&amp; createBackingMap(JSC::ExecState&amp; state, JSC::JSGlobalObject&amp; globalObject, JSC::JSObject&amp; mapLike)
+{
+    auto&amp; vm = state.vm();
+
+    ASSERT(mapLike.get(&amp;state, static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;builtinNames().backingMapPrivateName()).isUndefined());
+    auto backingMap = JSC::JSMap::create(&amp;state, vm, globalObject.mapStructure());
+    mapLike.putDirect(vm, static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;builtinNames().backingMapPrivateName(), backingMap, JSC::DontEnum);
+    return *backingMap;
+}
+
+JSC::JSValue forwardAttributeGetterToBackingMap(JSC::ExecState&amp; state, JSC::JSObject&amp; mapLike, const JSC::Identifier&amp; attributeName)
+{
+    return getBackingMap(state, mapLike).get(&amp;state, attributeName);
+}
+
+JSC::JSValue forwardFunctionCallToBackingMap(JSC::ExecState&amp; state, JSC::JSObject&amp; mapLike, const JSC::Identifier&amp; functionName)
+{
+    auto&amp; backingMap = getBackingMap(state, mapLike);
+
+    JSC::JSValue function = backingMap.get(&amp;state, functionName);
+    ASSERT(function);
+
+    JSC::CallData callData;
+    JSC::CallType callType = JSC::getCallData(function, callData);
+    ASSERT(callType != JSC::CallType::None);
+    JSC::MarkedArgumentBuffer arguments;
+    for (size_t cptr = 0; cptr &lt; state.argumentCount(); ++cptr)
+        arguments.append(state.uncheckedArgument(cptr));
+    return JSC::call(&amp;state, function, callType, callData, &amp;backingMap, arguments);
+}
+
+JSC::JSValue forwardForEachCallToBackingMap(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, JSC::JSObject&amp; mapLike)
+{
+    auto* function = globalObject.builtinInternalFunctions().jsDOMBindingInternals().m_mapLikeForEachFunction.get();
+    ASSERT(function);
+
+    getBackingMap(state, mapLike);
+
+    JSC::CallData callData;
+    JSC::CallType callType = JSC::getCallData(function, callData);
+    ASSERT(callType != JSC::CallType::None);
+    JSC::MarkedArgumentBuffer arguments;
+    for (size_t cptr = 0; cptr &lt; state.argumentCount(); ++cptr)
+        arguments.append(state.uncheckedArgument(cptr));
+    return JSC::call(&amp;state, function, callType, callData, &amp;mapLike, arguments);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMMapLikeh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSDOMMapLike.h (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMMapLike.h                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMMapLike.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+/*
+ * Copyright (C) 2017 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 CANON INC. ``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 CANON INC. OR
+ * 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 &quot;ActiveDOMCallback.h&quot;
+#include &quot;JSDOMBinding.h&quot;
+#include &quot;JSDOMConvert.h&quot;
+#include &quot;JSDOMGuardedObject.h&quot;
+#include &quot;ScriptExecutionContext.h&quot;
+#include &lt;builtins/BuiltinNames.h&gt;
+#include &lt;runtime/CommonIdentifiers.h&gt;
+#include &lt;runtime/JSMap.h&gt;
+
+namespace WebCore {
+
+JSC::JSMap&amp; createBackingMap(JSC::ExecState&amp;, JSC::JSGlobalObject&amp;, JSC::JSObject&amp;);
+void initializeBackingMap(JSC::VM&amp;, JSC::JSObject&amp;, JSC::JSMap&amp;);
+JSC::JSValue forwardAttributeGetterToBackingMap(JSC::ExecState&amp;, JSC::JSObject&amp;, const JSC::Identifier&amp;);
+JSC::JSValue forwardFunctionCallToBackingMap(JSC::ExecState&amp;, JSC::JSObject&amp;, const JSC::Identifier&amp;);
+JSC::JSValue forwardForEachCallToBackingMap(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, JSC::JSObject&amp;);
+
+template&lt;typename WrapperClass&gt; void synchronizeBackingMap(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass&gt; JSC::JSValue forwardSizeToMapLike(JSC::ExecState&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass&gt; JSC::JSValue forwardEntriesToMapLike(JSC::ExecState&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass&gt; JSC::JSValue forwardKeysToMapLike(JSC::ExecState&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass&gt; JSC::JSValue forwardValuesToMapLike(JSC::ExecState&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass&gt; JSC::JSValue forwardClearToMapLike(JSC::ExecState&amp;, WrapperClass&amp;);
+template&lt;typename WrapperClass, typename Callback&gt; JSC::JSValue forwardForEachToMapLike(JSC::ExecState&amp;, WrapperClass&amp;, Callback&amp;&amp;);
+template&lt;typename WrapperClass, typename ItemType&gt; JSC::JSValue forwardGetToMapLike(JSC::ExecState&amp;, WrapperClass&amp;, ItemType&amp;&amp;);
+template&lt;typename WrapperClass, typename ItemType&gt; JSC::JSValue forwardHasToMapLike(JSC::ExecState&amp;, WrapperClass&amp;, ItemType&amp;&amp;);
+template&lt;typename WrapperClass, typename ItemType&gt; JSC::JSValue forwardAddToMapLike(JSC::ExecState&amp;, WrapperClass&amp;, ItemType&amp;&amp;);
+template&lt;typename WrapperClass, typename ItemType&gt; JSC::JSValue forwardDeleteToMapLike(JSC::ExecState&amp;, WrapperClass&amp;, ItemType&amp;&amp;);
+
+class DOMMapLike final : public DOMGuarded&lt;JSC::JSMap&gt; {
+public:
+    static Ref&lt;DOMMapLike&gt; create(JSDOMGlobalObject&amp; globalObject, JSC::JSMap&amp; map) { return adoptRef(*new DOMMapLike(globalObject, map)); }
+
+    template&lt;typename Key, typename Value&gt; void set(typename Key::ParameterType&amp;&amp;, typename Value::ParameterType&amp;&amp;);
+
+    JSC::JSMap* backingMap() { return guarded(); }
+
+protected:
+    DOMMapLike(JSDOMGlobalObject&amp; globalObject, JSC::JSMap&amp; map) : DOMGuarded&lt;JSC::JSMap&gt;(globalObject, map) { }
+};
+
+template&lt;typename Key, typename Value&gt; inline void DOMMapLike::set(typename Key::ParameterType&amp;&amp; key, typename Value::ParameterType&amp;&amp; value)
+{
+    if (isEmpty())
+        return;
+    auto* state = globalObject()-&gt;globalExec();
+    JSC::JSLockHolder locker(state);
+    backingMap()-&gt;set(state,
+        toJS&lt;Key&gt;(*state, *globalObject(), std::forward&lt;typename Key::ParameterType&gt;(key)),
+        toJS&lt;Value&gt;(*state, *globalObject(), std::forward&lt;typename Value::ParameterType&gt;(value)));
+}
+
+template&lt;typename WrapperClass&gt; inline void synchronizeBackingMap(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, WrapperClass&amp; mapLike)
+{
+    auto backingMap = mapLike.wrapped().backingMap();
+    if (backingMap) {
+        ASSERT(backingMap-&gt;backingMap());
+        initializeBackingMap(state.vm(), mapLike, *backingMap-&gt;backingMap());
+        return;
+    }
+    auto&amp; map = createBackingMap(state, globalObject, mapLike);
+    mapLike.wrapped().synchronizeBackingMap(DOMMapLike::create(globalObject, map));
+}
+
+template&lt;typename WrapperClass&gt; inline JSC::JSValue forwardSizeToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike)
+{
+    return forwardAttributeGetterToBackingMap(state, mapLike, state.propertyNames().size);
+}
+
+template&lt;typename WrapperClass&gt; inline JSC::JSValue forwardEntriesToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike)
+{
+    return forwardFunctionCallToBackingMap(state, mapLike, state.propertyNames().builtinNames().entriesPublicName());
+}
+
+template&lt;typename WrapperClass&gt; inline JSC::JSValue forwardKeysToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike)
+{
+    return forwardFunctionCallToBackingMap(state, mapLike, state.propertyNames().builtinNames().keysPublicName());
+}
+
+template&lt;typename WrapperClass&gt; inline JSC::JSValue forwardValuesToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike)
+{
+    return forwardFunctionCallToBackingMap(state, mapLike, state.propertyNames().builtinNames().valuesPublicName());
+}
+
+template&lt;typename WrapperClass&gt; inline JSC::JSValue forwardClearToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike)
+{
+    mapLike.wrapped().clear();
+    return forwardFunctionCallToBackingMap(state, mapLike, state.vm().propertyNames-&gt;clear);
+}
+
+template&lt;typename WrapperClass, typename Callback&gt; inline JSC::JSValue forwardForEachToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike, Callback&amp;&amp;)
+{
+    return forwardForEachCallToBackingMap(state, *mapLike.globalObject(), mapLike);
+}
+
+template&lt;typename WrapperClass, typename ItemType&gt; inline JSC::JSValue forwardGetToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike, ItemType&amp;&amp;)
+{
+    return forwardFunctionCallToBackingMap(state, mapLike, state.propertyNames().builtinNames().getPublicName());
+}
+
+template&lt;typename WrapperClass, typename ItemType&gt; inline JSC::JSValue forwardHasToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike, ItemType&amp;&amp;)
+{
+    return forwardFunctionCallToBackingMap(state, mapLike, state.propertyNames().builtinNames().hasPublicName());
+}
+
+template&lt;typename WrapperClass, typename ItemType&gt; inline JSC::JSValue forwardAddToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike, ItemType&amp;&amp; item)
+{
+    if (mapLike.wrapped().addFromMapLike(std::forward&lt;ItemType&gt;(item)))
+        forwardFunctionCallToBackingMap(state, mapLike, state.vm().propertyNames-&gt;add);
+    return &amp;mapLike;
+}
+
+template&lt;typename WrapperClass, typename ItemType&gt; inline JSC::JSValue forwardDeleteToMapLike(JSC::ExecState&amp; state, WrapperClass&amp; mapLike, ItemType&amp;&amp; item)
+{
+    auto isDeleted = mapLike.wrapped().remove(std::forward&lt;ItemType&gt;(item));
+    UNUSED_PARAM(isDeleted);
+    auto result = forwardFunctionCallToBackingMap(state, mapLike, state.vm().propertyNames-&gt;deleteKeyword);
+    ASSERT_UNUSED(result, result.asBoolean() == isDeleted);
+    return result;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMPromisecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -38,41 +38,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-DeferredPromise::DeferredPromise(JSDOMGlobalObject&amp; globalObject, JSPromiseDeferred&amp; promiseDeferred)
-    : ActiveDOMCallback(globalObject.scriptExecutionContext())
-    , m_deferred(&amp;promiseDeferred)
-    , m_globalObject(&amp;globalObject)
-{
-    auto locker = lockDuringMarking(globalObject.vm().heap, globalObject.gcLock());
-    globalObject.vm().heap.writeBarrier(&amp;globalObject, &amp;promiseDeferred);
-    globalObject.deferredPromises(locker).add(this);
-}
-
-DeferredPromise::~DeferredPromise()
-{
-    clear();
-}
-
-void DeferredPromise::clear()
-{
-    ASSERT(!m_deferred || m_globalObject);
-    if (m_deferred &amp;&amp; m_globalObject) {
-        auto locker = lockDuringMarking(m_globalObject-&gt;vm().heap, m_globalObject-&gt;gcLock());
-        m_globalObject-&gt;deferredPromises(locker).remove(this);
-    }
-    m_deferred.clear();
-}
-
-void DeferredPromise::contextDestroyed()
-{
-    ActiveDOMCallback::contextDestroyed();
-    clear();
-}
-
</del><span class="cx"> JSC::JSValue DeferredPromise::promise() const
</span><span class="cx"> {
</span><del>-    ASSERT(m_deferred);
-    return m_deferred-&gt;promise();
</del><ins>+    ASSERT(deferred());
+    return deferred()-&gt;promise();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DeferredPromise::callFunction(ExecState&amp; exec, JSValue function, JSValue resolution)
</span><span class="lines">@@ -97,7 +66,7 @@
</span><span class="cx">     if (isSuspended())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_deferred);
</del><ins>+    ASSERT(deferred());
</ins><span class="cx">     ASSERT(m_globalObject);
</span><span class="cx">     auto&amp; state = *m_globalObject-&gt;globalExec();
</span><span class="cx">     JSC::JSLockHolder locker(&amp;state);
</span><span class="lines">@@ -109,7 +78,7 @@
</span><span class="cx">     if (isSuspended())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_deferred);
</del><ins>+    ASSERT(deferred());
</ins><span class="cx">     ASSERT(m_globalObject);
</span><span class="cx">     auto&amp; state = *m_globalObject-&gt;globalExec();
</span><span class="cx">     JSC::JSLockHolder locker(&amp;state);
</span><span class="lines">@@ -121,7 +90,7 @@
</span><span class="cx">     if (isSuspended())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_deferred);
</del><ins>+    ASSERT(deferred());
</ins><span class="cx">     ASSERT(m_globalObject);
</span><span class="cx">     auto&amp; state = *m_globalObject-&gt;globalExec();
</span><span class="cx">     JSC::JSLockHolder locker(&amp;state);
</span><span class="lines">@@ -133,7 +102,7 @@
</span><span class="cx">     if (isSuspended())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_deferred);
</del><ins>+    ASSERT(deferred());
</ins><span class="cx">     ASSERT(m_globalObject);
</span><span class="cx">     JSC::ExecState* state = m_globalObject-&gt;globalExec();
</span><span class="cx">     JSC::JSLockHolder locker(state);
</span><span class="lines">@@ -145,7 +114,7 @@
</span><span class="cx">     if (isSuspended())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_deferred);
</del><ins>+    ASSERT(deferred());
</ins><span class="cx">     ASSERT(m_globalObject);
</span><span class="cx">     JSC::ExecState* state = m_globalObject-&gt;globalExec();
</span><span class="cx">     JSC::JSLockHolder locker(state);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMPromiseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMPromise.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -25,14 +25,13 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &quot;ActiveDOMCallback.h&quot;
</del><span class="cx"> #include &quot;JSDOMConvert.h&quot;
</span><del>-#include &lt;heap/StrongInlines.h&gt;
</del><ins>+#include &quot;JSDOMGuardedObject.h&quot;
</ins><span class="cx"> #include &lt;runtime/JSPromiseDeferred.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class DeferredPromise : public RefCounted&lt;DeferredPromise&gt;, public ActiveDOMCallback {
</del><ins>+class DeferredPromise : public DOMGuarded&lt;JSC::JSPromiseDeferred&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;DeferredPromise&gt; create(JSDOMGlobalObject&amp; globalObject, JSC::JSPromiseDeferred&amp; deferred)
</span><span class="cx">     {
</span><span class="lines">@@ -39,18 +38,16 @@
</span><span class="cx">         return adoptRef(*new DeferredPromise(globalObject, deferred));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ~DeferredPromise();
-
-    template&lt;class IDLType&gt; 
</del><ins>+    template&lt;class IDLType&gt;
</ins><span class="cx">     void resolve(typename IDLType::ParameterType value)
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><del>-        resolve(*exec, toJS&lt;IDLType&gt;(*exec, *m_globalObject.get(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</del><ins>+        resolve(*exec, toJS&lt;IDLType&gt;(*exec, *globalObject(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void resolve()
</span><span class="lines">@@ -57,9 +54,9 @@
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><span class="cx">         resolve(*exec, JSC::jsUndefined());
</span><span class="cx">     }
</span><span class="lines">@@ -69,23 +66,23 @@
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><del>-        resolve(*exec, toJSNewlyCreated&lt;IDLType&gt;(*exec, *m_globalObject.get(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</del><ins>+        resolve(*exec, toJSNewlyCreated&lt;IDLType&gt;(*exec, *globalObject(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    template&lt;class IDLType&gt; 
</del><ins>+    template&lt;class IDLType&gt;
</ins><span class="cx">     void reject(typename IDLType::ParameterType value)
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><del>-        reject(*exec, toJS&lt;IDLType&gt;(*exec, *m_globalObject.get(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</del><ins>+        reject(*exec, toJS&lt;IDLType&gt;(*exec, *globalObject(), std::forward&lt;typename IDLType::ParameterType&gt;(value)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void reject();
</span><span class="lines">@@ -99,11 +96,11 @@
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><del>-        resolve(*exec, callback(*exec, *m_globalObject.get()));
</del><ins>+        resolve(*exec, callback(*exec, *globalObject()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename Callback&gt;
</span><span class="lines">@@ -111,32 +108,23 @@
</span><span class="cx">     {
</span><span class="cx">         if (isSuspended())
</span><span class="cx">             return;
</span><del>-        ASSERT(m_deferred);
-        ASSERT(m_globalObject);
-        JSC::ExecState* exec = m_globalObject-&gt;globalExec();
</del><ins>+        ASSERT(deferred());
+        ASSERT(globalObject());
+        JSC::ExecState* exec = globalObject()-&gt;globalExec();
</ins><span class="cx">         JSC::JSLockHolder locker(exec);
</span><del>-        reject(*exec, callback(*exec, *m_globalObject.get()));
</del><ins>+        reject(*exec, callback(*exec, *globalObject()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSC::JSValue promise() const;
</span><span class="cx"> 
</span><del>-    bool isSuspended() { return !m_deferred || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended.
-    JSDOMGlobalObject* globalObject() { return m_globalObject.get(); }
-
-    void visitAggregate(JSC::SlotVisitor&amp; visitor) { visitor.append(m_deferred); }
-
</del><span class="cx"> private:
</span><del>-    DeferredPromise(JSDOMGlobalObject&amp;, JSC::JSPromiseDeferred&amp;);
</del><ins>+    DeferredPromise(JSDOMGlobalObject&amp; globalObject, JSC::JSPromiseDeferred&amp; deferred) : DOMGuarded&lt;JSC::JSPromiseDeferred&gt;(globalObject, deferred) { }
</ins><span class="cx"> 
</span><del>-    void clear();
-    void contextDestroyed() override;
</del><ins>+    JSC::JSPromiseDeferred* deferred() const { return guarded(); }
</ins><span class="cx"> 
</span><span class="cx">     void callFunction(JSC::ExecState&amp;, JSC::JSValue function, JSC::JSValue resolution);
</span><del>-    void resolve(JSC::ExecState&amp; state, JSC::JSValue resolution) { callFunction(state, m_deferred-&gt;resolve(), resolution); }
-    void reject(JSC::ExecState&amp; state, JSC::JSValue resolution) { callFunction(state, m_deferred-&gt;reject(), resolution); }
-
-    JSC::Weak&lt;JSC::JSPromiseDeferred&gt; m_deferred;
-    JSC::Weak&lt;JSDOMGlobalObject&gt; m_globalObject;
</del><ins>+    void resolve(JSC::ExecState&amp; state, JSC::JSValue resolution) { callFunction(state, deferred()-&gt;resolve(), resolution); }
+    void reject(JSC::ExecState&amp; state, JSC::JSValue resolution) { callFunction(state, deferred()-&gt;reject(), resolution); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class DOMPromiseBase {
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx">     macro(appendFromJS) \
</span><span class="cx">     macro(associatedReadableByteStreamController) \
</span><span class="cx">     macro(autoAllocateChunkSize) \
</span><ins>+    macro(backingMap) \
</ins><span class="cx">     macro(body) \
</span><span class="cx">     macro(byobRequest) \
</span><span class="cx">     macro(cancel) \
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -1064,6 +1064,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $count += scalar @{$interface-&gt;iterable-&gt;functions} if $interface-&gt;iterable;
</span><ins>+    $count += scalar @{$interface-&gt;mapLike-&gt;functions} if $interface-&gt;mapLike;
</ins><span class="cx">     $count += scalar @{$interface-&gt;serializable-&gt;functions} if $interface-&gt;serializable;
</span><span class="cx"> 
</span><span class="cx">     return $count;
</span><span class="lines">@@ -2281,7 +2282,10 @@
</span><span class="cx"> 
</span><span class="cx">     return 0 if !$propertyCount;
</span><span class="cx"> 
</span><del>-    foreach my $attribute (@{$interface-&gt;attributes}) {
</del><ins>+    my @attributes = @{$interface-&gt;attributes};
+    push(@attributes, @{$interface-&gt;mapLike-&gt;attributes}) if $interface-&gt;mapLike;
+
+    foreach my $attribute (@attributes) {
</ins><span class="cx">         next if ($attribute-&gt;isStatic);
</span><span class="cx">         next if AttributeShouldBeOnInstance($interface, $attribute) != $isInstance;
</span><span class="cx"> 
</span><span class="lines">@@ -2322,6 +2326,7 @@
</span><span class="cx"> 
</span><span class="cx">     my @functions = @{$interface-&gt;functions};
</span><span class="cx">     push(@functions, @{$interface-&gt;iterable-&gt;functions}) if IsKeyValueIterableInterface($interface);
</span><ins>+    push(@functions, @{$interface-&gt;mapLike-&gt;functions}) if $interface-&gt;mapLike;
</ins><span class="cx">     push(@functions, @{$interface-&gt;serializable-&gt;functions}) if $interface-&gt;serializable;
</span><span class="cx">     foreach my $function (@functions) {
</span><span class="cx">         next if ($function-&gt;extendedAttributes-&gt;{PrivateIdentifier} and not $function-&gt;extendedAttributes-&gt;{PublicIdentifier});
</span><span class="lines">@@ -2988,13 +2993,15 @@
</span><span class="cx"> sub InterfaceNeedsIterator
</span><span class="cx"> {
</span><span class="cx">     my ($interface) = @_;
</span><del>-    
</del><ins>+
+    # FIXME: This should return 1 for maplike once we support them.
+    return 1 if $interface-&gt;mapLike;
+
</ins><span class="cx">     return 1 if $interface-&gt;iterable;
</span><span class="cx">     if (GetIndexedGetterFunction($interface)) {
</span><span class="cx">         my $lengthAttribute = GetAttributeWithName($interface, &quot;length&quot;);
</span><span class="cx">         return 1 if $lengthAttribute and $codeGenerator-&gt;IsIntegerType($lengthAttribute-&gt;type);
</span><span class="cx">     }
</span><del>-    # FIXME: This should return 1 for maplike and setlike once we support them.
</del><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3040,11 +3047,15 @@
</span><span class="cx"> 
</span><span class="cx">     my @functions = @{$interface-&gt;functions};
</span><span class="cx">     push(@functions, @{$interface-&gt;iterable-&gt;functions}) if IsKeyValueIterableInterface($interface);
</span><ins>+    push(@functions, @{$interface-&gt;mapLike-&gt;functions}) if $interface-&gt;mapLike;
</ins><span class="cx">     push(@functions, @{$interface-&gt;serializable-&gt;functions}) if $interface-&gt;serializable;
</span><span class="cx"> 
</span><ins>+    my @attributes = @{$interface-&gt;attributes};
+    push(@attributes, @{$interface-&gt;mapLike-&gt;attributes}) if $interface-&gt;mapLike;
+
</ins><span class="cx">     my $numConstants = @{$interface-&gt;constants};
</span><span class="cx">     my $numFunctions = @functions;
</span><del>-    my $numAttributes = @{$interface-&gt;attributes};
</del><ins>+    my $numAttributes = @attributes;
</ins><span class="cx"> 
</span><span class="cx">     if ($numFunctions &gt; 0) {
</span><span class="cx">         my $inAppleCopyright = 0;
</span><span class="lines">@@ -3090,7 +3101,7 @@
</span><span class="cx">     if ($numAttributes &gt; 0 || NeedsConstructorProperty($interface)) {
</span><span class="cx">         push(@implContent, &quot;// Attributes\n\n&quot;);
</span><span class="cx"> 
</span><del>-        foreach my $attribute (@{$interface-&gt;attributes}) {
</del><ins>+        foreach my $attribute (@attributes) {
</ins><span class="cx">             next if $attribute-&gt;extendedAttributes-&gt;{ForwardDeclareInHeader};
</span><span class="cx">             next if IsJSBuiltin($interface, $attribute);
</span><span class="cx"> 
</span><span class="lines">@@ -3104,7 +3115,7 @@
</span><span class="cx">             }
</span><span class="cx">             push(@implContent, &quot;#endif\n&quot;) if $conditionalString;
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         if (NeedsConstructorProperty($interface)) {
</span><span class="cx">             my $getter = &quot;js&quot; . $interfaceName . &quot;Constructor&quot;;
</span><span class="cx">             push(@implContent, &quot;JSC::EncodedJSValue ${getter}(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);\n&quot;);
</span><span class="lines">@@ -3358,6 +3369,8 @@
</span><span class="cx">             if (IsKeyValueIterableInterface($interface)) {
</span><span class="cx">                 my $functionName = GetFunctionName($interface, $className, @{$interface-&gt;iterable-&gt;functions}[0]);
</span><span class="cx">                 push(@implContent, &quot;    putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral(\&quot;[Symbol.Iterator]\&quot;), $functionName), DontEnum);\n&quot;);
</span><ins>+            } elsif ($interface-&gt;mapLike) {
+                push(@implContent, &quot;    putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, getDirect(vm, vm.propertyNames-&gt;builtinNames().valuesPublicName()), DontEnum);\n&quot;);
</ins><span class="cx">             } else {
</span><span class="cx">                 AddToImplIncludes(&quot;&lt;builtins/BuiltinNames.h&gt;&quot;);
</span><span class="cx">                 push(@implContent, &quot;    putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, globalObject()-&gt;arrayPrototype()-&gt;getDirect(vm, vm.propertyNames-&gt;builtinNames().valuesPrivateName()), DontEnum);\n&quot;);
</span><span class="lines">@@ -3433,6 +3446,7 @@
</span><span class="cx">         push(@implContent, &quot;    putDirect(vm, vm.propertyNames-&gt;valueOf, globalObject()-&gt;objectProtoValueOfFunction(), DontDelete | ReadOnly | DontEnum);\n&quot;);
</span><span class="cx">         push(@implContent, &quot;    putDirect(vm, vm.propertyNames-&gt;toPrimitiveSymbol, jsUndefined(), DontDelete | ReadOnly | DontEnum);\n&quot;);
</span><span class="cx">     }
</span><ins>+    push(@implContent, &quot;    synchronizeBackingMap(*globalObject()-&gt;globalExec(), *globalObject(), *this);\n&quot;) if $interface-&gt;mapLike;
</ins><span class="cx"> 
</span><span class="cx">     # Support for RuntimeEnabled attributes on instances.
</span><span class="cx">     foreach my $attribute (@{$interface-&gt;attributes}) {
</span><span class="lines">@@ -3586,7 +3600,7 @@
</span><span class="cx"> 
</span><span class="cx">     $numAttributes = $numAttributes + 1 if NeedsConstructorProperty($interface);
</span><span class="cx">     if ($numAttributes &gt; 0) {
</span><del>-        foreach my $attribute (@{$interface-&gt;attributes}) {
</del><ins>+        foreach my $attribute (@attributes) {
</ins><span class="cx">             next if IsJSBuiltin($interface, $attribute);
</span><span class="cx"> 
</span><span class="cx">             my $name = $attribute-&gt;name;
</span><span class="lines">@@ -3695,6 +3709,11 @@
</span><span class="cx">                     unshift(@arguments, &quot;impl&quot;) if !$attribute-&gt;isStatic;
</span><span class="cx">                 } elsif ($attribute-&gt;isStatic) {
</span><span class="cx">                     $functionName = &quot;${interfaceName}::${functionName}&quot;;
</span><ins>+                } elsif ($attribute-&gt;isMapLike) {
+                    my $ucPropertyName = $codeGenerator-&gt;WK_ucfirst($functionName);
+                    $functionName = &quot;forward&quot; . $codeGenerator-&gt;WK_ucfirst($functionName) . &quot;ToMapLike&quot;;
+                    push(@arguments, &quot;state&quot;);
+                    push(@arguments, &quot;thisObject&quot;);
</ins><span class="cx">                 } else {
</span><span class="cx">                     $functionName = &quot;impl.${functionName}&quot;;
</span><span class="cx">                 }
</span><span class="lines">@@ -3701,7 +3720,7 @@
</span><span class="cx"> 
</span><span class="cx">                 unshift(@arguments, @callWithArgs);
</span><span class="cx">                 my $jsType = NativeToJSValueUsingReferences($attribute, $interface, &quot;${functionName}(&quot; . join(&quot;, &quot;, @arguments) . &quot;)&quot;, &quot;thisObject&quot;);
</span><del>-                push(@implContent, &quot;    auto&amp; impl = thisObject.wrapped();\n&quot;) if !$attribute-&gt;isStatic;
</del><ins>+                push(@implContent, &quot;    auto&amp; impl = thisObject.wrapped();\n&quot;) unless $attribute-&gt;isStatic or $attribute-&gt;isMapLike;
</ins><span class="cx">                 push(@implContent, &quot;    JSValue result = $jsType;\n&quot;);
</span><span class="cx"> 
</span><span class="cx">                 push(@implContent, &quot;    thisObject.m_&quot; . $attribute-&gt;name . &quot;.set(state.vm(), &amp;thisObject, result);\n&quot;) if $attribute-&gt;extendedAttributes-&gt;{CachedAttribute};
</span><span class="lines">@@ -3776,7 +3795,7 @@
</span><span class="cx">         push(@implContent, &quot;}\n\n&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    foreach my $attribute (@{$interface-&gt;attributes}) {
</del><ins>+    foreach my $attribute (@attributes) {
</ins><span class="cx">         if (!IsReadonly($attribute)) {
</span><span class="cx">             next if IsJSBuiltin($interface, $attribute);
</span><span class="cx"> 
</span><span class="lines">@@ -3951,8 +3970,10 @@
</span><span class="cx">     # Functions
</span><span class="cx">     if ($numFunctions &gt; 0) {
</span><span class="cx">         my $inAppleCopyright = 0;
</span><del>-        foreach my $function (@{$interface-&gt;functions}) {
</del><ins>+        foreach my $function (@functions) {
</ins><span class="cx">             next if IsJSBuiltin($interface, $function);
</span><ins>+            next if $function-&gt;isIterable;
+            next if $function-&gt;isSerializer;
</ins><span class="cx">             if ($function-&gt;extendedAttributes-&gt;{AppleCopyright}) {
</span><span class="cx">                 if (!$inAppleCopyright) {
</span><span class="cx">                     push(@implContent, $beginAppleCopyrightForSourceFiles);
</span><span class="lines">@@ -4080,7 +4101,7 @@
</span><span class="cx">                 if ($isCustom) {
</span><span class="cx">                     push(@implContent, &quot;    return JSValue::encode(castedThis-&gt;&quot; . $functionImplementationName . &quot;(*state));\n&quot;);
</span><span class="cx">                 } else {
</span><del>-                    push(@implContent, &quot;    auto&amp; impl = castedThis-&gt;wrapped();\n&quot;);
</del><ins>+                    push(@implContent, &quot;    auto&amp; impl = castedThis-&gt;wrapped();\n&quot;) unless $function-&gt;isMapLike;
</ins><span class="cx"> 
</span><span class="cx">                     GenerateArgumentsCountCheck(\@implContent, $function, $interface);
</span><span class="cx"> 
</span><span class="lines">@@ -4170,6 +4191,7 @@
</span><span class="cx"> 
</span><span class="cx">     GenerateImplementationIterableFunctions($interface) if $interface-&gt;iterable;
</span><span class="cx">     GenerateSerializerFunction($interface, $className) if $interface-&gt;serializable;
</span><ins>+    AddToImplIncludes(&quot;JSDOMMapLike.h&quot;) if $interface-&gt;mapLike;
</ins><span class="cx"> 
</span><span class="cx">     if ($needsVisitChildren) {
</span><span class="cx">         push(@implContent, &quot;void ${className}::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)\n&quot;);
</span><span class="lines">@@ -4652,11 +4674,15 @@
</span><span class="cx"> 
</span><span class="cx">     if ($implementedBy) {
</span><span class="cx">         AddToImplIncludes(&quot;${implementedBy}.h&quot;, $conditional);
</span><del>-        unshift(@arguments, &quot;impl&quot;) if !$function-&gt;isStatic;
</del><ins>+        unshift(@arguments, &quot;impl&quot;) unless $function-&gt;isStatic;
</ins><span class="cx">         $functionName = &quot;WebCore::${implementedBy}::${functionImplementationName}&quot;;
</span><span class="cx">     } elsif ($function-&gt;isStatic || $isConstructor) {
</span><span class="cx">         $functionName = &quot;${interfaceName}::${functionImplementationName}&quot;;
</span><del>-    } else {
</del><ins>+    } elsif ($function-&gt;isMapLike) {
+        $functionName = &quot;forward&quot; . $codeGenerator-&gt;WK_ucfirst($function-&gt;name) . &quot;ToMapLike&quot;;
+        push(@arguments, &quot;*state&quot;);
+        push(@arguments, &quot;*castedThis&quot;);
+     } else {
</ins><span class="cx">         $functionName = &quot;impl.${functionImplementationName}&quot;;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsIDLParserpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (213107 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2017-02-28 01:20:54 UTC (rev 213107)
+++ trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx">     constants =&gt; '@',    # List of 'IDLConstant'
</span><span class="cx">     functions =&gt; '@',    # List of 'IDLOperation'
</span><span class="cx">     anonymousFunctions =&gt; '@', # List of 'IDLOperation'
</span><del>-    attributes =&gt; '@',    # List of 'IDLAttribute'    
</del><ins>+    attributes =&gt; '@',    # List of 'IDLAttribute'
</ins><span class="cx">     constructors =&gt; '@', # Constructors, list of 'IDLOperation'
</span><span class="cx">     customConstructors =&gt; '@', # Custom constructors, list of 'IDLOperation'
</span><span class="cx">     isException =&gt; '$', # Used for exception interfaces
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx">     isCallback =&gt; '$', # Used for callback interfaces
</span><span class="cx">     isPartial =&gt; '$', # Used for partial interfaces
</span><span class="cx">     iterable =&gt; '$', # Used for iterable interfaces
</span><ins>+    mapLike =&gt; '$', # Used for mapLike interfaces
</ins><span class="cx">     serializable =&gt; '$', # Used for serializable interfaces
</span><span class="cx">     extendedAttributes =&gt; '$',
</span><span class="cx"> });
</span><span class="lines">@@ -87,6 +88,9 @@
</span><span class="cx">     type =&gt; 'IDLType', # Return type
</span><span class="cx">     arguments =&gt; '@', # List of 'IDLArgument'
</span><span class="cx">     isStatic =&gt; '$',
</span><ins>+    isIterable =&gt; '$',
+    isSerializer =&gt; '$',
+    isMapLike =&gt; '$',
</ins><span class="cx">     specials =&gt; '@',
</span><span class="cx">     extendedAttributes =&gt; '$',
</span><span class="cx"> });
</span><span class="lines">@@ -97,6 +101,7 @@
</span><span class="cx">     name =&gt; '$',
</span><span class="cx">     type =&gt; 'IDLType',
</span><span class="cx">     isStatic =&gt; '$',
</span><ins>+    isMapLike =&gt; '$',
</ins><span class="cx">     isStringifier =&gt; '$',
</span><span class="cx">     isReadOnly =&gt; '$',
</span><span class="cx">     extendedAttributes =&gt; '$',
</span><span class="lines">@@ -111,6 +116,16 @@
</span><span class="cx">     extendedAttributes =&gt; '$',
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+# https://heycam.github.io/webidl/#es-maplike
+struct( IDLMapLike =&gt; {
+    isReadOnly =&gt; '$',
+    keyType =&gt; 'IDLType',
+    valueType =&gt; 'IDLType',
+    attributes =&gt; '@', # MapLike attributes (size)
+    functions =&gt; '@', # MapLike functions (entries, keys, values, forEach, get, has and if not readonly, delete, set and clear)
+    extendedAttributes =&gt; '$',
+});
+
</ins><span class="cx"> # https://heycam.github.io/webidl/#idl-serializers
</span><span class="cx"> struct( IDLSerializable =&gt; {
</span><span class="cx">     attributes =&gt; '@', # List of attributes to serialize
</span><span class="lines">@@ -194,7 +209,7 @@
</span><span class="cx"> sub assert
</span><span class="cx"> {
</span><span class="cx">     my $message = shift;
</span><del>-    
</del><ins>+
</ins><span class="cx">     my $mess = longmess();
</span><span class="cx">     print Dumper($mess);
</span><span class="cx"> 
</span><span class="lines">@@ -420,7 +435,7 @@
</span><span class="cx">     return $clonedType;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-my $nextAttribute_1 = '^(attribute|inherit|readonly)$';
</del><ins>+my $nextAttribute_1 = '^(attribute|inherit)$';
</ins><span class="cx"> my $nextPrimitiveType_1 = '^(int|long|short|unsigned)$';
</span><span class="cx"> my $nextPrimitiveType_2 = '^(double|float|unrestricted)$';
</span><span class="cx"> my $nextArgumentList_1 = '^(\(|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|double|float|in|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</span><span class="lines">@@ -436,7 +451,6 @@
</span><span class="cx"> my $nextSpecials_1 = '^(creator|deleter|getter|legacycaller|setter)$';
</span><span class="cx"> my $nextDefinitions_1 = '^(callback|dictionary|enum|exception|interface|partial|typedef)$';
</span><span class="cx"> my $nextExceptionMembers_1 = '^(\(|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|const|double|float|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</span><del>-my $nextAttributeRest_1 = '^(attribute|readonly)$';
</del><span class="cx"> my $nextInterfaceMembers_1 = '^(\(|ByteString|DOMString|USVString|Date|any|attribute|boolean|byte|const|creator|deleter|double|float|getter|inherit|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
</span><span class="cx"> my $nextSingleType_1 = '^(ByteString|DOMString|USVString|Date|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
</span><span class="cx"> my $nextArgumentName_1 = '^(attribute|callback|const|creator|deleter|dictionary|enum|exception|getter|implements|inherit|interface|legacycaller|partial|serializer|setter|static|stringifier|typedef|unrestricted)$';
</span><span class="lines">@@ -1140,9 +1154,11 @@
</span><span class="cx">     if ($next-&gt;value() eq &quot;serializer&quot;) {
</span><span class="cx">         return $self-&gt;parseSerializer($extendedAttributeList);
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     if ($next-&gt;value() =~ /$nextAttributeOrOperation_1/) {
</span><span class="cx">         my $qualifier = $self-&gt;parseQualifier();
</span><del>-        my $newDataNode = $self-&gt;parseAttributeOrOperationRest($extendedAttributeList);
</del><ins>+        my $isReadOnly = $self-&gt;parseReadOnly();
+        my $newDataNode = $self-&gt;parseAttributeOrOperationRest($extendedAttributeList, $isReadOnly);
</ins><span class="cx">         if (defined($newDataNode)) {
</span><span class="cx">             $newDataNode-&gt;isStatic(1) if $qualifier eq &quot;static&quot;;
</span><span class="cx">             $newDataNode-&gt;isStringifier(1) if $qualifier eq &quot;stringifier&quot;;
</span><span class="lines">@@ -1149,11 +1165,13 @@
</span><span class="cx">         }
</span><span class="cx">         return $newDataNode;
</span><span class="cx">     }
</span><ins>+    my $isReadOnly = $self-&gt;parseReadOnly();
+    $next = $self-&gt;nextToken();
</ins><span class="cx">     if ($next-&gt;value() =~ /$nextAttribute_1/) {
</span><del>-        return $self-&gt;parseAttribute($extendedAttributeList);
</del><ins>+        return $self-&gt;parseAttribute($extendedAttributeList, $isReadOnly);
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextAttributeOrOperation_2/) {
</span><del>-        return $self-&gt;parseOperationOrIterator($extendedAttributeList);
</del><ins>+        return $self-&gt;parseOperationOrIterator($extendedAttributeList, $isReadOnly);
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -1178,6 +1196,7 @@
</span><span class="cx">         my $toJSONFunction = IDLOperation-&gt;new();
</span><span class="cx">         $toJSONFunction-&gt;name(&quot;toJSON&quot;);
</span><span class="cx">         $toJSONFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+        $toJSONFunction-&gt;isSerializer(1);
</ins><span class="cx">         push(@{$newDataNode-&gt;functions}, $toJSONFunction);
</span><span class="cx"> 
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
</span><span class="lines">@@ -1315,10 +1334,11 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $extendedAttributeList = shift;
</span><ins>+    my $isReadOnly = shift;
</ins><span class="cx"> 
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><del>-    if ($next-&gt;value() =~ /$nextAttributeRest_1/) {
-        return $self-&gt;parseAttributeRest($extendedAttributeList);
</del><ins>+    if ($next-&gt;value() eq &quot;attribute&quot;) {
+        return $self-&gt;parseAttributeRest($extendedAttributeList, $isReadOnly);
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;;&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
</span><span class="lines">@@ -1339,11 +1359,12 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $extendedAttributeList = shift;
</span><ins>+    my $isReadOnly = shift;
</ins><span class="cx"> 
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() =~ /$nextAttribute_1/) {
</span><span class="cx">         $self-&gt;parseInherit();
</span><del>-        return $self-&gt;parseAttributeRest($extendedAttributeList);
</del><ins>+        return $self-&gt;parseAttributeRest($extendedAttributeList, $isReadOnly);
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -1352,14 +1373,15 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $extendedAttributeList = shift;
</span><ins>+    my $isReadOnly = shift;
</ins><span class="cx"> 
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><del>-    if ($next-&gt;value() =~ /$nextAttributeRest_1/) {
</del><ins>+    if ($next-&gt;value() eq &quot;attribute&quot;) {
</ins><span class="cx">         my $newDataNode = IDLAttribute-&gt;new();
</span><del>-        $newDataNode-&gt;isReadOnly($self-&gt;parseReadOnly());
</del><ins>+        $newDataNode-&gt;isReadOnly($isReadOnly);
</ins><span class="cx"> 
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;attribute&quot;, __LINE__);
</span><del>-        
</del><ins>+
</ins><span class="cx">         my $type = $self-&gt;parseType();
</span><span class="cx">         $newDataNode-&gt;type($type);
</span><span class="cx"> 
</span><span class="lines">@@ -1405,6 +1427,7 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $extendedAttributeList = shift;
</span><ins>+    my $isReadOnly = shift;
</ins><span class="cx"> 
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() =~ /$nextSpecials_1/) {
</span><span class="lines">@@ -1413,6 +1436,9 @@
</span><span class="cx">     if ($next-&gt;value() eq &quot;iterable&quot;) {
</span><span class="cx">         return $self-&gt;parseIterableRest($extendedAttributeList);
</span><span class="cx">     }
</span><ins>+    if ($next-&gt;value() eq &quot;maplike&quot;) {
+        return $self-&gt;parseMapLikeRest($extendedAttributeList, $isReadOnly);
+    }
</ins><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextAttributeOrOperationRest_1/) {
</span><span class="cx">         my $returnType = $self-&gt;parseReturnType();
</span><span class="cx">         my $next = $self-&gt;nextToken();
</span><span class="lines">@@ -1508,32 +1534,54 @@
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $extendedAttributeList = shift;
</span><span class="cx"> 
</span><ins>+    my $newDataNode = IDLIterable-&gt;new();
+    $newDataNode-&gt;extendedAttributes($extendedAttributeList);
+
+    $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
+    my $type1 = $self-&gt;parseType();
+
+    if ($self-&gt;nextToken()-&gt;value() eq &quot;,&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;, __LINE__);
+
+        my $type2 = $self-&gt;parseType();
+        $newDataNode-&gt;isKeyValue(1);
+        $newDataNode-&gt;keyType($type1);
+        $newDataNode-&gt;valueType($type2);
+    } else {
+        $newDataNode-&gt;isKeyValue(0);
+        $newDataNode-&gt;valueType($type1);
+    }
+    $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
+
</ins><span class="cx">     my $symbolIteratorFunction = IDLOperation-&gt;new();
</span><span class="cx">     $symbolIteratorFunction-&gt;name(&quot;[Symbol.Iterator]&quot;);
</span><span class="cx">     $symbolIteratorFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+    $symbolIteratorFunction-&gt;isIterable(1);
</ins><span class="cx"> 
</span><span class="cx">     my $entriesFunction = IDLOperation-&gt;new();
</span><span class="cx">     $entriesFunction-&gt;name(&quot;entries&quot;);
</span><span class="cx">     $entriesFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+    $entriesFunction-&gt;isIterable(1);
</ins><span class="cx"> 
</span><span class="cx">     my $keysFunction = IDLOperation-&gt;new();
</span><span class="cx">     $keysFunction-&gt;name(&quot;keys&quot;);
</span><span class="cx">     $keysFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+    $keysFunction-&gt;isIterable(1);
</ins><span class="cx"> 
</span><span class="cx">     my $valuesFunction = IDLOperation-&gt;new();
</span><span class="cx">     $valuesFunction-&gt;name(&quot;values&quot;);
</span><span class="cx">     $valuesFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+    $valuesFunction-&gt;isIterable(1);
</ins><span class="cx"> 
</span><span class="cx">     my $forEachFunction = IDLOperation-&gt;new();
</span><span class="cx">     $forEachFunction-&gt;name(&quot;forEach&quot;);
</span><span class="cx">     $forEachFunction-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+    $forEachFunction-&gt;isIterable(1);
</ins><span class="cx">     my $forEachArgument = IDLArgument-&gt;new();
</span><span class="cx">     $forEachArgument-&gt;name(&quot;callback&quot;);
</span><span class="cx">     $forEachArgument-&gt;type(makeSimpleType(&quot;any&quot;));
</span><span class="cx">     push(@{$forEachFunction-&gt;arguments}, ($forEachArgument));
</span><span class="cx"> 
</span><del>-    my $newDataNode = IDLIterable-&gt;new();
-    $newDataNode-&gt;extendedAttributes($extendedAttributeList);
</del><span class="cx">     push(@{$newDataNode-&gt;functions}, $symbolIteratorFunction);
</span><span class="cx">     push(@{$newDataNode-&gt;functions}, $entriesFunction);
</span><span class="cx">     push(@{$newDataNode-&gt;functions}, $keysFunction);
</span><span class="lines">@@ -1540,22 +1588,145 @@
</span><span class="cx">     push(@{$newDataNode-&gt;functions}, $valuesFunction);
</span><span class="cx">     push(@{$newDataNode-&gt;functions}, $forEachFunction);
</span><span class="cx"> 
</span><del>-    $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
-    my $type1 = $self-&gt;parseType();
</del><ins>+    return $newDataNode;
+}
</ins><span class="cx"> 
</span><del>-    if ($self-&gt;nextToken()-&gt;value() eq &quot;,&quot;) {
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;, __LINE__);
</del><ins>+sub parseMapLikeRest
+{
+    my $self = shift;
+    my $extendedAttributeList = shift;
+    my $isReadOnly = shift;
</ins><span class="cx"> 
</span><del>-        my $type2 = $self-&gt;parseType();
-        $newDataNode-&gt;isKeyValue(1);
-        $newDataNode-&gt;keyType($type1);
-        $newDataNode-&gt;valueType($type2);
-    } else {
-        $newDataNode-&gt;isKeyValue(0);
-        $newDataNode-&gt;valueType($type1);
</del><ins>+    my $next = $self-&gt;nextToken();
+    if ($next-&gt;value() eq &quot;maplike&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;maplike&quot;, __LINE__);
+        my $mapLikeNode = $self-&gt;parseMapLikeProperties($extendedAttributeList, $isReadOnly);
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
+        return $mapLikeNode;
</ins><span class="cx">     }
</span><ins>+    $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
+}
+
+sub parseMapLikeProperties
+{
+    my $self = shift;
+    my $extendedAttributeList = shift;
+    my $isReadOnly = shift;
+
+    my $newDataNode = IDLMapLike-&gt;new();
+    $newDataNode-&gt;extendedAttributes($extendedAttributeList);
+    $newDataNode-&gt;isReadOnly($isReadOnly);
+
+    $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
+    $newDataNode-&gt;keyType($self-&gt;parseType());
+    $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;, __LINE__);
+    $newDataNode-&gt;valueType($self-&gt;parseType());
</ins><span class="cx">     $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
</span><span class="cx"> 
</span><ins>+    my $notEnumerableExtendedAttributeList = $extendedAttributeList;
+    $notEnumerableExtendedAttributeList-&gt;{NotEnumerable} = 1;
+
+    my $sizeAttribute = IDLAttribute-&gt;new();
+    $sizeAttribute-&gt;name(&quot;size&quot;);
+    $sizeAttribute-&gt;isMapLike(1);
+    $sizeAttribute-&gt;extendedAttributes($extendedAttributeList);
+    $sizeAttribute-&gt;isReadOnly(1);
+    $sizeAttribute-&gt;type(makeSimpleType(&quot;any&quot;));
+    push(@{$newDataNode-&gt;attributes}, $sizeAttribute);
+
+    my $getFunction = IDLOperation-&gt;new();
+    $getFunction-&gt;name(&quot;get&quot;);
+    $getFunction-&gt;isMapLike(1);
+    my $getArgument = IDLArgument-&gt;new();
+    $getArgument-&gt;name(&quot;key&quot;);
+    $getArgument-&gt;type($newDataNode-&gt;keyType);
+    $getArgument-&gt;extendedAttributes($extendedAttributeList);
+    push(@{$getFunction-&gt;arguments}, ($getArgument));
+    $getFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $getFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $hasFunction = IDLOperation-&gt;new();
+    $hasFunction-&gt;name(&quot;has&quot;);
+    $hasFunction-&gt;isMapLike(1);
+    my $hasArgument = IDLArgument-&gt;new();
+    $hasArgument-&gt;name(&quot;key&quot;);
+    $hasArgument-&gt;type($newDataNode-&gt;keyType);
+    $hasArgument-&gt;extendedAttributes($extendedAttributeList);
+    push(@{$hasFunction-&gt;arguments}, ($hasArgument));
+    $hasFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $hasFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $entriesFunction = IDLOperation-&gt;new();
+    $entriesFunction-&gt;name(&quot;entries&quot;);
+    $entriesFunction-&gt;isMapLike(1);
+    $entriesFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $entriesFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $keysFunction = IDLOperation-&gt;new();
+    $keysFunction-&gt;name(&quot;keys&quot;);
+    $keysFunction-&gt;isMapLike(1);
+    $keysFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $keysFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $valuesFunction = IDLOperation-&gt;new();
+    $valuesFunction-&gt;name(&quot;values&quot;);
+    $valuesFunction-&gt;isMapLike(1);
+    $valuesFunction-&gt;extendedAttributes($extendedAttributeList);
+    $valuesFunction-&gt;extendedAttributes-&gt;{NotEnumerable} = 1;
+    $valuesFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $forEachFunction = IDLOperation-&gt;new();
+    $forEachFunction-&gt;name(&quot;forEach&quot;);
+    $forEachFunction-&gt;isMapLike(1);
+    $forEachFunction-&gt;extendedAttributes({});
+    $forEachFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+    my $forEachArgument = IDLArgument-&gt;new();
+    $forEachArgument-&gt;name(&quot;callback&quot;);
+    $forEachArgument-&gt;type(makeSimpleType(&quot;any&quot;));
+    $forEachArgument-&gt;extendedAttributes($extendedAttributeList);
+    push(@{$forEachFunction-&gt;arguments}, ($forEachArgument));
+
+    push(@{$newDataNode-&gt;functions}, $getFunction);
+    push(@{$newDataNode-&gt;functions}, $hasFunction);
+    push(@{$newDataNode-&gt;functions}, $entriesFunction);
+    push(@{$newDataNode-&gt;functions}, $keysFunction);
+    push(@{$newDataNode-&gt;functions}, $valuesFunction);
+    push(@{$newDataNode-&gt;functions}, $forEachFunction);
+
+    return $newDataNode if $isReadOnly;
+
+    my $addFunction = IDLOperation-&gt;new();
+    $addFunction-&gt;name(&quot;add&quot;);
+    $addFunction-&gt;isMapLike(1);
+    my $addArgument = IDLArgument-&gt;new();
+    $addArgument-&gt;name(&quot;key&quot;);
+    $addArgument-&gt;type($newDataNode-&gt;keyType);
+    $addArgument-&gt;extendedAttributes($extendedAttributeList);
+    push(@{$addFunction-&gt;arguments}, ($addArgument));
+    $addFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $addFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    my $clearFunction = IDLOperation-&gt;new();
+    $clearFunction-&gt;name(&quot;clear&quot;);
+    $clearFunction-&gt;isMapLike(1);
+    $clearFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $clearFunction-&gt;type(makeSimpleType(&quot;void&quot;));
+
+    my $deleteFunction = IDLOperation-&gt;new();
+    $deleteFunction-&gt;name(&quot;delete&quot;);
+    $deleteFunction-&gt;isMapLike(1);
+    my $deleteArgument = IDLArgument-&gt;new();
+    $deleteArgument-&gt;name(&quot;key&quot;);
+    $deleteArgument-&gt;type($newDataNode-&gt;keyType);
+    $deleteArgument-&gt;extendedAttributes($extendedAttributeList);
+    push(@{$deleteFunction-&gt;arguments}, ($deleteArgument));
+    $deleteFunction-&gt;extendedAttributes($notEnumerableExtendedAttributeList);
+    $deleteFunction-&gt;type(makeSimpleType(&quot;any&quot;));
+
+    push(@{$newDataNode-&gt;functions}, $addFunction);
+    push(@{$newDataNode-&gt;functions}, $clearFunction);
+    push(@{$newDataNode-&gt;functions}, $deleteFunction);
+
</ins><span class="cx">     return $newDataNode;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1570,14 +1741,14 @@
</span><span class="cx"> 
</span><span class="cx">         my $name = $self-&gt;parseOptionalIdentifier();
</span><span class="cx">         $newDataNode-&gt;name(identifierRemoveNullablePrefix($name));
</span><del>-        
</del><ins>+
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;(&quot;, $name, __LINE__);
</span><del>-        
</del><ins>+
</ins><span class="cx">         push(@{$newDataNode-&gt;arguments}, @{$self-&gt;parseArgumentList()});
</span><del>-        
</del><ins>+
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;)&quot;, __LINE__);
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
</span><del>-        
</del><ins>+
</ins><span class="cx">         $newDataNode-&gt;extendedAttributes($extendedAttributeList);
</span><span class="cx">         return $newDataNode;
</span><span class="cx">     }
</span><span class="lines">@@ -2393,6 +2564,10 @@
</span><span class="cx">             $interface-&gt;iterable($item);
</span><span class="cx">             next;
</span><span class="cx">         }
</span><ins>+        if (ref($item) eq &quot;IDLMapLike&quot;) {
+            $interface-&gt;mapLike($item);
+            next;
+        }
</ins><span class="cx">         if (ref($item) eq &quot;IDLOperation&quot;) {
</span><span class="cx">             if ($item-&gt;name eq &quot;&quot;) {
</span><span class="cx">                 push(@{$interface-&gt;anonymousFunctions}, $item);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSMapLikecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,416 @@
</span><ins>+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include &quot;config.h&quot;
+#include &quot;JSMapLike.h&quot;
+
+#include &quot;JSDOMBinding.h&quot;
+#include &quot;JSDOMBindingCaller.h&quot;
+#include &quot;JSDOMConstructorNotConstructable.h&quot;
+#include &quot;JSDOMConvert.h&quot;
+#include &quot;JSDOMExceptionHandling.h&quot;
+#include &quot;JSDOMMapLike.h&quot;
+#include &quot;JSDOMWrapperCache.h&quot;
+#include &lt;runtime/Error.h&gt;
+#include &lt;runtime/FunctionPrototype.h&gt;
+#include &lt;wtf/GetPtr.h&gt;
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionGet(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionHas(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionEntries(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionKeys(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionValues(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionForEach(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionAdd(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionClear(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionDelete(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsMapLikeSize(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+JSC::EncodedJSValue jsMapLikeConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSMapLikeConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSMapLikePrototype : public JSC::JSNonFinalObject {
+public:
+    using Base = JSC::JSNonFinalObject;
+    static JSMapLikePrototype* create(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+    {
+        JSMapLikePrototype* ptr = new (NotNull, JSC::allocateCell&lt;JSMapLikePrototype&gt;(vm.heap)) JSMapLikePrototype(vm, globalObject, structure);
+        ptr-&gt;finishCreation(vm);
+        return ptr;
+    }
+
+    DECLARE_INFO;
+    static JSC::Structure* createStructure(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+private:
+    JSMapLikePrototype(JSC::VM&amp; vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+        : JSC::JSNonFinalObject(vm, structure)
+    {
+    }
+
+    void finishCreation(JSC::VM&amp;);
+};
+
+using JSMapLikeConstructor = JSDOMConstructorNotConstructable&lt;JSMapLike&gt;;
+
+template&lt;&gt; JSValue JSMapLikeConstructor::prototypeForStructure(JSC::VM&amp; vm, const JSDOMGlobalObject&amp; globalObject)
+{
+    UNUSED_PARAM(vm);
+    return globalObject.functionPrototype();
+}
+
+template&lt;&gt; void JSMapLikeConstructor::initializeProperties(VM&amp; vm, JSDOMGlobalObject&amp; globalObject)
+{
+    putDirect(vm, vm.propertyNames-&gt;prototype, JSMapLike::prototype(vm, &amp;globalObject), DontDelete | ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames-&gt;name, jsNontrivialString(&amp;vm, String(ASCIILiteral(&quot;MapLike&quot;))), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames-&gt;length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template&lt;&gt; const ClassInfo JSMapLikeConstructor::s_info = { &quot;MapLike&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSMapLikeConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSMapLikePrototypeTableValues[] =
+{
+    { &quot;constructor&quot;, DontEnum, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsMapLikeConstructor), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSMapLikeConstructor) } },
+    { &quot;size&quot;, DontEnum | ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsMapLikeSize), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(0) } },
+    { &quot;get&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionGet), (intptr_t) (1) } },
+    { &quot;has&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionHas), (intptr_t) (1) } },
+    { &quot;entries&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionEntries), (intptr_t) (0) } },
+    { &quot;keys&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionKeys), (intptr_t) (0) } },
+    { &quot;values&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionValues), (intptr_t) (0) } },
+    { &quot;forEach&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionForEach), (intptr_t) (1) } },
+    { &quot;add&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionAdd), (intptr_t) (1) } },
+    { &quot;clear&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionClear), (intptr_t) (0) } },
+    { &quot;delete&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsMapLikePrototypeFunctionDelete), (intptr_t) (1) } },
+};
+
+const ClassInfo JSMapLikePrototype::s_info = { &quot;MapLikePrototype&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSMapLikePrototype) };
+
+void JSMapLikePrototype::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    reifyStaticProperties(vm, JSMapLikePrototypeTableValues, *this);
+    putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, getDirect(vm, vm.propertyNames-&gt;builtinNames().valuesPublicName()), DontEnum);
+}
+
+const ClassInfo JSMapLike::s_info = { &quot;MapLike&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSMapLike) };
+
+JSMapLike::JSMapLike(Structure* structure, JSDOMGlobalObject&amp; globalObject, Ref&lt;MapLike&gt;&amp;&amp; impl)
+    : JSDOMWrapper&lt;MapLike&gt;(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSMapLike::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+    synchronizeBackingMap(*globalObject()-&gt;globalExec(), *globalObject(), *this);
+}
+
+JSObject* JSMapLike::createPrototype(VM&amp; vm, JSGlobalObject* globalObject)
+{
+    return JSMapLikePrototype::create(vm, globalObject, JSMapLikePrototype::createStructure(vm, globalObject, globalObject-&gt;objectPrototype()));
+}
+
+JSObject* JSMapLike::prototype(VM&amp; vm, JSGlobalObject* globalObject)
+{
+    return getDOMPrototype&lt;JSMapLike&gt;(vm, globalObject);
+}
+
+void JSMapLike::destroy(JSC::JSCell* cell)
+{
+    JSMapLike* thisObject = static_cast&lt;JSMapLike*&gt;(cell);
+    thisObject-&gt;JSMapLike::~JSMapLike();
+}
+
+template&lt;&gt; inline JSMapLike* BindingCaller&lt;JSMapLike&gt;::castForAttribute(ExecState&amp; state, EncodedJSValue thisValue)
+{
+    return jsDynamicDowncast&lt;JSMapLike*&gt;(state.vm(), JSValue::decode(thisValue));
+}
+
+template&lt;&gt; inline JSMapLike* BindingCaller&lt;JSMapLike&gt;::castForOperation(ExecState&amp; state)
+{
+    return jsDynamicDowncast&lt;JSMapLike*&gt;(state.vm(), state.thisValue());
+}
+
+static inline JSValue jsMapLikeSizeGetter(ExecState&amp;, JSMapLike&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsMapLikeSize(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSMapLike&gt;::attribute&lt;jsMapLikeSizeGetter&gt;(state, thisValue, &quot;size&quot;);
+}
+
+static inline JSValue jsMapLikeSizeGetter(ExecState&amp; state, JSMapLike&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    JSValue result = toJS&lt;IDLAny&gt;(forwardSizeToMapLike(state, thisObject));
+    return result;
+}
+
+EncodedJSValue jsMapLikeConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    VM&amp; vm = state-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    JSMapLikePrototype* domObject = jsDynamicDowncast&lt;JSMapLikePrototype*&gt;(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!domObject))
+        return throwVMTypeError(state, throwScope);
+    return JSValue::encode(JSMapLike::getConstructor(state-&gt;vm(), domObject-&gt;globalObject()));
+}
+
+bool setJSMapLikeConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    VM&amp; vm = state-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    JSValue value = JSValue::decode(encodedValue);
+    JSMapLikePrototype* domObject = jsDynamicDowncast&lt;JSMapLikePrototype*&gt;(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!domObject)) {
+        throwVMTypeError(state, throwScope);
+        return false;
+    }
+    // Shadowing a built-in constructor
+    return domObject-&gt;putDirect(state-&gt;vm(), state-&gt;propertyNames().constructor, value);
+}
+
+JSValue JSMapLike::getConstructor(VM&amp; vm, const JSGlobalObject* globalObject)
+{
+    return getDOMConstructor&lt;JSMapLikeConstructor&gt;(vm, *jsCast&lt;const JSDOMGlobalObject*&gt;(globalObject));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionGetCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionGet(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionGetCaller&gt;(state, &quot;get&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionGetCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardGetToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionHasCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionHas(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionHasCaller&gt;(state, &quot;has&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionHasCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardHasToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionEntriesCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionEntries(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionEntriesCaller&gt;(state, &quot;entries&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionEntriesCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardEntriesToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionKeysCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionKeys(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionKeysCaller&gt;(state, &quot;keys&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionKeysCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardKeysToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionValuesCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionValues(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionValuesCaller&gt;(state, &quot;values&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionValuesCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardValuesToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionForEachCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionForEach(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionForEachCaller&gt;(state, &quot;forEach&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionForEachCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto callback = convert&lt;IDLAny&gt;(*state, state-&gt;uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardForEachToMapLike(*state, *castedThis, WTFMove(callback))));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionAddCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionAdd(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionAddCaller&gt;(state, &quot;add&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionAddCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardAddToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionClearCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionClear(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionClearCaller&gt;(state, &quot;clear&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionClearCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    forwardClearToMapLike(*state, *castedThis);
+    return JSValue::encode(jsUndefined());
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionDeleteCaller(JSC::ExecState*, JSMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsMapLikePrototypeFunctionDelete(ExecState* state)
+{
+    return BindingCaller&lt;JSMapLike&gt;::callOperation&lt;jsMapLikePrototypeFunctionDeleteCaller&gt;(state, &quot;delete&quot;);
+}
+
+static inline JSC::EncodedJSValue jsMapLikePrototypeFunctionDeleteCaller(JSC::ExecState* state, JSMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardDeleteToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+bool JSMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle&lt;JSC::Unknown&gt; handle, void*, SlotVisitor&amp; visitor)
+{
+    UNUSED_PARAM(handle);
+    UNUSED_PARAM(visitor);
+    return false;
+}
+
+void JSMapLikeOwner::finalize(JSC::Handle&lt;JSC::Unknown&gt; handle, void* context)
+{
+    auto* jsMapLike = static_cast&lt;JSMapLike*&gt;(handle.slot()-&gt;asCell());
+    auto&amp; world = *static_cast&lt;DOMWrapperWorld*&gt;(context);
+    uncacheWrapper(world, &amp;jsMapLike-&gt;wrapped(), jsMapLike);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern &quot;C&quot; { extern void (*const __identifier(&quot;??_7MapLike@WebCore@@6B@&quot;)[])(); }
+#else
+extern &quot;C&quot; { extern void* _ZTVN7WebCore7MapLikeE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref&lt;MapLike&gt;&amp;&amp; impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast&lt;void**&gt;(impl.ptr()));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast&lt;void*&gt;(__identifier(&quot;??_7MapLike@WebCore@@6B@&quot;));
+#else
+    void* expectedVTablePointer = &amp;_ZTVN7WebCore7MapLikeE[2];
+#if COMPILER(CLANG)
+    // If this fails MapLike does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(__is_polymorphic(MapLike), &quot;MapLike is not polymorphic&quot;);
+#endif
+#endif
+    // If you hit this assertion you either have a use after free bug, or
+    // MapLike has subclasses. If MapLike has subclasses that get passed
+    // to toJS() we currently require MapLike you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createWrapper&lt;MapLike&gt;(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, MapLike&amp; impl)
+{
+    return wrap(state, globalObject, impl);
+}
+
+MapLike* JSMapLike::toWrapped(JSC::VM&amp; vm, JSC::JSValue value)
+{
+    if (auto* wrapper = jsDynamicDowncast&lt;JSMapLike*&gt;(vm, value))
+        return &amp;wrapper-&gt;wrapped();
+    return nullptr;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSMapLikeh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.h (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.h                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include &quot;JSDOMWrapper.h&quot;
+#include &quot;MapLike.h&quot;
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+namespace WebCore {
+
+class JSMapLike : public JSDOMWrapper&lt;MapLike&gt; {
+public:
+    using Base = JSDOMWrapper&lt;MapLike&gt;;
+    static JSMapLike* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref&lt;MapLike&gt;&amp;&amp; impl)
+    {
+        JSMapLike* ptr = new (NotNull, JSC::allocateCell&lt;JSMapLike&gt;(globalObject-&gt;vm().heap)) JSMapLike(structure, *globalObject, WTFMove(impl));
+        ptr-&gt;finishCreation(globalObject-&gt;vm());
+        return ptr;
+    }
+
+    static JSC::JSObject* createPrototype(JSC::VM&amp;, JSC::JSGlobalObject*);
+    static JSC::JSObject* prototype(JSC::VM&amp;, JSC::JSGlobalObject*);
+    static MapLike* toWrapped(JSC::VM&amp;, JSC::JSValue);
+    static void destroy(JSC::JSCell*);
+
+    DECLARE_INFO;
+
+    static JSC::Structure* createStructure(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+    static JSC::JSValue getConstructor(JSC::VM&amp;, const JSC::JSGlobalObject*);
+protected:
+    JSMapLike(JSC::Structure*, JSDOMGlobalObject&amp;, Ref&lt;MapLike&gt;&amp;&amp;);
+
+    void finishCreation(JSC::VM&amp;);
+};
+
+class JSMapLikeOwner : public JSC::WeakHandleOwner {
+public:
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle&lt;JSC::Unknown&gt;, void* context, JSC::SlotVisitor&amp;);
+    virtual void finalize(JSC::Handle&lt;JSC::Unknown&gt;, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&amp;, MapLike*)
+{
+    static NeverDestroyed&lt;JSMapLikeOwner&gt; owner;
+    return &amp;owner.get();
+}
+
+inline void* wrapperKey(MapLike* wrappableObject)
+{
+    return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, MapLike&amp;);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, MapLike* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref&lt;MapLike&gt;&amp;&amp;);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr&lt;MapLike&gt;&amp;&amp; impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template&lt;&gt; struct JSDOMWrapperConverterTraits&lt;MapLike&gt; {
+    using WrapperClass = JSMapLike;
+    using ToWrappedReturnType = MapLike*;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSReadOnlyMapLikecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.cpp (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.cpp        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,359 @@
</span><ins>+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include &quot;config.h&quot;
+#include &quot;JSReadOnlyMapLike.h&quot;
+
+#include &quot;JSDOMBinding.h&quot;
+#include &quot;JSDOMBindingCaller.h&quot;
+#include &quot;JSDOMConstructorNotConstructable.h&quot;
+#include &quot;JSDOMConvert.h&quot;
+#include &quot;JSDOMExceptionHandling.h&quot;
+#include &quot;JSDOMMapLike.h&quot;
+#include &quot;JSDOMWrapperCache.h&quot;
+#include &lt;runtime/Error.h&gt;
+#include &lt;runtime/FunctionPrototype.h&gt;
+#include &lt;wtf/GetPtr.h&gt;
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionGet(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionHas(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionEntries(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionKeys(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionValues(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionForEach(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsReadOnlyMapLikeSize(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+JSC::EncodedJSValue jsReadOnlyMapLikeConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSReadOnlyMapLikeConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSReadOnlyMapLikePrototype : public JSC::JSNonFinalObject {
+public:
+    using Base = JSC::JSNonFinalObject;
+    static JSReadOnlyMapLikePrototype* create(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+    {
+        JSReadOnlyMapLikePrototype* ptr = new (NotNull, JSC::allocateCell&lt;JSReadOnlyMapLikePrototype&gt;(vm.heap)) JSReadOnlyMapLikePrototype(vm, globalObject, structure);
+        ptr-&gt;finishCreation(vm);
+        return ptr;
+    }
+
+    DECLARE_INFO;
+    static JSC::Structure* createStructure(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+private:
+    JSReadOnlyMapLikePrototype(JSC::VM&amp; vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+        : JSC::JSNonFinalObject(vm, structure)
+    {
+    }
+
+    void finishCreation(JSC::VM&amp;);
+};
+
+using JSReadOnlyMapLikeConstructor = JSDOMConstructorNotConstructable&lt;JSReadOnlyMapLike&gt;;
+
+template&lt;&gt; JSValue JSReadOnlyMapLikeConstructor::prototypeForStructure(JSC::VM&amp; vm, const JSDOMGlobalObject&amp; globalObject)
+{
+    UNUSED_PARAM(vm);
+    return globalObject.functionPrototype();
+}
+
+template&lt;&gt; void JSReadOnlyMapLikeConstructor::initializeProperties(VM&amp; vm, JSDOMGlobalObject&amp; globalObject)
+{
+    putDirect(vm, vm.propertyNames-&gt;prototype, JSReadOnlyMapLike::prototype(vm, &amp;globalObject), DontDelete | ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames-&gt;name, jsNontrivialString(&amp;vm, String(ASCIILiteral(&quot;ReadOnlyMapLike&quot;))), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames-&gt;length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template&lt;&gt; const ClassInfo JSReadOnlyMapLikeConstructor::s_info = { &quot;ReadOnlyMapLike&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSReadOnlyMapLikeConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSReadOnlyMapLikePrototypeTableValues[] =
+{
+    { &quot;constructor&quot;, DontEnum, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsReadOnlyMapLikeConstructor), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSReadOnlyMapLikeConstructor) } },
+    { &quot;size&quot;, DontEnum | ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsReadOnlyMapLikeSize), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(0) } },
+    { &quot;get&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionGet), (intptr_t) (1) } },
+    { &quot;has&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionHas), (intptr_t) (1) } },
+    { &quot;entries&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionEntries), (intptr_t) (0) } },
+    { &quot;keys&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionKeys), (intptr_t) (0) } },
+    { &quot;values&quot;, DontEnum | JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionValues), (intptr_t) (0) } },
+    { &quot;forEach&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsReadOnlyMapLikePrototypeFunctionForEach), (intptr_t) (1) } },
+};
+
+const ClassInfo JSReadOnlyMapLikePrototype::s_info = { &quot;ReadOnlyMapLikePrototype&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSReadOnlyMapLikePrototype) };
+
+void JSReadOnlyMapLikePrototype::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    reifyStaticProperties(vm, JSReadOnlyMapLikePrototypeTableValues, *this);
+    putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, getDirect(vm, vm.propertyNames-&gt;builtinNames().valuesPublicName()), DontEnum);
+}
+
+const ClassInfo JSReadOnlyMapLike::s_info = { &quot;ReadOnlyMapLike&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSReadOnlyMapLike) };
+
+JSReadOnlyMapLike::JSReadOnlyMapLike(Structure* structure, JSDOMGlobalObject&amp; globalObject, Ref&lt;ReadOnlyMapLike&gt;&amp;&amp; impl)
+    : JSDOMWrapper&lt;ReadOnlyMapLike&gt;(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSReadOnlyMapLike::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+    synchronizeBackingMap(*globalObject()-&gt;globalExec(), *globalObject(), *this);
+}
+
+JSObject* JSReadOnlyMapLike::createPrototype(VM&amp; vm, JSGlobalObject* globalObject)
+{
+    return JSReadOnlyMapLikePrototype::create(vm, globalObject, JSReadOnlyMapLikePrototype::createStructure(vm, globalObject, globalObject-&gt;objectPrototype()));
+}
+
+JSObject* JSReadOnlyMapLike::prototype(VM&amp; vm, JSGlobalObject* globalObject)
+{
+    return getDOMPrototype&lt;JSReadOnlyMapLike&gt;(vm, globalObject);
+}
+
+void JSReadOnlyMapLike::destroy(JSC::JSCell* cell)
+{
+    JSReadOnlyMapLike* thisObject = static_cast&lt;JSReadOnlyMapLike*&gt;(cell);
+    thisObject-&gt;JSReadOnlyMapLike::~JSReadOnlyMapLike();
+}
+
+template&lt;&gt; inline JSReadOnlyMapLike* BindingCaller&lt;JSReadOnlyMapLike&gt;::castForAttribute(ExecState&amp; state, EncodedJSValue thisValue)
+{
+    return jsDynamicDowncast&lt;JSReadOnlyMapLike*&gt;(state.vm(), JSValue::decode(thisValue));
+}
+
+template&lt;&gt; inline JSReadOnlyMapLike* BindingCaller&lt;JSReadOnlyMapLike&gt;::castForOperation(ExecState&amp; state)
+{
+    return jsDynamicDowncast&lt;JSReadOnlyMapLike*&gt;(state.vm(), state.thisValue());
+}
+
+static inline JSValue jsReadOnlyMapLikeSizeGetter(ExecState&amp;, JSReadOnlyMapLike&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsReadOnlyMapLikeSize(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::attribute&lt;jsReadOnlyMapLikeSizeGetter&gt;(state, thisValue, &quot;size&quot;);
+}
+
+static inline JSValue jsReadOnlyMapLikeSizeGetter(ExecState&amp; state, JSReadOnlyMapLike&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    JSValue result = toJS&lt;IDLAny&gt;(forwardSizeToMapLike(state, thisObject));
+    return result;
+}
+
+EncodedJSValue jsReadOnlyMapLikeConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    VM&amp; vm = state-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    JSReadOnlyMapLikePrototype* domObject = jsDynamicDowncast&lt;JSReadOnlyMapLikePrototype*&gt;(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!domObject))
+        return throwVMTypeError(state, throwScope);
+    return JSValue::encode(JSReadOnlyMapLike::getConstructor(state-&gt;vm(), domObject-&gt;globalObject()));
+}
+
+bool setJSReadOnlyMapLikeConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    VM&amp; vm = state-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    JSValue value = JSValue::decode(encodedValue);
+    JSReadOnlyMapLikePrototype* domObject = jsDynamicDowncast&lt;JSReadOnlyMapLikePrototype*&gt;(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!domObject)) {
+        throwVMTypeError(state, throwScope);
+        return false;
+    }
+    // Shadowing a built-in constructor
+    return domObject-&gt;putDirect(state-&gt;vm(), state-&gt;propertyNames().constructor, value);
+}
+
+JSValue JSReadOnlyMapLike::getConstructor(VM&amp; vm, const JSGlobalObject* globalObject)
+{
+    return getDOMConstructor&lt;JSReadOnlyMapLikeConstructor&gt;(vm, *jsCast&lt;const JSDOMGlobalObject*&gt;(globalObject));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionGetCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionGet(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionGetCaller&gt;(state, &quot;get&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionGetCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardGetToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionHasCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionHas(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionHasCaller&gt;(state, &quot;has&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionHasCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto key = convert&lt;IDLDOMString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardHasToMapLike(*state, *castedThis, WTFMove(key))));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionEntriesCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionEntries(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionEntriesCaller&gt;(state, &quot;entries&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionEntriesCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardEntriesToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionKeysCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionKeys(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionKeysCaller&gt;(state, &quot;keys&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionKeysCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardKeysToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionValuesCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionValues(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionValuesCaller&gt;(state, &quot;values&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionValuesCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardValuesToMapLike(*state, *castedThis)));
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionForEachCaller(JSC::ExecState*, JSReadOnlyMapLike*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlyMapLikePrototypeFunctionForEach(ExecState* state)
+{
+    return BindingCaller&lt;JSReadOnlyMapLike&gt;::callOperation&lt;jsReadOnlyMapLikePrototypeFunctionForEachCaller&gt;(state, &quot;forEach&quot;);
+}
+
+static inline JSC::EncodedJSValue jsReadOnlyMapLikePrototypeFunctionForEachCaller(JSC::ExecState* state, JSReadOnlyMapLike* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto callback = convert&lt;IDLAny&gt;(*state, state-&gt;uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS&lt;IDLAny&gt;(forwardForEachToMapLike(*state, *castedThis, WTFMove(callback))));
+}
+
+bool JSReadOnlyMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle&lt;JSC::Unknown&gt; handle, void*, SlotVisitor&amp; visitor)
+{
+    UNUSED_PARAM(handle);
+    UNUSED_PARAM(visitor);
+    return false;
+}
+
+void JSReadOnlyMapLikeOwner::finalize(JSC::Handle&lt;JSC::Unknown&gt; handle, void* context)
+{
+    auto* jsReadOnlyMapLike = static_cast&lt;JSReadOnlyMapLike*&gt;(handle.slot()-&gt;asCell());
+    auto&amp; world = *static_cast&lt;DOMWrapperWorld*&gt;(context);
+    uncacheWrapper(world, &amp;jsReadOnlyMapLike-&gt;wrapped(), jsReadOnlyMapLike);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern &quot;C&quot; { extern void (*const __identifier(&quot;??_7ReadOnlyMapLike@WebCore@@6B@&quot;)[])(); }
+#else
+extern &quot;C&quot; { extern void* _ZTVN7WebCore15ReadOnlyMapLikeE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref&lt;ReadOnlyMapLike&gt;&amp;&amp; impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast&lt;void**&gt;(impl.ptr()));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast&lt;void*&gt;(__identifier(&quot;??_7ReadOnlyMapLike@WebCore@@6B@&quot;));
+#else
+    void* expectedVTablePointer = &amp;_ZTVN7WebCore15ReadOnlyMapLikeE[2];
+#if COMPILER(CLANG)
+    // If this fails ReadOnlyMapLike does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(__is_polymorphic(ReadOnlyMapLike), &quot;ReadOnlyMapLike is not polymorphic&quot;);
+#endif
+#endif
+    // If you hit this assertion you either have a use after free bug, or
+    // ReadOnlyMapLike has subclasses. If ReadOnlyMapLike has subclasses that get passed
+    // to toJS() we currently require ReadOnlyMapLike you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createWrapper&lt;ReadOnlyMapLike&gt;(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, ReadOnlyMapLike&amp; impl)
+{
+    return wrap(state, globalObject, impl);
+}
+
+ReadOnlyMapLike* JSReadOnlyMapLike::toWrapped(JSC::VM&amp; vm, JSC::JSValue value)
+{
+    if (auto* wrapper = jsDynamicDowncast&lt;JSReadOnlyMapLike*&gt;(vm, value))
+        return &amp;wrapper-&gt;wrapped();
+    return nullptr;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSReadOnlyMapLikeh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.h (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.h                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.h        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include &quot;JSDOMWrapper.h&quot;
+#include &quot;ReadOnlyMapLike.h&quot;
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+namespace WebCore {
+
+class JSReadOnlyMapLike : public JSDOMWrapper&lt;ReadOnlyMapLike&gt; {
+public:
+    using Base = JSDOMWrapper&lt;ReadOnlyMapLike&gt;;
+    static JSReadOnlyMapLike* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref&lt;ReadOnlyMapLike&gt;&amp;&amp; impl)
+    {
+        JSReadOnlyMapLike* ptr = new (NotNull, JSC::allocateCell&lt;JSReadOnlyMapLike&gt;(globalObject-&gt;vm().heap)) JSReadOnlyMapLike(structure, *globalObject, WTFMove(impl));
+        ptr-&gt;finishCreation(globalObject-&gt;vm());
+        return ptr;
+    }
+
+    static JSC::JSObject* createPrototype(JSC::VM&amp;, JSC::JSGlobalObject*);
+    static JSC::JSObject* prototype(JSC::VM&amp;, JSC::JSGlobalObject*);
+    static ReadOnlyMapLike* toWrapped(JSC::VM&amp;, JSC::JSValue);
+    static void destroy(JSC::JSCell*);
+
+    DECLARE_INFO;
+
+    static JSC::Structure* createStructure(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+    static JSC::JSValue getConstructor(JSC::VM&amp;, const JSC::JSGlobalObject*);
+protected:
+    JSReadOnlyMapLike(JSC::Structure*, JSDOMGlobalObject&amp;, Ref&lt;ReadOnlyMapLike&gt;&amp;&amp;);
+
+    void finishCreation(JSC::VM&amp;);
+};
+
+class JSReadOnlyMapLikeOwner : public JSC::WeakHandleOwner {
+public:
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle&lt;JSC::Unknown&gt;, void* context, JSC::SlotVisitor&amp;);
+    virtual void finalize(JSC::Handle&lt;JSC::Unknown&gt;, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&amp;, ReadOnlyMapLike*)
+{
+    static NeverDestroyed&lt;JSReadOnlyMapLikeOwner&gt; owner;
+    return &amp;owner.get();
+}
+
+inline void* wrapperKey(ReadOnlyMapLike* wrappableObject)
+{
+    return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, ReadOnlyMapLike&amp;);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, ReadOnlyMapLike* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref&lt;ReadOnlyMapLike&gt;&amp;&amp;);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr&lt;ReadOnlyMapLike&gt;&amp;&amp; impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template&lt;&gt; struct JSDOMWrapperConverterTraits&lt;ReadOnlyMapLike&gt; {
+    using WrapperClass = JSReadOnlyMapLike;
+    using ToWrappedReturnType = ReadOnlyMapLike*;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestTestMapLikeidl"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/TestMapLike.idl (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/TestMapLike.idl                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestMapLike.idl        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+interface MapLike {
+    maplike&lt;DOMString, DOMString&gt;;
+};
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestTestReadOnlyMapLikeidl"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/TestReadOnlyMapLike.idl (0 => 213108)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/TestReadOnlyMapLike.idl                                (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestReadOnlyMapLike.idl        2017-02-28 01:34:35 UTC (rev 213108)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+interface ReadOnlyMapLike {
+    readonly maplike&lt;DOMString, DOMString&gt;;
+};
</ins></span></pre>
</div>
</div>

</body>
</html>