<!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>[279443] trunk</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/279443">279443</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2021-06-30 16:53:16 -0700 (Wed, 30 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>RemotePlayback must keep its media element alive when there is a pending activity
https://bugs.webkit.org/show_bug.cgi?id=227471
<rdar://79694015>

Reviewed by Geoffrey Garen.

Source/WebCore:

Fixed the bug that the media element's JS wrapper can be collected while there is still
a pending activity for RemotePlayback. In fact, the newly added test demonstrates that
the media element can be deleted without this patch.

This patch also introduces new extended IDL interface attribute GenerateAddOpaqueRoot
to make adding an opaque root as a part of visitChildren easy in the DOM code.

Test: media/remoteplayback-watch-availability-gc.html

* Modules/remoteplayback/RemotePlayback.cpp:
(WebCore::RemotePlayback::ownerNode const):
* Modules/remoteplayback/RemotePlayback.h:
* Modules/remoteplayback/RemotePlayback.idl:
* bindings/scripts/CodeGeneratorJS.pm:
(InstanceNeedsVisitChildren):
(GenerateImplementation):
* bindings/scripts/IDLAttributes.json:
* bindings/scripts/test/BindingTestGlobalConstructors.idl:
* bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp: Added.
(WebCore::JSTestGenerateAddOpaqueRootDOMConstructor::prototypeForStructure):
(WebCore::JSTestGenerateAddOpaqueRootDOMConstructor::initializeProperties):
(WebCore::JSTestGenerateAddOpaqueRootPrototype::finishCreation):
(WebCore::JSTestGenerateAddOpaqueRoot::JSTestGenerateAddOpaqueRoot):
(WebCore::JSTestGenerateAddOpaqueRoot::finishCreation):
(WebCore::JSTestGenerateAddOpaqueRoot::createPrototype):
(WebCore::JSTestGenerateAddOpaqueRoot::prototype):
(WebCore::JSTestGenerateAddOpaqueRoot::getConstructor):
(WebCore::JSTestGenerateAddOpaqueRoot::destroy):
(WebCore::JSC_DEFINE_CUSTOM_GETTER):
(WebCore::jsTestGenerateAddOpaqueRoot_someAttributeGetter):
(WebCore::JSTestGenerateAddOpaqueRoot::subspaceForImpl):
(WebCore::JSTestGenerateAddOpaqueRoot::visitChildrenImpl):
(WebCore::JSTestGenerateAddOpaqueRoot::analyzeHeap):
(WebCore::JSTestGenerateAddOpaqueRootOwner::isReachableFromOpaqueRoots):
(WebCore::JSTestGenerateAddOpaqueRootOwner::finalize):
(WebCore::toJSNewlyCreated):
(WebCore::toJS):
(WebCore::JSTestGenerateAddOpaqueRoot::toWrapped):
* bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h: Added.
(WebCore::JSTestGenerateAddOpaqueRoot::create):
(WebCore::JSTestGenerateAddOpaqueRoot::createStructure):
(WebCore::JSTestGenerateAddOpaqueRoot::subspaceFor):
(WebCore::wrapperOwner):
(WebCore::wrapperKey):
(WebCore::toJS):
(WebCore::toJSNewlyCreated):
* bindings/scripts/test/JS/JSTestGlobalObject.cpp:
(WebCore::jsTestGlobalObject_TestGenerateAddOpaqueRootConstructorGetter):
(WebCore::JSC_DEFINE_CUSTOM_GETTER):
* bindings/scripts/test/SupplementalDependencies.dep:
* bindings/scripts/test/TestGenerateAddOpaqueRoot.idl: Added.
* testing/Internals.cpp:
(WebCore::Internals::isElementAlive const):
(WebCore::Internals::mediaElementCount):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Added a GC test.

* media/remoteplayback-watch-availability-gc-expected.txt: Added.
* media/remoteplayback-watch-availability-gc.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesremoteplaybackRemotePlaybackcpp">trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesremoteplaybackRemotePlaybackh">trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.h</a></li>
<li><a href="#trunkSourceWebCoreModulesremoteplaybackRemotePlaybackidl">trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.idl</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsIDLAttributesjson">trunk/Source/WebCore/bindings/scripts/IDLAttributes.json</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestBindingTestGlobalConstructorsidl">trunk/Source/WebCore/bindings/scripts/test/BindingTestGlobalConstructors.idl</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestGlobalObjectcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestSupplementalDependenciesdep">trunk/Source/WebCore/bindings/scripts/test/SupplementalDependencies.dep</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsh">trunk/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsidl">trunk/Source/WebCore/testing/Internals.idl</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediaremoteplaybackwatchavailabilitygcexpectedtxt">trunk/LayoutTests/media/remoteplayback-watch-availability-gc-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediaremoteplaybackwatchavailabilitygchtml">trunk/LayoutTests/media/remoteplayback-watch-availability-gc.html</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestGenerateAddOpaqueRootcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestGenerateAddOpaqueRooth">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestTestGenerateAddOpaqueRootidl">trunk/Source/WebCore/bindings/scripts/test/TestGenerateAddOpaqueRoot.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/LayoutTests/ChangeLog 2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2021-06-30  Ryosuke Niwa  <rniwa@webkit.org>
+
+        RemotePlayback must keep its media element alive when there is a pending activity
+        https://bugs.webkit.org/show_bug.cgi?id=227471
+        <rdar://79694015>
+
+        Reviewed by Geoffrey Garen.
+
+        Added a GC test.
+
+        * media/remoteplayback-watch-availability-gc-expected.txt: Added.
+        * media/remoteplayback-watch-availability-gc.html: Added.
+
</ins><span class="cx"> 2021-06-30  Ayumi Kojima  <ayumi_kojima@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [ MacOS wk1 ] crypto/workers/subtle/hrsa-postMessage-worker.html is flaky failing.
</span></span></pre></div>
<a id="trunkLayoutTestsmediaremoteplaybackwatchavailabilitygcexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/remoteplayback-watch-availability-gc-expected.txt (0 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/remoteplayback-watch-availability-gc-expected.txt                                (rev 0)
+++ trunk/LayoutTests/media/remoteplayback-watch-availability-gc-expected.txt   2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+This tests that calling watchAvailability will keep the media element alive until the callback is called. You should see PASS below:
+
+PASS
</ins></span></pre></div>
<a id="trunkLayoutTestsmediaremoteplaybackwatchavailabilitygchtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/remoteplayback-watch-availability-gc.html (0 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/remoteplayback-watch-availability-gc.html                                (rev 0)
+++ trunk/LayoutTests/media/remoteplayback-watch-availability-gc.html   2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+let elementIdentifier = null;
+let parentIdentifier = null;
+let iterationCount = 20;
+let watchdogTimer = null;
+function runTest() {
+    if (!iterationCount)
+        return endTest('PASS');
+
+    internals.queueTask('DOMManipulation', () => {
+        GCController.collect();
+    });
+
+    (() => {
+        const element = document.createElement('video');
+        elementIdentifier = internals.elementIdentifier(element);
+
+        const parentNode = document.createElement('div');
+        parentIdentifier = internals.elementIdentifier(parentNode);
+        parentNode.appendChild(element);
+
+        element.remote.watchAvailability(checkElement);
+        watchdogTimer = setTimeout(() => endTest('FAIL - the callback was never called'), 3000);
+    })();
+
+    GCController.collect();
+}
+
+function checkElement()
+{
+    clearTimeout(watchdogTimer);
+
+    if (!internals.isElementAlive(elementIdentifier))
+        return endTest('FAIL - element is no longer alive');
+
+    if (!internals.isElementAlive(parentIdentifier))
+        return endTest('FAIL - parent is no longer alive');
+
+    --iterationCount;
+    setTimeout(() => runTest(), 0);
+}
+
+function endTest(status)
+{
+    result.textContent = status;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+</script>
+</head>
+<body onload='runTest()'>
+<p>This tests that calling watchAvailability will keep the media element alive until the callback is called. You should see PASS below:</p>
+<p id="result">Running</p>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/ChangeLog      2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2021-06-30  Ryosuke Niwa  <rniwa@webkit.org>
+
+        RemotePlayback must keep its media element alive when there is a pending activity
+        https://bugs.webkit.org/show_bug.cgi?id=227471
+        <rdar://79694015>
+
+        Reviewed by Geoffrey Garen.
+
+        Fixed the bug that the media element's JS wrapper can be collected while there is still
+        a pending activity for RemotePlayback. In fact, the newly added test demonstrates that
+        the media element can be deleted without this patch.
+
+        This patch also introduces new extended IDL interface attribute GenerateAddOpaqueRoot
+        to make adding an opaque root as a part of visitChildren easy in the DOM code.
+
+        Test: media/remoteplayback-watch-availability-gc.html
+
+        * Modules/remoteplayback/RemotePlayback.cpp:
+        (WebCore::RemotePlayback::ownerNode const):
+        * Modules/remoteplayback/RemotePlayback.h:
+        * Modules/remoteplayback/RemotePlayback.idl:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (InstanceNeedsVisitChildren):
+        (GenerateImplementation):
+        * bindings/scripts/IDLAttributes.json:
+        * bindings/scripts/test/BindingTestGlobalConstructors.idl:
+        * bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp: Added.
+        (WebCore::JSTestGenerateAddOpaqueRootDOMConstructor::prototypeForStructure):
+        (WebCore::JSTestGenerateAddOpaqueRootDOMConstructor::initializeProperties):
+        (WebCore::JSTestGenerateAddOpaqueRootPrototype::finishCreation):
+        (WebCore::JSTestGenerateAddOpaqueRoot::JSTestGenerateAddOpaqueRoot):
+        (WebCore::JSTestGenerateAddOpaqueRoot::finishCreation):
+        (WebCore::JSTestGenerateAddOpaqueRoot::createPrototype):
+        (WebCore::JSTestGenerateAddOpaqueRoot::prototype):
+        (WebCore::JSTestGenerateAddOpaqueRoot::getConstructor):
+        (WebCore::JSTestGenerateAddOpaqueRoot::destroy):
+        (WebCore::JSC_DEFINE_CUSTOM_GETTER):
+        (WebCore::jsTestGenerateAddOpaqueRoot_someAttributeGetter):
+        (WebCore::JSTestGenerateAddOpaqueRoot::subspaceForImpl):
+        (WebCore::JSTestGenerateAddOpaqueRoot::visitChildrenImpl):
+        (WebCore::JSTestGenerateAddOpaqueRoot::analyzeHeap):
+        (WebCore::JSTestGenerateAddOpaqueRootOwner::isReachableFromOpaqueRoots):
+        (WebCore::JSTestGenerateAddOpaqueRootOwner::finalize):
+        (WebCore::toJSNewlyCreated):
+        (WebCore::toJS):
+        (WebCore::JSTestGenerateAddOpaqueRoot::toWrapped):
+        * bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h: Added.
+        (WebCore::JSTestGenerateAddOpaqueRoot::create):
+        (WebCore::JSTestGenerateAddOpaqueRoot::createStructure):
+        (WebCore::JSTestGenerateAddOpaqueRoot::subspaceFor):
+        (WebCore::wrapperOwner):
+        (WebCore::wrapperKey):
+        (WebCore::toJS):
+        (WebCore::toJSNewlyCreated):
+        * bindings/scripts/test/JS/JSTestGlobalObject.cpp:
+        (WebCore::jsTestGlobalObject_TestGenerateAddOpaqueRootConstructorGetter):
+        (WebCore::JSC_DEFINE_CUSTOM_GETTER):
+        * bindings/scripts/test/SupplementalDependencies.dep:
+        * bindings/scripts/test/TestGenerateAddOpaqueRoot.idl: Added.
+        * testing/Internals.cpp:
+        (WebCore::Internals::isElementAlive const):
+        (WebCore::Internals::mediaElementCount):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
</ins><span class="cx"> 2021-06-30  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r278391) Sometimes load durations show up as large negative numbers in WebInspector
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesremoteplaybackRemotePlaybackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.cpp (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.cpp   2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.cpp      2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -58,6 +58,18 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void* RemotePlayback::opaqueRootConcurrently() const
+{
+    if (auto* element = m_mediaElement.get())
+        return element->opaqueRoot();
+    return nullptr;
+}
+
+Node* RemotePlayback::ownerNode() const
+{
+    return m_mediaElement.get();
+}
+
</ins><span class="cx"> void RemotePlayback::watchAvailability(Ref<RemotePlaybackAvailabilityCallback>&& callback, Ref<DeferredPromise>&& promise)
</span><span class="cx"> {
</span><span class="cx">     // 6.2.1.3 Getting the remote playback devices availability information
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesremoteplaybackRemotePlaybackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.h (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.h     2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.h        2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -68,6 +68,9 @@
</span><span class="cx">     using RefCounted::ref;
</span><span class="cx">     using RefCounted::deref;
</span><span class="cx"> 
</span><ins>+    void* opaqueRootConcurrently() const;
+    Node* ownerNode() const;
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit RemotePlayback(HTMLMediaElement&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesremoteplaybackRemotePlaybackidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.idl (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.idl   2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/Modules/remoteplayback/RemotePlayback.idl      2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -34,7 +34,9 @@
</span><span class="cx">     ActiveDOMObject,
</span><span class="cx">     Conditional=WIRELESS_PLAYBACK_TARGET,
</span><span class="cx">     EnabledBySetting=RemotePlayback,
</span><del>-    Exposed=Window
</del><ins>+    Exposed=Window,
+    GenerateIsReachable=ImplOwnerNodeRoot,
+    GenerateAddOpaqueRoot=opaqueRootConcurrently
</ins><span class="cx"> ] interface RemotePlayback : EventTarget {
</span><span class="cx">     Promise<long> watchAvailability(RemotePlaybackAvailabilityCallback callback);
</span><span class="cx">     Promise<undefined> cancelWatchAvailability(optional long id);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm    2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -2195,6 +2195,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return 1 if $interface->extendedAttributes->{JSCustomMarkFunction};
</span><ins>+    return 1 if $interface->extendedAttributes->{GenerateAddOpaqueRoot};
</ins><span class="cx">     return 1 if $interface->extendedAttributes->{Plugin};
</span><span class="cx">     return 1 if $interface->extendedAttributes->{ReportExtraMemoryCost};
</span><span class="cx">     return 0;
</span><span class="lines">@@ -4887,6 +4888,10 @@
</span><span class="cx">             push(@implContent, "    thisObject->wrapped().pluginReplacementScriptObject().visit(visitor);\n");
</span><span class="cx">             push(@implContent, "#endif\n");
</span><span class="cx">         }
</span><ins>+        if ($interface->extendedAttributes->{GenerateAddOpaqueRoot}) {
+            my $functionName = $interface->extendedAttributes->{GenerateAddOpaqueRoot};
+            push(@implContent, "    visitor.addOpaqueRoot(thisObject->wrapped().${functionName}());\n");
+        }
</ins><span class="cx">         if ($interface->extendedAttributes->{ReportExtraMemoryCost}) {
</span><span class="cx">             push(@implContent, "    visitor.reportExtraMemoryVisited(thisObject->wrapped().memoryCost());\n");
</span><span class="cx">             if ($interface->extendedAttributes->{ReportExternalMemoryCost}) {;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsIDLAttributesjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/IDLAttributes.json (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/IDLAttributes.json 2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/bindings/scripts/IDLAttributes.json    2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -223,6 +223,10 @@
</span><span class="cx">             "contextsAllowed": ["interface"],
</span><span class="cx">             "values": ["", "Impl", "ImplWebGLRenderingContext", "ImplCanvasBase", "ImplDocument", "ImplElementRoot", "ImplOwnerNodeRoot", "ImplScriptExecutionContext", "ReachableFromDOMWindow", "ReachableFromNavigator"]
</span><span class="cx">         },
</span><ins>+        "GenerateAddOpaqueRoot": {
+            "contextsAllowed": ["interface"],
+            "values": ["*"]
+        },
</ins><span class="cx">         "Global": {
</span><span class="cx">             "contextsAllowed": ["interface"],
</span><span class="cx">             "values": ["*"],
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestBindingTestGlobalConstructorsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/BindingTestGlobalConstructors.idl (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/BindingTestGlobalConstructors.idl     2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/bindings/scripts/test/BindingTestGlobalConstructors.idl        2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -13,6 +13,7 @@
</span><span class="cx">     attribute TestEventConstructorConstructor TestEventConstructor;
</span><span class="cx">     attribute TestEventTargetConstructor TestEventTarget;
</span><span class="cx">     attribute TestExceptionConstructor TestException;
</span><ins>+    attribute TestGenerateAddOpaqueRootConstructor TestGenerateAddOpaqueRoot;
</ins><span class="cx">     attribute TestGenerateIsReachableConstructor TestGenerateIsReachable;
</span><span class="cx">     attribute TestGlobalObjectConstructor TestGlobalObject;
</span><span class="cx">     attribute TestIndexedSetterNoIdentifierConstructor TestIndexedSetterNoIdentifier;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestGenerateAddOpaqueRootcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp (0 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp                            (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp       2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -0,0 +1,283 @@
</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 "config.h"
+#include "JSTestGenerateAddOpaqueRoot.h"
+
+#include "ActiveDOMObject.h"
+#include "DOMIsoSubspaces.h"
+#include "JSDOMAttribute.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMGlobalObjectInlines.h"
+#include "JSDOMWrapperCache.h"
+#include "ScriptExecutionContext.h"
+#include "WebCoreJSClientData.h"
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/HeapAnalyzer.h>
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
+#include <JavaScriptCore/SlotVisitorMacros.h>
+#include <JavaScriptCore/SubspaceInlines.h>
+#include <wtf/GetPtr.h>
+#include <wtf/PointerPreparations.h>
+#include <wtf/URL.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+// Attributes
+
+static JSC_DECLARE_CUSTOM_GETTER(jsTestGenerateAddOpaqueRootConstructor);
+static JSC_DECLARE_CUSTOM_GETTER(jsTestGenerateAddOpaqueRoot_someAttribute);
+
+class JSTestGenerateAddOpaqueRootPrototype final : public JSC::JSNonFinalObject {
+public:
+    using Base = JSC::JSNonFinalObject;
+    static JSTestGenerateAddOpaqueRootPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+    {
+        JSTestGenerateAddOpaqueRootPrototype* ptr = new (NotNull, JSC::allocateCell<JSTestGenerateAddOpaqueRootPrototype>(vm.heap)) JSTestGenerateAddOpaqueRootPrototype(vm, globalObject, structure);
+        ptr->finishCreation(vm);
+        return ptr;
+    }
+
+    DECLARE_INFO;
+    template<typename CellType, JSC::SubspaceAccess>
+    static JSC::IsoSubspace* subspaceFor(JSC::VM& vm)
+    {
+        STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTestGenerateAddOpaqueRootPrototype, Base);
+        return &vm.plainObjectSpace;
+    }
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+private:
+    JSTestGenerateAddOpaqueRootPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+        : JSC::JSNonFinalObject(vm, structure)
+    {
+    }
+
+    void finishCreation(JSC::VM&);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTestGenerateAddOpaqueRootPrototype, JSTestGenerateAddOpaqueRootPrototype::Base);
+
+using JSTestGenerateAddOpaqueRootDOMConstructor = JSDOMConstructorNotConstructable<JSTestGenerateAddOpaqueRoot>;
+
+template<> const ClassInfo JSTestGenerateAddOpaqueRootDOMConstructor::s_info = { "TestGenerateAddOpaqueRoot", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestGenerateAddOpaqueRootDOMConstructor) };
+
+template<> JSValue JSTestGenerateAddOpaqueRootDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+    UNUSED_PARAM(vm);
+    return globalObject.functionPrototype();
+}
+
+template<> void JSTestGenerateAddOpaqueRootDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    putDirect(vm, vm.propertyNames->prototype, JSTestGenerateAddOpaqueRoot::prototype(vm, globalObject), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+    putDirect(vm, vm.propertyNames->name, jsNontrivialString(vm, "TestGenerateAddOpaqueRoot"_s), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+    putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+}
+
+/* Hash table for prototype */
+
+static const HashTableValue JSTestGenerateAddOpaqueRootPrototypeTableValues[] =
+{
+    { "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGenerateAddOpaqueRootConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
+    { "someAttribute", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGenerateAddOpaqueRoot_someAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
+};
+
+const ClassInfo JSTestGenerateAddOpaqueRootPrototype::s_info = { "TestGenerateAddOpaqueRoot", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestGenerateAddOpaqueRootPrototype) };
+
+void JSTestGenerateAddOpaqueRootPrototype::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    reifyStaticProperties(vm, JSTestGenerateAddOpaqueRoot::info(), JSTestGenerateAddOpaqueRootPrototypeTableValues, *this);
+    JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+const ClassInfo JSTestGenerateAddOpaqueRoot::s_info = { "TestGenerateAddOpaqueRoot", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestGenerateAddOpaqueRoot) };
+
+JSTestGenerateAddOpaqueRoot::JSTestGenerateAddOpaqueRoot(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TestGenerateAddOpaqueRoot>&& impl)
+    : JSDOMWrapper<TestGenerateAddOpaqueRoot>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSTestGenerateAddOpaqueRoot::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+    static_assert(!std::is_base_of<ActiveDOMObject, TestGenerateAddOpaqueRoot>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
+
+}
+
+JSObject* JSTestGenerateAddOpaqueRoot::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return JSTestGenerateAddOpaqueRootPrototype::create(vm, &globalObject, JSTestGenerateAddOpaqueRootPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSTestGenerateAddOpaqueRoot::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return getDOMPrototype<JSTestGenerateAddOpaqueRoot>(vm, globalObject);
+}
+
+JSValue JSTestGenerateAddOpaqueRoot::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+    return getDOMConstructor<JSTestGenerateAddOpaqueRootDOMConstructor, DOMConstructorID::TestGenerateAddOpaqueRoot>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSTestGenerateAddOpaqueRoot::destroy(JSC::JSCell* cell)
+{
+    JSTestGenerateAddOpaqueRoot* thisObject = static_cast<JSTestGenerateAddOpaqueRoot*>(cell);
+    thisObject->JSTestGenerateAddOpaqueRoot::~JSTestGenerateAddOpaqueRoot();
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsTestGenerateAddOpaqueRootConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = JSC::getVM(lexicalGlobalObject);
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto* prototype = jsDynamicCast<JSTestGenerateAddOpaqueRootPrototype*>(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!prototype))
+        return throwVMTypeError(lexicalGlobalObject, throwScope);
+    return JSValue::encode(JSTestGenerateAddOpaqueRoot::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
+}
+
+static inline JSValue jsTestGenerateAddOpaqueRoot_someAttributeGetter(JSGlobalObject& lexicalGlobalObject, JSTestGenerateAddOpaqueRoot& thisObject)
+{
+    auto& vm = JSC::getVM(&lexicalGlobalObject);
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto& impl = thisObject.wrapped();
+    RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.someAttribute())));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsTestGenerateAddOpaqueRoot_someAttribute, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+    return IDLAttribute<JSTestGenerateAddOpaqueRoot>::get<jsTestGenerateAddOpaqueRoot_someAttributeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+JSC::IsoSubspace* JSTestGenerateAddOpaqueRoot::subspaceForImpl(JSC::VM& vm)
+{
+    auto& clientData = *static_cast<JSVMClientData*>(vm.clientData);
+    auto& spaces = clientData.subspaces();
+    if (auto* space = spaces.m_subspaceForTestGenerateAddOpaqueRoot.get())
+        return space;
+    static_assert(std::is_base_of_v<JSC::JSDestructibleObject, JSTestGenerateAddOpaqueRoot> || !JSTestGenerateAddOpaqueRoot::needsDestruction);
+    if constexpr (std::is_base_of_v<JSC::JSDestructibleObject, JSTestGenerateAddOpaqueRoot>)
+        spaces.m_subspaceForTestGenerateAddOpaqueRoot = makeUnique<IsoSubspace> ISO_SUBSPACE_INIT(vm.heap, vm.destructibleObjectHeapCellType.get(), JSTestGenerateAddOpaqueRoot);
+    else
+        spaces.m_subspaceForTestGenerateAddOpaqueRoot = makeUnique<IsoSubspace> ISO_SUBSPACE_INIT(vm.heap, vm.cellHeapCellType.get(), JSTestGenerateAddOpaqueRoot);
+    auto* space = spaces.m_subspaceForTestGenerateAddOpaqueRoot.get();
+IGNORE_WARNINGS_BEGIN("unreachable-code")
+IGNORE_WARNINGS_BEGIN("tautological-compare")
+    void (*myVisitOutputConstraint)(JSC::JSCell*, JSC::SlotVisitor&) = JSTestGenerateAddOpaqueRoot::visitOutputConstraints;
+    void (*jsCellVisitOutputConstraint)(JSC::JSCell*, JSC::SlotVisitor&) = JSC::JSCell::visitOutputConstraints;
+    if (myVisitOutputConstraint != jsCellVisitOutputConstraint)
+        clientData.outputConstraintSpaces().append(space);
+IGNORE_WARNINGS_END
+IGNORE_WARNINGS_END
+    return space;
+}
+
+template<typename Visitor>
+void JSTestGenerateAddOpaqueRoot::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+    auto* thisObject = jsCast<JSTestGenerateAddOpaqueRoot*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    visitor.addOpaqueRoot(thisObject->wrapped().ownerObjectConcurrently());
+}
+
+DEFINE_VISIT_CHILDREN(JSTestGenerateAddOpaqueRoot);
+
+void JSTestGenerateAddOpaqueRoot::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+    auto* thisObject = jsCast<JSTestGenerateAddOpaqueRoot*>(cell);
+    analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
+    if (thisObject->scriptExecutionContext())
+        analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+    Base::analyzeHeap(cell, analyzer);
+}
+
+bool JSTestGenerateAddOpaqueRootOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
+{
+    UNUSED_PARAM(handle);
+    UNUSED_PARAM(visitor);
+    UNUSED_PARAM(reason);
+    return false;
+}
+
+void JSTestGenerateAddOpaqueRootOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+    auto* jsTestGenerateAddOpaqueRoot = static_cast<JSTestGenerateAddOpaqueRoot*>(handle.slot()->asCell());
+    auto& world = *static_cast<DOMWrapperWorld*>(context);
+    uncacheWrapper(world, &jsTestGenerateAddOpaqueRoot->wrapped(), jsTestGenerateAddOpaqueRoot);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestGenerateAddOpaqueRoot@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore25TestGenerateAddOpaqueRootE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<TestGenerateAddOpaqueRoot>&& impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+    const void* actualVTablePointer = getVTablePointer(impl.ptr());
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = __identifier("??_7TestGenerateAddOpaqueRoot@WebCore@@6B@");
+#else
+    void* expectedVTablePointer = &_ZTVN7WebCore25TestGenerateAddOpaqueRootE[2];
+#endif
+
+    // If this fails TestGenerateAddOpaqueRoot does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(std::is_polymorphic<TestGenerateAddOpaqueRoot>::value, "TestGenerateAddOpaqueRoot is not polymorphic");
+
+    // If you hit this assertion you either have a use after free bug, or
+    // TestGenerateAddOpaqueRoot has subclasses. If TestGenerateAddOpaqueRoot has subclasses that get passed
+    // to toJS() we currently require TestGenerateAddOpaqueRoot you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createWrapper<TestGenerateAddOpaqueRoot>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, TestGenerateAddOpaqueRoot& impl)
+{
+    return wrap(lexicalGlobalObject, globalObject, impl);
+}
+
+TestGenerateAddOpaqueRoot* JSTestGenerateAddOpaqueRoot::toWrapped(JSC::VM& vm, JSC::JSValue value)
+{
+    if (auto* wrapper = jsDynamicCast<JSTestGenerateAddOpaqueRoot*>(vm, value))
+        return &wrapper->wrapped();
+    return nullptr;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestGenerateAddOpaqueRooth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h (0 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h                              (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.h 2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -0,0 +1,95 @@
</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 "JSDOMWrapper.h"
+#include "TestGenerateAddOpaqueRoot.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSTestGenerateAddOpaqueRoot : public JSDOMWrapper<TestGenerateAddOpaqueRoot> {
+public:
+    using Base = JSDOMWrapper<TestGenerateAddOpaqueRoot>;
+    static JSTestGenerateAddOpaqueRoot* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TestGenerateAddOpaqueRoot>&& impl)
+    {
+        JSTestGenerateAddOpaqueRoot* ptr = new (NotNull, JSC::allocateCell<JSTestGenerateAddOpaqueRoot>(globalObject->vm().heap)) JSTestGenerateAddOpaqueRoot(structure, *globalObject, WTFMove(impl));
+        ptr->finishCreation(globalObject->vm());
+        return ptr;
+    }
+
+    static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+    static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+    static TestGenerateAddOpaqueRoot* toWrapped(JSC::VM&, JSC::JSValue);
+    static void destroy(JSC::JSCell*);
+
+    DECLARE_INFO;
+
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
+    }
+
+    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+    template<typename, JSC::SubspaceAccess mode> static JSC::IsoSubspace* subspaceFor(JSC::VM& vm)
+    {
+        if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+            return nullptr;
+        return subspaceForImpl(vm);
+    }
+    static JSC::IsoSubspace* subspaceForImpl(JSC::VM& vm);
+    DECLARE_VISIT_CHILDREN;
+
+    static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+protected:
+    JSTestGenerateAddOpaqueRoot(JSC::Structure*, JSDOMGlobalObject&, Ref<TestGenerateAddOpaqueRoot>&&);
+
+    void finishCreation(JSC::VM&);
+};
+
+class JSTestGenerateAddOpaqueRootOwner final : public JSC::WeakHandleOwner {
+public:
+    bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
+    void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TestGenerateAddOpaqueRoot*)
+{
+    static NeverDestroyed<JSTestGenerateAddOpaqueRootOwner> owner;
+    return &owner.get();
+}
+
+inline void* wrapperKey(TestGenerateAddOpaqueRoot* wrappableObject)
+{
+    return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, TestGenerateAddOpaqueRoot&);
+inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, TestGenerateAddOpaqueRoot* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<TestGenerateAddOpaqueRoot>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<TestGenerateAddOpaqueRoot>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<TestGenerateAddOpaqueRoot> {
+    using WrapperClass = JSTestGenerateAddOpaqueRoot;
+    using ToWrappedReturnType = TestGenerateAddOpaqueRoot*;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp     2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp        2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> #include "JSTestEventConstructor.h"
</span><span class="cx"> #include "JSTestEventTarget.h"
</span><span class="cx"> #include "JSTestException.h"
</span><ins>+#include "JSTestGenerateAddOpaqueRoot.h"
</ins><span class="cx"> #include "JSTestGenerateIsReachable.h"
</span><span class="cx"> #include "JSTestGlobalObject.h"
</span><span class="cx"> #include "JSTestIndexedSetterNoIdentifier.h"
</span><span class="lines">@@ -183,6 +184,7 @@
</span><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestEventConstructorConstructor);
</span><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestEventTargetConstructor);
</span><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestExceptionConstructor);
</span><ins>+static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestGenerateAddOpaqueRootConstructor);
</ins><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestGenerateIsReachableConstructor);
</span><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestGlobalObjectConstructor);
</span><span class="cx"> static JSC_DECLARE_CUSTOM_GETTER(jsTestGlobalObject_TestIndexedSetterNoIdentifierConstructor);
</span><span class="lines">@@ -241,13 +243,13 @@
</span><span class="cx"> 
</span><span class="cx"> /* Hash table */
</span><span class="cx"> 
</span><del>-static const struct CompactHashIndex JSTestGlobalObjectTableIndex[267] = {
</del><ins>+static const struct CompactHashIndex JSTestGlobalObjectTableIndex[268] = {
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 40, -1 },
</del><ins>+    { 41, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { 0, -1 },
</span><span class="cx">     { 4, -1 },
</span><del>-    { 44, -1 },
</del><ins>+    { 45, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -255,15 +257,15 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 54, -1 },
</del><ins>+    { 55, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 48, -1 },
</del><ins>+    { 49, -1 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 63, -1 },
</del><ins>+    { 64, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -277,14 +279,14 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 34, -1 },
</del><ins>+    { 35, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 66, -1 },
-    { 13, 260 },
</del><ins>+    { 67, -1 },
+    { 13, 261 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -292,11 +294,11 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 38, -1 },
-    { 19, 257 },
</del><ins>+    { 39, -1 },
+    { 20, 258 },
</ins><span class="cx">     { 6, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 45, -1 },
</del><ins>+    { 46, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -305,7 +307,7 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 36, -1 },
</del><ins>+    { 37, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -312,7 +314,7 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 21, 265 },
</del><ins>+    { 22, 266 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -326,8 +328,8 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 29, -1 },
-    { 56, -1 },
</del><ins>+    { 30, -1 },
+    { 57, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -334,19 +336,19 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 9, 256 },
</del><ins>+    { 9, 257 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 58, -1 },
-    { 18, -1 },
</del><ins>+    { 59, -1 },
+    { 19, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 17, -1 },
</del><ins>+    { 18, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 35, -1 },
</del><ins>+    { 36, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -354,14 +356,14 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 23, -1 },
</del><ins>+    { 24, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { 2, -1 },
</span><del>-    { 37, -1 },
</del><ins>+    { 38, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 20, -1 },
</del><ins>+    { 21, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -374,15 +376,15 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 27, -1 },
</del><ins>+    { 28, -1 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 42, -1 },
</del><ins>+    { 43, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 53, -1 },
</del><ins>+    { 54, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -390,7 +392,7 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 47, -1 },
</del><ins>+    { 48, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { 10, -1 },
</span><span class="lines">@@ -400,12 +402,12 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 64, -1 },
</del><ins>+    { 65, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 26, -1 },
-    { 31, -1 },
</del><ins>+    { 27, -1 },
+    { 32, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -415,9 +417,9 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 15, 259 },
</del><ins>+    { 15, 260 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 59, -1 },
</del><ins>+    { 60, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -426,11 +428,11 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 33, 266 },
</del><ins>+    { 34, 267 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 16, -1 },
</del><ins>+    { 16, 256 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 62, -1 },
</del><ins>+    { 63, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -449,7 +451,7 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 46, -1 },
</del><ins>+    { 47, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -462,7 +464,7 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 57, -1 },
</del><ins>+    { 58, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { 1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -471,10 +473,10 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 49, 263 },
-    { 7, 262 },
</del><ins>+    { 50, 264 },
+    { 7, 263 },
</ins><span class="cx">     { -1, -1 },
</span><del>-    { 60, -1 },
</del><ins>+    { 61, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="lines">@@ -483,32 +485,33 @@
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { 14, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 24, -1 },
</del><ins>+    { 25, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 30, -1 },
</del><ins>+    { 31, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { 3, -1 },
</span><del>-    { 51, -1 },
-    { -1, -1 },
</del><span class="cx">     { 52, -1 },
</span><span class="cx">     { -1, -1 },
</span><ins>+    { 53, -1 },
</ins><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><span class="cx">     { -1, -1 },
</span><del>-    { 22, 258 },
-    { 25, 264 },
-    { 28, 261 },
-    { 32, -1 },
-    { 39, -1 },
-    { 41, -1 },
-    { 43, -1 },
-    { 50, -1 },
-    { 55, -1 },
-    { 61, -1 },
-    { 65, -1 },
</del><ins>+    { -1, -1 },
+    { 17, -1 },
+    { 23, 259 },
+    { 26, 265 },
+    { 29, 262 },
+    { 33, -1 },
+    { 40, -1 },
+    { 42, -1 },
+    { 44, -1 },
+    { 51, -1 },
+    { 56, -1 },
+    { 62, -1 },
+    { 66, -1 },
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -539,6 +542,7 @@
</span><span class="cx">     { "TestEventConstructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestEventConstructorConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><span class="cx">     { "TestEventTarget", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestEventTargetConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><span class="cx">     { "TestException", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestExceptionConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><ins>+    { "TestGenerateAddOpaqueRoot", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestGenerateAddOpaqueRootConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</ins><span class="cx">     { "TestGenerateIsReachable", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestGenerateIsReachableConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><span class="cx">     { "TestGlobalObject", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestGlobalObjectConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><span class="cx">     { "TestIndexedSetterNoIdentifier", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestGlobalObject_TestIndexedSetterNoIdentifierConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
</span><span class="lines">@@ -599,7 +603,7 @@
</span><span class="cx">     { "regularOperation", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestGlobalObjectInstanceFunction_regularOperation), (intptr_t) (1) } },
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static const HashTable JSTestGlobalObjectTable = { 67, 255, true, JSTestGlobalObject::info(), JSTestGlobalObjectTableValues, JSTestGlobalObjectTableIndex };
</del><ins>+static const HashTable JSTestGlobalObjectTable = { 68, 255, true, JSTestGlobalObject::info(), JSTestGlobalObjectTableValues, JSTestGlobalObjectTableIndex };
</ins><span class="cx"> /* Hash table for constructor */
</span><span class="cx"> 
</span><span class="cx"> static const HashTableValue JSTestGlobalObjectConstructorTableValues[] =
</span><span class="lines">@@ -1017,6 +1021,17 @@
</span><span class="cx">     return IDLAttribute<JSTestGlobalObject>::get<jsTestGlobalObject_TestExceptionConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSValue jsTestGlobalObject_TestGenerateAddOpaqueRootConstructorGetter(JSGlobalObject& lexicalGlobalObject, JSTestGlobalObject& thisObject)
+{
+    UNUSED_PARAM(lexicalGlobalObject);
+    return JSTestGenerateAddOpaqueRoot::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsTestGlobalObject_TestGenerateAddOpaqueRootConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+    return IDLAttribute<JSTestGlobalObject>::get<jsTestGlobalObject_TestGenerateAddOpaqueRootConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
</ins><span class="cx"> static inline JSValue jsTestGlobalObject_TestGenerateIsReachableConstructorGetter(JSGlobalObject& lexicalGlobalObject, JSTestGlobalObject& thisObject)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(lexicalGlobalObject);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestSupplementalDependenciesdep"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/SupplementalDependencies.dep (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/SupplementalDependencies.dep  2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/bindings/scripts/test/SupplementalDependencies.dep     2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -110,6 +110,9 @@
</span><span class="cx"> JSTestException.h: 
</span><span class="cx"> DOMTestException.h: 
</span><span class="cx"> WebDOMTestException.h: 
</span><ins>+JSTestGenerateAddOpaqueRoot.h: 
+DOMTestGenerateAddOpaqueRoot.h: 
+WebDOMTestGenerateAddOpaqueRoot.h: 
</ins><span class="cx"> JSTestGenerateIsReachable.h: 
</span><span class="cx"> DOMTestGenerateIsReachable.h: 
</span><span class="cx"> WebDOMTestGenerateIsReachable.h: 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestTestGenerateAddOpaqueRootidl"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/scripts/test/TestGenerateAddOpaqueRoot.idl (0 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/TestGenerateAddOpaqueRoot.idl                         (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestGenerateAddOpaqueRoot.idl    2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/*
+ * Copyright (C) 2021 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. ``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. 
+ */
+
+[
+    Exposed=TestGlobalObject,
+    GenerateAddOpaqueRoot=ownerObjectConcurrently
+] interface TestGenerateAddOpaqueRoot {
+    readonly attribute DOMString someAttribute;
+};
+
</ins></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp       2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/testing/Internals.cpp  2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -2706,6 +2706,11 @@
</span><span class="cx">     return element.document().identifierForElement(element).toUInt64();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Internals::isElementAlive(Document& document, uint64_t elementIdentifier) const
+{
+    return document.searchForElementByIdentifier(makeObjectIdentifier<ElementIdentifierType>(elementIdentifier));
+}
+
</ins><span class="cx"> uint64_t Internals::frameIdentifier(const Document& document) const
</span><span class="cx"> {
</span><span class="cx">     if (auto* page = document.page())
</span><span class="lines">@@ -3865,6 +3870,11 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO)
</span><span class="cx"> 
</span><ins>+unsigned Internals::mediaElementCount()
+{
+    return HTMLMediaElement::allMediaElements().size();
+}
+
</ins><span class="cx"> Vector<String> Internals::mediaResponseSources(HTMLMediaElement& media)
</span><span class="cx"> {
</span><span class="cx">     auto* resourceLoader = media.lastMediaResourceLoaderForTesting();
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.h (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.h 2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/testing/Internals.h    2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -484,6 +484,8 @@
</span><span class="cx">     uint64_t storageAreaMapCount() const;
</span><span class="cx"> 
</span><span class="cx">     uint64_t elementIdentifier(Element&) const;
</span><ins>+    bool isElementAlive(Document&, uint64_t documentIdentifier) const;
+
</ins><span class="cx">     uint64_t frameIdentifier(const Document&) const;
</span><span class="cx">     uint64_t pageIdentifier(const Document&) const;
</span><span class="cx"> 
</span><span class="lines">@@ -644,6 +646,7 @@
</span><span class="cx">     String getImageSourceURL(Element&);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO)
</span><ins>+    unsigned mediaElementCount();
</ins><span class="cx">     Vector<String> mediaResponseSources(HTMLMediaElement&);
</span><span class="cx">     Vector<String> mediaResponseContentRanges(HTMLMediaElement&);
</span><span class="cx">     void simulateAudioInterruption(HTMLMediaElement&);
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.idl (279442 => 279443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.idl       2021-06-30 23:51:58 UTC (rev 279442)
+++ trunk/Source/WebCore/testing/Internals.idl  2021-06-30 23:53:16 UTC (rev 279443)
</span><span class="lines">@@ -875,6 +875,7 @@
</span><span class="cx">     readonly attribute unsigned long long storageAreaMapCount;
</span><span class="cx"> 
</span><span class="cx">     unsigned long long elementIdentifier(Element element);
</span><ins>+    [CallWith=Document] boolean isElementAlive(unsigned long long documentIdentifier);
</ins><span class="cx">     unsigned long long frameIdentifier(Document document);
</span><span class="cx">     unsigned long long pageIdentifier(Document document);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>