gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] [SCM] Gnash branch, master, updated. 2d2eeba97b5ca7a7c972


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. 2d2eeba97b5ca7a7c9725c24e51a2b95ef9745a6
Date: Fri, 10 Dec 2010 18:29:12 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  2d2eeba97b5ca7a7c9725c24e51a2b95ef9745a6 (commit)
       via  b7dad4b58f280b918c76674499853e8ef32bab1c (commit)
      from  229ef2efc472c26a032ee0b0e18c1187a6cf2527 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=2d2eeba97b5ca7a7c9725c24e51a2b95ef9745a6


commit 2d2eeba97b5ca7a7c9725c24e51a2b95ef9745a6
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Dec 10 19:20:27 2010 +0100

    Fix crashes and const correct.

diff --git a/libbase/GnashAlgorithm.h b/libbase/GnashAlgorithm.h
index 689f826..8d01149 100644
--- a/libbase/GnashAlgorithm.h
+++ b/libbase/GnashAlgorithm.h
@@ -54,7 +54,8 @@ struct FirstElement
 template<typename T>
 struct CreatePointer
 {
-    const T* operator()(const T& t) { 
+    typedef T* result_type;
+    result_type operator()(T& t) { 
         return &t;
     }
 };
diff --git a/libcore/Relay.cpp b/libcore/Relay.cpp
index 7b2af24..c949145 100644
--- a/libcore/Relay.cpp
+++ b/libcore/Relay.cpp
@@ -22,12 +22,15 @@
 
 namespace gnash {
 
-
-/// Destructor of ActiveRelay needs definition of movie_root.
 ActiveRelay::~ActiveRelay()
 {
 }
 
+void
+ActiveRelay::clean()
+{
+    getRoot(*_owner).removeAdvanceCallback(this);
+}
 
 void
 ActiveRelay::setReachable()
diff --git a/libcore/Relay.h b/libcore/Relay.h
index c1f94a1..a00a4f2 100644
--- a/libcore/Relay.h
+++ b/libcore/Relay.h
@@ -49,12 +49,21 @@ namespace gnash {
 class Relay : boost::noncopyable
 {
 public:
-    virtual ~Relay() {};
+    virtual ~Relay() = 0;
 
     /// A Relay itself is not a GC object, but may point to GC resources.
     virtual void setReachable() {}
+
+    /// Handle any cleanup necessary before the Relay is destroyed.
+    //
+    /// Only the replacement of one Relay by another should cause this
+    /// to happen. The cleanup may involve deregistration.
+    virtual void clean() {}
 };
 
+inline Relay::~Relay()
+{
+}
 
 /// A native type that requires periodic updates from the core (movie_root).
 //
@@ -87,6 +96,11 @@ public:
     /// Do not override this function.
     virtual void setReachable();
 
+    /// Remove the ActiveRelay from movie_root's callback set.
+    //
+    /// This must be called before the Relay is destroyed!
+    virtual void clean();
+
     /// Return the as_object that this Relay is attached to.
     as_object& owner() const {
         return *_owner;
diff --git a/libcore/as_object.h b/libcore/as_object.h
index 9edf79f..77f977a 100644
--- a/libcore/as_object.h
+++ b/libcore/as_object.h
@@ -609,6 +609,7 @@ public:
     /// actionscript.all and the swfdec testsuite.
     void setRelay(Relay* p) {
         if (p) _array = false;
+        if (_relay) _relay->clean();
         _relay.reset(p);
     }
 
@@ -877,7 +878,7 @@ as_object* getObjectWithPrototype(Global_as& gl, const 
ObjectURI& c);
 ///                 false.
 template<typename T>
 bool
-isNativeType(as_object* obj, T*& relay)
+isNativeType(const as_object* obj, T*& relay)
 {
     if (!obj) return false;
     relay = dynamic_cast<T*>(obj->relay());
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 3ecf5f6..0d8e757 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -99,6 +99,17 @@ namespace {
 // Utility classes
 namespace {
 
+/// Execute an ActiveRelay if the object has that type.
+struct ExecuteCallback
+{
+    void operator()(const as_object* o) const {
+        ActiveRelay* a;
+        if (isNativeType(o, a)) {
+            a->update();
+        }
+    }
+};
+
 /// Identify and delete ExecutableCode that matches a particular target.
 class RemoveTargetCode
 {
@@ -1439,14 +1450,29 @@ movie_root::executeAdvanceCallbacks()
 
     if (!_objectCallbacks.empty()) {
 
-        // Copy it, as the call can change the original, which is not only 
-        // bad for invalidating iterators, but also allows infinite recursion.
-        std::vector<ActiveRelay*> currentCallbacks;
-        std::copy(_objectCallbacks.begin(), _objectCallbacks.end(),
-                std::back_inserter(currentCallbacks));
-
-        std::for_each(currentCallbacks.begin(), currentCallbacks.end(), 
-                std::mem_fun(&ActiveRelay::update));
+        // We have two considerations:
+        // 1. any update can change the active callbacks by removing or
+        //    adding to the original callbacks list.
+        // 2. Additionally, an as_object may destroy its own Relay. This can
+        //    happen if the callback itself calls a native constructor on
+        //    an object that already has a Relay. If this is an ActiveRelay
+        //    registered with movie_root, a pointer to the destroyed object
+        //    will still be held, resulting in memory corruption. This is an
+        //    *extremely* unlikely case, but we are very careful!
+        //
+        // By copying to a new container we avoid errors caused by changes to
+        // the original set (such as infinite recursions or invalidated
+        // iterators). We also know that no as_object will be destroyed
+        // during processing, even though its Relay may be.
+        std::vector<as_object*> currentCallbacks;
+
+        std::transform(_objectCallbacks.begin(), _objectCallbacks.end(),
+            std::back_inserter(currentCallbacks),
+            boost::bind(CreatePointer<as_object>(),
+                boost::bind(std::mem_fun(&ActiveRelay::owner), _1)));
+
+        std::for_each(currentCallbacks.begin(), currentCallbacks.end(),
+                ExecuteCallback());
     }
 
     if (!_loadCallbacks.empty()) {
diff --git a/libcore/swf/DefineTextTag.cpp b/libcore/swf/DefineTextTag.cpp
index 11f9ae4..8587568 100644
--- a/libcore/swf/DefineTextTag.cpp
+++ b/libcore/swf/DefineTextTag.cpp
@@ -17,8 +17,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-// Derived from text.cpp       -- Thatcher Ulrich <address@hidden> 2003
-
 #include "DefineTextTag.h"
 
 #include <algorithm>
@@ -72,7 +70,7 @@ DefineTextTag::extractStaticText(std::vector<const 
TextRecord*>& to,
 
     /// Insert pointers to all our TextRecords into to.
     std::transform(_textRecords.begin(), _textRecords.end(),
-            std::back_inserter(to), CreatePointer<TextRecord>());
+            std::back_inserter(to), CreatePointer<const TextRecord>());
 
     /// Count the number of DisplayObjects in this definition's text records.
     numChars = std::accumulate(_textRecords.begin(), _textRecords.end(),
diff --git a/libcore/vm/fn_call.h b/libcore/vm/fn_call.h
index c77c1d5..3b77b99 100644
--- a/libcore/vm/fn_call.h
+++ b/libcore/vm/fn_call.h
@@ -239,7 +239,7 @@ template<typename T>
 struct ThisIsNative
 {
     typedef T value_type;
-    value_type* operator()(as_object* o) const {
+    value_type* operator()(const as_object* o) const {
         return dynamic_cast<value_type*>(o->relay());
     }
 };
@@ -251,7 +251,7 @@ template<typename T = DisplayObject>
 struct IsDisplayObject
 {
     typedef T value_type;
-    value_type* operator()(as_object* o) const {
+    value_type* operator()(const as_object* o) const {
         if (!o) return 0;
         return dynamic_cast<T*>(o->displayObject());
     }

http://git.savannah.gnu.org/cgit//commit/?id=b7dad4b58f280b918c76674499853e8ef32bab1c


commit b7dad4b58f280b918c76674499853e8ef32bab1c
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Dec 10 18:24:54 2010 +0100

    Ensure that the this object is valid.

diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 1180e74..a184e7d 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -898,7 +898,7 @@ attachSoundInterface(as_object& o)
 as_value
 sound_new(const fn_call& fn)
 {
-    as_object* so = fn.this_ptr;
+    as_object* so = ensure<ValidThis>(fn);
     Sound_as* s(new Sound_as(so));
     so->setRelay(s);
 

-----------------------------------------------------------------------

Summary of changes:
 libbase/GnashAlgorithm.h      |    3 +-
 libcore/Relay.cpp             |    7 ++++-
 libcore/Relay.h               |   16 ++++++++++++++-
 libcore/as_object.h           |    3 +-
 libcore/asobj/Sound_as.cpp    |    2 +-
 libcore/movie_root.cpp        |   42 +++++++++++++++++++++++++++++++++-------
 libcore/swf/DefineTextTag.cpp |    4 +--
 libcore/vm/fn_call.h          |    4 +-
 8 files changed, 62 insertions(+), 19 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]