<!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>[178633] trunk/Source/WebCore</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/178633">178633</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2015-01-18 12:57:26 -0800 (Sun, 18 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/125251">r125251</a>): wrapper lifetimes of SVGElementInstance are incorrect
https://bugs.webkit.org/show_bug.cgi?id=132148

Reviewed by Anders Carlsson.

Test: svg/custom/use-instanceRoot-event-listeners.xhtml

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::addEventListener): Updated for the new return type
of JSListener::create. For the event type, use JSString::toAtomicString instead of
calling JSString::value and then converting to an AtomicString.
(WebCore::JSDOMWindow::removeEventListener): Same changes as for addEventListener.

* bindings/js/JSEventListener.cpp:
(WebCore::forwardsEventListeners): Added. Helper to detect the special case needed
for SVGElementInstance. In the future, for better encapsulation, we could use virtual
functions, but for now hard coding this single class seems fine.
(WebCore::correspondingElementWrapper): Added. For use if forwardsEventListeners
returns true, to find out where event listeners will be forwarded.
(WebCore::createJSEventListenerForAttribute): Added. Replaces the old function
createJSAttributeEventListener, for SVGElementInstance attributes only.
(WebCore::createJSEventListenerForAdd): Added. Helper function to avoid repeated
generated code in the addElementListener bindings other than the DOMWindow one.

* bindings/js/JSEventListener.h:
(WebCore::JSEventListener::create): Changed to return a Ref instead of a PassRefPtr.
(WebCore::createJSEventListenerForAttribute): Renamed from createJSAttributeEventListener,
changed to return a RefPtr instead of a PassRefPtr and to take references rather than
pointers for non-null things.
(WebCore::createJSEventListenerForRemove): Added. Small wrapper that calls
createJSEventListenerForAdd since they are currently identical.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateAttributeEventListenerCall): Removed the special case for JSSVGElementInstance
and updated to call the new createJSEventListenerForAttribute. The special case for
SVGElementInstance is now in JSEventListener.h/cpp, which is nicer since we prefer to
keep the generated code simpler if possible.
(GenerateEventListenerCall): Removed the special case for JSSVGElementInstance. This
has been dead code since the explicit definition of add/removeEventListener was removed
from SVGElementInstance.idl, and was also a problem if someone were to use the
addEventListener function from EventTarget on an SVGElementInstance object. The function
needs to be generic at runtime. Use toAtomicString as in JSDOMWindow::addEventListener above.
Call the two new functions, createJSEventListenerForAdd and createJSEventListenerForRemove.
Those new functions properly handle SVGElementInstance.
(GenerateImplementation): Don't pass the class name to GenerateAttributeEventListenerCall
or GenerateEventListenerCall any more.
(GenerateConstructorDefinition): Use JSString::toAtomicString instead of calling
JSString::value and then converting to AtomicString.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMWindowCustomcpp">trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSEventListenercpp">trunk/Source/WebCore/bindings/js/JSEventListener.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSEventListenerh">trunk/Source/WebCore/bindings/js/JSEventListener.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (178632 => 178633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-18 18:39:59 UTC (rev 178632)
+++ trunk/Source/WebCore/ChangeLog        2015-01-18 20:57:26 UTC (rev 178633)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2015-01-18  Darin Adler  &lt;darin@apple.com&gt;
+
+        REGRESSION (r125251): wrapper lifetimes of SVGElementInstance are incorrect
+        https://bugs.webkit.org/show_bug.cgi?id=132148
+
+        Reviewed by Anders Carlsson.
+
+        Test: svg/custom/use-instanceRoot-event-listeners.xhtml
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::addEventListener): Updated for the new return type
+        of JSListener::create. For the event type, use JSString::toAtomicString instead of
+        calling JSString::value and then converting to an AtomicString.
+        (WebCore::JSDOMWindow::removeEventListener): Same changes as for addEventListener.
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::forwardsEventListeners): Added. Helper to detect the special case needed
+        for SVGElementInstance. In the future, for better encapsulation, we could use virtual
+        functions, but for now hard coding this single class seems fine.
+        (WebCore::correspondingElementWrapper): Added. For use if forwardsEventListeners
+        returns true, to find out where event listeners will be forwarded.
+        (WebCore::createJSEventListenerForAttribute): Added. Replaces the old function
+        createJSAttributeEventListener, for SVGElementInstance attributes only.
+        (WebCore::createJSEventListenerForAdd): Added. Helper function to avoid repeated
+        generated code in the addElementListener bindings other than the DOMWindow one.
+
+        * bindings/js/JSEventListener.h:
+        (WebCore::JSEventListener::create): Changed to return a Ref instead of a PassRefPtr.
+        (WebCore::createJSEventListenerForAttribute): Renamed from createJSAttributeEventListener,
+        changed to return a RefPtr instead of a PassRefPtr and to take references rather than
+        pointers for non-null things.
+        (WebCore::createJSEventListenerForRemove): Added. Small wrapper that calls
+        createJSEventListenerForAdd since they are currently identical.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateAttributeEventListenerCall): Removed the special case for JSSVGElementInstance
+        and updated to call the new createJSEventListenerForAttribute. The special case for
+        SVGElementInstance is now in JSEventListener.h/cpp, which is nicer since we prefer to
+        keep the generated code simpler if possible.
+        (GenerateEventListenerCall): Removed the special case for JSSVGElementInstance. This
+        has been dead code since the explicit definition of add/removeEventListener was removed
+        from SVGElementInstance.idl, and was also a problem if someone were to use the
+        addEventListener function from EventTarget on an SVGElementInstance object. The function
+        needs to be generic at runtime. Use toAtomicString as in JSDOMWindow::addEventListener above.
+        Call the two new functions, createJSEventListenerForAdd and createJSEventListenerForRemove.
+        Those new functions properly handle SVGElementInstance.
+        (GenerateImplementation): Don't pass the class name to GenerateAttributeEventListenerCall
+        or GenerateEventListenerCall any more.
+        (GenerateConstructorDefinition): Use JSString::toAtomicString instead of calling
+        JSString::value and then converting to AtomicString.
+
</ins><span class="cx"> 2015-01-17  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: highlight data for overlay should use protocol type builders
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMWindowCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (178632 => 178633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp        2015-01-18 18:39:59 UTC (rev 178632)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp        2015-01-18 20:57:26 UTC (rev 178633)
</span><span class="lines">@@ -652,7 +652,7 @@
</span><span class="cx">     if (!listener.isObject())
</span><span class="cx">         return jsUndefined();
</span><span class="cx"> 
</span><del>-    impl().addEventListener(exec-&gt;argument(0).toString(exec)-&gt;value(exec), JSEventListener::create(asObject(listener), this, false, globalObject()-&gt;world()), exec-&gt;argument(2).toBoolean(exec));
</del><ins>+    impl().addEventListener(exec-&gt;argument(0).toString(exec)-&gt;toAtomicString(exec), JSEventListener::create(asObject(listener), this, false, globalObject()-&gt;world()), exec-&gt;argument(2).toBoolean(exec));
</ins><span class="cx">     return jsUndefined();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -666,7 +666,7 @@
</span><span class="cx">     if (!listener.isObject())
</span><span class="cx">         return jsUndefined();
</span><span class="cx"> 
</span><del>-    impl().removeEventListener(exec-&gt;argument(0).toString(exec)-&gt;value(exec), JSEventListener::create(asObject(listener), this, false, globalObject()-&gt;world()).get(), exec-&gt;argument(2).toBoolean(exec));
</del><ins>+    impl().removeEventListener(exec-&gt;argument(0).toString(exec)-&gt;toAtomicString(exec), JSEventListener::create(asObject(listener), this, false, globalObject()-&gt;world()).ptr(), exec-&gt;argument(2).toBoolean(exec));
</ins><span class="cx">     return jsUndefined();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSEventListenercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSEventListener.cpp (178632 => 178633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSEventListener.cpp        2015-01-18 18:39:59 UTC (rev 178632)
+++ trunk/Source/WebCore/bindings/js/JSEventListener.cpp        2015-01-18 20:57:26 UTC (rev 178633)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include &quot;JSEventTarget.h&quot;
</span><span class="cx"> #include &quot;JSMainThreadExecState.h&quot;
</span><span class="cx"> #include &quot;JSMainThreadExecStateInstrumentation.h&quot;
</span><ins>+#include &quot;JSSVGElementInstance.h&quot;
</ins><span class="cx"> #include &quot;ScriptController.h&quot;
</span><span class="cx"> #include &quot;WorkerGlobalScope.h&quot;
</span><span class="cx"> #include &lt;runtime/ExceptionHelpers.h&gt;
</span><span class="lines">@@ -163,4 +164,33 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// SVGElementInstance forwards listeners to its corresponding element, so the listeners are
+// protected by the wrapper of the corresponding element, not the element instance's wrapper.
+
+bool forwardsEventListeners(JSC::JSObject&amp; object)
+{
+    if (object.classInfo() == JSSVGElementInstance::info())
+        return true;
+    ASSERT(!object.inherits(JSSVGElementInstance::info()));
+    return false;
+}
+
+static JSC::JSObject&amp; correspondingElementWrapper(JSC::ExecState&amp; state, JSC::JSObject&amp; wrapper)
+{
+    JSSVGElementInstance&amp; castedWrapper = *jsCast&lt;JSSVGElementInstance*&gt;(&amp;wrapper);
+    return *asObject(toJS(&amp;state, castedWrapper.globalObject(), *castedWrapper.impl().correspondingElement()));
+}
+
+RefPtr&lt;JSEventListener&gt; createJSEventListenerForAttribute(JSC::ExecState&amp; state, JSC::JSValue listener, JSSVGElementInstance&amp; wrapper)
+{
+    return createJSEventListenerForAttribute(state, listener, correspondingElementWrapper(state, wrapper));
+}
+
+Ref&lt;JSEventListener&gt; createJSEventListenerForAdd(JSC::ExecState&amp; state, JSC::JSObject&amp; listener, JSC::JSObject&amp; wrapper)
+{
+    JSC::JSObject&amp; actualWrapper = forwardsEventListeners(wrapper) ? correspondingElementWrapper(state, wrapper) : wrapper;
+    ASSERT(!forwardsEventListeners(actualWrapper));
+    return JSEventListener::create(&amp;listener, &amp;actualWrapper, false, currentWorld(&amp;state));
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSEventListenerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSEventListener.h (178632 => 178633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSEventListener.h        2015-01-18 18:39:59 UTC (rev 178632)
+++ trunk/Source/WebCore/bindings/js/JSEventListener.h        2015-01-18 20:57:26 UTC (rev 178633)
</span><span class="lines">@@ -30,12 +30,13 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx">     class JSDOMGlobalObject;
</span><ins>+    class JSSVGElementInstance;
</ins><span class="cx"> 
</span><span class="cx">     class JSEventListener : public EventListener {
</span><span class="cx">     public:
</span><del>-        static PassRefPtr&lt;JSEventListener&gt; create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld&amp; world)
</del><ins>+        static Ref&lt;JSEventListener&gt; create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld&amp; world)
</ins><span class="cx">         {
</span><del>-            return adoptRef(new JSEventListener(listener, wrapper, isAttribute, world));
</del><ins>+            return adoptRef(*new JSEventListener(listener, wrapper, isAttribute, world));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         static const JSEventListener* cast(const EventListener* listener)
</span><span class="lines">@@ -75,6 +76,15 @@
</span><span class="cx">         RefPtr&lt;DOMWrapperWorld&gt; m_isolatedWorld;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    // For &quot;onXXX&quot; event attributes.
+    RefPtr&lt;JSEventListener&gt; createJSEventListenerForAttribute(JSC::ExecState&amp;, JSC::JSValue listener, JSC::JSObject&amp; wrapper);
+    RefPtr&lt;JSEventListener&gt; createJSEventListenerForAttribute(JSC::ExecState&amp;, JSC::JSValue listener, JSSVGElementInstance&amp; wrapper);
+
+    Ref&lt;JSEventListener&gt; createJSEventListenerForAdd(JSC::ExecState&amp;, JSC::JSObject&amp; listener, JSC::JSObject&amp; wrapper);
+    Ref&lt;JSEventListener&gt; createJSEventListenerForRemove(JSC::ExecState&amp;, JSC::JSObject&amp; listener, JSC::JSObject&amp; wrapper);
+
+    bool forwardsEventListeners(JSC::JSObject&amp; wrapper);
+
</ins><span class="cx">     inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
</span><span class="cx">     {
</span><span class="cx">         // initializeJSFunction can trigger code that deletes this event listener
</span><span class="lines">@@ -106,16 +116,19 @@
</span><span class="cx">         return m_jsFunction.get();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Creates a JS EventListener for an &quot;onXXX&quot; event attribute.
-    inline PassRefPtr&lt;JSEventListener&gt; createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
</del><ins>+    inline RefPtr&lt;JSEventListener&gt; createJSEventListenerForAttribute(JSC::ExecState&amp; state, JSC::JSValue listener, JSC::JSObject&amp; wrapper)
</ins><span class="cx">     {
</span><ins>+        ASSERT(!forwardsEventListeners(wrapper));
</ins><span class="cx">         if (!listener.isObject())
</span><del>-            return 0;
</del><ins>+            return nullptr;
+        return JSEventListener::create(asObject(listener), &amp;wrapper, true, currentWorld(&amp;state));
+    }
</ins><span class="cx"> 
</span><del>-        return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
</del><ins>+    inline Ref&lt;JSEventListener&gt; createJSEventListenerForRemove(JSC::ExecState&amp; state, JSC::JSObject&amp; listener, JSC::JSObject&amp; wrapper)
+    {
+        return createJSEventListenerForAdd(state, listener, wrapper);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // JSEventListener_h
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (178632 => 178633)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2015-01-18 18:39:59 UTC (rev 178632)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2015-01-18 20:57:26 UTC (rev 178633)
</span><span class="lines">@@ -142,56 +142,31 @@
</span><span class="cx"> 
</span><span class="cx"> sub GenerateAttributeEventListenerCall
</span><span class="cx"> {
</span><del>-    my $className = shift;
</del><span class="cx">     my $implSetterFunctionName = shift;
</span><span class="cx">     my $windowEventListener = shift;
</span><span class="cx"> 
</span><span class="cx">     my $wrapperObject = $windowEventListener ? &quot;globalObject&quot; : &quot;castedThis&quot;;
</span><span class="cx">     my @GenerateEventListenerImpl = ();
</span><span class="cx"> 
</span><del>-    if ($className eq &quot;JSSVGElementInstance&quot;) {
-        # SVGElementInstances have to create JSEventListeners with the wrapper equal to the correspondingElement
-        $wrapperObject = &quot;asObject(correspondingElementWrapper)&quot;;
-
-        push(@GenerateEventListenerImpl, &lt;&lt;END);
-    JSValue correspondingElementWrapper = toJS(exec, castedThis-&gt;globalObject(), impl.correspondingElement());
-    if (correspondingElementWrapper.isObject())
-END
-
-        # Add leading whitespace to format the impl.set... line correctly
-        push(@GenerateEventListenerImpl, &quot;    &quot;);
-    }
-
-    push(@GenerateEventListenerImpl, &quot;    impl.set$implSetterFunctionName(createJSAttributeEventListener(exec, value, $wrapperObject));\n&quot;);
</del><ins>+    push(@GenerateEventListenerImpl, &quot;    impl.set$implSetterFunctionName(createJSEventListenerForAttribute(*exec, value, *$wrapperObject));\n&quot;);
</ins><span class="cx">     return @GenerateEventListenerImpl;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub GenerateEventListenerCall
</span><span class="cx"> {
</span><del>-    my $className = shift;
</del><span class="cx">     my $functionName = shift;
</span><del>-    my $passRefPtrHandling = ($functionName eq &quot;add&quot;) ? &quot;&quot; : &quot;.get()&quot;;
</del><ins>+    my $suffix = ucfirst $functionName;
+    my $passRefPtrHandling = ($functionName eq &quot;add&quot;) ? &quot;&quot; : &quot;.ptr()&quot;;
</ins><span class="cx"> 
</span><span class="cx">     $implIncludes{&quot;JSEventListener.h&quot;} = 1;
</span><span class="cx"> 
</span><span class="cx">     my @GenerateEventListenerImpl = ();
</span><del>-    my $wrapperObject = &quot;castedThis&quot;;
-    if ($className eq &quot;JSSVGElementInstance&quot;) {
-        # SVGElementInstances have to create JSEventListeners with the wrapper equal to the correspondingElement
-        $wrapperObject = &quot;asObject(correspondingElementWrapper)&quot;;
</del><span class="cx"> 
</span><del>-        push(@GenerateEventListenerImpl, &lt;&lt;END);
-    JSValue correspondingElementWrapper = toJS(exec, castedThis-&gt;globalObject(), impl.correspondingElement());
-    if (!correspondingElementWrapper.isObject())
-        return JSValue::encode(jsUndefined());
-END
-    }
-
</del><span class="cx">     push(@GenerateEventListenerImpl, &lt;&lt;END);
</span><span class="cx">     JSValue listener = exec-&gt;argument(1);
</span><del>-    if (!listener.isObject())
</del><ins>+    if (UNLIKELY(!listener.isObject()))
</ins><span class="cx">         return JSValue::encode(jsUndefined());
</span><del>-    impl.${functionName}EventListener(exec-&gt;argument(0).toString(exec)-&gt;value(exec), JSEventListener::create(asObject(listener), $wrapperObject, false, currentWorld(exec))$passRefPtrHandling, exec-&gt;argument(2).toBoolean(exec));
</del><ins>+    impl.${functionName}EventListener(exec-&gt;argument(0).toString(exec)-&gt;toAtomicString(exec), createJSEventListenerFor$suffix(*exec, *asObject(listener), *castedThis)$passRefPtrHandling, exec-&gt;argument(2).toBoolean(exec));
</ins><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> END
</span><span class="cx">     return @GenerateEventListenerImpl;
</span><span class="lines">@@ -2597,7 +2572,7 @@
</span><span class="cx">                         $implIncludes{&quot;JSErrorHandler.h&quot;} = 1;
</span><span class="cx">                         push(@implContent, &quot;    impl.set$implSetterFunctionName(createJSErrorHandler(exec, value, castedThis));\n&quot;);
</span><span class="cx">                     } else {
</span><del>-                        push(@implContent, GenerateAttributeEventListenerCall($className, $implSetterFunctionName, $windowEventListener));
</del><ins>+                        push(@implContent, GenerateAttributeEventListenerCall($implSetterFunctionName, $windowEventListener));
</ins><span class="cx">                     }
</span><span class="cx">                 } elsif ($attribute-&gt;signature-&gt;type =~ /Constructor$/) {
</span><span class="cx">                     my $constructorType = $attribute-&gt;signature-&gt;type;
</span><span class="lines">@@ -2837,9 +2812,9 @@
</span><span class="cx"> 
</span><span class="cx">                     # For compatibility with legacy content, the EventListener calls are generated without GenerateArgumentsCountCheck.
</span><span class="cx">                     if ($function-&gt;signature-&gt;name eq &quot;addEventListener&quot;) {
</span><del>-                        push(@implContent, GenerateEventListenerCall($className, &quot;add&quot;));
</del><ins>+                        push(@implContent, GenerateEventListenerCall(&quot;add&quot;));
</ins><span class="cx">                     } elsif ($function-&gt;signature-&gt;name eq &quot;removeEventListener&quot;) {
</span><del>-                        push(@implContent, GenerateEventListenerCall($className, &quot;remove&quot;));
</del><ins>+                        push(@implContent, GenerateEventListenerCall(&quot;remove&quot;));
</ins><span class="cx">                     } else {
</span><span class="cx">                         GenerateArgumentsCountCheck(\@implContent, $function, $interface);
</span><span class="cx"> 
</span><span class="lines">@@ -4521,7 +4496,7 @@
</span><span class="cx">     if (!executionContext)
</span><span class="cx">         return throwVMError(exec, createReferenceError(exec, &quot;Constructor associated execution context is unavailable&quot;));
</span><span class="cx"> 
</span><del>-    AtomicString eventType = exec-&gt;argument(0).toString(exec)-&gt;value(exec);
</del><ins>+    AtomicString eventType = exec-&gt;argument(0).toString(exec)-&gt;toAtomicString(exec);
</ins><span class="cx">     if (UNLIKELY(exec-&gt;hadException()))
</span><span class="cx">         return JSValue::encode(jsUndefined());
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>