2009-03-26 Darin Adler <darin@apple.com>
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Mar 2009 23:50:00 +0000 (23:50 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Mar 2009 23:50:00 +0000 (23:50 +0000)
        Reviewed by Geoff Garen.

        Removed code that casts EventListener down to derived classes
        without type checking. A crash could happen if you added event
        listeners with Objective-C and then manipulated the class with
        JavaScript.

        * bindings/js/JSDOMApplicationCacheCustom.cpp:
        (WebCore::JSDOMApplicationCache::mark): Removed all the casts
        and used the markIfNotNull function and mark functions on
        EventListener instead.
        * bindings/js/JSMessagePortCustom.cpp:
        (WebCore::JSMessagePort::mark): Ditto.
        * bindings/js/JSWorkerContextCustom.cpp:
        (WebCore::JSWorkerContext::mark): Ditto.
        * bindings/js/JSWorkerCustom.cpp:
        (WebCore::JSWorker::mark): Ditto.
        * bindings/js/JSXMLHttpRequestCustom.cpp:
        (WebCore::JSXMLHttpRequest::mark): Ditto.
        * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
        (WebCore::JSXMLHttpRequestUpload::mark): Ditto.

        * bindings/js/JSEventListener.cpp:
        (WebCore::JSAbstractEventListener::handleEvent): Used function,
        the new name for what used to be called listenerObj.
        (WebCore::JSAbstractEventListener::virtualIsInline): Renamed since
        this doesn't need to be virtual for callers who have a pointer to
        this class, not the base class.
        (WebCore::JSEventListener::function): Renamed from listenerObj.
        (WebCore::JSProtectedEventListener::function): Ditto.

        * bindings/js/JSEventListener.h: Removed unneeded forward class
        declarations. Made all virtual functions private since there's no
        need to call any of them on a particular derived class, only on
        EventListener. Explicitly declare JSEventListener::mark as virtual
        since it's now overriding a function in the EventListener base class.
        Made JSProtectedEventListener::m_globalObject protected so the
        JSLazyEventListener derived class can use it directly instead of using
        a virtual function to get the pointer.

        * bindings/js/JSLazyEventListener.cpp:
        (WebCore::JSLazyEventListener::parseCode): Use m_globalObject instead
        of globalObject since the latter is a virtual function and there's no
        need to pay virtual function overhead.
        (WebCore::JSLazyEventListener::function): Renamed from listenerObj.

        * bindings/js/JSLazyEventListener.h: Moved forward declaration of the
        Node class here from JSEventListener.h.

        * bindings/scripts/CodeGeneratorJS.pm: Removed now-unneeded cast to
        JSEventListener when getting the script object from a listener.

        * dom/EventListener.h: Added virtual function and mark functions
        so we can extract the JavaScript function object or mark a JavaScript
        event listener in a type safe manner.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@42021 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
WebCore/ChangeLog
WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
WebCore/bindings/js/JSEventListener.cpp
WebCore/bindings/js/JSEventListener.h
WebCore/bindings/js/JSLazyEventListener.cpp
WebCore/bindings/js/JSLazyEventListener.h
WebCore/bindings/js/JSMessagePortCustom.cpp
WebCore/bindings/js/JSWorkerContextCustom.cpp
WebCore/bindings/js/JSWorkerCustom.cpp
WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/dom/EventListener.h

index 3342802..25689cb 100644 (file)
@@ -1,3 +1,61 @@
+2009-03-26  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff Garen.
+
+        Removed code that casts EventListener down to derived classes
+        without type checking. A crash could happen if you added event
+        listeners with Objective-C and then manipulated the class with
+        JavaScript.
+
+        * bindings/js/JSDOMApplicationCacheCustom.cpp:
+        (WebCore::JSDOMApplicationCache::mark): Removed all the casts
+        and used the markIfNotNull function and mark functions on
+        EventListener instead.
+        * bindings/js/JSMessagePortCustom.cpp:
+        (WebCore::JSMessagePort::mark): Ditto.
+        * bindings/js/JSWorkerContextCustom.cpp:
+        (WebCore::JSWorkerContext::mark): Ditto.
+        * bindings/js/JSWorkerCustom.cpp:
+        (WebCore::JSWorker::mark): Ditto.
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::mark): Ditto.
+        * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
+        (WebCore::JSXMLHttpRequestUpload::mark): Ditto.
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSAbstractEventListener::handleEvent): Used function,
+        the new name for what used to be called listenerObj.
+        (WebCore::JSAbstractEventListener::virtualIsInline): Renamed since
+        this doesn't need to be virtual for callers who have a pointer to
+        this class, not the base class.
+        (WebCore::JSEventListener::function): Renamed from listenerObj.
+        (WebCore::JSProtectedEventListener::function): Ditto.
+
+        * bindings/js/JSEventListener.h: Removed unneeded forward class
+        declarations. Made all virtual functions private since there's no
+        need to call any of them on a particular derived class, only on
+        EventListener. Explicitly declare JSEventListener::mark as virtual
+        since it's now overriding a function in the EventListener base class.
+        Made JSProtectedEventListener::m_globalObject protected so the
+        JSLazyEventListener derived class can use it directly instead of using
+        a virtual function to get the pointer.
+
+        * bindings/js/JSLazyEventListener.cpp:
+        (WebCore::JSLazyEventListener::parseCode): Use m_globalObject instead
+        of globalObject since the latter is a virtual function and there's no
+        need to pay virtual function overhead.
+        (WebCore::JSLazyEventListener::function): Renamed from listenerObj.
+
+        * bindings/js/JSLazyEventListener.h: Moved forward declaration of the
+        Node class here from JSEventListener.h.
+
+        * bindings/scripts/CodeGeneratorJS.pm: Removed now-unneeded cast to
+        JSEventListener when getting the script object from a listener.
+
+        * dom/EventListener.h: Added virtual function and mark functions
+        so we can extract the JavaScript function object or mark a JavaScript
+        event listener in a type safe manner.
+
 2009-03-26  Peter Kasting  <pkasting@google.com>
 
         Reviewed by Adele Peterson.
index 5305e1a..20d09dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,38 +46,21 @@ void JSDOMApplicationCache::mark()
 {
     DOMObject::mark();
 
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onchecking()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onerror()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onnoupdate()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->ondownloading()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onprogress()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onupdateready()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->oncached()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onobsolete()))
-        listener->mark();
+    markIfNotNull(m_impl->onchecking());
+    markIfNotNull(m_impl->onerror());
+    markIfNotNull(m_impl->onnoupdate());
+    markIfNotNull(m_impl->ondownloading());
+    markIfNotNull(m_impl->onprogress());
+    markIfNotNull(m_impl->onupdateready());
+    markIfNotNull(m_impl->oncached());
+    markIfNotNull(m_impl->onobsolete());
 
     typedef DOMApplicationCache::EventListenersMap EventListenersMap;
     typedef DOMApplicationCache::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = m_impl->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+            (*vecIter)->mark();
     }
 }
 
index a6a0f8c..4c9cf0d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
 {
     JSLock lock(false);
 
-    JSObject* listener = listenerObj();
+    JSObject* listener = function();
     if (!listener)
         return;
 
@@ -125,7 +125,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
     }
 }
 
-bool JSAbstractEventListener::isInline() const
+bool JSAbstractEventListener::virtualIsInline() const
 {
     return m_isInline;
 }
@@ -153,7 +153,7 @@ JSEventListener::~JSEventListener()
     }
 }
 
-JSObject* JSEventListener::listenerObj() const
+JSObject* JSEventListener::function() const
 {
     return m_listener;
 }
@@ -207,7 +207,7 @@ JSProtectedEventListener::~JSProtectedEventListener()
 #endif
 }
 
-JSObject* JSProtectedEventListener::listenerObj() const
+JSObject* JSProtectedEventListener::function() const
 {
     return m_listener;
 }
index f3e413f..9589001 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
 
 namespace WebCore {
 
-    class Event;
     class JSDOMGlobalObject;
-    class Node;
 
     class JSAbstractEventListener : public EventListener {
     public:
-        virtual void handleEvent(Event*, bool isWindowEvent);
-        virtual bool isInline() const;
-        virtual JSC::JSObject* listenerObj() const = 0;
-        virtual JSDOMGlobalObject* globalObject() const = 0;
+        bool isInline() const { return m_isInline; }
 
     protected:
         JSAbstractEventListener(bool isInline)
@@ -43,6 +38,10 @@ namespace WebCore {
         }
 
     private:
+        virtual void handleEvent(Event*, bool isWindowEvent);
+        virtual JSDOMGlobalObject* globalObject() const = 0;
+        virtual bool virtualIsInline() const;
+
         bool m_isInline;
     };
 
@@ -54,14 +53,15 @@ namespace WebCore {
         }
         virtual ~JSEventListener();
 
-        virtual JSC::JSObject* listenerObj() const;
-        virtual JSDOMGlobalObject* globalObject() const;
         void clearGlobalObject();
-        void mark();
 
     private:
         JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
 
+        virtual JSC::JSObject* function() const;
+        virtual void mark();
+        virtual JSDOMGlobalObject* globalObject() const;
+
         JSC::JSObject* m_listener;
         JSDOMGlobalObject* m_globalObject;
     };
@@ -74,17 +74,17 @@ namespace WebCore {
         }
         virtual ~JSProtectedEventListener();
 
-        virtual JSC::JSObject* listenerObj() const;
-        virtual JSDOMGlobalObject* globalObject() const;
         void clearGlobalObject();
 
     protected:
         JSProtectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
 
         mutable JSC::ProtectedPtr<JSC::JSObject> m_listener;
+        JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
 
     private:
-        JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+        virtual JSC::JSObject* function() const;
+        virtual JSDOMGlobalObject* globalObject() const;
     };
 
 } // namespace WebCore
index 1dd84cd..3c80efe 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -49,7 +49,7 @@ JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const Strin
         m_lineNumber = 1;
 }
 
-JSObject* JSLazyEventListener::listenerObj() const
+JSObject* JSLazyEventListener::function() const
 {
     parseCode();
     return m_listener;
@@ -74,8 +74,8 @@ void JSLazyEventListener::parseCode() const
     if (m_parsed)
         return;
 
-    if (globalObject()->scriptExecutionContext()->isDocument()) {
-        JSDOMWindow* window = static_cast<JSDOMWindow*>(globalObject());
+    if (m_globalObject->scriptExecutionContext()->isDocument()) {
+        JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject.get());
         Frame* frame = window->impl()->frame();
         if (!frame)
             return;
@@ -87,10 +87,10 @@ void JSLazyEventListener::parseCode() const
 
     m_parsed = true;
 
-    ExecState* exec = globalObject()->globalExec();
+    ExecState* exec = m_globalObject->globalExec();
 
     ArgList args;
-    UString sourceURL(globalObject()->scriptExecutionContext()->url().string());
+    UString sourceURL(m_globalObject->scriptExecutionContext()->url().string());
     args.append(eventParameterName(m_type, exec));
     args.append(jsString(exec, m_code));
 
@@ -123,7 +123,7 @@ void JSLazyEventListener::parseCode() const
 
     if (m_listener) {
         ASSERT(isInline());
-        JSDOMWindow::ProtectedListenersMap& listeners = globalObject()->jsProtectedInlineEventListeners();
+        JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners();
         listeners.set(m_listener, const_cast<JSLazyEventListener*>(this));
     }
 }
index 6815d94..5424883 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,8 @@
 
 namespace WebCore {
 
+    class Node;
+
     class JSLazyEventListener : public JSProtectedEventListener {
     public:
         enum LazyEventListenerType {
@@ -34,18 +36,17 @@ namespace WebCore {
 #endif
         };
 
-        virtual bool wasCreatedFromMarkup() const { return true; }
-
         static PassRefPtr<JSLazyEventListener> create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
         {
             return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber));
         }
-        virtual JSC::JSObject* listenerObj() const;
 
-    protected:
+    private:
         JSLazyEventListener(LazyEventListenerType, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber);
 
-    private:
+        virtual JSC::JSObject* function() const;
+        virtual bool wasCreatedFromMarkup() const { return true; }
+
         void parseCode() const;
 
         mutable String m_functionName;
index e54f478..394f9b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,11 +42,8 @@ void JSMessagePort::mark()
 {
     DOMObject::mark();
 
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onmessage()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onclose()))
-        listener->mark();
+    markIfNotNull(m_impl->onmessage());
+    markIfNotNull(m_impl->onclose());
 
     if (MessagePort* entangledPort = m_impl->entangledPort()) {
         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort);
@@ -58,10 +55,8 @@ void JSMessagePort::mark()
     typedef MessagePort::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = m_impl->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) 
+            (*vecIter)->mark();
     }
 }
 
index b0634b9..a28cb75 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,17 +53,14 @@ void JSWorkerContext::mark()
 
     markActiveObjectsForContext(*globalData(), scriptExecutionContext());
 
-    if (JSEventListener* listener = static_cast<JSEventListener*>(impl()->onmessage()))
-        listener->mark();
+    markIfNotNull(impl()->onmessage());
 
     typedef WorkerContext::EventListenersMap EventListenersMap;
     typedef WorkerContext::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = impl()->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+            (*vecIter)->mark();
     }
 }
 
index 6953317..12103d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,20 +41,15 @@ void JSWorker::mark()
 {
     DOMObject::mark();
 
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onmessage()))
-        listener->mark();
-
-    if (JSEventListener* listener = static_cast<JSEventListener*>(m_impl->onerror()))
-        listener->mark();
+    markIfNotNull(m_impl->onmessage());
+    markIfNotNull(m_impl->onerror());
 
     typedef Worker::EventListenersMap EventListenersMap;
     typedef Worker::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = m_impl->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+            (*vecIter)->mark();
     }
 }
 
index 86e9436..a7f78b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,32 +59,19 @@ void JSXMLHttpRequest::mark()
             wrapper->mark();
     }
 
-    if (JSEventListener* onReadyStateChangeListener = static_cast<JSEventListener*>(m_impl->onreadystatechange()))
-        onReadyStateChangeListener->mark();
-
-    if (JSEventListener* onAbortListener = static_cast<JSEventListener*>(m_impl->onabort()))
-        onAbortListener->mark();
-
-    if (JSEventListener* onErrorListener = static_cast<JSEventListener*>(m_impl->onerror()))
-        onErrorListener->mark();
-
-    if (JSEventListener* onLoadListener = static_cast<JSEventListener*>(m_impl->onload()))
-        onLoadListener->mark();
-
-    if (JSEventListener* onLoadStartListener = static_cast<JSEventListener*>(m_impl->onloadstart()))
-        onLoadStartListener->mark();
-    
-    if (JSEventListener* onProgressListener = static_cast<JSEventListener*>(m_impl->onprogress()))
-        onProgressListener->mark();
+    markIfNotNull(m_impl->onreadystatechange());
+    markIfNotNull(m_impl->onabort());
+    markIfNotNull(m_impl->onerror());
+    markIfNotNull(m_impl->onload());
+    markIfNotNull(m_impl->onloadstart());
+    markIfNotNull(m_impl->onprogress());
     
     typedef XMLHttpRequest::EventListenersMap EventListenersMap;
     typedef XMLHttpRequest::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = m_impl->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+            (*vecIter)->mark();
     }
 }
 
index 0b56f75..26342e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,29 +51,18 @@ void JSXMLHttpRequestUpload::mark()
             wrapper->mark();
     }
 
-    if (JSEventListener* onAbortListener = static_cast<JSEventListener*>(m_impl->onabort()))
-        onAbortListener->mark();
-
-    if (JSEventListener* onErrorListener = static_cast<JSEventListener*>(m_impl->onerror()))
-        onErrorListener->mark();
-
-    if (JSEventListener* onLoadListener = static_cast<JSEventListener*>(m_impl->onload()))
-        onLoadListener->mark();
-
-    if (JSEventListener* onLoadStartListener = static_cast<JSEventListener*>(m_impl->onloadstart()))
-        onLoadStartListener->mark();
-    
-    if (JSEventListener* onProgressListener = static_cast<JSEventListener*>(m_impl->onprogress()))
-        onProgressListener->mark();
+    markIfNotNull(m_impl->onabort());
+    markIfNotNull(m_impl->onerror());
+    markIfNotNull(m_impl->onload());
+    markIfNotNull(m_impl->onloadstart());
+    markIfNotNull(m_impl->onprogress());
     
     typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap;
     typedef XMLHttpRequestUpload::ListenerVector ListenerVector;
     EventListenersMap& eventListeners = m_impl->eventListeners();
     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
-        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
-            JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
-            listener->mark();
-        }
+        for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+            (*vecIter)->mark();
     }
 }
 
index 1c59ce0..08ef971 100644 (file)
@@ -1086,19 +1086,12 @@ sub GenerateImplementation
                     push(@implContent, "    $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
                     push(@implContent, "    return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature,  0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))") . " : jsUndefined();\n");
                 } elsif ($type eq "EventListener") {
-                    $implIncludes{"JSEventListener.h"} = 1;
                     $implIncludes{"EventListener.h"} = 1;
-                    my $listenerType;
-                    if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) {
-                        $listenerType = "JSProtectedEventListener";
-                    } else {
-                        $listenerType = "JSEventListener";
-                    }
                     push(@implContent, "    UNUSED_PARAM(exec);\n");
                     push(@implContent, "    $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
-                    push(@implContent, "    if (${listenerType}* listener = static_cast<${listenerType}*>(imp->$implGetterFunctionName())) {\n");
-                    push(@implContent, "        if (JSObject* listenerObj = listener->listenerObj())\n");
-                    push(@implContent, "            return listenerObj;\n");
+                    push(@implContent, "    if (EventListener* listener = imp->$implGetterFunctionName()) {\n");
+                    push(@implContent, "        if (JSObject* function = listener->function())\n");
+                    push(@implContent, "            return function;\n");
                     push(@implContent, "    }\n");
                     push(@implContent, "    return jsNull();\n");
                 } elsif ($attribute->signature->type =~ /Constructor$/) {
index 24fce86..b7daa6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 #include <wtf/RefCounted.h>
 
+namespace JSC {
+    class JSObject;
+}
+
 namespace WebCore {
 
     class Event;
@@ -31,10 +35,21 @@ namespace WebCore {
     public:
         virtual ~EventListener() { }
         virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
-        virtual bool isInline() const { return false; }
         virtual bool wasCreatedFromMarkup() const { return false; }
+
+#if USE(JSC)
+        virtual JSC::JSObject* function() const { return 0; }
+        virtual void mark() { }
+#endif
+
+        bool isInline() const { return virtualIsInline(); }
+
+    private:
+        virtual bool virtualIsInline() const { return false; }
     };
 
+    inline void markIfNotNull(EventListener* listener) { if (listener) listener->mark(); }
+
 }
 
 #endif