gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11599: Separate DisplayObject typin


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11599: Separate DisplayObject typing from as_object.
Date: Wed, 04 Nov 2009 18:29:00 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11599 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-11-04 18:29:00 +0100
message:
  Separate DisplayObject typing from as_object.
  
  Various other cleanups.
modified:
  gui/pythonmod/gnash-view.cpp
  libcore/Bitmap.cpp
  libcore/Bitmap.h
  libcore/BitmapMovie.cpp
  libcore/BitmapMovie.h
  libcore/Button.cpp
  libcore/Button.h
  libcore/DisplayList.cpp
  libcore/DisplayObject.cpp
  libcore/DisplayObject.h
  libcore/DisplayObjectContainer.h
  libcore/InteractiveObject.h
  libcore/MorphShape.cpp
  libcore/MorphShape.h
  libcore/Movie.h
  libcore/MovieClip.cpp
  libcore/MovieClip.h
  libcore/SWFMovie.cpp
  libcore/SWFMovie.h
  libcore/Shape.h
  libcore/StaticText.h
  libcore/TextField.cpp
  libcore/TextField.h
  libcore/Video.cpp
  libcore/Video.h
  libcore/as_environment.cpp
  libcore/as_object.cpp
  libcore/as_object.h
  libcore/as_value.cpp
  libcore/asobj/Color_as.cpp
  libcore/asobj/MovieClipLoader.cpp
  libcore/asobj/Selection_as.cpp
  libcore/asobj/flash/display/DisplayObjectContainer_as.cpp
  libcore/asobj/flash/display/MovieClip_as.cpp
  libcore/asobj/flash/display/MovieClip_as.h
  libcore/asobj/flash/geom/Transform_as.cpp
  libcore/movie_root.cpp
  libcore/parser/BitmapMovieDefinition.cpp
  libcore/parser/BitmapMovieDefinition.h
  libcore/parser/SWFMovieDefinition.cpp
  libcore/parser/SWFMovieDefinition.h
  libcore/parser/movie_definition.h
  libcore/parser/sprite_definition.cpp
  libcore/parser/sprite_definition.h
  libcore/swf/DefineButtonTag.cpp
  libcore/swf/DefineButtonTag.h
  libcore/swf/DefineEditTextTag.cpp
  libcore/swf/DefineEditTextTag.h
  libcore/swf/DefineMorphShapeTag.cpp
  libcore/swf/DefineMorphShapeTag.h
  libcore/swf/DefineShapeTag.cpp
  libcore/swf/DefineShapeTag.h
  libcore/swf/DefineTextTag.cpp
  libcore/swf/DefineTextTag.h
  libcore/swf/DefineVideoStreamTag.cpp
  libcore/swf/DefineVideoStreamTag.h
  libcore/swf/DefinitionTag.h
  libcore/swf/DoABCTag.h
  libcore/swf/ScriptLimitsTag.h
  libcore/swf/StartSoundTag.cpp
  libcore/swf/StreamSoundBlockTag.cpp
  libcore/swf/SymbolClassTag.h
  libcore/swf_function.cpp
  libcore/vm/ASHandlers.cpp
  libcore/vm/ActionExec.cpp
  libcore/vm/ExecutableCode.h
  libcore/vm/fn_call.h
  testsuite/DummyCharacter.h
  testsuite/DummyMovieDefinition.h
  testsuite/actionscript.all/TextField.as
  testsuite/as3compile.all/MovieClip.as
  testsuite/as3compile.all/Object.as
  testsuite/libcore.all/AsValueTest.cpp
  testsuite/libcore.all/DisplayListTest.cpp
  testsuite/misc-ming.all/DefineTextTest-Runner.cpp
  testsuite/misc-ming.all/DragDropTestRunner.cpp
  testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
  testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
  testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
  testsuite/misc-ming.all/attachMovieTestRunner.cpp
  testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
  testsuite/misc-ming.all/intervalTestRunner.cpp
  testsuite/misc-ming.all/loadMovieTestRunner.cpp
  testsuite/misc-swfc.all/button_test1runner.cpp
  testsuite/movies.all/gravity_embedded-TestRunner.cpp
=== modified file 'gui/pythonmod/gnash-view.cpp'
--- a/gui/pythonmod/gnash-view.cpp      2009-10-26 07:14:13 +0000
+++ b/gui/pythonmod/gnash-view.cpp      2009-11-04 17:29:00 +0000
@@ -68,7 +68,7 @@
     std::auto_ptr<gnash::RunResources> run_info;
 
     std::auto_ptr<gnash::movie_definition> movie_definition;
-    boost::intrusive_ptr<gnash::Movie> movie;
+    gnash::Movie* movie;
     std::auto_ptr<gnash::movie_root> stage;
     std::auto_ptr<gnash::SystemClock> system_clock;
     std::auto_ptr<gnash::InterruptableVirtualClock> virtual_clock;
@@ -111,17 +111,19 @@
     gnash::string_table& st = vm.getStringTable();
        gnash::as_value obj;
 
-    gnash::as_value func = view->movie->getMember(st.find(func_name));
+    gnash::as_value func = getObject(view->movie)->getMember(
+            st.find(func_name));
+
     if( !func.is_function() ) {
         return NULL;
     }
 
     gnash::as_value result;
     if( input_data ) {
-        result = view->movie->callMethod(st.find(func_name),
+        result = getObject(view->movie)->callMethod(st.find(func_name),
                                          gnash::as_value(input_data));
     } else {
-        result = view->movie->callMethod(st.find(func_name));
+        result = getObject(view->movie)->callMethod(st.find(func_name));
     }
     if( !result.is_string() ) {
         return NULL;
@@ -479,7 +481,7 @@
     gnash::URL::parse_querystring(url.querystring(), variables);
 
     gnash::Movie* m = view->stage->init(view->movie_definition.get(), 
variables);
-    view->movie.reset(m);
+    view->movie = m;
 
     view->stage->set_background_alpha(1.0f);
 

=== modified file 'libcore/Bitmap.cpp'
--- a/libcore/Bitmap.cpp        2009-10-12 09:42:13 +0000
+++ b/libcore/Bitmap.cpp        2009-11-04 15:03:15 +0000
@@ -28,9 +28,10 @@
 
 namespace gnash {
 
-Bitmap::Bitmap(BitmapData_as* bd, DisplayObject* parent)
+Bitmap::Bitmap(movie_root& mr, as_object* object, BitmapData_as* bd,
+        DisplayObject* parent)
     :
-    DisplayObject(parent),
+    DisplayObject(mr, object, parent),
     _bitmapData(bd),
     _bitmapInfo(0),
     _width(_bitmapData->getWidth()),
@@ -39,9 +40,10 @@
     _shape.setBounds(SWFRect(0, 0, pixelsToTwips(_width), 
pixelsToTwips(_height)));
 }
 
-Bitmap::Bitmap(const BitmapMovieDefinition* const def, DisplayObject* parent)
+Bitmap::Bitmap(movie_root& mr, as_object* object,
+        const BitmapMovieDefinition* def, DisplayObject* parent)
     :
-    DisplayObject(parent),
+    DisplayObject(mr, object, parent),
     _def(def),
     _bitmapData(0),
     _bitmapInfo(0),
@@ -127,7 +129,7 @@
         }
     }
 
-    Renderer* renderer = getRunResources(*this).renderer();
+    Renderer* renderer = stage().runResources().renderer();
     if (renderer) _bitmapInfo = renderer->createBitmapInfo(im);
 
 }

=== modified file 'libcore/Bitmap.h'
--- a/libcore/Bitmap.h  2009-10-12 09:42:13 +0000
+++ b/libcore/Bitmap.h  2009-11-04 15:03:15 +0000
@@ -45,9 +45,11 @@
 {
 public:
 
-       Bitmap(BitmapData_as* bd, DisplayObject* parent);
+       Bitmap(movie_root& mr, as_object* object, BitmapData_as* bd,
+            DisplayObject* parent);
        
-    Bitmap(const BitmapMovieDefinition* const def, DisplayObject* parent);
+    Bitmap(movie_root& mr, as_object* object, const BitmapMovieDefinition* def,
+            DisplayObject* parent);
 
     ~Bitmap();
 

=== modified file 'libcore/BitmapMovie.cpp'
--- a/libcore/BitmapMovie.cpp   2009-10-12 09:42:13 +0000
+++ b/libcore/BitmapMovie.cpp   2009-11-04 15:03:15 +0000
@@ -17,20 +17,22 @@
 
 #include "BitmapMovie.h"
 #include "BitmapMovieDefinition.h"
+#include "Bitmap.h"
 
 namespace gnash {
 
-BitmapMovie::BitmapMovie(const BitmapMovieDefinition* const def,
+BitmapMovie::BitmapMovie(as_object* object, const BitmapMovieDefinition* def,
         DisplayObject* parent)
        :
-       Movie(def, parent),
+       Movie(object, def, parent),
     _def(def)
 {
     assert(def);
-    boost::intrusive_ptr<DisplayObject> ch = def->createDisplayObject(this);
+    assert(object);
+    Bitmap* bm = new Bitmap(getRoot(*object), 0, def, this);
 
     const int depth = 1 + DisplayObject::staticDepthOffset;
-    placeDisplayObject(ch.get(), depth);
+    placeDisplayObject(bm, depth);
 }
 
 } // namespace gnash

=== modified file 'libcore/BitmapMovie.h'
--- a/libcore/BitmapMovie.h     2009-08-12 12:18:43 +0000
+++ b/libcore/BitmapMovie.h     2009-11-04 15:03:15 +0000
@@ -42,7 +42,8 @@
 
 public:
 
-       BitmapMovie(const BitmapMovieDefinition* const def, DisplayObject* 
parent); 
+       BitmapMovie(as_object* object, const BitmapMovieDefinition* def,
+            DisplayObject* parent); 
 
        virtual ~BitmapMovie() {}
     

=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp        2009-10-23 06:25:25 +0000
+++ b/libcore/Button.cpp        2009-11-04 18:08:14 +0000
@@ -225,22 +225,19 @@
 
 }
 
-// Forward declarations
-static as_object* getButtonInterface();
-
 namespace {
     void addInstanceProperty(Button& b, DisplayObject* d) {
         if (!d) return;
         const std::string& name = d->get_name();
         if (name.empty()) return;
-        b.init_member(name, d, 0);
+        getObject(&b)->init_member(name, getObject(d), 0);
     }
 
     void removeInstanceProperty(Button& b, DisplayObject* d) {
         if (!d) return;
         const std::string& name = d->get_name();
         if (name.empty()) return;
-        b.delProperty(getStringTable(b).find(name));
+        getObject(&b)->delProperty(getStringTable(*getObject(&b)).find(name));
     }
 }
 
@@ -290,27 +287,27 @@
 
 }
 
-Button::Button(const SWF::DefineButtonTag* const def, DisplayObject* parent)
+Button::Button(as_object* object, const SWF::DefineButtonTag* def,
+        DisplayObject* parent)
     :
-    InteractiveObject(parent),
+    InteractiveObject(object, parent),
     _lastMouseFlags(FLAG_IDLE),
     _mouseFlags(FLAG_IDLE),
     _mouseState(MOUSESTATE_UP),
     _def(def)
 {
-
-    set_prototype(getButtonInterface());
+    assert(object);
 
     // check up presence Key events
     if (_def->hasKeyPressHandler()) {
-        getRoot(*this).add_key_listener(this);
+        stage().add_key_listener(this);
     }
 
 }
 
 Button::~Button()
 {
-    getRoot(*this).remove_key_listener(this);
+    stage().remove_key_listener(this);
 }
 
 bool
@@ -318,8 +315,8 @@
 {
     // TODO: check whether the AS or the tag value takes precedence.
     as_value track;
-    string_table& st = getStringTable(*this);
-    if (get_member(st.find("trackAsMenu"), &track)) {
+    string_table& st = getStringTable(*getObject(this));
+    if (getObject(this)->get_member(st.find("trackAsMenu"), &track)) {
         return track.to_bool();
     }
     if (_def) return _def->trackAsMenu();
@@ -330,7 +327,7 @@
 Button::isEnabled()
 {
     as_value enabled;
-    if (!get_member(NSV::PROP_ENABLED, &enabled)) return false;
+    if (!getObject(this)->get_member(NSV::PROP_ENABLED, &enabled)) return 
false;
 
     return enabled.to_bool();
 }
@@ -356,7 +353,7 @@
     // We only respond to valid key code (should we assert here?)
     if ( id.keyCode() == key::INVALID ) return false;
 
-    ButtonActionPusher xec(getRoot(*this), this); 
+    ButtonActionPusher xec(stage(), this); 
     _def->forEachTrigger(id, xec);
 
     return xec.called;
@@ -501,7 +498,7 @@
         if (!_def->hasSound()) break;
 
         // Check if there is a sound handler
-        sound::sound_handler* s = getRunResources(*this).soundHandler();
+        sound::sound_handler* s = 
getRunResources(*getObject(this)).soundHandler();
         if (!s) break;
 
         int bi; // button sound array index [0..3]
@@ -567,7 +564,7 @@
     // the action queue on mouse event.
     //
 
-    movie_root& mr = getRoot(*this);
+    movie_root& mr = stage();
 
     ButtonActionPusher xec(mr, this); 
     _def->forEachTrigger(event, xec);
@@ -802,7 +799,7 @@
     if (initObj) {
         log_unimpl("Button placed with an initObj. How did this happen? "
                 "We'll copy the properties anyway");
-        copyProperties(*initObj);
+        getObject(this)->copyProperties(*initObj);
     }
 
     saveOriginalTarget(); // for soft refs
@@ -851,9 +848,8 @@
 
 #ifdef GNASH_USE_GC
 void
-Button::markReachableResources() const
+Button::markOwnResources() const
 {
-    assert(isReachable());
 
     _def->setReachable();
 
@@ -867,10 +863,8 @@
 
     // Mark hit DisplayObjects as reachable
     std::for_each(_hitCharacters.begin(), _hitCharacters.end(),
-            std::mem_fun(&as_object::setReachable));
+            std::mem_fun(&DisplayObject::setReachable));
 
-    // DisplayObject class members
-    markDisplayObjectReachable();
 }
 #endif // GNASH_USE_GC
 
@@ -931,22 +925,8 @@
     return _def->getSWFVersion();
 }
 
-static as_object*
-getButtonInterface()
-{
-  static boost::intrusive_ptr<as_object> proto;
-  if ( proto == NULL )
-  {
-    proto = new as_object(getObjectInterface());
-    VM::get().addStatic(proto.get());
-
-    attachButtonInterface(*proto);
-  }
-  return proto.get();
-}
-
 static as_value
-button_ctor(const fn_call& /* fn */)
+button_ctor(const fn_call& /*fn*/)
 {
     return as_value();
 }
@@ -956,8 +936,9 @@
 {
     // This is going to be the global Button "class"/"function"
     Global_as& gl = getGlobal(global);
-    as_object* proto = getButtonInterface();
+    as_object* proto = gl.createObject();
     as_object* cl = gl.createClass(&button_ctor, proto);
+    attachButtonInterface(*proto);
 
     // Register _global.MovieClip
     global.init_member(getName(uri), cl, as_object::DefaultFlags,
@@ -1023,7 +1004,7 @@
 as_value
 button_blendMode(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1031,7 +1012,7 @@
 as_value
 button_cacheAsBitmap(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1039,7 +1020,7 @@
 as_value
 button_filters(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1047,7 +1028,7 @@
 as_value
 button_scale9Grid(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1055,7 +1036,7 @@
 as_value
 button_getTabIndex(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1063,7 +1044,7 @@
 as_value
 button_setTabIndex(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }
@@ -1071,7 +1052,7 @@
 as_value
 button_getDepth(const fn_call& fn)
 {
-    as_object* obj = ensure<ThisIs<Button> >(fn);
+    Button* obj = ensure<IsDisplayObject<Button> >(fn);
     UNUSED(obj);
     return as_value();
 }

=== modified file 'libcore/Button.h'
--- a/libcore/Button.h  2009-10-12 09:42:13 +0000
+++ b/libcore/Button.h  2009-11-04 15:03:15 +0000
@@ -70,7 +70,11 @@
                MOUSESTATE_HIT
        };
 
-       Button(const SWF::DefineButtonTag* const def, DisplayObject* parent);
+    /// Construct a Button
+    //
+    /// A button should always have an associated object.
+       Button(as_object* object, const SWF::DefineButtonTag* def,
+            DisplayObject* parent);
 
        ~Button();
        
@@ -96,11 +100,6 @@
        virtual InteractiveObject* topmostMouseEntity(boost::int32_t x,
             boost::int32_t y);
        
-       virtual bool wantsInstanceName() const
-       {
-               return true; // buttons can be referenced 
-       }
-       
        virtual void mouseEvent(const event_id& event);
 
     virtual bool handleFocus();
@@ -145,7 +144,7 @@
        ///     - the vector of state DisplayObjects (_stateCharacters)
        ///     - the vector of hit DisplayObjects (_hitCharacters)
        ///
-       void markReachableResources() const;
+       void markOwnResources() const;
 #endif // GNASH_USE_GC
 
 private:

=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp   2009-10-26 10:12:17 +0000
+++ b/libcore/DisplayList.cpp   2009-11-04 13:37:17 +0000
@@ -945,7 +945,7 @@
                     (chOld->get_ratio() == chNew->get_ratio());
 
                 if (!is_ratio_compatible || chOld->isDynamic() ||
-                        !chOld->isActionScriptReferenceable()) {
+                        !isReferenceable(*chOld)) {
                     // replace the DisplayObject in old list with
                     // corresponding DisplayObject in new list
                     _charsByDepth.insert(itOldBackup, *itNewBackup);

=== modified file 'libcore/DisplayObject.cpp'
--- a/libcore/DisplayObject.cpp 2009-10-26 10:12:17 +0000
+++ b/libcore/DisplayObject.cpp 2009-11-04 15:03:15 +0000
@@ -77,11 +77,14 @@
 const int DisplayObject::removedDepthOffset;
 const int DisplayObject::noClipDepthValue;
 
-DisplayObject::DisplayObject(DisplayObject* parent)
+DisplayObject::DisplayObject(movie_root& mr, as_object* object,
+        DisplayObject* parent)
     :
     _parent(parent),
     m_invalidated(true),
     m_child_invalidated(true),
+    _object(object),
+    _stage(mr),
     m_depth(0),
     _xscale(100),
     _yscale(100),
@@ -101,13 +104,20 @@
     assert(m_old_invalidated_ranges.isNull());
 
     // This informs the core that the object is a DisplayObject.
-    setDisplayObject();
+    if (_object) _object->setDisplayObject(this);
+}
+
+as_object*
+DisplayObject::object() const
+{
+    return _object;
 }
 
 std::string
 DisplayObject::getNextUnnamedInstanceName()
 {
-    movie_root& mr = getRoot(*this);
+    assert(_object);
+    movie_root& mr = getRoot(*_object);
        std::ostringstream ss;
        ss << "instance" << mr.nextUnnamedInstance();
        return ss.str();
@@ -153,11 +163,14 @@
 
 
 as_object*
-DisplayObject::get_path_element(string_table::key key)
+DisplayObject::pathElement(string_table::key key)
 {
-       string_table& st = getStringTable(*this);
-    if (key == st.find("..")) return get_parent();
-       if (key == st.find(".") || key == st.find("this")) return this;
+    as_object* obj = getObject(this);
+    if (!obj) return 0;
+
+       string_table& st = getStringTable(*obj);
+    if (key == st.find("..")) return getObject(get_parent());
+       if (key == st.find(".") || key == st.find("this")) return obj;
        return 0;
 }
 
@@ -242,7 +255,7 @@
 as_value
 DisplayObject::blendMode(const fn_call& fn)
 {
-    DisplayObject* ch = ensure<ThisIs<DisplayObject> >(fn);
+    DisplayObject* ch = ensure<IsDisplayObject<> >(fn);
 
     // This is AS-correct, but doesn't do anything.
     // TODO: implement in the renderers!
@@ -316,7 +329,8 @@
     // Remove focus from this DisplayObject if it changes from visible to
     // invisible (see Selection.as).
     if (_visible && !visible) {
-        movie_root& mr = getRoot(*this);
+        assert(_object);
+        movie_root& mr = getRoot(*_object);
         if (mr.getFocus() == this) {
             mr.setFocus(0);
         }
@@ -474,8 +488,9 @@
 void
 DisplayObject::queueEvent(const event_id& id, int lvl)
 {
-
-       movie_root& root = getRoot(*this);
+    if (!_object) return;
+    assert(_object);
+       movie_root& root = getRoot(*_object);
        std::auto_ptr<ExecutableCode> event(new QueuedEvent(this, id));
        root.pushAction(event, lvl);
 }
@@ -493,19 +508,19 @@
 as_function*
 DisplayObject::getUserDefinedEventHandler(const std::string& name) const
 {
-       string_table::key key = getStringTable(*this).find(name);
+    if (!_object) return 0;
+       string_table::key key = getStringTable(*_object).find(name);
        return getUserDefinedEventHandler(key);
 }
 
 as_function*
 DisplayObject::getUserDefinedEventHandler(string_table::key key) const 
 {
+    if (!_object) return 0;
+
        as_value tmp;
 
-       // const cast is needed due to getter/setter members possibly
-       // modifying this object even when only get !
-       if (const_cast<DisplayObject*>(this)->get_member(key, &tmp))
-       {
+       if (_object->get_member(key, &tmp)) {
                return tmp.to_as_function();
        }
        return 0;
@@ -630,7 +645,7 @@
        assert(topLevel);
 
        if (path.empty()) {
-               if (&getRoot(*this).getRootMovie() == this) return "/";
+               if (&getRoot(*_object).getRootMovie() == this) return "/";
                std::stringstream ss;
                ss << "_level" << m_depth-DisplayObject::staticDepthOffset;
                return ss.str();
@@ -638,7 +653,7 @@
 
        // Build the target string from the parents stack
        std::string target;
-       if (topLevel != &getRoot(*this).getRootMovie()) {
+       if (topLevel != &getRoot(*_object).getRootMovie()) {
                std::stringstream ss;
                ss << "_level" << 
             topLevel->get_depth() - DisplayObject::staticDepthOffset;
@@ -729,19 +744,20 @@
     /// see new_child_in_unload_test.c)
        /// We don't destroy ourself twice, right ?
 
-    clearProperties();
+    if (_object) _object->clearProperties();
 
        assert(!_destroyed);
        _destroyed = true;
 }
 
 void
-DisplayObject::markDisplayObjectReachable() const
+DisplayObject::markReachableResources() const
 {
-       if ( _parent ) _parent->setReachable();
+    markOwnResources();
+    if (_object) _object->setReachable();
+       if (_parent) _parent->setReachable();
        if (_mask) _mask->setReachable();
        if (_maskee) _maskee->setReachable();
-       markAsObjectReachable();
 }
 
 void
@@ -918,16 +934,16 @@
         as_value& val)
 {
     
-    string_table& st = getStringTable(obj);
+    string_table& st = getStringTable(*getObject(&obj));
     const std::string& propname = st.value(key);
 
     // Check _level0.._level9
-    movie_root& mr = getRoot(obj);
+    movie_root& mr = getRoot(*getObject(&obj));
     unsigned int levelno;
     if (mr.isLevelTarget(propname, levelno)) {
         Movie* mo = mr.getLevel(levelno);
         if (mo) {
-            val = mo;
+            val = getObject(mo);
             return true;
         }
         return false;
@@ -937,7 +953,7 @@
     if (mc) {
         DisplayObject* ch = mc->getDisplayListObject(key);
         if (ch) {
-           val = ch;
+           val = getObject(ch);
            return true;
         }
     }
@@ -950,12 +966,14 @@
         default:
             break;
         case NSV::PROP_uROOT:
-            if (getSWFVersion(obj) < 5) break;
-            val = obj.getAsRoot();
+            if (getSWFVersion(*getObject(&obj)) < 5) break;
+            val = getObject(obj.getAsRoot());
             return true;
         case NSV::PROP_uGLOBAL:
-            if (getSWFVersion(obj) < 6) break;
-            val = &getGlobal(obj);
+            // TODO: clean up this mess.
+            assert(getObject(&obj));
+            if (getSWFVersion(*getObject(&obj)) < 6) break;
+            val = &getGlobal(*getObject(&obj));
             return true;
     }
 
@@ -977,7 +995,7 @@
         const as_value& val)
 {
     // These magic properties are case insensitive in all versions!
-    string_table& st = getStringTable(obj);
+    string_table& st = getStringTable(*getObject(&obj));
     const std::string& propname = st.value(key);
     const string_table::key noCaseKey = 
st.find(boost::to_lower_copy(propname));
     return doSet(noCaseKey, obj, val);
@@ -988,7 +1006,7 @@
 as_value
 getQuality(DisplayObject& o)
 {
-    movie_root& mr = getRoot(o);
+    movie_root& mr = getRoot(*getObject(&o));
     switch (mr.getQuality())
     {
         case QUALITY_BEST:
@@ -1008,7 +1026,7 @@
 void
 setQuality(DisplayObject& o, const as_value& val)
 {
-    movie_root& mr = getRoot(o);
+    movie_root& mr = getRoot(*getObject(&o));
 
     if (!val.is_string()) return;
 
@@ -1039,7 +1057,7 @@
 as_value
 getHighQuality(DisplayObject& o)
 {
-    movie_root& mr = getRoot(o);
+    movie_root& mr = getRoot(*getObject(&o));
     switch (mr.getQuality())
     {
         case QUALITY_BEST:
@@ -1056,7 +1074,7 @@
 void
 setHighQuality(DisplayObject& o, const as_value& val)
 {
-    movie_root& mr = getRoot(o);
+    movie_root& mr = getRoot(*getObject(&o));
 
     const double q = val.to_number();
 
@@ -1275,7 +1293,7 @@
 {
        // Local coord of mouse IN PIXELS.
        boost::int32_t x, y, buttons;
-       getRoot(o).get_mouse_state(x, y, buttons);
+       getRoot(*getObject(&o)).get_mouse_state(x, y, buttons);
 
        SWFMatrix m = o.getWorldMatrix();
     point a(pixelsToTwips(x), pixelsToTwips(y));
@@ -1289,7 +1307,7 @@
 {
        // Local coord of mouse IN PIXELS.
        boost::int32_t x, y, buttons;
-       getRoot(o).get_mouse_state(x, y, buttons);
+       getRoot(*getObject(&o)).get_mouse_state(x, y, buttons);
 
        SWFMatrix m = o.getWorldMatrix();
     point a(pixelsToTwips(x), pixelsToTwips(y));
@@ -1328,7 +1346,7 @@
 as_value
 getParent(DisplayObject& o)
 {
-    as_object* p = o.get_parent();
+    as_object* p = getObject(o.get_parent());
     return p ? p : as_value();
 }
 
@@ -1342,7 +1360,7 @@
 getNameProperty(DisplayObject& o)
 {
     const std::string& name = o.get_name();
-    if (getSWFVersion(o) < 6 && name.empty()) return as_value(); 
+    if (getSWFVersion(*getObject(&o)) < 6 && name.empty()) return as_value(); 
     return as_value(name);
 }
 

=== modified file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h   2009-10-26 10:12:17 +0000
+++ b/libcore/DisplayObject.h   2009-11-04 15:03:15 +0000
@@ -60,6 +60,11 @@
 
 namespace gnash {
 
+/// Returns true if the DisplayObject is referenceable in ActionScript
+//
+/// A DisplayObject is referenceable if it has an associated object.
+bool isReferenceable(DisplayObject& d);
+
 /// Attaches common DisplayObject properties such as _height, _x, _visible
 //
 /// This should be called by DisplayObject subclasses to ensure that
@@ -92,7 +97,13 @@
 /// DisplayObject is the base class for all DisplayList objects.
 //
 /// It represents a single active element in a movie. This class does not
-/// provide any interactivity.
+/// supply any interactivity. The hierarchy of DisplayObjects in a movie
+/// provides all visual elements in a SWF. The DisplayObject hierarchy
+/// is independent of ActionScript resources, but can be controlled via AS.
+//
+/// DisplayObjects that can be controlled through ActionScript have an
+/// associated as_object. DisplayObjects such as Shape, do not have an
+/// associated object and cannot be referenced in AS.
 //
 /// Derived classes include InteractiveObject, StaticText, Bitmap,
 /// Video, and Shape.
@@ -109,11 +120,21 @@
 /// dynamic DisplayObjects, but tags are not always stored. They are not
 /// stored in most InteractiveObjects because most properties can be
 /// overridden during SWF execution.
-class DisplayObject : public as_object, boost::noncopyable
+class DisplayObject : public GcResource, boost::noncopyable
 {
 public:
 
-    DisplayObject(DisplayObject* parent);
+    /// Construct a DisplayObject
+    //
+    /// @param mr       The movie_root containing the DisplayObject hierarchy.
+    ///                 All DisplayObjects may need movie_root resources.
+    /// @param object   An object to be associated with this DisplayObject.
+    ///                 If this is non-null, the DisplayObject will be
+    ///                 referenceable in ActionScript. Referenceable
+    ///                 DisplayObjects may access AS resources through their
+    ///                 associated object.
+    /// @param parent   The parent of the new DisplayObject. This may be null.
+    DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
 
     virtual ~DisplayObject() {}
 
@@ -187,6 +208,16 @@
         return _parent->get_environment();
     }
 
+    /// Enumerate any non-proper properties
+    //
+    /// This function is called by enumerateProperties(as_environment&) 
+    /// to allow for enumeration of properties that are derived from the
+    /// DisplayObject type, e.g. DisplayList members.
+    ///
+    /// The default implementation adds nothing
+    ///
+    virtual void enumerateNonProperties(as_environment&) const {}
+
     /// \brief
     /// Return the parent of this DisplayObject, or NULL if
     /// the DisplayObject has no parent.
@@ -204,6 +235,8 @@
         _parent = parent;
     }
 
+    virtual MovieClip* to_movie() { return 0; }
+
     int get_depth() const { return m_depth; }
 
     void  set_depth(int d) { m_depth = d; }
@@ -540,7 +573,7 @@
     /// In ActionScript 1.0, everything seems to be CASE
     /// INSENSITIVE.
     ///
-    virtual as_object* get_path_element(string_table::key key);
+    virtual as_object* pathElement(string_table::key key);
 
     /// Advance this DisplayObject to next frame.
     //
@@ -665,26 +698,10 @@
         return 0;
     }
 
-    /// Returns true when the object (type) should get a instance name even 
-    /// if none is provided manually.
-    virtual bool wantsInstanceName() const
-    {
-        return false; 
-    }
-
-    /// Returns true when the object (type) can be referenced by ActionScipt
-    bool isActionScriptReferenceable() const
-    {
-        // The way around
-        // [ wantsInstanceName() returning isActionScriptReferenceable() ]
-        // would be cleaner, but I wouldn't want to touch all files now.
-        return wantsInstanceName();
-    }
-
     /// Returns the closest as-referenceable ancestor
     DisplayObject* getClosestASReferenceableAncestor() 
     {
-        if ( isActionScriptReferenceable() ) return this;
+        if (isReferenceable(*this)) return this;
         assert(_parent);
         return _parent->getClosestASReferenceableAncestor();
     }
@@ -956,11 +973,30 @@
         return _yscale;
     }
 
+    as_object* object() const;
+
     /// Getter-setter for blendMode.
     static as_value blendMode(const fn_call& fn);
   
+    /// Mark all reachable resources.
+    //
+    /// Try not to override this function in derived classes. This always
+    /// marks the base class's resources and calls markOwnResources() to
+    /// take care of any further GC resources.
+    virtual void markReachableResources() const;
+
+    /// Called by markReachableResources()
+    //
+    /// DisplayObjects should mark their own resources in this function.
+    virtual void markOwnResources() const {}
+
 protected:
 
+    /// Get the movie_root to which this DisplayObject belongs.
+    movie_root& stage() {
+        return _stage;
+    }
+
     /// Register currently computable target as
     /// the "original" one. This will be used by
     /// soft references (as_value) and should be
@@ -972,27 +1008,6 @@
         _origTarget=getTarget();
     }
 
-#ifdef GNASH_USE_GC
-    /// Mark all reachable resources, override from as_object.
-    //
-    /// The default implementation calls markDisplayObjectReachable().
-    ///
-    /// If a derived class provides access to more GC-managed
-    /// resources, it should override this method and call 
-    /// markDisplayObjectReachableResources() as the last step.
-    ///
-    virtual void markReachableResources() const
-    {
-        markDisplayObjectReachable();
-    }
-
-    /// Mark DisplayObject-specific reachable resources
-    //
-    /// These are: the DisplayObject's parent, mask, maskee and the default
-    ///                         as_object reachable stuff.
-    ///
-    void markDisplayObjectReachable() const;
-#endif // GNASH_USE_GC
 
     const Events& get_event_handlers() const
     {
@@ -1067,7 +1082,6 @@
     /// Will be set by set_invalidated() and used by
     /// get_invalidated_bounds().
     InvalidatedRanges m_old_invalidated_ranges;
-    
 
 private:
 
@@ -1077,6 +1091,12 @@
     /// Build the _target member recursive on parent
     std::string computeTargetPath() const;
 
+    /// The as_object to which this DisplayObject is attached.
+    as_object* _object;
+
+    /// The movie_root to which this DisplayObject belongs.
+    movie_root& _stage;
+
     int m_depth;
     cxform m_color_transform;
     SWFMatrix m_matrix;
@@ -1132,6 +1152,23 @@
 
 };
 
+inline bool
+isReferenceable(DisplayObject& d)
+{
+    return d.object();
+}
+
+/// Return the as_object associated with a DisplayObject if it exists
+//
+/// @param d    The DisplayObject to check. May be null.
+/// @return     null if either the DisplayObject or the associated object is
+///             null. Otherwise the associated object.
+inline as_object*
+getObject(DisplayObject* d)
+{
+    return d ? d->object() : 0;
+}
+
 /// Stream operator for DisplayObject blend mode.
 std::ostream&
 operator<<(std::ostream& o, DisplayObject::BlendMode bm);

=== modified file 'libcore/DisplayObjectContainer.h'
--- a/libcore/DisplayObjectContainer.h  2009-10-12 09:42:13 +0000
+++ b/libcore/DisplayObjectContainer.h  2009-11-04 15:03:15 +0000
@@ -48,10 +48,12 @@
 
 public:
     
-    DisplayObjectContainer(DisplayObject* parent)
+    DisplayObjectContainer(as_object* object, DisplayObject* parent)
         :
-        InteractiveObject(parent)
-    {}
+        InteractiveObject(object, parent)
+    {
+        assert(object);
+    }
 
     virtual ~DisplayObjectContainer();
 

=== modified file 'libcore/InteractiveObject.h'
--- a/libcore/InteractiveObject.h       2009-10-12 09:42:13 +0000
+++ b/libcore/InteractiveObject.h       2009-11-04 15:03:15 +0000
@@ -43,10 +43,14 @@
 
 public:
 
-       InteractiveObject(DisplayObject* parent)
+       InteractiveObject(as_object* object, DisplayObject* parent)
                :
-               DisplayObject(parent)
+               DisplayObject(getRoot(*object), object, parent)
        {
+        // It's a bit too late for this assertion as we've already
+        // deferenced it. All InteractiveObjects are AS-referenceable,
+        // so they must have an object.
+        assert(object);
        }
 
     virtual ~InteractiveObject() {}

=== modified file 'libcore/MorphShape.cpp'
--- a/libcore/MorphShape.cpp    2009-10-12 09:42:13 +0000
+++ b/libcore/MorphShape.cpp    2009-11-04 15:03:15 +0000
@@ -27,10 +27,10 @@
 {
 
 
-MorphShape::MorphShape(const SWF::DefineMorphShapeTag* const def,
-        DisplayObject* parent)
+MorphShape::MorphShape(movie_root& mr, as_object* object,
+        const SWF::DefineMorphShapeTag* def, DisplayObject* parent)
     :
-    DisplayObject(parent),
+    DisplayObject(mr, object, parent),
     _def(def),
     _shape(_def->shape1())
 {

=== modified file 'libcore/MorphShape.h'
--- a/libcore/MorphShape.h      2009-10-12 09:42:13 +0000
+++ b/libcore/MorphShape.h      2009-11-04 15:03:15 +0000
@@ -50,8 +50,8 @@
 
 public:
 
-    MorphShape(const SWF::DefineMorphShapeTag* const def, 
-            DisplayObject* parent);
+    MorphShape(movie_root& mr, as_object* object,
+            const SWF::DefineMorphShapeTag* def, DisplayObject* parent);
 
        virtual void display(Renderer& renderer);
 
@@ -69,9 +69,7 @@
        /// Mark reachable resources (for the GC)
        void markReachableResources() const
        {
-               assert(isReachable());
         _def->setReachable();
-               markDisplayObjectReachable();
        }
 #endif
 

=== modified file 'libcore/Movie.h'
--- a/libcore/Movie.h   2009-10-12 09:42:13 +0000
+++ b/libcore/Movie.h   2009-11-04 15:03:15 +0000
@@ -49,9 +49,10 @@
 
 public:
 
-       Movie(const movie_definition* const def, DisplayObject* parent)
+       Movie(as_object* object, const movie_definition* def,
+            DisplayObject* parent)
         :
-        MovieClip(def, this, parent)
+        MovieClip(object, def, this, parent)
     {}
 
        virtual ~Movie() {}

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-10-28 09:14:04 +0000
+++ b/libcore/MovieClip.cpp     2009-11-04 20:39:35 +0000
@@ -28,7 +28,6 @@
 #include "movie_definition.h"
 #include "as_value.h"
 #include "as_function.h"
-#include "Bitmap.h"
 #include "TextField.h"
 #include "ControlTag.h"
 #include "fn_call.h"
@@ -55,7 +54,6 @@
 #include "namedStrings.h"
 #include "styles.h" // for cap_style_e and join_style_e enums
 #include "PlaceObject2Tag.h" 
-#include "flash/display/BitmapData_as.h"
 #include "flash/geom/Matrix_as.h"
 #include "ExportableResource.h"
 #include "GnashNumeric.h"
@@ -414,31 +412,28 @@
 } // anonymous namespace
 
 
-MovieClip::MovieClip(const movie_definition* const def, Movie* r,
-        DisplayObject* parent)
+MovieClip::MovieClip(as_object* object, const movie_definition* def,
+        Movie* r, DisplayObject* parent)
     :
-    DisplayObjectContainer(parent),
+    DisplayObjectContainer(object, parent),
     _def(def),
     _swf(r),
     _playState(PLAYSTATE_PLAY),
     _currentFrame(0),
     _hasLooped(false),
     _callingFrameActions(false),
-    _environment(getVM(*this)),
+    _environment(getVM(*object)),
     m_sound_stream_id(-1),
     _droptarget(),
     _lockroot(false)
 {
     assert(_swf);
-
-    if (!isAS3(getVM(*this))) {
-        set_prototype(getMovieClipAS2Interface());
-        attachMovieClipAS2Properties(*this);
-    }
-    else {
-        set_prototype(getMovieClipAS3Interface());
-    }
-            
+    assert(object);
+
+    if (!isAS3(getVM(*object)) && !get_parent()) {
+        object->init_member("$version", getVM(*object).getPlayerVersion(), 0); 
+    }
+
     _environment.set_target(this);
 
 }
@@ -447,8 +442,8 @@
 {
     stopStreamSound();
 
-    getRoot(*this).remove_key_listener(this);
-    getRoot(*this).remove_mouse_listener(this);
+    stage().remove_key_listener(this);
+    stage().remove_mouse_listener(this);
 
     deleteAllChecked(_loadVariableRequests);
 }
@@ -498,7 +493,7 @@
 MovieClip::getTextFieldVariables(string_table::key name_key, as_value& val)
 {
 
-    const std::string& name = getStringTable(*this).value(name_key);
+    const std::string& name = getStringTable(*getObject(this)).value(name_key);
 
     // Try textfield variables
     TextFields* etc = get_textfield_variable(name);
@@ -623,7 +618,10 @@
         return NULL;
     }
 
-    MovieClip* newmovieclip = new MovieClip(_def.get(), _swf, parent);
+    as_object* o = getObjectWithPrototype(getGlobal(*getObject(this)), 
+            NSV::CLASS_MOVIE_CLIP);
+
+    MovieClip* newmovieclip = new MovieClip(o, _def.get(), _swf, parent);
     newmovieclip->set_name(newname);
 
     newmovieclip->setDynamic();
@@ -650,8 +648,7 @@
 void
 MovieClip::queueAction(const action_buffer& action)
 {
-    movie_root& root = getRoot(*this);
-    root.pushAction(action, this);
+    stage().pushAction(action, this);
 }
 
 void
@@ -768,7 +765,7 @@
 
         if ( method )
         {
-            call_method0(as_value(method.get()), _environment, this);
+            call_method0(method.get(), _environment, getObject(this));
             called = true;
         }
     }
@@ -782,33 +779,35 @@
 }
 
 as_object*
-MovieClip::get_path_element(string_table::key key)
+MovieClip::pathElement(string_table::key key)
 {
-    as_object* obj = DisplayObject::get_path_element(key);
+    as_object* obj = DisplayObject::pathElement(key);
     if (obj) return obj;
 
     // See if we have a match on the display list.
-    DisplayObject* ch = getDisplayListObject(key);
-    if (ch) return ch;
-
-    std::string name = getStringTable(*this).value(key);
-    
+    obj = getObject(getDisplayListObject(key));
+    if (obj) return obj;
+
+    std::string name = getStringTable(*getObject(this)).value(key);
+ 
+    obj = getObject(this);
+
+    assert(obj);
+
     // See if it's a member
     as_value tmp;
-    if ( !as_object::get_member(key, &tmp, 0) )
-    {
-        return NULL;
-    }
-    if ( ! tmp.is_object() )
-    {
-        return NULL;
-    }
-    if ( tmp.is_sprite() )
-    {
-        return tmp.toDisplayObject(true);
+    if (!obj->as_object::get_member(key, &tmp, 0)) {
+        return NULL;
+    }
+    if (!tmp.is_object()) {
+        return NULL;
+    }
+    if (tmp.is_sprite())
+    {
+        return getObject(tmp.toDisplayObject(true));
     }
 
-    return tmp.to_object(getGlobal(*this));
+    return tmp.to_object(getGlobal(*getObject(this)));
 }
 
 bool
@@ -827,7 +826,7 @@
     //                property (ie: have a textfield use _x as variable name 
and
     //                be scared)
     //
-    TextFields* etc = 
get_textfield_variable(getStringTable(*this).value(name));
+    TextFields* etc = 
get_textfield_variable(getStringTable(*getObject(this)).value(name));
     if ( etc )
     {
 #ifdef DEBUG_DYNTEXT_VARIABLES
@@ -961,8 +960,7 @@
 #endif
         std::auto_ptr<ExecutableCode> code(new GlobalCode(a, this));
 
-        movie_root& root = getRoot(*this);
-        root.pushAction(code, movie_root::apINIT);
+        stage().pushAction(code, movie_root::apINIT);
     }
     else
     {
@@ -1246,13 +1244,6 @@
     return std::auto_ptr<GnashImage>();
 }
 
-void
-MovieClip::attachBitmap(BitmapData_as* bd, int depth)
-{
-    DisplayObject* ch = new Bitmap(bd, this);
-    attachCharacter(*ch, depth, 0);
-}
-
 DisplayObject*
 MovieClip::add_display_object(const SWF::PlaceObject2Tag* tag,
         DisplayList& dlist)
@@ -1277,10 +1268,11 @@
     
     if (existing_char) return NULL;
 
-    DisplayObject* ch = cdef->createDisplayObject(this);
+    Global_as& gl = getGlobal(*getObject(this));
+    DisplayObject* ch = cdef->createDisplayObject(gl, this);
 
     if (tag->hasName()) ch->set_name(tag->getName());
-    else if (ch->wantsInstanceName())
+    else if (isReferenceable(*ch))
     {
         std::string instance_name = getNextUnnamedInstanceName();
         ch->set_name(instance_name);
@@ -1350,19 +1342,20 @@
 
     // if the existing DisplayObject is not a shape, move it instead
     // of replacing.
-    if (existing_char->isActionScriptReferenceable()) {
+    if (isReferenceable(*existing_char)) {
         move_display_object(tag, dlist);
         return;
     }
 
-    DisplayObject* ch = cdef->createDisplayObject(this);
+    Global_as& gl = getGlobal(*getObject(this));
+    DisplayObject* ch = cdef->createDisplayObject(gl, this);
 
     // TODO: check if we can drop this for REPLACE!
     // should we rename the DisplayObject when it's REPLACE tag?
     if(tag->hasName()) {
         ch->set_name(tag->getName());
     }
-    else if (ch->wantsInstanceName()) {
+    else if (isReferenceable(*ch)) {
         std::string instance_name = getNextUnnamedInstanceName();
         ch->set_name(instance_name);
     }
@@ -1421,9 +1414,9 @@
 
     // For SWF6 and above: the MovieClip can always receive focus if
     // focusEnabled evaluates to true.
-    if (getSWFVersion(*this) > 5) {
+    if (getSWFVersion(*getObject(this)) > 5) {
         as_value focusEnabled;
-        if (get_member(NSV::PROP_FOCUS_ENABLED, &focusEnabled)) {
+        if (getObject(this)->get_member(NSV::PROP_FOCUS_ENABLED, 
&focusEnabled)) {
             if (focusEnabled.to_bool() == true) return true; 
         }
     }
@@ -1677,8 +1670,8 @@
 MovieClip::trackAsMenu()
 {
     as_value track;
-    string_table& st = getStringTable(*this);
-    return (get_member(st.find("trackAsMenu"), &track) && track.to_bool());
+    string_table& st = getStringTable(*getObject(this));
+    return (getObject(this)->get_member(st.find("trackAsMenu"), &track) && 
track.to_bool());
 }
 
 bool
@@ -1723,13 +1716,13 @@
 void
 MovieClip::stop_drag()
 {
-    getRoot(*this).stop_drag();
+    stage().stop_drag();
 }
 
 void
 MovieClip::set_background_color(const rgba& color)
 {
-    getRoot(*this).set_background_color(color);
+    stage().set_background_color(color);
 }
 
 void
@@ -1781,11 +1774,11 @@
 MovieClip::getDisplayListObject(string_table::key key)
 {
 
-    const std::string& name = getStringTable(*this).value(key);
+    const std::string& name = getStringTable(*getObject(this)).value(key);
 
     // Try items on our display list.
     DisplayObject* ch;
-    if (getSWFVersion(*this) >= 7 ) {
+    if (getSWFVersion(*getObject(this)) >= 7 ) {
         ch = _displayList.getDisplayObjectByName(name);
     }
     else ch = _displayList.getDisplayObjectByName_i(name);
@@ -1795,7 +1788,7 @@
 
     // If the object is an ActionScript referenciable one we
     // return it, otherwise we return ourselves
-    if (ch->isActionScriptReferenceable()) {
+    if (isReferenceable(*ch)) {
         return ch;
     }
     return this;
@@ -1842,8 +1835,8 @@
 void
 MovieClip::registerAsListener()
 {
-    getRoot(*this).add_key_listener(this);
-    getRoot(*this).add_mouse_listener(this);
+    stage().add_key_listener(this);
+    stage().add_mouse_listener(this);
 }
 
 
@@ -1863,7 +1856,7 @@
 #endif
 
     // Register this movieclip as a live one
-    getRoot(*this).addLiveChar(this);
+    stage().addLiveChar(this);
   
 
     // Register this movieclip as a core broadcasters listener
@@ -1888,7 +1881,7 @@
         executeFrameTags(0, _displayList, SWF::ControlTag::TAG_DLIST |
                 SWF::ControlTag::TAG_ACTION);
 
-        if (getSWFVersion(*this) > 5)
+        if (getSWFVersion(*getObject(this)) > 5)
         {
 #ifdef GNASH_DEBUG
             log_debug(_("Queuing ONLOAD event for movieclip %s"), getTarget());
@@ -1931,7 +1924,7 @@
         queueEvent(event_id::INITIALIZE, movie_root::apINIT);
 
         std::auto_ptr<ExecutableCode> code(new ConstructEvent(this));
-        getRoot(*this).pushAction(code, movie_root::apCONSTRUCT);
+        stage().pushAction(code, movie_root::apCONSTRUCT);
 
     }
     else {
@@ -1940,7 +1933,7 @@
         // after the display list has been populated, so that _height and
         // _width (which depend on bounds) are correct.
         if (initObj) {
-            copyProperties(*initObj);
+            getObject(this)->copyProperties(*initObj);
         }
 
         constructAsScriptObject(); 
@@ -1996,14 +1989,14 @@
         {
             // Set the new prototype *after* the constructor was called
             boost::intrusive_ptr<as_object> proto = ctor->getPrototype();
-            set_prototype(proto);
+            getObject(this)->set_prototype(proto);
 
             // Call event handlers *after* setting up the __proto__
             // but *before* calling the registered class constructor
             notifyEvent(event_id::CONSTRUCT);
             eventHandlersInvoked = true;
 
-            int swfversion = getSWFVersion(*this);
+            int swfversion = getSWFVersion(*getObject(this));
 
             // Set the '__constructor__' and 'constructor' members, as well
             // as calling the actual constructor.
@@ -2017,22 +2010,22 @@
 
                 const int flags = PropFlags::dontEnum;
 
-                set_member(NSV::PROP_uuCONSTRUCTORuu, ctor);
-                set_member_flags(NSV::PROP_uuCONSTRUCTORuu, flags);
+                getObject(this)->set_member(NSV::PROP_uuCONSTRUCTORuu, ctor);
+                getObject(this)->set_member_flags(NSV::PROP_uuCONSTRUCTORuu, 
flags);
                 if ( swfversion == 6 )
                 {
-                    set_member(NSV::PROP_CONSTRUCTOR, ctor);
-                    set_member_flags(NSV::PROP_CONSTRUCTOR, flags);
+                    getObject(this)->set_member(NSV::PROP_CONSTRUCTOR, ctor);
+                    getObject(this)->set_member_flags(NSV::PROP_CONSTRUCTOR, 
flags);
                 }
 
                 // Provide a 'super' reference..
                 // Super is computed from the object we're constructing,
                 // It will work as long as we did set its __proto__ 
                 // and __constructor__ properties already.
-                as_object* super = get_super();
+                as_object* super = getObject(this)->get_super();
 
                 as_environment& env = get_environment();
-                fn_call call(this, env);
+                fn_call call(getObject(this), env);
                 call.super = super;
 
                     // we don't use the constructor return (should we?)
@@ -2086,22 +2079,22 @@
             log_debug(_("Posting data '%s' to url '%s'"), postdata, url.str());
         }
         
-        const movie_root& mr = getRoot(*this);
+        const movie_root& mr = stage();
 
         boost::intrusive_ptr<movie_definition> md(
             MovieFactory::makeMovie(url, mr.runResources(), NULL, true, 
postdata));
 
-        if (!md)
-        {
+        if (!md) {
             log_error(_("can't create movie_definition for %s"),
                 url.str());
             return false;
         }
 
-        boost::intrusive_ptr<Movie> extern_movie;
-        extern_movie = md->createMovie(parent);
-        if (extern_movie == NULL)
-        {
+        as_object* us = getObject(this);
+        assert(us);
+
+        Movie* extern_movie = md->createMovie(getGlobal(*us), parent);
+        if (!extern_movie) {
             log_error(_("can't create extern Movie "
                 "for %s"), url.str());
             return false;
@@ -2135,21 +2128,15 @@
         }
         extern_movie->set_clip_depth(get_clip_depth());
     
-        parent_sp->replace_display_object(extern_movie.get(), get_depth(),
+        parent_sp->replace_display_object(extern_movie, get_depth(),
                      true, true);
     }
     else
     {
-        movie_root& root = getRoot(*this);
-        unsigned int level = get_depth()-DisplayObject::staticDepthOffset;
+        const size_t level = get_depth() - DisplayObject::staticDepthOffset;
         
-#ifndef GNASH_USE_GC
-        // Make sure we won't kill ourself !
-        assert(get_ref_count() > 1);
-#endif // ndef GNASH_USE_GC
-
         // how about lockRoot here ?
-        root.loadLevel(level, url); // extern_movie.get());
+        stage().loadLevel(level, url); // extern_movie.get());
     }
 
     return true;
@@ -2162,17 +2149,17 @@
     // Host security check will be will be done by LoadVariablesThread
     // (down by getStream, that is)
     
-    const movie_root& mr = getRoot(*this);
+    const movie_root& mr = stage();
     URL url(urlstr, mr.runResources().baseURL());
 
     std::string postdata;
     
     // Encode our vars for sending.
-    if (sendVarsMethod != METHOD_NONE) getURLEncodedVars(*this, postdata);
+    if (sendVarsMethod != METHOD_NONE) getURLEncodedVars(*getObject(this), 
postdata);
 
     try 
     {
-        const StreamProvider& sp = getRunResources(*this).streamProvider();
+        const StreamProvider& sp = 
getRunResources(*getObject(this)).streamProvider();
         
         if (sendVarsMethod == METHOD_POST)
         {
@@ -2237,13 +2224,13 @@
 void
 MovieClip::setVariables(const MovieVariables& vars)
 {
-    string_table& st = getStringTable(*this);
+    string_table& st = getStringTable(*getObject(this));
     for (MovieVariables::const_iterator it=vars.begin(), itEnd=vars.end();
         it != itEnd; ++it)
     {
         const std::string& name = it->first;
         const std::string& val = it->second;
-        set_member(st.find(name), val);
+        getObject(this)->set_member(st.find(name), val);
     }
 }
 
@@ -2271,7 +2258,7 @@
     else
     {
         // removing _level#
-        getRoot(*this).dropLevel(depth);
+        stage().dropLevel(depth);
         // I guess this can only happen if someone uses 
         // _swf.swapDepth([0..1048575])
     }
@@ -2296,7 +2283,7 @@
     as_value enabled;
     // const_cast needed due to get_member being non-const due to the 
     // possibility that a getter-setter would actually modify us ...
-    if (!const_cast<MovieClip*>(this)->get_member(NSV::PROP_ENABLED, &enabled))
+    if 
(!getObject(const_cast<MovieClip*>(this))->get_member(NSV::PROP_ENABLED, 
&enabled))
     {
          // We're enabled if there's no 'enabled' member...
          return true;
@@ -2310,7 +2297,7 @@
     as_value val;
     // const_cast needed due to get_member being non-const due to the 
     // possibility that a getter-setter would actually modify us ...
-    if (!const_cast<MovieClip*>(this)->get_member(
+    if (!getObject(const_cast<MovieClip*>(this))->get_member(
                 NSV::PROP_USEHANDCURSOR, &val))
     {
          // true if not found..
@@ -2367,7 +2354,7 @@
     }
 };
 void
-MovieClip::markReachableResources() const
+MovieClip::markOwnResources() const
 {
     ReachableMarker marker;
 
@@ -2394,8 +2381,6 @@
     // Mark our relative root
     _swf->setReachable();
 
-    markDisplayObjectReachable();
-
 }
 #endif // GNASH_USE_GC
 
@@ -2440,7 +2425,7 @@
     // If we have a parent, we descend to it unless 
     // our _lockroot is true AND our or the VM's
     // SWF version is > 6
-    int topSWFVersion = getRoot(*this).getRootMovie().version();
+    int topSWFVersion = stage().getRootMovie().version();
 
     if (getDefinitionVersion() > 6 || topSWFVersion > 6) {
         if (getLockRoot()) return this;
@@ -2467,7 +2452,7 @@
 {
     if ( m_sound_stream_id == -1 ) return; // nothing to do
 
-    sound::sound_handler* handler = getRunResources(*this).soundHandler();
+    sound::sound_handler* handler = 
getRunResources(*getObject(this)).soundHandler();
     if (handler)
     {
         handler->stop_sound(m_sound_stream_id);

=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h       2009-10-28 07:46:49 +0000
+++ b/libcore/MovieClip.h       2009-11-04 17:27:42 +0000
@@ -115,8 +115,8 @@
     /// @param parent
     ///     Parent of the created instance in the display list.
     ///     May be 0 for top-level movies (_level#).
-    MovieClip(const movie_definition* const def, Movie* root,
-            DisplayObject* parent);
+    MovieClip(as_object* object, const movie_definition* def,
+            Movie* root, DisplayObject* parent);
 
     virtual ~MovieClip();
 
@@ -231,11 +231,6 @@
         return _droptarget;
     }
     
-    virtual bool wantsInstanceName() const
-    {
-        return true; // sprites can be referenced 
-    }
-
     virtual void advance();
 
     /// Set the sprite state at the specified frame number.
@@ -523,7 +518,7 @@
     DisplayObject* getDisplayListObject(string_table::key name);
 
     /// Overridden to look in DisplayList for a match
-    as_object* get_path_element(string_table::key key);
+    as_object* pathElement(string_table::key key);
 
     /// Execute the actions for the specified frame. 
     //
@@ -612,9 +607,6 @@
     /// testsuite/misc-ming.all/displaylist_depths_test.swf
     void removeMovieClip();
 
-    /// Create a Bitmap DisplayObject at the specified depth.
-    void attachBitmap(BitmapData_as* bd, int depth);
-
     /// Render this MovieClip to a GnashImage using the passed transform
     //
     /// @return     The GnashImage with the MovieClip drawn onto it.
@@ -742,9 +734,7 @@
 
 protected:
 
-#ifdef GNASH_USE_GC
-    /// Mark sprite-specific reachable resources and invoke
-    /// the parent's class version (markDisplayObjectReachable)
+    /// Mark sprite-specific reachable resources.
     //
     /// sprite-specific reachable resources are:
     ///     - DisplayList items (current, backup and frame0 ones)
@@ -754,8 +744,7 @@
     /// - Textfields having an associated variable registered in this instance.
     /// - Relative root of this instance (_swf)
     ///
-    virtual void markReachableResources() const;
-#endif // GNASH_USE_GC
+    virtual void markOwnResources() const;
     
     // Used by BitmapMovie.
     void placeDisplayObject(DisplayObject* ch, int depth) {       

=== modified file 'libcore/SWFMovie.cpp'
--- a/libcore/SWFMovie.cpp      2009-04-15 05:54:30 +0000
+++ b/libcore/SWFMovie.cpp      2009-11-04 15:03:15 +0000
@@ -29,11 +29,13 @@
 
 namespace gnash {
 
-SWFMovie::SWFMovie(const SWFMovieDefinition* const def, DisplayObject* parent)
+SWFMovie::SWFMovie(as_object* object, const SWFMovieDefinition* def,
+        DisplayObject* parent)
        :
-       Movie(def, parent),
+       Movie(object, def, parent),
        _def(def)
 {
+    assert(object);
 }
 
 void

=== modified file 'libcore/SWFMovie.h'
--- a/libcore/SWFMovie.h        2009-04-15 06:41:11 +0000
+++ b/libcore/SWFMovie.h        2009-11-04 15:03:15 +0000
@@ -41,7 +41,8 @@
 
 public:
 
-       SWFMovie(const SWFMovieDefinition* const def, DisplayObject* parent);
+       SWFMovie(as_object* object, const SWFMovieDefinition* def,
+            DisplayObject* parent);
 
        virtual ~SWFMovie() {}
 

=== modified file 'libcore/Shape.h'
--- a/libcore/Shape.h   2009-10-12 09:42:13 +0000
+++ b/libcore/Shape.h   2009-11-04 15:03:15 +0000
@@ -39,17 +39,19 @@
 
 public:
 
-    Shape(boost::shared_ptr<DynamicShape> sh, DisplayObject* parent)
+    Shape(movie_root& mr, as_object* object, boost::shared_ptr<DynamicShape> 
sh,
+            DisplayObject* parent)
         :
-        DisplayObject(parent),
+        DisplayObject(mr, object, parent),
         _shape(sh)
     {
         assert(_shape.get());
     }
 
-       Shape(const SWF::DefineShapeTag* const def, DisplayObject* parent)
+       Shape(movie_root& mr, as_object* object, const SWF::DefineShapeTag* def,
+            DisplayObject* parent)
                :
-               DisplayObject(parent),
+               DisplayObject(mr, object, parent),
                _def(def)
        {
            assert(_def);
@@ -61,19 +63,15 @@
         return _def ? _def->bounds() : _shape->getBounds();
     }
     
-    virtual bool pointInShape(boost::int32_t  x, boost::int32_t  y) const;
+    virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
 
 protected:
 
-#ifdef GNASH_USE_GC
        /// Mark reachable resources (for the GC)
-       void markReachableResources() const
+       virtual void markReachableResources() const
        {
-               assert(isReachable());
         if (_def) _def->setReachable();
-               markDisplayObjectReachable();
        }
-#endif
 
 private:
        

=== modified file 'libcore/StaticText.h'
--- a/libcore/StaticText.h      2009-10-12 09:42:13 +0000
+++ b/libcore/StaticText.h      2009-11-04 15:03:15 +0000
@@ -43,9 +43,10 @@
 {
 public:
 
-       StaticText(const SWF::DefineTextTag* const def, DisplayObject* parent)
+       StaticText(movie_root& mr, as_object* object, const SWF::DefineTextTag* 
def,
+            DisplayObject* parent)
                :
-        DisplayObject(parent),
+        DisplayObject(mr, object, parent),
         _def(def),
         _selectionColor(0, 255, 255, 255)
        {
@@ -101,9 +102,7 @@
        /// Mark reachable resources (for the GC)
        void markReachableResources() const
        {
-               assert(isReachable());
         _def->setReachable();
-               markDisplayObjectReachable();
        }
 #endif
 

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2009-11-03 22:43:22 +0000
+++ b/libcore/TextField.cpp     2009-11-04 20:07:58 +0000
@@ -128,9 +128,22 @@
     as_value textfield_textHeight(const fn_call& fn);
 }
 
-TextField::TextField(DisplayObject* parent, const SWF::DefineEditTextTag& def)
+as_object*
+createTextFieldObject(Global_as& gl)
+{
+    as_value tf(gl.getMember(NSV::CLASS_TEXT_FIELD));
+    as_function* ctor = tf.to_as_function();
+    if (!ctor) return 0;
+    fn_call::Args args;
+    as_environment env(getVM(gl));
+    return ctor->constructInstance(env, args).get();
+}
+
+
+TextField::TextField(as_object* object, DisplayObject* parent,
+        const SWF::DefineEditTextTag& def)
     :
-    InteractiveObject(parent),
+    InteractiveObject(object, parent),
     _tag(&def),
     _textDefined(def.hasText()),
     _htmlTextDefined(def.hasText()),
@@ -176,12 +189,15 @@
     _bounds(def.bounds()),
     _selection(0, 0)
 {
+
+    assert(object);
+
     // WARNING! remember to set the font *before* setting text value!
     boost::intrusive_ptr<const Font> f = def.getFont();
     if (!f) f = fontlib::get_default_font(); 
     setFont(f);
 
-    int version = getSWFVersion(*parent);
+    int version = getSWFVersion(*object);
     
     // set default text *before* calling registerTextVariable
     // (if the textvariable already exist and has a value
@@ -196,9 +212,10 @@
 
 }
 
-TextField::TextField(DisplayObject* parent, const SWFRect& bounds)
+TextField::TextField(as_object* object, DisplayObject* parent,
+        const SWFRect& bounds)
     :
-    InteractiveObject(parent),
+    InteractiveObject(object, parent),
     _textDefined(false),
     _htmlTextDefined(false),
     _restrictDefined(false),
@@ -253,18 +270,19 @@
 void
 TextField::init()
 {
-    as_environment env(getVM(*this));
+#if 0
+    as_environment env(getVM(*getObject(this)));
     as_object* proto = env.find_object("_global.TextField.prototype");
     if (proto) {
         attachPrototypeProperties(*proto);
     }
      
-    set_prototype(proto);
+    getObject(this)->set_prototype(proto);
 
-    as_object* ar = getGlobal(*this).createArray();
-    ar->callMethod(NSV::PROP_PUSH, this);
-    set_member(NSV::PROP_uLISTENERS, ar);
-    
+    as_object* ar = getGlobal(*getObject(this)).createArray();
+    ar->callMethod(NSV::PROP_PUSH, getObject(this));
+    getObject(this)->set_member(NSV::PROP_uLISTENERS, ar);
+#endif
     registerTextVariable();
 
     reset_bounding_box(0, 0);
@@ -544,7 +562,7 @@
 TextField::replaceSelection(const std::string& replace)
 {
 
-    const int version = getSWFVersion(*this);
+    const int version = getSWFVersion(*getObject(this));
     const std::wstring& wstr = utf8::decodeCanonicalString(replace, version);
     
     const size_t start = _selection.first;
@@ -579,6 +597,7 @@
 
     _selection = std::make_pair(start, end);
 }
+
 bool
 TextField::notifyEvent(const event_id& ev)
 {    
@@ -586,12 +605,12 @@
     {
                case event_id::PRESS:
                {
-                       movie_root& root = getRoot(*this);
+                       movie_root& root = stage();
                        
                        int x_mouse = pixelsToTwips(root.getXMouseLoc());
                        int y_mouse = pixelsToTwips(root.getYMouseLoc());
                        
-                       SWFMatrix m = this->getMatrix();
+                       SWFMatrix m = getMatrix();
                        
                        x_mouse -= m.get_x_translation();
                        y_mouse -= m.get_y_translation();
@@ -854,7 +873,7 @@
 void
 TextField::updateText(const std::string& str)
 {
-    int version = getSWFVersion(*this);
+    int version = getSWFVersion(*getObject(this));
     const std::wstring& wstr = utf8::decodeCanonicalString(str, version);
     updateText(wstr);
 }
@@ -875,7 +894,7 @@
 void
 TextField::updateHtmlText(const std::string& str)
 {
-    int version = getSWFVersion(*this);
+    int version = getSWFVersion(*getObject(this));
     const std::wstring& wstr = utf8::decodeCanonicalString(str, version);
     updateHtmlText(wstr);
 }
@@ -912,7 +931,7 @@
         as_object* tgt = ref.first;
         if ( tgt )
         {
-            int version = getSWFVersion(*this);
+            int version = getSWFVersion(*getObject(this));
             // we shouldn't truncate, right?
             tgt->set_member(ref.second, utf8::encodeCanonicalString(wstr,
                         version)); 
@@ -945,7 +964,7 @@
         as_object* tgt = ref.first;
         if ( tgt )
         {
-            int version = getSWFVersion(*this);
+            int version = getSWFVersion(*getObject(this));
             // we shouldn't truncate, right?
             tgt->set_member(ref.second, utf8::encodeCanonicalString(wstr,
                         version)); 
@@ -972,7 +991,7 @@
     // with a pre-existing value.
     const_cast<TextField*>(this)->registerTextVariable();
 
-    int version = getSWFVersion(*this);
+    int version = getSWFVersion(*getObject(const_cast<TextField*>(this)));
 
     return utf8::encodeCanonicalString(_text, version);
 }
@@ -981,7 +1000,7 @@
 TextField::get_htmltext_value() const
 {
     const_cast<TextField*>(this)->registerTextVariable();
-    int version = getSWFVersion(*this);
+    int version = getSWFVersion(*getObject(const_cast<TextField*>(this)));
     return utf8::encodeCanonicalString(_htmlText, version);
 }
 
@@ -1998,7 +2017,7 @@
     /// Why isn't get_environment const again ?
     as_environment& env = const_cast<TextField*>(this)->get_environment();
 
-    as_object* target = env.get_target();
+    as_object* target = getObject(env.get_target());
     if ( ! target )
     {
         IF_VERBOSE_MALFORMED_SWF(
@@ -2040,7 +2059,7 @@
     }
 
     ret.first = target;
-    ret.second = getStringTable(*this).find(parsedName);
+    ret.second = getStringTable(*object()).find(parsedName);
 
     return ret;
 }
@@ -2054,16 +2073,14 @@
     log_debug(_("registerTextVariable() called"));
 #endif
 
-    if ( _text_variable_registered )
-    {
+    if (_text_variable_registered) {
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug(_("registerTextVariable() no-op call (already registered)"));
 #endif
         return;
     }
 
-    if ( _variable_name.empty() )
-    {
+    if (_variable_name.empty()) {
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug(_("string is empty, consider as registered"));
 #endif
@@ -2073,8 +2090,7 @@
 
     VariableRef varRef = parseTextVariableRef(_variable_name);
     as_object* target = varRef.first;
-    if ( ! target )
-    {
+    if (!target) {
         log_debug(_("VariableName associated to text field (%s) refer to "
                     "an unknown target. It is possible that the DisplayObject "
                     "will be instantiated later in the SWF stream. "
@@ -2083,56 +2099,51 @@
         return;
     }
 
-    string_table::key key = varRef.second;
-
+    const string_table::key key = varRef.second;
+    as_object* obj = getObject(this);
+    const int version = getSWFVersion(*obj);
+    string_table& st = getStringTable(*obj);
+    
     // check if the VariableName already has a value,
     // in that case update text value
     as_value val;
-    
-    int version = getSWFVersion(*this);
-    
-    if (target->get_member(key, &val) )
-    {
+    if (target->get_member(key, &val) ) {
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug(_("target object (%s @ %p) does have a member named %s"),
-            typeName(*target), (void*)target, 
getStringTable(*this).value(key));
+            typeName(*target), (void*)target, st.value(key));
 #endif
         // TODO: pass environment to to_string ?
         // as_environment& env = get_environment();
         setTextValue(utf8::decodeCanonicalString(val.to_string(), version));
     }
-    else if ( _textDefined )
-    {
+    else if (_textDefined) {
         as_value newVal = as_value(utf8::encodeCanonicalString(_text, 
version));
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug(_("target sprite (%s @ %p) does NOT have a member "
                     "named %s (no problem, we'll add it with value %s)"),
                     typeName(*target), (void*)target,
-                    getStringTable(*this).value(key), newVal);
+                    st.value(key), newVal);
 #endif
         target->set_member(key, newVal);
     }
-    else
-    {
+    else {
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug(_("target sprite (%s @ %p) does NOT have a member "
                     "named %s, and we don't have text defined"),
-                    typeName(*target), (void*)target,
-                    getStringTable(*this).value(key));
+                    typeName(*target), (void*)target, st.value(key));
 #endif
     }
 
-    MovieClip* sprite = target->to_movie();
+    MovieClip* sprite = get<MovieClip>(target);
 
-    if ( sprite )
-    {
+    if (sprite) {
         // add the textfield variable to the target sprite
         // TODO: have set_textfield_variable take a string_table::key instead ?
 #ifdef DEBUG_DYNTEXT_VARIABLES
         log_debug("Calling set_textfield_variable(%s) against sprite %s",
-                getStringTable(*this).value(key), sprite->getTarget());
+                st.value(key), sprite->getTarget());
 #endif
-        sprite->set_textfield_variable(getStringTable(*this).value(key), this);
+        sprite->set_textfield_variable(st.value(key), this);
 
     }
     _text_variable_registered=true;
@@ -2713,9 +2724,8 @@
 void
 TextField::onChanged()
 {
-    as_value met(PROPNAME("onChanged"));
-    as_value targetVal(this);
-    callMethod(NSV::PROP_BROADCAST_MESSAGE, met, targetVal);
+    as_object* obj = getObject(this);
+    obj->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onChanged", obj);
 }
 
 /// This is called by movie_root when focus is applied to this TextField.
@@ -2727,7 +2737,7 @@
 TextField::handleFocus()
 {
 
-    if (getSWFVersion(*this) < 6) return false;
+    if (getSWFVersion(*getObject(this)) < 6) return false;
 
     set_invalidated();
 
@@ -2738,7 +2748,7 @@
 
     // why should we add to the key listener list every time
     // we call setFocus()???
-    getRoot(*this).add_key_listener(this);
+    stage().add_key_listener(this);
 
     m_cursor = _text.size();
     format_text();
@@ -2755,22 +2765,16 @@
     set_invalidated();
     m_has_focus = false;
 
-    movie_root& root = getRoot(*this);
-    root.remove_key_listener(this);
+    stage().remove_key_listener(this);
     format_text(); // is this needed ?
 
 }
 
 void
-TextField::markReachableResources() const
+TextField::markOwnResources() const
 {
-
     if (_tag) _tag->setReachable();
-
     if (_font) _font->setReachable();
-
-    // recurse to parent...
-    markDisplayObjectReachable();
 }
 
 void
@@ -2870,7 +2874,7 @@
 as_value
 textfield_createTextField(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     
     // name, depth, x, y, width, height
     if (fn.nargs < 6) {
@@ -2882,11 +2886,11 @@
     }
 
     const std::string& name = fn.arg(0).to_string();
-    int depth = fn.arg(1).to_int();
-    int x = fn.arg(2).to_int();
-    int y = fn.arg(3).to_int();
+    const int depth = fn.arg(1).to_int();
+    const int x = fn.arg(2).to_int();
+    const int y = fn.arg(3).to_int();
+    
     int width = fn.arg(4).to_int();
-
     if (width < 0) {
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror(_("createTextField: negative width (%d)"
@@ -2911,7 +2915,9 @@
     //  1. Call "new _global.TextField()" (which takes care of
     //     assigning properties to the prototype).
     //  2. Make that object into a TextField and put it on the display list.
-    DisplayObject* tf = new TextField(ptr.get(), bounds);
+    as_object* obj = createTextFieldObject(getGlobal(fn));
+
+    DisplayObject* tf = new TextField(obj, ptr, bounds);
 
     // Give name and mark as dynamic
     tf->set_name(name);
@@ -2923,17 +2929,16 @@
     // update caches (although shouldn't be needed as we only set translation)
     tf->setMatrix(matrix, true); 
 
-    DisplayObject* txt = ptr->addDisplayListObject(tf, depth);
+    ptr->addDisplayListObject(tf, depth);
 
-    // createTextField returns void, it seems
-    if (getSWFVersion(fn) > 7) return as_value(txt);
+    if (getSWFVersion(fn) > 7) return as_value(obj);
     return as_value(); 
 }
 
 as_value
 textfield_background(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->getDrawBackground());
@@ -2948,7 +2953,7 @@
 as_value
 textfield_border(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->getDrawBorder());
@@ -2963,7 +2968,7 @@
 as_value
 textfield_backgroundColor(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->getBackgroundColor().toRGB());
@@ -2980,7 +2985,7 @@
 as_value
 textfield_borderColor(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->getBorderColor().toRGB());
@@ -2998,7 +3003,7 @@
 as_value
 textfield_textColor(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs) {
         // Getter
@@ -3016,7 +3021,7 @@
 as_value
 textfield_embedFonts(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs) {
         // Getter
@@ -3031,7 +3036,7 @@
 as_value
 textfield_wordWrap(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->doWordWrap());
@@ -3046,7 +3051,7 @@
 as_value
 textfield_html(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (fn.nargs == 0) {
         return as_value(ptr->doHtml());
@@ -3061,7 +3066,7 @@
 as_value
 textfield_selectable(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs == 0 ) // getter
     {
@@ -3078,7 +3083,7 @@
 as_value
 textfield_length(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs == 0 ) // getter
     {
@@ -3099,7 +3104,7 @@
 as_value
 textfield_textHeight(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs == 0 ) // getter
     {
@@ -3125,7 +3130,7 @@
 as_value
 textfield_textWidth(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs == 0 ) // getter
     {
@@ -3151,7 +3156,7 @@
 as_value
 textfield_autoSize(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs == 0 ) // getter
     {
@@ -3185,7 +3190,7 @@
 as_value
 textfield_type(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs)
     {
@@ -3212,7 +3217,7 @@
 as_value
 textfield_variable(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs)
     {
@@ -3243,7 +3248,7 @@
 textfield_getDepth(const fn_call& fn)
 {
     // Unlike MovieClip.getDepth this works only for TextFields.
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     const int n = text->get_depth();
     return as_value(n);
 }
@@ -3251,7 +3256,7 @@
 as_value
 textfield_getFontList(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     LOG_ONCE(log_unimpl("TextField.getFontList()"));
@@ -3262,7 +3267,7 @@
 as_value
 textfield_getNewTextFormat(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     LOG_ONCE(log_unimpl("TextField.getNewTextFormat()"));
@@ -3279,7 +3284,7 @@
 as_value
 textfield_getTextFormat(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     Global_as& gl = getGlobal(fn);
     as_function* ctor = gl.getMember(NSV::CLASS_TEXT_FORMAT).to_as_function();
@@ -3326,7 +3331,7 @@
 textfield_setTextFormat(const fn_call& fn)
 {
 
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( ! fn.nargs )
     {
@@ -3391,20 +3396,18 @@
 as_value
 textfield_setNewTextFormat(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
-    //UNUSED(text);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
+    UNUSED(text);
 
     LOG_ONCE( log_unimpl("TextField.setNewTextFormat(), we'll delegate "
                 "to setTextFormat") );
     return textfield_setTextFormat(fn);
-
-    //return as_value();
 }
 
 as_value
 textfield_password(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs)
     {
@@ -3419,7 +3422,7 @@
 as_value
 textfield_multiline(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs) {
         // Getter
@@ -3433,7 +3436,7 @@
 as_value
 textfield_restrict(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs) {
         // Getter
@@ -3453,7 +3456,7 @@
 as_value
 textfield_bottomScroll(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     LOG_ONCE(log_unimpl("TextField.bottomScroll is not complete"));
@@ -3473,7 +3476,7 @@
 as_value
 textfield_maxhscroll(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
         LOG_ONCE(log_unimpl("TextField.maxhscroll is not complete"));
@@ -3499,7 +3502,7 @@
 as_value
 textfield_maxChars(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs)
     {
@@ -3520,7 +3523,7 @@
 as_value
 textfield_text(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
     if (!fn.nargs)
     {
         // Getter
@@ -3530,7 +3533,7 @@
     }
 
     // Setter
-    int version = getSWFVersion(*ptr);
+    const int version = getSWFVersion(fn);
     ptr->setTextValue(
             utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
 
@@ -3540,7 +3543,7 @@
 as_value
 textfield_htmlText(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> ptr = ensure<ThisIs<TextField> >(fn);
+    TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
     if (!fn.nargs)
     {
         // Getter
@@ -3548,7 +3551,7 @@
     }
 
     // Setter
-    const int version = getSWFVersion(*ptr);
+    const int version = getSWFVersion(fn);
     
     ptr->setHtmlTextValue(
             utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
@@ -3566,7 +3569,7 @@
 as_value
 textfield_replaceSel(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if (!fn.nargs) {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -3581,7 +3584,7 @@
     const std::string& replace = fn.arg(0).to_string();
 
     /// Do nothing if text is empty and version less than 8.
-    const int version = getSWFVersion(*text);
+    const int version = getSWFVersion(fn);
     if (version < 8 && replace.empty()) return as_value();
 
     text->replaceSelection(replace);
@@ -3592,7 +3595,7 @@
 as_value
 textfield_scroll(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     if (!fn.nargs)
@@ -3609,7 +3612,7 @@
 as_value
 textfield_hscroll(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     LOG_ONCE(log_unimpl("TextField._hscroll is not complete"));
@@ -3628,7 +3631,7 @@
 as_value
 textfield_maxscroll(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
     UNUSED(text);
 
     LOG_ONCE(log_unimpl("TextField.maxscroll is not complete"));
@@ -3650,7 +3653,7 @@
     using std::string;
     using std::wstring;
 
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     if ( fn.nargs < 3 )
     {
@@ -3674,7 +3677,7 @@
     wstring::size_type start = fn.arg(0).to_int();
     wstring::size_type end = userEnd;
 
-    int version = getSWFVersion(*text);
+    int version = getSWFVersion(fn);
 
     // TODO: check if it's possible for SWF6 to use this function
     //       and if it is whether to_string should be to_string_versioned
@@ -3726,7 +3729,7 @@
 as_value
 textfield_removeTextField(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextField> text = ensure<ThisIs<TextField> >(fn);
+    TextField* text = ensure<IsDisplayObject<TextField> >(fn);
 
     text->removeTextField();
 
@@ -3753,9 +3756,10 @@
 {
 
     if (isAS3(fn)) {
+        as_object* obj = ensure<ValidThis>(fn);
         SWFRect nullRect;
-        as_object* obj = new TextField(0, nullRect);
-        return as_value(obj);
+        obj->setDisplayObject(new TextField(obj, 0, nullRect));
+        return as_value();
     }
 
     as_object* obj = ensure<ValidThis>(fn);
@@ -3771,6 +3775,9 @@
         attachPrototypeProperties(*proto);
     }
 
+    as_object* ar = getGlobal(fn).createArray();
+    ar->callMethod(NSV::PROP_PUSH, obj);
+    obj->set_member(NSV::PROP_uLISTENERS, ar);
     return as_value();
 }
 

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2009-10-13 05:58:20 +0000
+++ b/libcore/TextField.h       2009-11-04 20:00:18 +0000
@@ -92,14 +92,16 @@
        };
 
     /// Constructs a TextField as specified in a DefineEditText tag.
-       TextField(DisplayObject* parent, const SWF::DefineEditTextTag& def);
+       TextField(as_object* object, DisplayObject* parent,
+            const SWF::DefineEditTextTag& def);
 
     /// Constructs a TextField with default values and the specified bounds.
     //
     /// Notably, the default textHeight is 12pt (240 twips).
        /// @param parent A pointer to the DisplayObject parent of this 
TextField
        /// @param bounds A SWFRect specifying the bounds of this TextField
-    TextField(DisplayObject* parent, const SWFRect& bounds);
+    TextField(as_object* object, DisplayObject* parent, const SWFRect& bounds);
+
 
        ~TextField();
 
@@ -121,11 +123,6 @@
     /// TODO: work out what this means for dynamic TextFields.
     virtual int getDefinitionVersion() const;
 
-    bool wantsInstanceName() const
-       {
-               return true; // text fields can be referenced 
-       }       
-
        /// This function is called as a user-input handler
        bool notifyEvent(const event_id& id);   
 
@@ -614,7 +611,7 @@
        ///  - Our definition
        ///  - Common DisplayObject resources
        ///
-       void markReachableResources() const;
+       void markOwnResources() const;
 
 private:
 
@@ -859,6 +856,11 @@
        
 };
 
+/// Native function to create a plain object with TextField properties
+//
+/// This function calls the TextField constructor.
+as_object* createTextFieldObject(Global_as& gl);
+
 /// Initialize the global TextField class
 void textfield_class_init(as_object& global, const ObjectURI& uri);
 

=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2009-10-23 06:25:25 +0000
+++ b/libcore/Video.cpp 2009-11-04 18:25:13 +0000
@@ -52,29 +52,20 @@
     as_value video_height(const fn_call& fn);
 }
 
-Video::Video(const SWF::DefineVideoStreamTag* const def, DisplayObject* parent)
+Video::Video(as_object* object,
+        const SWF::DefineVideoStreamTag* def, DisplayObject* parent)
        :
-       DisplayObject(parent),
+       DisplayObject(getRoot(*object), object, parent),
        m_def(def),
        _ns(0),
-       _embeddedStream(m_def ? true : false),
+       _embeddedStream(m_def),
        _lastDecodedVideoFrameNum(-1),
        _lastDecodedVideoFrame(),
     _smoothing(false)
 {
-
-       set_prototype(getVideoInterface(*this));
-
-    // TODO: For AS2 a genuine Video object can only be created from a 
-    // SWF tag. 
-       if (_embeddedStream)
-       {
-        // TODO: this should happen using the native creation function
-        // once Video is a Relay.
-               initializeDecoder();
-        
-        attachPrototypeProperties(*get_prototype());
-       }
+    assert(object);
+    assert(def);
+    initializeDecoder();
 }
 
 Video::~Video()
@@ -138,8 +129,6 @@
 void
 Video::display(Renderer& renderer)
 {
-       // if m_def is NULL we've been constructed by 'new Video', in this
-       // case I think display() would never be invoked on us...
        assert(m_def);
 
        SWFMatrix m = getWorldMatrix();
@@ -258,7 +247,7 @@
     saveOriginalTarget(); // for softref
 
     // Register this video instance as a live DisplayObject
-    getRoot(*this).addLiveChar(this);
+    stage().addLiveChar(this);
 }
 
 
@@ -278,11 +267,7 @@
     
        ranges.add(m_old_invalidated_ranges);
        
-       // NOTE: do not use m_def->boundss()
-
-       // if m_def is NULL we've been constructed by 'new Video', in this
-       // case I think add_invalidated_bouns would never be invoked on us...
-       assert ( m_def );
+       assert (m_def);
 
        SWFRect bounds; 
        bounds.expand_to_transformed_rect(getWorldMatrix(), m_def->bounds());
@@ -303,7 +288,9 @@
 {
        // This is going to be the global Video "class"/"function"
     Global_as& gl = getGlobal(global);
-    as_object* cl = gl.createClass(&video_ctor, getVideoInterface(global));
+    as_object* proto = gl.createObject();
+    as_object* cl = gl.createClass(&video_ctor, proto);
+    attachVideoInterface(*proto);
 
        // Register _global.Video
        global.init_member(getName(uri), cl, as_object::DefaultFlags,
@@ -329,33 +316,25 @@
        return SWFRect();
 }
 
-#ifdef GNASH_USE_GC
 void
-Video::markReachableResources() const
+Video::markOwnResources() const
 {
        if (_ns) _ns->setReachable();
+}
 
-       // Invoke DisplayObject's version of reachability mark
-       markDisplayObjectReachable();
+as_object*
+createVideoObject(Global_as& gl)
+{
+    // TODO: how to use this for AS3 as well?
+    // Turn into constructBuiltin()
+    as_object* obj = getObjectWithPrototype(gl, NSV::CLASS_VIDEO);
+    as_object* proto = obj->get_prototype();
+    if (proto) attachPrototypeProperties(*proto);
+    return obj;
 }
-#endif // GNASH_USE_GC
 
 namespace {
 
-as_object*
-getVideoInterface(as_object& where)
-{
-       static boost::intrusive_ptr<as_object> proto;
-       if ( proto == NULL )
-       {
-               proto = new as_object(getObjectInterface());
-               getVM(where).addStatic(proto.get());
-
-               attachVideoInterface(*proto);
-       }
-       return proto.get();
-}
-
 void
 attachVideoInterface(as_object& o)
 {
@@ -384,7 +363,7 @@
 as_value
 video_attach(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
 
        if (fn.nargs < 1)
        {
@@ -412,7 +391,7 @@
 as_value
 video_deblocking(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
     UNUSED(video);
 
     log_unimpl("Video.deblocking");
@@ -422,7 +401,7 @@
 as_value
 video_smoothing(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
 
     if (!fn.nargs) return as_value(video->smoothing());
 
@@ -436,21 +415,21 @@
 as_value
 video_width(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
     return as_value(video->width());
 }
 
 as_value
 video_height(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
     return as_value(video->height());
 }
 
 as_value
 video_clear(const fn_call& fn)
 {
-       boost::intrusive_ptr<Video> video = ensure<ThisIs<Video> >(fn);
+       Video* video = ensure<IsDisplayObject<Video> >(fn);
 
     video->clear();
     return as_value();
@@ -459,7 +438,7 @@
 as_value
 video_ctor(const fn_call& /* fn */)
 {
-       return as_value(); // will keep alive
+       return as_value();
 }
 
 } // anonymous namespace

=== modified file 'libcore/Video.h'
--- a/libcore/Video.h   2009-10-12 09:42:13 +0000
+++ b/libcore/Video.h   2009-11-04 18:25:13 +0000
@@ -48,7 +48,8 @@
 
 public:
        
-       Video(const SWF::DefineVideoStreamTag* const def, DisplayObject* 
parent);
+       Video(as_object* object, const SWF::DefineVideoStreamTag* def,
+            DisplayObject* parent);
 
        ~Video();
 
@@ -68,12 +69,6 @@
 
        void display(Renderer& renderer);
 
-       // For sure isActionScriptReferenceable...
-       bool wantsInstanceName() const
-       {
-               return true; // text fields can be referenced 
-       }       
-
        void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
 
        /// Set the input stream for this video
@@ -105,15 +100,12 @@
 
 protected:
     
-#ifdef GNASH_USE_GC
-       /// Mark video-specific reachable resources and invoke
-       /// the parent's class version (markDisplayObjectReachable)
+       /// Mark video-specific reachable resources.
        //
        /// video-specific reachable resources are:
        ///     - Associated NetStream if any (_ns) 
        ///
-       virtual void markReachableResources() const;
-#endif // GNASH_USE_GC
+       virtual void markOwnResources() const;
 
 private:
 
@@ -147,6 +139,12 @@
     bool _smoothing;
 };
 
+/// Native function to create a plain object with Video properties
+//
+/// This adds properties to the prototype, but does not add a Video
+/// DisplayObject.
+as_object* createVideoObject(Global_as& gl);
+
 void video_class_init(as_object& global, const ObjectURI& uri);
 
 void registerVideoNative(as_object& global);

=== modified file 'libcore/as_environment.cpp'
--- a/libcore/as_environment.cpp        2009-10-23 06:25:25 +0000
+++ b/libcore/as_environment.cpp        2009-10-28 11:29:28 +0000
@@ -80,7 +80,8 @@
 as_object*
 getElement(as_object* obj, string_table::key key)
 {
-    //Global_as& gl = getGlobal(*obj); 
+    DisplayObject* d = obj->displayObject();
+    if (d) return d->pathElement(key);
     return obj->get_path_element(key);
 }
 
@@ -150,12 +151,13 @@
             varname.find(':') == std::string::npos)
         {
             // Consider it all a path ...
-                as_object* target = find_object(varname, &scopeStack); 
+            as_object* target = find_object(varname, &scopeStack); 
             if ( target ) 
             {
                 // ... but only if it resolves to a sprite
-                MovieClip* m = target->to_movie();
-                if ( m ) return as_value(m);
+                DisplayObject* d = target->displayObject();
+                MovieClip* m = d ? d->to_movie() : 0;
+                if (m) return as_value(getObject(m));
             }
         }
         return get_variable_raw(varname, scopeStack, retTarget);
@@ -224,21 +226,25 @@
     // Check current target members. TODO: shouldn't target be in scope stack ?
     if (m_target)
     {
-        if (m_target->get_member(key, &val)) {
+        as_object* obj = getObject(m_target);
+        assert(obj);
+        if (obj->get_member(key, &val)) {
 #ifdef GNASH_DEBUG_GET_VARIABLE
             log_debug("Found %s in target %p", varname, m_target->getTarget());
 #endif
-            if ( retTarget ) *retTarget = m_target;
+            if ( retTarget ) *retTarget = obj;
             return val;
         }
     }
     else if ( _original_target ) // this only for swf5+ ?
     {
-        if (_original_target->get_member(key, &val)) {
+        as_object* obj = getObject(_original_target);
+        assert(obj);
+        if (obj->get_member(key, &val)) {
 #ifdef GNASH_DEBUG_GET_VARIABLE
             log_debug("Found %s in original target %s", varname, 
_original_target->getTarget());
 #endif
-            if ( retTarget ) *retTarget = _original_target;
+            if ( retTarget ) *retTarget = obj;
             return val;
         }
     }
@@ -248,7 +254,7 @@
 #ifdef GNASH_DEBUG_GET_VARIABLE
         log_debug("Took %s as this, returning original target %s", varname, 
_original_target->getTarget());
 #endif
-        val.set_as_object(_original_target);
+        val.set_as_object(getObject(_original_target));
         if ( retTarget ) *retTarget = NULL; // correct ??
         return val;
     }
@@ -317,7 +323,7 @@
 
 
     // Try target
-    std::pair<bool,bool> ret = m_target->delProperty(varkey);
+    std::pair<bool,bool> ret = getObject(m_target)->delProperty(varkey);
     if ( ret.first )
     {
         return ret.second;
@@ -340,7 +346,7 @@
     );
 
     // Path lookup rigamarole.
-    as_object* target = m_target;
+    as_object* target = getObject(m_target);
     std::string path;
     std::string var;
     //log_debug(_("set_variable(%s, %s)"), varname, val);
@@ -421,8 +427,10 @@
     
     // TODO: shouldn't m_target be in the scope chain ?
     //assert(m_target);
-    if ( m_target ) m_target->set_member(varkey, val);
-    else if ( _original_target ) _original_target->set_member(varkey, val);
+    if (m_target) getObject(m_target)->set_member(varkey, val);
+    else if (_original_target) {
+        getObject(_original_target)->set_member(varkey, val);
+    }
     else
     {
         log_error("as_environment(%p)::set_variable_raw(%s, %s): "
@@ -574,7 +582,7 @@
 #ifdef DEBUG_TARGET_FINDING 
         log_debug(_("Returning m_target (empty path)"));
 #endif
-        return m_target; // or should we return the *original* path ?
+        return getObject(m_target); // or should we return the *original* path 
?
     }
     
     VM& vm = _vm;
@@ -582,7 +590,7 @@
     int swfVersion = vm.getSWFVersion();
 
     as_object* env = 0;
-    env = m_target; 
+    env = getObject(m_target); 
 
     bool firstElementParsed = false;
     bool dot_allowed = true;
@@ -610,10 +618,10 @@
 #ifdef DEBUG_TARGET_FINDING 
             log_debug(_("Path is '/', return the root (%p)"), (void*)root);
 #endif
-            return root; // that's all folks.. 
+            return getObject(root); // that's all folks.. 
         }
 
-        env = root;
+        env = getObject(root);
         firstElementParsed = true;
         dot_allowed = false;
 
@@ -704,7 +712,7 @@
                 }
 
                 // Try current target  (if any)
-                assert(env == m_target);
+                assert(env == getObject(m_target));
                 if (env) {
                     element = getElement(env, subpartKey);
                     if (element) break;

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2009-10-26 08:22:49 +0000
+++ b/libcore/as_object.cpp     2009-11-04 13:37:17 +0000
@@ -272,7 +272,7 @@
 
 as_object::as_object(Global_as& gl)
        :
-    _displayObject(false),
+    _displayObject(0),
     _array(false),
     _relay(0),
        _vm(getVM(gl)),
@@ -282,7 +282,7 @@
 
 as_object::as_object()
        :
-    _displayObject(false),
+    _displayObject(0),
     _array(false),
     _relay(0),
        _vm(VM::get()),
@@ -292,7 +292,7 @@
 
 as_object::as_object(as_object* proto)
        :
-    _displayObject(false),
+    _displayObject(0),
     _array(false),
     _relay(0),
        _vm(VM::get()),
@@ -303,7 +303,7 @@
 
 as_object::as_object(boost::intrusive_ptr<as_object> proto)
        :
-    _displayObject(false),
+    _displayObject(0),
     _array(false),
     _relay(0),
        _vm(VM::get()),
@@ -398,8 +398,8 @@
        Property* prop = pr.getProperty();
     if (!prop) {
         if (displayObject()) {
-            DisplayObject& d = static_cast<DisplayObject&>(*this);
-            if (getDisplayObjectProperty(d, name, *val)) return true;
+            DisplayObject* d = displayObject();
+            if (getDisplayObjectProperty(*d, name, *val)) return true;
         }
         while (pr()) {
             if ((prop = pr.getProperty())) break;
@@ -686,7 +686,7 @@
 
     bool tfVarFound = false;
     if (displayObject()) {
-        MovieClip* mc = dynamic_cast<MovieClip*>(this);
+        MovieClip* mc = dynamic_cast<MovieClip*>(displayObject());
         if (mc) tfVarFound = mc->setTextFieldVariables(key, val, nsname);
         // We still need to set the member.
     }
@@ -706,8 +706,8 @@
        if (!prop) { 
 
         if (displayObject()) {
-            DisplayObject& d = static_cast<DisplayObject&>(*this);
-            if (setDisplayObjectProperty(d, key, val)) return true;
+            DisplayObject* d = displayObject();
+            if (setDisplayObjectProperty(*d, key, val)) return true;
             // TODO: should we execute triggers?
         }
 
@@ -1069,7 +1069,7 @@
 
     // Hack to handle MovieClips.
        if (displayObject()) {
-        static_cast<const DisplayObject&>(*this).enumerateNonProperties(env);
+        displayObject()->enumerateNonProperties(env);
     }
 
        // this set will keep track of visited objects,
@@ -1337,6 +1337,7 @@
 
     /// Proxy objects can contain references to other as_objects.
     if (_relay) _relay->setReachable();
+    if (_displayObject) _displayObject->setReachable();
 }
 #endif // GNASH_USE_GC
 
@@ -1379,11 +1380,16 @@
        }
 }
 
-DisplayObject*
-getDisplayObject(as_object* obj)
+as_object*
+getObjectWithPrototype(Global_as& gl, string_table::key c)
 {
-    if (!obj || !obj->displayObject()) return 0;
-    return &static_cast<DisplayObject&>(*obj);
+    as_object* ctor = gl.getMember(c).to_object(gl);
+    as_object* proto = ctor ?
+        ctor->getMember(NSV::PROP_PROTOTYPE).to_object(gl) : 0;
+
+    as_object* o = gl.createObject();
+    o->set_prototype(proto ? proto : as_value());
+    return o;
 }
 
 /// Get the VM from an as_object

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2009-10-23 06:25:25 +0000
+++ b/libcore/as_object.h       2009-11-04 12:23:50 +0000
@@ -807,21 +807,14 @@
     bool set_member_flags(string_table::key name,
             int setTrue, int setFalse=0, string_table::key nsname = 0);
 
-    /// Cast to a sprite, or return NULL
-    virtual MovieClip* to_movie() { return NULL; }
-
-    const MovieClip* to_movie() const {
-        return const_cast<as_object*>(this)->to_movie();
-    }
-
     /// Cast to a as_function, or return NULL
     virtual as_function* to_function() { return NULL; }
 
     /// Cast to a DisplayObject, or return NULL
-    virtual DisplayObject* toDisplayObject() { return NULL; }
+    DisplayObject* toDisplayObject() { return displayObject(); }
 
     const DisplayObject* toDisplayObject() const {
-        return const_cast<as_object*>(this)->toDisplayObject();
+        return const_cast<as_object*>(this)->displayObject();
     }
 
     /// Return true if this is a 'super' object
@@ -995,7 +988,7 @@
     }
 
     /// Return true if this is a DisplayObject.
-    bool displayObject() const {
+    DisplayObject* displayObject() const {
         return _displayObject;
     }
 
@@ -1003,22 +996,12 @@
     //
     /// This enables DisplayObject properties such as _x and _y. A flag
     /// is used to avoid RTTI on every get and set of properties.
-    void setDisplayObject() {
-        _displayObject = true;
+    void setDisplayObject(DisplayObject* d) {
+        _displayObject = d;
     }
 
 protected:
 
-    /// Enumerate any non-proper properties
-    //
-    /// This function is called by enumerateProperties(as_environment&) 
-    /// to allow for enumeration of properties that are not "proper"
-    /// (not contained in the as_object PropertyList).
-    ///
-    /// The default implementation adds nothing
-    ///
-    virtual void enumerateNonProperties(as_environment&) const {}
-
     ///Get a member value at a given slot.
     //
     ///This is a wrapper around get_member_default.
@@ -1089,7 +1072,7 @@
     //
     /// These magic properties are invoked in get_member only if the
     /// object is a DisplayObject
-    bool _displayObject;
+    DisplayObject* _displayObject;
 
     /// An array is a special type of object.
     //
@@ -1179,6 +1162,21 @@
 void getURLEncodedVars(as_object& o, std::string& data);
 
 
+/// Extract the DisplayObject attached to an object
+//
+/// @return     0 if no DisplayObject is attached, or if it is not the
+///             requested type
+/// @param o    The object to check.
+template<typename T>
+T*
+get(as_object* o)
+{
+    if (!o) return 0;
+    return dynamic_cast<T*>(o->displayObject());
+}
+
+as_object* getObjectWithPrototype(Global_as& gl, string_table::key c);
+
 /// Comparator for ObjectURI so it can serve as a key in stdlib containers.
 inline bool
 operator<(const ObjectURI& a, const ObjectURI& b)
@@ -1223,12 +1221,6 @@
 }
 
 
-/// Return the DisplayObject part of an as_object
-//
-/// @param obj      The object whose DisplayObject part should be returned
-/// @return         The DisplayObject if the object is one, otherwise 0.
-DisplayObject* getDisplayObject(as_object* obj);
-
 /// Get the VM from an as_object
 VM& getVM(const as_object& o);
 

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2009-10-23 06:25:25 +0000
+++ b/libcore/as_value.cpp      2009-10-27 09:44:54 +0000
@@ -912,7 +912,7 @@
                        return getFun();
 
                case MOVIECLIP:
-                       return toDisplayObject();
+                       return getObject(toDisplayObject());
 
                case STRING:
                        return global.createString(getStr());
@@ -992,7 +992,7 @@
     if (obj->displayObject()) {
         // The static cast is fine as long as the as_object is genuinely
         // a DisplayObject.
-               setDisplayObject(static_cast<DisplayObject&>(*obj));
+               setDisplayObject(*obj->displayObject());
                return;
        }
        as_function* func = obj->to_function();

=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp        2009-10-26 08:41:46 +0000
+++ b/libcore/asobj/Color_as.cpp        2009-10-27 09:44:54 +0000
@@ -278,7 +278,7 @@
     const as_value& target = obj->getMember(NSV::PROP_TARGET);
     MovieClip* sp = target.to_sprite();
     if (sp) return sp;
-    as_object* o = fn.env().find_target(target.to_string());
+    DisplayObject* o = fn.env().find_target(target.to_string());
     if (o) return o->to_movie();
     return 0;
 }

=== modified file 'libcore/asobj/MovieClipLoader.cpp'
--- a/libcore/asobj/MovieClipLoader.cpp 2009-10-26 08:41:46 +0000
+++ b/libcore/asobj/MovieClipLoader.cpp 2009-11-04 13:37:17 +0000
@@ -202,7 +202,7 @@
                return as_value(false);
        }
 
-    as_value targetVal(sprite);
+    as_value targetVal(getObject(sprite));
 
     movie_root& mr = getRoot(*ptr);
        URL url(str_url, mr.runResources().baseURL());
@@ -218,8 +218,8 @@
         // was attempted (sandbox) or no status information is available
         // (supposedly the Adobe mozilla plugin).
                as_value arg2(0.0);
-               ptr->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onLoadError", 
sprite,
-                arg1, arg2);
+               ptr->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onLoadError",
+                getObject(sprite), arg1, arg2);
 
                return as_value(true);
        }
@@ -296,9 +296,9 @@
                return as_value();
        }
 
-       boost::intrusive_ptr<as_object> target = 
fn.arg(0).to_object(getGlobal(fn));
+       as_object* target = fn.arg(0).to_object(getGlobal(fn));
   
-       if (!target.get()) {
+       if (!target) {
                IF_VERBOSE_ASCODING_ERRORS(
                log_aserror(_("MovieClipLoader.getProgress(%s): first argument 
is "
                 "not an object"), fn.arg(0));
@@ -306,7 +306,7 @@
                return as_value();
        }
 
-       MovieClip* sp = target->to_movie();
+       MovieClip* sp = get<MovieClip>(target);
        if (!sp) {
                IF_VERBOSE_ASCODING_ERRORS(
                log_aserror(_("MovieClipLoader.getProgress(%s): first argument 
is "

=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp    2009-10-26 08:41:46 +0000
+++ b/libcore/asobj/Selection_as.cpp    2009-11-04 13:37:17 +0000
@@ -104,8 +104,6 @@
 as_value
 selection_getBeginIndex(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
-    
     movie_root& mr = getRoot(fn);
     DisplayObject* focus = mr.getFocus();
 
@@ -126,8 +124,6 @@
 as_value
 selection_getCaretIndex(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
-
     movie_root& mr = getRoot(fn);
     DisplayObject* focus = mr.getFocus();
 
@@ -142,8 +138,6 @@
 as_value
 selection_getEndIndex(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
-
     movie_root& mr = getRoot(fn);
     DisplayObject* focus = mr.getFocus();
 
@@ -159,8 +153,6 @@
 as_value
 selection_getFocus(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
-    
     movie_root& mr = getRoot(fn);
 
     DisplayObject* ch = mr.getFocus();
@@ -195,8 +187,6 @@
 selection_setFocus(const fn_call& fn)
 {
 
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
-
     /// Handle invalid arguments: must be one argument, or no action is
     /// taken.
     if (!fn.nargs || fn.nargs > 1) {
@@ -225,8 +215,8 @@
     }
     else {
         /// Try converting directly to DisplayObject.
-        ch = dynamic_cast<DisplayObject*>(
-                focus.to_object(getGlobal(fn)));
+        as_object* obj = focus.to_object(getGlobal(fn));
+        ch = get<DisplayObject>(obj);
     }
 
     // If the argument does not resolve to a DisplayObject, do nothing.
@@ -242,7 +232,6 @@
 as_value
 selection_setSelection(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
 
     movie_root& mr = getRoot(fn);
     DisplayObject* focus = mr.getFocus();

=== modified file 'libcore/asobj/flash/display/DisplayObjectContainer_as.cpp'
--- a/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-10-23 
06:25:25 +0000
+++ b/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-10-27 
09:44:54 +0000
@@ -164,7 +164,7 @@
         return ret;
     }
 
-    return as_value(ptr->addChild(ch));
+    return as_value(getObject(ptr->addChild(ch)));
 }
 
 as_value
@@ -214,7 +214,7 @@
     std::stringstream ss; fn.dump_args(ss);
     log_debug("TESTING: addChildAt(%s)", ss.str());
     
-    return as_value(ptr->addChildAt(ch, depth));
+    return as_value(getObject(ptr->addChildAt(ch, depth)));
 
 }
 

=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp      2009-10-26 10:20:25 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp      2009-11-04 16:55:59 
+0000
@@ -37,6 +37,7 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
 #include "NativeFunction.h" 
+#include "Bitmap.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -117,49 +118,36 @@
 }
 
 // extern (used by Global.cpp)
+// proto = getDisplayObjectContainerInterface();
+// proto = getDisplayObjectContainerInterface();
 void
 movieclip_class_init(as_object& where, const ObjectURI& uri)
 {
+    Global_as& gl = getGlobal(where);
+    as_object* proto = gl.createObject();
+
     if (isAS3(getVM(where))) {
-
-        static boost::intrusive_ptr<as_object> cl =
-            new as_object(getMovieClipAS3Interface());
+        as_object* cl = new as_object(proto);
+        attachMovieClipAS3Interface(*proto);
         
         // TODO: fix AVM2Global::createClass to work for AVM2.
-        Global_as& gl = getGlobal(where);
         cl->init_member(NSV::PROP_CONSTRUCTOR,
                 gl.createFunction(movieclip_as3_ctor));
 
         log_debug("AVM2 MovieClip, proto %s", cl);
 
-        where.init_member("MovieClip", cl);
+        where.init_member(getName(uri), cl, as_object::DefaultFlags,
+                getNamespace(uri));
         return;
     }
 
-    static boost::intrusive_ptr<as_object> cl;
-
-    if (!cl) {
-        Global_as& gl = getGlobal(where);
-        as_object* proto = getMovieClipAS2Interface();
-        cl = gl.createClass(&movieclip_as2_ctor, proto);
-        getVM(where).addStatic(cl.get());
-    }
-
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    as_object* cl = gl.createClass(&movieclip_as2_ctor, proto);
+    attachMovieClipAS2Interface(*proto);
+
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 
-as_object*
-getMovieClipAS3Interface()
-{
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = getDisplayObjectContainerInterface();
-        attachMovieClipAS3Interface(*o);
-    }
-    return o.get();
-}
-
 void
 registerMovieClipNative(as_object& where)
 {
@@ -222,34 +210,6 @@
 
 }
 
-/// Properties (and/or methods) attached to every *instance* of a MovieClip 
-void
-attachMovieClipAS2Properties(DisplayObject& o)
-{
-
-    // This is a normal property, can be overridden, deleted and enumerated
-    // See swfdec/test/trace/movieclip-version-#.swf for why we only
-    // initialize this if we don't have a parent
-    if (!o.get_parent()) o.init_member("$version",
-            getVM(o).getPlayerVersion(), 0); 
-
-}
-
-as_object*
-getMovieClipAS2Interface()
-{
-    static boost::intrusive_ptr<as_object> proto;
-    if ( proto == NULL )
-    {
-        proto = new as_object(getObjectInterface());
-        VM& vm = VM::get();
-        vm.addStatic(proto.get());
-        attachMovieClipAS2Interface(*proto);
-    }
-    return proto.get();
-}
-
-
 namespace {
 
 // =======================
@@ -353,7 +313,7 @@
 as_value
 movieclip_createEmptyMovieClip(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs != 2) {
         if (fn.nargs < 2) {
@@ -373,9 +333,9 @@
         )
     }
 
-    // TODO: improve MovieClip ctor (and don't use it here anyway).
     Movie* m = getRoot(fn).topLevelMovie();
-    MovieClip* mc = new MovieClip(0, m, ptr.get());
+    as_object* o = getObjectWithPrototype(getGlobal(fn), 
NSV::CLASS_MOVIE_CLIP);
+    MovieClip* mc = new MovieClip(o, 0, m, ptr);
 
     mc->set_name(fn.arg(0).to_string());
     mc->setDynamic();
@@ -383,15 +343,15 @@
     // Unlike other MovieClip methods, the depth argument of an empty movie 
clip
     // can be any number. All numbers are converted to an int32_t, and are 
valid
     // depths even when outside the usual bounds.
-    DisplayObject* ch = ptr->addDisplayListObject(mc, fn.arg(1).to_int());
-    return as_value(ch);
+    ptr->addDisplayListObject(mc, fn.arg(1).to_int());
+    return as_value(o);
 }
 
 
 as_value
 movieclip_play(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     movieclip->setPlayState(MovieClip::PLAYSTATE_PLAY);
     return as_value();
@@ -400,7 +360,7 @@
 as_value
 movieclip_stop(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     movieclip->setPlayState(MovieClip::PLAYSTATE_STOP);
 
@@ -412,7 +372,7 @@
 as_value
 movieclip_removeMovieClip(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     movieclip->removeMovieClip();
     return as_value();
 }
@@ -421,7 +381,7 @@
 as_value
 movieclip_cacheAsBitmap(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE( log_unimpl(_("MovieClip.cacheAsBitmap()")) );
     return as_value();
@@ -431,7 +391,7 @@
 as_value
 movieclip_filters(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.filters()")));
     return as_value();
@@ -441,7 +401,7 @@
 as_value
 movieclip_forceSmoothing(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.forceSmoothing()")));
     return as_value();
@@ -451,7 +411,7 @@
 as_value
 movieclip_opaqueBackground(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.opaqueBackground()")));
     return as_value();
@@ -461,7 +421,7 @@
 as_value
 movieclip_scale9Grid(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.scale9Grid()")));
     return as_value();
@@ -471,7 +431,7 @@
 as_value
 movieclip_scrollRect(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.scrollRect()")));
     return as_value();
@@ -481,7 +441,7 @@
 as_value
 movieclip_tabIndex(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
     LOG_ONCE(log_unimpl(_("MovieClip.tabIndex()")));
     return as_value();
@@ -493,7 +453,7 @@
 as_value
 movieclip_attachMovie(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs < 3 || fn.nargs > 4)
     {
@@ -555,7 +515,8 @@
     
     boost::int32_t depthValue = static_cast<boost::int32_t>(depth);
 
-    DisplayObject* newch = exported_movie->createDisplayObject(movieclip);
+    Global_as& gl = getGlobal(fn);
+    DisplayObject* newch = exported_movie->createDisplayObject(gl, movieclip);
 
     newch->set_name(newname);
     newch->setDynamic();
@@ -584,7 +545,7 @@
         return as_value();
     }
 
-    return as_value(newch);
+    return as_value(getObject(newch));
 }
 
 
@@ -592,7 +553,7 @@
 as_value
 movieclip_attachAudio(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (!fn.nargs)
     {
@@ -623,7 +584,7 @@
 as_value
 movieclip_attachVideo(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(movieclip);
 
     LOG_ONCE( log_unimpl("MovieClip.attachVideo()") );
@@ -635,9 +596,9 @@
 movieclip_getDepth(const fn_call& fn)
 {
     // Unlike TextField.getDepth this works for any DisplayObject
-    DisplayObject* movieclip = ensure<ThisIs<DisplayObject> >(fn);
+    DisplayObject* d = ensure<IsDisplayObject<> >(fn);
 
-    const int n = movieclip->get_depth();
+    const int n = d->get_depth();
 
     return as_value(n);
 }
@@ -649,7 +610,7 @@
 movieclip_swapDepths(const fn_call& fn)
 {
 
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     const int this_depth = movieclip->get_depth();
 
@@ -784,7 +745,7 @@
 as_value
 movieclip_duplicateMovieClip(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
     
     if (fn.nargs < 2)
     {
@@ -826,13 +787,13 @@
         ch = movieclip->duplicateMovieClip(newname, depthValue);
     }
 
-    return as_value(ch);
+    return as_value(getObject(ch));
 }
 
 as_value
 movieclip_gotoAndPlay(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs < 1)
     {
@@ -861,7 +822,7 @@
 
 as_value movieclip_gotoAndStop(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs < 1)
     {
@@ -890,7 +851,7 @@
 
 as_value movieclip_nextFrame(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     const size_t frame_count = movieclip->get_frame_count();
     const size_t current_frame = movieclip->get_current_frame();
@@ -905,7 +866,7 @@
 as_value
 movieclip_prevFrame(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     const size_t current_frame = movieclip->get_current_frame();
     if (current_frame > 0)
@@ -919,7 +880,7 @@
 as_value
 movieclip_getBytesLoaded(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     return as_value(movieclip->get_bytes_loaded());
 }
@@ -927,7 +888,7 @@
 as_value
 movieclip_getBytesTotal(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     // @@ horrible uh ?
     return as_value(movieclip->get_bytes_total());
@@ -940,13 +901,13 @@
 as_value
 movieclip_loadMovie(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     as_value val;
     if (fn.nargs > 1) {
-        val = movieclip->callMethod(NSV::PROP_METH, fn.arg(1));
+        val = getObject(movieclip)->callMethod(NSV::PROP_METH, fn.arg(1));
     }
-    else val = movieclip->callMethod(NSV::PROP_METH);
+    else val = getObject(movieclip)->callMethod(NSV::PROP_METH);
 
     if (fn.nargs < 1) // url
     {
@@ -984,7 +945,7 @@
     // This is just an optimization if we aren't going
     // to send the data anyway. It might be wrong, though.
     if (method != MovieClip::METHOD_NONE) {
-        getURLEncodedVars(*movieclip, data);
+        getURLEncodedVars(*getObject(movieclip), data);
     }
  
     mr.loadMovie(urlstr, target, data, method);
@@ -996,16 +957,19 @@
 as_value
 movieclip_loadVariables(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
+
+    as_object* obj = getObject(movieclip);
+    assert(obj);
 
     // This always calls MovieClip.meth, even when there are no
     // arguments.
     as_value val;
     if (fn.nargs > 1)
     {
-        val = movieclip->callMethod(NSV::PROP_METH, fn.arg(1));
+        val = obj->callMethod(NSV::PROP_METH, fn.arg(1));
     }
-    else val = movieclip->callMethod(NSV::PROP_METH);
+    else val = obj->callMethod(NSV::PROP_METH);
 
     if (fn.nargs < 1) // url
     {
@@ -1043,7 +1007,7 @@
 as_value
 movieclip_unloadMovie(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     movieclip->unloadMovie();
 
@@ -1053,7 +1017,7 @@
 as_value
 movieclip_hitTest(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     switch (fn.nargs)
     {
@@ -1119,7 +1083,7 @@
 as_value
 movieclip_getNextHighestDepth(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     int nextdepth = movieclip->getNextHighestDepth();
     return as_value(static_cast<double>(nextdepth));
@@ -1129,7 +1093,7 @@
 as_value
 movieclip_getInstanceAtDepth(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> mc = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* mc = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs < 1 || fn.arg(0).is_undefined()) {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -1146,7 +1110,7 @@
     // we want 'undefined', not 'null'
     if (!ch) return as_value();
 
-    return as_value(ch);
+    return as_value(getObject(ch));
 }
 
 /// MovieClip.getURL(url:String[, window:String[, method:String]])
@@ -1158,7 +1122,7 @@
 as_value
 movieclip_getURL(const fn_call& fn)
 {
-    as_object* movieclip = ensure<ThisIs<as_object> >(fn);
+    as_object* movieclip = ensure<ValidThis>(fn);
 
     std::string urlstr;
     std::string target;
@@ -1219,7 +1183,7 @@
 as_value
 movieclip_getSWFVersion(const fn_call& fn)
 {
-    DisplayObject* o = getDisplayObject(fn.this_ptr);
+    DisplayObject* o = get<DisplayObject>(fn.this_ptr);
     if (!o) return as_value(-1);
     return as_value(o->getDefinitionVersion());
 }
@@ -1255,7 +1219,7 @@
 as_value
 movieclip_getTextSnapshot(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> obj = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     // If not found, construction fails.
     as_value textSnapshot(fn.env().find_object("TextSnapshot"));
@@ -1272,7 +1236,7 @@
 
     // Construct a flash.geom.Transform object with "this" as argument.
     fn_call::Args args;
-    args += obj.get();
+    args += getObject(movieclip);
 
     boost::intrusive_ptr<as_object> ts =
         tsCtor->constructInstance(fn.env(), args);
@@ -1285,7 +1249,7 @@
 as_value
 movieclip_getBounds(const fn_call& fn)
 {
-    DisplayObject* movieclip = ensure<ThisIs<DisplayObject> >(fn);
+    DisplayObject* movieclip = ensure<IsDisplayObject<> >(fn);
 
     SWFRect bounds = movieclip->getBounds();
 
@@ -1336,7 +1300,7 @@
 as_value
 movieclip_globalToLocal(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     as_value ret;
 
@@ -1398,7 +1362,7 @@
 as_value
 movieclip_localToGlobal(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     as_value ret;
 
@@ -1461,9 +1425,9 @@
 movieclip_setMask(const fn_call& fn)
 {
     // swfdec/test/image/mask-textfield-6.swf shows that setMask should also
-    // work against TextFields, we have no tests for other DisplayObject types 
so
-    // we generalize it for any DisplayObject.
-    DisplayObject* maskee = ensure<ThisIs<DisplayObject> >(fn);
+    // work against TextFields, we have no tests for other DisplayObject
+    // types so we generalize it for any DisplayObject.
+    DisplayObject* maskee = ensure<IsDisplayObject<> >(fn);
 
     if ( ! fn.nargs )
     {
@@ -1477,14 +1441,14 @@
     if ( arg.is_null() || arg.is_undefined() )
     {
         // disable mask
-        maskee->setMask(NULL);
+        maskee->setMask(0);
     }
     else
     {
 
-        boost::intrusive_ptr<as_object> obj ( arg.to_object(getGlobal(fn)) );
-        DisplayObject* mask = dynamic_cast<DisplayObject*>(obj.get());
-        if ( ! mask )
+        as_object* obj = arg.to_object(getGlobal(fn));
+        DisplayObject* mask = get<DisplayObject>(obj);
+        if (!mask)
         {
             IF_VERBOSE_ASCODING_ERRORS(
             log_aserror(_("%s.setMask(%s) : first argument is not a 
DisplayObject"),
@@ -1505,7 +1469,7 @@
 as_value
 movieclip_endFill(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     IF_VERBOSE_ASCODING_ERRORS(
     if ( fn.nargs )
@@ -1525,7 +1489,7 @@
 as_value
 movieclip_lineTo(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( fn.nargs < 2 )
     {
@@ -1579,7 +1543,7 @@
 as_value
 movieclip_moveTo(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( fn.nargs < 2 )
     {
@@ -1639,7 +1603,7 @@
 as_value
 movieclip_lineStyle(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( ! fn.nargs )
     {
@@ -1789,7 +1753,7 @@
 as_value
 movieclip_curveTo(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( fn.nargs < 4 )
     {
@@ -1870,7 +1834,7 @@
 as_value
 movieclip_clear(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     IF_VERBOSE_ASCODING_ERRORS(
     if ( fn.nargs )
@@ -1892,7 +1856,7 @@
 as_value
 movieclip_beginFill(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( fn.nargs < 1 )
     {
@@ -1941,7 +1905,7 @@
 as_value
 movieclip_beginGradientFill(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if ( fn.nargs < 5 )
     {
@@ -2194,7 +2158,7 @@
 as_value
 movieclip_startDrag(const fn_call& fn)
 {
-    MovieClip* movieclip = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* movieclip = ensure<IsDisplayObject<MovieClip> >(fn);
 
     drag_state st;
     st.setCharacter(movieclip);
@@ -2275,7 +2239,7 @@
 as_value
 movieclip_beginBitmapFill(const fn_call& fn)
 {
-    MovieClip* ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     LOG_ONCE( log_unimpl (__FUNCTION__) );
     return as_value();
@@ -2285,7 +2249,7 @@
 as_value
 movieclip_getRect(const fn_call& fn)
 {
-    MovieClip* ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     LOG_ONCE( log_unimpl (__FUNCTION__) );
     return as_value();
@@ -2295,7 +2259,7 @@
 as_value
 movieclip_lineGradientStyle(const fn_call& fn)
 {
-    MovieClip* ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     LOG_ONCE( log_unimpl (__FUNCTION__) );
     return as_value();
@@ -2308,7 +2272,7 @@
 
     GNASH_REPORT_FUNCTION;
 
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (fn.nargs < 2) {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -2331,7 +2295,8 @@
 
     int depth = fn.arg(1).to_int();
 
-    ptr->attachBitmap(bd, depth);
+    DisplayObject* bm = new Bitmap(getRoot(fn), 0, bd, ptr);
+    ptr->attachCharacter(*bm, depth, 0);
 
     return as_value();
 }
@@ -2348,7 +2313,7 @@
 as_value
 movieclip_transform(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
 
     // If not found, construction fails.
     as_value transform(fn.env().find_object("flash.geom.Transform"));
@@ -2362,7 +2327,7 @@
 
     // Construct a flash.geom.Transform object with "this" as argument.
     fn_call::Args args;
-    args += ptr.get();
+    args += getObject(ptr);
 
     boost::intrusive_ptr<as_object> newTrans =
         transCtor->constructInstance(fn.env(), args);
@@ -2382,7 +2347,7 @@
 as_value
 movieclip_lockroot(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
 
     if (!fn.nargs) {
         return as_value(ptr->getLockRoot());
@@ -2401,11 +2366,15 @@
 {
     assert(isAS3(fn));
 
+    as_object* obj = ensure<ValidThis>(fn);
+
     // TODO: currently it's necessary to have a top-level movie to initialize
     // a MovieClip.
     Movie* m = getRoot(fn).topLevelMovie();
 
-    return new MovieClip(0, m, 0);
+    // Okay, this looks silly.
+    new MovieClip(obj, 0, m, 0);
+    return as_value();
 }
 
 
@@ -2427,7 +2396,7 @@
 as_value
 movieclip_addFrameScript(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     log_unimpl (__FUNCTION__);
     return as_value();
@@ -2436,7 +2405,7 @@
 as_value
 movieclip_nextScene(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     log_unimpl (__FUNCTION__);
     return as_value();
@@ -2445,7 +2414,7 @@
 as_value
 movieclip_prevScene(const fn_call& fn)
 {
-    boost::intrusive_ptr<MovieClip> ptr = ensure<ThisIs<MovieClip> >(fn);
+    MovieClip* ptr = ensure<IsDisplayObject<MovieClip> >(fn);
     UNUSED(ptr);
     log_unimpl (__FUNCTION__);
     return as_value();

=== modified file 'libcore/asobj/flash/display/MovieClip_as.h'
--- a/libcore/asobj/flash/display/MovieClip_as.h        2009-07-28 11:58:27 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.h        2009-11-04 20:39:35 
+0000
@@ -35,18 +35,9 @@
 /// Initialize the global MovieClip class
 void movieclip_class_init(as_object& where, const ObjectURI& uri);
 
-/// Get an as_object with the AS3 MovieClip interface.
-as_object* getMovieClipAS3Interface();
-
 /// Register ASNative MovieClip methods (AS2 only).
 void registerMovieClipNative(as_object& where);
 
-/// Used by MovieClip's ctor to attach properties to MovieClip instances.
-void attachMovieClipAS2Properties(DisplayObject& d);
-
-/// Get an as_object with the AS2 MovieClip interface.
-as_object* getMovieClipAS2Interface();
-
 } // gnash namespace
 
 #endif

=== modified file 'libcore/asobj/flash/geom/Transform_as.cpp'
--- a/libcore/asobj/flash/geom/Transform_as.cpp 2009-10-23 06:25:25 +0000
+++ b/libcore/asobj/flash/geom/Transform_as.cpp 2009-11-04 13:37:17 +0000
@@ -344,9 +344,8 @@
 
     // TODO: does this have to be a MovieClip or can it be any DisplayObject?
     as_object* o = fn.arg(0).to_object(getGlobal(fn));
-    if (!o) return as_value();
+    MovieClip* mc = get<MovieClip>(o);
 
-    MovieClip* mc = o->to_movie();
     if (!mc) return as_value();
 
     obj->setRelay(new Transform_as(*mc));

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2009-10-27 08:23:55 +0000
+++ b/libcore/movie_root.cpp    2009-11-04 20:01:38 +0000
@@ -19,7 +19,6 @@
 
 #include "GnashSystemIOHeaders.h" // write()
 
-#include "smart_ptr.h" // GNASH_USE_GC
 #include "movie_root.h"
 #include "log.h"
 #include "MovieClip.h"
@@ -191,7 +190,7 @@
 Movie*
 movie_root::init(movie_definition* def, const MovieClip::MovieVariables& vars)
 {
-    Movie* mr = def->createMovie();
+    Movie* mr = def->createMovie(*_vm.getGlobal());
     mr->setVariables(vars);
     setRootMovie(mr);
     return mr;
@@ -453,7 +452,7 @@
                return false;
        }
 
-       Movie* extern_movie = md->createMovie();
+       Movie* extern_movie = md->createMovie(*_vm.getGlobal());
 
        if (!extern_movie) {
                log_error(_("can't create extern Movie for %s"),
@@ -833,13 +832,13 @@
     // Set _droptarget if dragging a sprite
     MovieClip* dragging = 0;
     DisplayObject* draggingChar = getDraggingCharacter();
-    if ( draggingChar ) dragging = draggingChar->to_movie();
-    if ( dragging )
+    if (draggingChar) dragging = draggingChar->to_movie();
+    if (dragging)
     {
         // TODO: optimize making findDropTarget and getTopmostMouseEntity
         //       use a single scan.
         const DisplayObject* dropChar = findDropTarget(x, y, dragging);
-        if ( dropChar )
+        if (dropChar)
         {
             // Use target of closest script DisplayObject containing this
             dropChar = dropChar->getClosestASReferenceableAncestor();
@@ -1330,24 +1329,28 @@
     DisplayObject* from = _currentFocus;
 
     if (from) {
-
         // Perform any actions required on killing focus (only TextField).
         from->killFocus();
-        from->callMethod(NSV::PROP_ON_KILL_FOCUS, to);
+
+        /// A valid focus must have an associated object.
+        assert(getObject(from));
+        getObject(from)->callMethod(NSV::PROP_ON_KILL_FOCUS, getObject(to));
     }
 
     _currentFocus = to;
 
     if (to) {
-        to->callMethod(NSV::PROP_ON_SET_FOCUS, from);
+        assert(getObject(to));
+        getObject(to)->callMethod(NSV::PROP_ON_SET_FOCUS, getObject(from));
     }
 
     as_object* sel = getSelectionObject();
 
-    /// Notify Selection listeners with previous and new focus as arguments.
+    // Notify Selection listeners with previous and new focus as arguments.
+    // Either argument may be null.
     if (sel) {
         sel->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onSetFocus",
-                from, to);
+                getObject(from), getObject(to));
     }
 
        assert(testInvariant());
@@ -1482,7 +1485,7 @@
 /// Sets the value of _showMenu and calls the gui handler to process the 
 /// fscommand to change the display of the context menu
 void
-movie_root::setShowMenuState( bool state )
+movie_root::setShowMenuState(bool state)
 {
        _showMenu = state;
        //FIXME: The gui code for show menu is semantically different than what
@@ -1511,7 +1514,7 @@
 void
 movie_root::setStageScaleMode(ScaleMode sm)
 {
-    if ( _scaleMode == sm ) return; // nothing to do
+    if (_scaleMode == sm) return; // nothing to do
 
     bool notifyResize = false;
     
@@ -1541,7 +1544,8 @@
         as_object* stage = getStageObject();
         if (stage) {
             log_debug("notifying Stage listeners about a resize");
-            stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
+            stage->callMethod(NSV::PROP_BROADCAST_MESSAGE,
+                    "onResize");
         }
     }
 }
@@ -1734,14 +1738,13 @@
                        target->getTargetPath());
 #endif
 
-       std::auto_ptr<ExecutableCode> code ( new GlobalCode(buf, target) );
+       std::auto_ptr<ExecutableCode> code(new GlobalCode(buf, target));
 
        _actionQueue[lvl].push_back(code.release());
 }
 
 void
-movie_root::pushAction(as_function* func,
-        DisplayObject* target, int lvl)
+movie_root::pushAction(as_function* func, DisplayObject* target, int lvl)
 {
        assert(lvl >= 0 && lvl < apSIZE);
 #ifdef GNASH_DEBUG
@@ -1749,7 +1752,7 @@
             target->getTargetPath());
 #endif
 
-       std::auto_ptr<ExecutableCode> code ( new FunctionCode(func, target) );
+       std::auto_ptr<ExecutableCode> code(new FunctionCode(func, target));
 
        _actionQueue[lvl].push_back(code.release());
 }
@@ -1935,7 +1938,7 @@
             i!=e; ++i) {
                
         const DisplayObject* ret = i->second->findDropTarget(x, y, dragging);
-               if ( ret ) return ret;
+               if (ret) return ret;
        }
        return 0;
 }
@@ -1997,24 +2000,26 @@
                for (LiveChars::iterator i=_liveChars.begin(), 
e=_liveChars.end(); i!=e;)
                {
                        DisplayObject* ch = *i;
-                       if ( ch->unloaded() )
-                       {
+                       if (ch->unloaded()) {
                                // the sprite might have been destroyed already
                                // by effect of an unload() call with no 
onUnload
                                // handlers available either in self or child
                                // DisplayObjects
-                               if ( ! ch->isDestroyed() )
-                               {
+                               if (!ch->isDestroyed()) {
+
 #ifdef GNASH_DEBUG_DLIST_CLEANUP
-                                       cout << ch->getTarget() << "(" << 
typeName(*ch) << ") was unloaded but not destroyed, destroying now" << endl;
+                                       cout << ch->getTarget() << "(" << 
typeName(*ch) <<
+                        ") was unloaded but not destroyed, destroying now" <<
+                        endl;
 #endif
                                        ch->destroy();
-                                       needScan=true; // ->destroy() might 
mark already-scanned chars as unloaded
+                    // destroy() might mark already-scanned chars as unloaded
+                                       needScan = true; 
                                }
 #ifdef GNASH_DEBUG_DLIST_CLEANUP
-                               else
-                               {
-                                       cout << ch->getTarget() << "(" << 
typeName(*ch) << ") was unloaded and destroyed" << endl;
+                               else {
+                                       cout << ch->getTarget() << "(" << 
typeName(*ch) <<
+                        ") was unloaded and destroyed" << endl;
                                }
 #endif
 
@@ -2024,14 +2029,12 @@
                                cleaned++;
 #endif
                        }
-                       else
-                       {
-                               ++i;
-                       }
+                       else ++i; 
                }
 
 #ifdef GNASH_DEBUG_DLIST_CLEANUP
-               cout << " Scan " << scansCount << " cleaned " << cleaned << " 
instances" << endl;
+               cout << " Scan " << scansCount << " cleaned " << cleaned <<
+            " instances" << endl;
 #endif
        } while (needScan);
 
@@ -2114,13 +2117,19 @@
        //       root movie is replaced by a load to _level0... 
        //       (but I guess we'd also drop loadMovie requests in that
        //       case... just not tested)
-       as_object* o = _movies.begin()->second;
+       as_object* o = getObject(_movies.begin()->second);
+    assert(o);
 
        std::string::size_type from = 0;
        while (std::string::size_type to = tgtstr.find('.', from))
        {
                std::string part(tgtstr, from, to - from);
-               o = o->get_path_element(st.find(part));
+
+        // TODO: there is surely a cleaner way to implement path finding.
+        o = o->displayObject() ?
+            o->displayObject()->pathElement(st.find(part)) :
+            o->get_path_element(st.find(part));
+
                if (!o) {
 #ifdef GNASH_DEBUG_TARGET_RESOLUTION
                        log_debug("Evaluating DisplayObject target path: 
element "
@@ -2446,9 +2455,10 @@
 #endif
 
 void
-movie_root::handleFsCommand(const std::string& cmd, const std::string& arg) 
const
+movie_root::handleFsCommand(const std::string& cmd, const std::string& arg)
+    const
 {
-       if ( _fsCommandHandler ) _fsCommandHandler->notify(cmd, arg);
+       if (_fsCommandHandler) _fsCommandHandler->notify(cmd, arg);
 }
 
 void

=== modified file 'libcore/parser/BitmapMovieDefinition.cpp'
--- a/libcore/parser/BitmapMovieDefinition.cpp  2009-10-12 09:42:13 +0000
+++ b/libcore/parser/BitmapMovieDefinition.cpp  2009-11-04 16:55:59 +0000
@@ -25,13 +25,16 @@
 #include "log.h"
 #include "Bitmap.h"
 #include "Renderer.h"
+#include "Global_as.h"
+#include "namedStrings.h"
 
 namespace gnash {
 
 Movie*
-BitmapMovieDefinition::createMovie(DisplayObject* parent)
+BitmapMovieDefinition::createMovie(Global_as& gl, DisplayObject* parent)
 {
-    return new BitmapMovie(this, parent);
+    as_object* o = getObjectWithPrototype(gl, NSV::CLASS_MOVIE_CLIP);
+    return new BitmapMovie(o, this, parent);
 }
 
 BitmapMovieDefinition::BitmapMovieDefinition(std::auto_ptr<GnashImage> image,
@@ -48,10 +51,11 @@
 }
 
 DisplayObject*
-BitmapMovieDefinition::createDisplayObject(DisplayObject* parent) const
+BitmapMovieDefinition::createDisplayObject(Global_as& /*gl*/,
+        DisplayObject* /*parent*/) const
 {
-    /// What should we do if construction of the bitmap fails?
-    return new Bitmap(this, parent);
+    std::abort();
+    return 0;
 }
 
 #ifdef GNASH_USE_GC

=== modified file 'libcore/parser/BitmapMovieDefinition.h'
--- a/libcore/parser/BitmapMovieDefinition.h    2009-10-12 09:42:13 +0000
+++ b/libcore/parser/BitmapMovieDefinition.h    2009-11-04 15:03:15 +0000
@@ -60,7 +60,8 @@
        BitmapMovieDefinition(std::auto_ptr<GnashImage> image, Renderer* 
renderer,
             const std::string& url);
 
-    virtual DisplayObject* createDisplayObject(DisplayObject*) const;
+    virtual DisplayObject* createDisplayObject(Global_as&, DisplayObject*)
+        const;
 
        virtual int     get_version() const {
                return _version;
@@ -104,7 +105,7 @@
        }
        
        /// Create a playable Movie from this def.
-       virtual Movie* createMovie(DisplayObject* parent=0);
+       virtual Movie* createMovie(Global_as& gl, DisplayObject* parent = 0);
 
        virtual const std::string& get_url() const {
                return _url;

=== modified file 'libcore/parser/SWFMovieDefinition.cpp'
--- a/libcore/parser/SWFMovieDefinition.cpp     2009-10-01 13:19:43 +0000
+++ b/libcore/parser/SWFMovieDefinition.cpp     2009-11-04 16:55:59 +0000
@@ -40,6 +40,9 @@
 #include "ExportableResource.h"
 #include "GnashAlgorithm.h"
 #include "SWFParser.h"
+#include "Global_as.h"
+#include "namedStrings.h"
+#include "as_function.h"
 
 #include <boost/bind.hpp>
 #include <boost/version.hpp>
@@ -418,9 +421,10 @@
 }
 
 Movie*
-SWFMovieDefinition::createMovie(DisplayObject* parent)
+SWFMovieDefinition::createMovie(Global_as& gl, DisplayObject* parent)
 {
-       return new SWFMovie(this, parent);
+    as_object* o = getObjectWithPrototype(gl, NSV::CLASS_MOVIE_CLIP);
+       return new SWFMovie(o, this, parent);
 }
 
 

=== modified file 'libcore/parser/SWFMovieDefinition.h'
--- a/libcore/parser/SWFMovieDefinition.h       2009-10-12 09:42:13 +0000
+++ b/libcore/parser/SWFMovieDefinition.h       2009-11-04 15:03:15 +0000
@@ -388,9 +388,10 @@
        /// The _root reference of the newly created movie_root
        /// will be set to a newly created Movie.
        ///
-       Movie* createMovie(DisplayObject* parent=0);
+       Movie* createMovie(Global_as& gl, DisplayObject* parent = 0);
 
-    virtual DisplayObject* createDisplayObject(DisplayObject*) const {
+    virtual DisplayObject* createDisplayObject(Global_as&, DisplayObject*)
+        const {
         return 0;
     }
 

=== modified file 'libcore/parser/movie_definition.h'
--- a/libcore/parser/movie_definition.h 2009-10-01 13:19:43 +0000
+++ b/libcore/parser/movie_definition.h 2009-11-04 15:03:15 +0000
@@ -134,7 +134,7 @@
        /// SWFMovieDefinition is one such example, future examples
        /// should include jpeg_movie_def and similar..
        ///
-       virtual Movie* createMovie(DisplayObject* /*parent*/=0)
+       virtual Movie* createMovie(Global_as& /*gl*/, DisplayObject* 
/*parent*/=0)
        {
                return NULL;
        }

=== modified file 'libcore/parser/sprite_definition.cpp'
--- a/libcore/parser/sprite_definition.cpp      2009-10-12 09:42:13 +0000
+++ b/libcore/parser/sprite_definition.cpp      2009-11-04 20:39:35 +0000
@@ -28,6 +28,8 @@
 #include "SWFStream.h" // for use
 #include "GnashAlgorithm.h"
 #include "SWFParser.h"
+#include "namedStrings.h"
+#include "Global_as.h"
 
 #include <vector>
 #include <string>
@@ -41,13 +43,19 @@
 namespace gnash {
 
 DisplayObject*
-sprite_definition::createDisplayObject(DisplayObject* parent) const
+sprite_definition::createDisplayObject(Global_as& gl, DisplayObject* parent)
+    const
 {
 #ifdef DEBUG_REGISTER_CLASS
        log_debug(_("Instantiating sprite_def %p"), (void*)this);
 #endif
-       MovieClip* si = new MovieClip(this, parent->get_root(), parent);
-       return si;
+
+    // Should not call MovieClip constructor (probably), but should
+    // attach MovieClip.prototype
+
+    as_object* obj = getObjectWithPrototype(gl, NSV::CLASS_MOVIE_CLIP);
+    DisplayObject* mc = new MovieClip(obj, this, parent->get_root(), parent);
+       return mc;
 }
 
 sprite_definition::~sprite_definition()

=== modified file 'libcore/parser/sprite_definition.h'
--- a/libcore/parser/sprite_definition.h        2009-10-12 09:42:13 +0000
+++ b/libcore/parser/sprite_definition.h        2009-10-26 09:54:37 +0000
@@ -235,7 +235,8 @@
        // the parent movie's display list.
        //
        // overloads from SWF::DefinitionTag
-       virtual DisplayObject* createDisplayObject(DisplayObject* parent) const;
+       virtual DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const;
 
        // See dox in movie_definition.h
        virtual void addControlTag(SWF::ControlTag* c)

=== modified file 'libcore/swf/DefineButtonTag.cpp'
--- a/libcore/swf/DefineButtonTag.cpp   2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineButtonTag.cpp   2009-11-04 15:21:01 +0000
@@ -32,6 +32,9 @@
 #include "filter_factory.h"
 #include "GnashKey.h" // for gnash::key::codeMap
 #include "GnashAlgorithm.h"
+#include "Global_as.h"
+#include "namedStrings.h"
+#include "as_function.h"
 
 namespace gnash {
 namespace SWF {
@@ -234,9 +237,11 @@
 }
 
 DisplayObject*
-DefineButtonTag::createDisplayObject(DisplayObject* parent) const
+DefineButtonTag::createDisplayObject(Global_as& gl, DisplayObject* parent)
+    const
 {
-    DisplayObject* ch = new Button(this, parent);
+    as_object* obj = getObjectWithPrototype(gl, NSV::CLASS_BUTTON);
+    DisplayObject* ch = new Button(obj, this, parent);
     return ch;
 }
 
@@ -327,12 +332,14 @@
     assert(button);
     assert(_definitionTag);
 
-    DisplayObject* o = _definitionTag->createDisplayObject(button);
+    Global_as& gl = getGlobal(*getObject(button));
+
+    DisplayObject* o = _definitionTag->createDisplayObject(gl, button);
 
     o->setMatrix(_matrix, true);
     o->set_cxform(_cxform);
     o->set_depth(_buttonLayer + DisplayObject::staticDepthOffset + 1);
-    if (name && o->wantsInstanceName()) {
+    if (name && isReferenceable(*o)) {
         o->set_name(button->getNextUnnamedInstanceName());
     }
     return o;

=== modified file 'libcore/swf/DefineButtonTag.h'
--- a/libcore/swf/DefineButtonTag.h     2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineButtonTag.h     2009-10-26 09:54:37 +0000
@@ -208,7 +208,8 @@
     virtual ~DefineButtonTag();
 
     /// Create a mutable instance of our definition.
-    DisplayObject* createDisplayObject(DisplayObject* parent) const;
+    DisplayObject* createDisplayObject(Global_as& gl, DisplayObject* parent)
+        const;
 
     /// Access the ButtonRecords directly. Used for modifying the
     /// Cxform by a DefineButtonCxform tag.

=== modified file 'libcore/swf/DefineEditTextTag.cpp'
--- a/libcore/swf/DefineEditTextTag.cpp 2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineEditTextTag.cpp 2009-11-04 20:01:00 +0000
@@ -20,6 +20,7 @@
 #include "movie_definition.h"
 #include "Font.h"
 #include "SWFStream.h"
+#include "Global_as.h"
 
 namespace gnash {
 namespace SWF {
@@ -39,11 +40,13 @@
 }
 
 DisplayObject*
-DefineEditTextTag::createDisplayObject(DisplayObject* parent) const
+DefineEditTextTag::createDisplayObject(Global_as& gl, DisplayObject* parent)
+    const
 {
        // Resolve the font, if possible
        getFont();
-       TextField* ch = new TextField(parent, *this);
+    as_object* obj = createTextFieldObject(gl);
+       TextField* ch = new TextField(obj, parent, *this);
 
        // This gives an "instance name" to the TextField, but
        // it is not really what we need.

=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h   2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineEditTextTag.h   2009-10-26 09:54:37 +0000
@@ -67,7 +67,8 @@
 
     const SWFRect& bounds() const { return _rect; }
 
-    DisplayObject* createDisplayObject(DisplayObject* parent) const;
+    DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const;
 
        /// Return a reference to the default text associated
        /// with this EditText definition.

=== modified file 'libcore/swf/DefineMorphShapeTag.cpp'
--- a/libcore/swf/DefineMorphShapeTag.cpp       2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineMorphShapeTag.cpp       2009-11-04 15:03:15 +0000
@@ -29,6 +29,7 @@
 #include "MovieClip.h"
 #include "GnashNumeric.h"
 #include "RunResources.h"
+#include "Global_as.h"
 
 namespace gnash {
 namespace SWF {
@@ -55,9 +56,10 @@
 }
 
 DisplayObject*
-DefineMorphShapeTag::createDisplayObject(DisplayObject* parent) const
+DefineMorphShapeTag::createDisplayObject(Global_as& gl,
+        DisplayObject* parent) const
 {
-    return new MorphShape(this, parent);
+    return new MorphShape(getRoot(gl), 0, this, parent);
 }
 
 void

=== modified file 'libcore/swf/DefineMorphShapeTag.h'
--- a/libcore/swf/DefineMorphShapeTag.h 2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineMorphShapeTag.h 2009-10-26 09:54:37 +0000
@@ -50,7 +50,8 @@
 
     virtual ~DefineMorphShapeTag() {}
 
-       virtual DisplayObject* createDisplayObject(DisplayObject* parent) const;
+       virtual DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const;
 
     virtual void display(Renderer& renderer, const MorphShape& inst) const;
 

=== modified file 'libcore/swf/DefineShapeTag.cpp'
--- a/libcore/swf/DefineShapeTag.cpp    2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineShapeTag.cpp    2009-11-04 15:03:15 +0000
@@ -31,6 +31,7 @@
 #include "MovieClip.h"
 #include "SWF.h"
 #include "Renderer.h"
+#include "Global_as.h"
 
 #include <algorithm>
 
@@ -63,9 +64,10 @@
 }
 
 DisplayObject*
-DefineShapeTag::createDisplayObject(DisplayObject* parent) const
+DefineShapeTag::createDisplayObject(Global_as& gl, DisplayObject* parent)
+    const
 {
-       return new Shape(this, parent);
+       return new Shape(getRoot(gl), 0, this, parent);
 }
     
 bool

=== modified file 'libcore/swf/DefineShapeTag.h'
--- a/libcore/swf/DefineShapeTag.h      2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineShapeTag.h      2009-10-26 09:54:37 +0000
@@ -42,7 +42,8 @@
     virtual void display(Renderer& renderer, const DisplayObject& inst) const;
 
     // Create a Shape DisplayObject.
-       virtual DisplayObject* createDisplayObject(DisplayObject* parent) const;
+       virtual DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const;
        
     /// Get cached bounds of this shape.
     const SWFRect& bounds() const { return _shape.getBounds(); }

=== modified file 'libcore/swf/DefineTextTag.cpp'
--- a/libcore/swf/DefineTextTag.cpp     2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineTextTag.cpp     2009-11-04 15:03:15 +0000
@@ -15,6 +15,7 @@
 #include "Font.h"
 #include "StaticText.h"
 #include "GnashAlgorithm.h"
+#include "Global_as.h"
 
 #include <algorithm>
 #include <numeric>
@@ -40,9 +41,10 @@
 }
 
 DisplayObject*
-DefineTextTag::createDisplayObject(DisplayObject* parent) const
+DefineTextTag::createDisplayObject(Global_as& gl, DisplayObject* parent)
+    const
 {
-    return new StaticText(this, parent);
+    return new StaticText(getRoot(gl), 0, this, parent);
 }
 
 bool

=== modified file 'libcore/swf/DefineTextTag.h'
--- a/libcore/swf/DefineTextTag.h       2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineTextTag.h       2009-10-26 09:54:37 +0000
@@ -67,7 +67,8 @@
     bool extractStaticText(std::vector<const TextRecord*>& to, size_t& size)
         const;
 
-    virtual DisplayObject* createDisplayObject(DisplayObject* parent) const;
+    virtual DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const;
 
 private:
 

=== modified file 'libcore/swf/DefineVideoStreamTag.cpp'
--- a/libcore/swf/DefineVideoStreamTag.cpp      2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineVideoStreamTag.cpp      2009-11-04 18:25:13 +0000
@@ -25,6 +25,7 @@
 #include "movie_definition.h"
 #include "GnashAlgorithm.h"
 #include "GnashNumeric.h"
+#include "Global_as.h"
 
 namespace gnash {
 namespace SWF {
@@ -133,9 +134,12 @@
 }
 
 DisplayObject*
-DefineVideoStreamTag::createDisplayObject(DisplayObject* parent) const
+DefineVideoStreamTag::createDisplayObject(Global_as& gl,
+        DisplayObject* parent) const
 {
-       DisplayObject* ch = new Video(this, parent);
+
+    as_object* obj = createVideoObject(gl);
+       DisplayObject* ch = new Video(obj, this, parent);
        return ch;
 }
 

=== modified file 'libcore/swf/DefineVideoStreamTag.h'
--- a/libcore/swf/DefineVideoStreamTag.h        2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefineVideoStreamTag.h        2009-10-26 09:54:37 +0000
@@ -83,7 +83,8 @@
 
        ~DefineVideoStreamTag();
 
-       DisplayObject* createDisplayObject(DisplayObject* parent) const;
+       DisplayObject* createDisplayObject(Global_as& gl, DisplayObject* parent)
+        const;
 
        /// Read tag SWF::DEFINEVIDEOSTREAM 
        //

=== modified file 'libcore/swf/DefinitionTag.h'
--- a/libcore/swf/DefinitionTag.h       2009-10-12 09:42:13 +0000
+++ b/libcore/swf/DefinitionTag.h       2009-10-26 09:54:37 +0000
@@ -28,6 +28,7 @@
 
 namespace gnash {
        class DisplayObject;
+       class Global_as;
        class SWFMatrix;
        class SWFRect;
     namespace SWF {
@@ -45,12 +46,19 @@
 
        virtual ~DefinitionTag() {};
        
-       /// Create a DisplayObject with the given parent and id
+       /// Create a DisplayObject with the given parent.
        //
+    /// This function will determine the correct prototype and associated
+    /// object using the passed global.
+    //
+    /// @param gl       The global object used to set prototype and
+    ///                 associated object.
+    //
     /// Calling this function creates a new DisplayObject from the
     /// DefinitionTag and adds it as a child of the specified parent
     /// DisplayObject.
-       virtual DisplayObject* createDisplayObject(DisplayObject* parent) const 
= 0;
+       virtual DisplayObject* createDisplayObject(Global_as& gl,
+            DisplayObject* parent) const = 0;
        
 };
 

=== modified file 'libcore/swf/DoABCTag.h'
--- a/libcore/swf/DoABCTag.h    2009-07-14 06:47:54 +0000
+++ b/libcore/swf/DoABCTag.h    2009-10-27 09:44:54 +0000
@@ -50,7 +50,7 @@
             return;
         }
 
-               VM& vm = getVM(*m);
+               VM& vm = getVM(*getObject(m));
         
         log_debug("getting machine.");
                Machine *mach = vm.getMachine();

=== modified file 'libcore/swf/ScriptLimitsTag.h'
--- a/libcore/swf/ScriptLimitsTag.h     2009-07-14 06:47:54 +0000
+++ b/libcore/swf/ScriptLimitsTag.h     2009-10-27 09:44:54 +0000
@@ -43,7 +43,7 @@
     {
         log_debug("Setting script limits: recursion %s, timeout %s",
                 _recursionLimit, _timeoutLimit);
-        getRoot(*m).setScriptLimits(_recursionLimit, _timeoutLimit);
+        getRoot(*getObject(m)).setScriptLimits(_recursionLimit, _timeoutLimit);
     }
 
     static void loader(SWFStream& in, TagType tag, movie_definition& m,

=== modified file 'libcore/swf/StartSoundTag.cpp'
--- a/libcore/swf/StartSoundTag.cpp     2009-07-14 06:01:56 +0000
+++ b/libcore/swf/StartSoundTag.cpp     2009-10-27 09:44:54 +0000
@@ -76,7 +76,7 @@
 StartSoundTag::execute(MovieClip* m, DisplayList& /* dlist */) const
 {
 
-    sound::sound_handler* handler = getRunResources(*m).soundHandler();
+    sound::sound_handler* handler = 
getRunResources(*getObject(m)).soundHandler();
 
     if (handler)
     {

=== modified file 'libcore/swf/StreamSoundBlockTag.cpp'
--- a/libcore/swf/StreamSoundBlockTag.cpp       2009-07-14 06:01:56 +0000
+++ b/libcore/swf/StreamSoundBlockTag.cpp       2009-10-27 09:44:54 +0000
@@ -34,7 +34,7 @@
 StreamSoundBlockTag::execute(MovieClip* m, DisplayList& /*dlist*/) const
 {
 
-       sound::sound_handler* handler = getRunResources(*m).soundHandler(); 
+       sound::sound_handler* handler = 
getRunResources(*getObject(m)).soundHandler(); 
        if (handler)
        {
                // This makes it possible to stop only the stream when 
framejumping.

=== modified file 'libcore/swf/SymbolClassTag.h'
--- a/libcore/swf/SymbolClassTag.h      2009-07-14 07:23:01 +0000
+++ b/libcore/swf/SymbolClassTag.h      2009-10-27 09:44:54 +0000
@@ -44,7 +44,7 @@
 
        virtual void execute(MovieClip* m, DisplayList& /* dlist */) const
        {
-               VM& vm = getVM(*m);
+               VM& vm = getVM(*getObject(m));
                Machine* mach = vm.getMachine();
                log_debug("SymbolClassTag: Creating class %s.", _rootClass);
                mach->instantiateClass(_rootClass, vm.getGlobal());

=== modified file 'libcore/swf_function.cpp'
--- a/libcore/swf_function.cpp  2009-10-23 06:25:25 +0000
+++ b/libcore/swf_function.cpp  2009-10-27 09:44:54 +0000
@@ -253,7 +253,7 @@
                        DisplayObject* tgtch = m_env.get_target();
                        if (tgtch) {
                                // NOTE: _lockroot will be handled by 
getAsRoot()
-                               as_object* r = tgtch->getAsRoot();
+                               as_object* r = getObject(tgtch->getAsRoot());
                                m_env.setRegister(current_reg, as_value(r));
                                ++current_reg;
                        }
@@ -262,7 +262,7 @@
                if (m_function2_flags & PRELOAD_PARENT) {
                        DisplayObject* tgtch = m_env.get_target();
             if (tgtch) {
-                as_object* parent = tgtch->get_parent();
+                as_object* parent = getObject(tgtch->get_parent());
                 m_env.setRegister(current_reg, parent);
                 ++current_reg;
             }

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-10-23 06:25:25 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-11-04 20:01:38 +0000
@@ -1036,11 +1036,8 @@
     DisplayObject *target = NULL;
     if ( tgt_str.empty() )
     {
-        as_object* obj = thread.getTarget();
-
-        target = dynamic_cast<DisplayObject*>(obj);
-        if ( ! target )
-        {
+        target = get<DisplayObject>(thread.getTarget());
+        if (!target) {
             log_error(_("ActionGetProperty(<empty>) called, but current "
                         "target is not a DisplayObject"));
         }
@@ -1134,7 +1131,7 @@
         return;
     }
 
-    boost::intrusive_ptr<MovieClip> sprite = ch->to_movie();
+    MovieClip* sprite = ch->to_movie();
     if ( ! sprite )
     {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -1313,8 +1310,7 @@
     as_environment& env = thread.env;
 
     // Get the "instance"
-    boost::intrusive_ptr<as_object> instance = 
-        convertToObject(getGlobal(thread.env), env.top(0));
+    as_object* instance = convertToObject(getGlobal(thread.env), env.top(0));
 
     // Get the "super" function
     as_function* super = env.top(1).to_as_function();
@@ -2097,9 +2093,9 @@
 // Reserved:4
 // LoadTargetFlag:1
 // LoadVariableFlag:1
+/// @param target        the target window, or _level1..10
 void
-SWFHandlers::CommonGetUrl(as_environment& env,
-        as_value target, // the target window, or _level1..10
+SWFHandlers::CommonGetUrl(as_environment& env, as_value target,
         const std::string& url, boost::uint8_t method)
 {
 
@@ -2126,8 +2122,7 @@
         static_cast<MovieClip::VariablesMethod>(method & 3);
 
     std::string target_string;
-    if ( ! target.is_undefined() && ! target.is_null() )
-    {
+    if (!target.is_undefined() && !target.is_null()) {
         target_string = target.to_string();
     }
 
@@ -2206,7 +2201,7 @@
         //         no matter the target found on stack (which
         //         is the target to load the resource into).
         //
-        DisplayObject* curtgt = env.get_target();
+        as_object* curtgt = getObject(env.get_target());
         if (!curtgt) {
             log_error(_("CommonGetUrl: current target is undefined"));
             return;
@@ -2326,12 +2321,10 @@
     boost::uint8_t method = code[thread.getCurrentPC() + 3];
 
     as_value url_val = env.top(1);
-    if ( url_val.is_undefined() )
-    {
+    if (url_val.is_undefined()) {
         log_error(_("Undefined GetUrl2 url on stack, skipping"));
     }
-    else
-    {
+    else {
         const std::string& url = url_val.to_string();
         CommonGetUrl(env, env.top(0), url, method);
     }

=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2009-10-21 08:51:44 +0000
+++ b/libcore/vm/ActionExec.cpp 2009-10-27 09:44:54 +0000
@@ -761,7 +761,7 @@
         return _withStack.back().object();
     }
     else {
-        return env.get_target();
+        return getObject(env.get_target());
     }
 }
 
@@ -833,7 +833,7 @@
 as_object*
 ActionExec::getThisPointer()
 {
-    return _func ? _this_ptr.get() : env.get_original_target(); 
+    return _func ? _this_ptr.get() : getObject(env.get_original_target()); 
 }
 
 } // end of namespace gnash

=== modified file 'libcore/vm/ExecutableCode.h'
--- a/libcore/vm/ExecutableCode.h       2009-10-26 10:12:17 +0000
+++ b/libcore/vm/ExecutableCode.h       2009-10-27 09:44:54 +0000
@@ -230,7 +230,7 @@
     virtual void execute()
     {
         as_environment env(getVM(*func)); env.set_target(target);
-        func->call(fn_call(target, env));
+        func->call(fn_call(getObject(target), env));
     }
 
 #ifdef GNASH_USE_GC

=== modified file 'libcore/vm/fn_call.h'
--- a/libcore/vm/fn_call.h      2009-10-23 06:25:25 +0000
+++ b/libcore/vm/fn_call.h      2009-10-26 15:30:50 +0000
@@ -290,6 +290,19 @@
 };
 
 
+/// Check that the 'this' pointer is a DisplayObject
+//
+/// By default this just checks for any DisplayObject type.
+template<typename T = DisplayObject>
+struct IsDisplayObject
+{
+    typedef T value_type;
+    value_type* operator()(as_object* o) const {
+        if (!o) return 0;
+        return dynamic_cast<T*>(o->displayObject());
+    }
+};
+
 /// Check that the 'this' pointer is not null.
 struct ValidThis
 {

=== modified file 'testsuite/DummyCharacter.h'
--- a/testsuite/DummyCharacter.h        2009-10-12 09:50:35 +0000
+++ b/testsuite/DummyCharacter.h        2009-11-04 15:06:07 +0000
@@ -45,9 +45,9 @@
 
 public:
 
-       DummyCharacter(DisplayObject* parent)
+       DummyCharacter(as_object* object, DisplayObject* parent)
                :
-               InteractiveObject(parent)
+               InteractiveObject(object, parent)
        {
        }
 

=== modified file 'testsuite/DummyMovieDefinition.h'
--- a/testsuite/DummyMovieDefinition.h  2009-10-12 09:42:13 +0000
+++ b/testsuite/DummyMovieDefinition.h  2009-11-04 15:03:15 +0000
@@ -21,6 +21,8 @@
 #include "SWFMovieDefinition.h" // for inheritance
 #include "SWFRect.h" // for composition
 #include "SWFMovie.h" // for createMovie
+#include "Global_as.h"
+#include "namedStrings.h"
 
 #include <string>
 #include <memory> // for auto_ptr
@@ -50,10 +52,6 @@
 
 public:
 
-    virtual DisplayObject* createDisplayObject(DisplayObject*) {
-        return 0;
-    }
-
 
        /// Default constructor
        //
@@ -133,9 +131,10 @@
        }
        
        /// Create a playable movie instance from a def.
-       virtual Movie* createMovie(DisplayObject* parent=NULL)
+       virtual Movie* createMovie(Global_as& gl, DisplayObject* parent=NULL)
        {
-               return new SWFMovie(this, parent);
+        as_object* o = getObjectWithPrototype(gl, NSV::CLASS_MOVIE_CLIP);
+               return new SWFMovie(o, this, parent);
        }
        
        virtual const PlayList& get_playlist(size_t frame_number) const

=== modified file 'testsuite/actionscript.all/TextField.as'
--- a/testsuite/actionscript.all/TextField.as   2009-11-03 22:43:22 +0000
+++ b/testsuite/actionscript.all/TextField.as   2009-11-04 20:11:16 +0000
@@ -1194,6 +1194,7 @@
 
 _global.TextField = function() {
     storedthis = this;
+    this.bo = "stringo";
     args = arguments.length;
     count++;
 };
@@ -1205,15 +1206,18 @@
 // replaced shows that the native functions (making into a real TextField)
 // is done in createTextField.
 r = _root.createTextField("tfmo", 2, 2, 10, 10, 6);
-xcheck_equals(count, 1);
+check_equals(count, 1);
 check_equals(args, 0);
 check_equals(_root.tfmo._x, 2);
 
 /// The returned object is still the this pointer that our fake constructor
 /// worked on.
-xcheck_equals(_root.tfmo, storedthis);
+check_equals(_root.tfmo, storedthis);
 xcheck(_root.tfmo === storedthis);
 
+check_equals(_root.tfmo.bo, "stringo");
+check(_root.tfmo.hasOwnProperty("bo"));
+
 // Not sure why this isn't the case for version 6 or 7.
 #if OUTPUT_VERSION >= 8
 check_equals(r.toString(), "Hoppla!");
@@ -1274,11 +1278,11 @@
 //------------------------------------------------------------
 
 #if OUTPUT_VERSION == 6
-     check_totals(520);
+     check_totals(522);
 #elif OUTPUT_VERSION == 7
- check_totals(544);
+ check_totals(546);
 #elif OUTPUT_VERSION == 8
- check_totals(545);
+ check_totals(547);
 #endif
 
 #endif

=== modified file 'testsuite/as3compile.all/MovieClip.as'
--- a/testsuite/as3compile.all/MovieClip.as     2009-07-06 12:34:10 +0000
+++ b/testsuite/as3compile.all/MovieClip.as     2009-11-04 16:55:59 +0000
@@ -30,13 +30,13 @@
             xcheck_equals(MovieClip, "[class MovieClip]");
             xcheck_equals(MovieClip.prototype, "[object Object]");
             xcheck_equals(MovieClip.constructor, "[class Class]");
-            check(!MovieClip.hasOwnProperty("constructor"));
+            xcheck(!MovieClip.hasOwnProperty("constructor"));
 
             // Check that this object is a MovieClip and has MovieClip
             // functions (no need to check them all).
             xcheck(this instanceof MovieClip);
-            check_equals(typeof(this.nextFrame), "function");
-            check_equals(typeof(this.play), "function");
+            xcheck_equals(typeof(this.nextFrame), "function");
+            xcheck_equals(typeof(this.play), "function");
             
             xcheck(MovieClip.prototype.hasOwnProperty("constructor"));
             
@@ -70,7 +70,7 @@
             
             var m = new MovieClip();
             xcheck_equals(m.constructor, "[class MovieClip]");
-            check(!m.hasOwnProperty("constructor"));
+            xcheck(!m.hasOwnProperty("constructor"));
             
             // MovieClip properties
             xcheck(m.hasOwnProperty("nextFrame"));

=== modified file 'testsuite/as3compile.all/Object.as'
--- a/testsuite/as3compile.all/Object.as        2009-07-30 11:20:20 +0000
+++ b/testsuite/as3compile.all/Object.as        2009-11-04 16:55:59 +0000
@@ -57,8 +57,8 @@
             check(!Object.prototype.hasOwnProperty("__proto__"));
             check(!Object.prototype.hasOwnProperty("prototype"));
 
-            xcheck(Object.prototype.isPrototypeOf(MovieClip));
-            xcheck(Object.prototype.isPrototypeOf(this));
+            check(Object.prototype.isPrototypeOf(MovieClip));
+            check(Object.prototype.isPrototypeOf(this));
 
             var a = new Object();
             xcheck_equals(a, "[object Object]");       

=== modified file 'testsuite/libcore.all/AsValueTest.cpp'
--- a/testsuite/libcore.all/AsValueTest.cpp     2009-10-23 07:42:46 +0000
+++ b/testsuite/libcore.all/AsValueTest.cpp     2009-11-04 15:06:07 +0000
@@ -23,7 +23,6 @@
 
 #include "VM.h"
 #include "DummyMovieDefinition.h"
-#include "DummyCharacter.h"
 #include "ManualClock.h"
 #include "movie_definition.h"
 #include "dejagnu.h"
@@ -118,12 +117,12 @@
     movie_root stage(*md, clock, runResources);
 
     MovieClip::MovieVariables v;
-    stage.init(md, v);
+    Movie* m = stage.init(md, v);
 
     // run the tests
     test_isnan();
     test_el();
-    test_obj(&stage.getRootMovie());
+    test_obj(getObject(m));
     test_conversion();
    
 }

=== modified file 'testsuite/libcore.all/DisplayListTest.cpp'
--- a/testsuite/libcore.all/DisplayListTest.cpp 2009-10-21 07:24:55 +0000
+++ b/testsuite/libcore.all/DisplayListTest.cpp 2009-11-04 15:06:07 +0000
@@ -72,8 +72,11 @@
     MovieClip* root = const_cast<Movie*>(&stage.getRootMovie());
 
        // just a couple of DisplayObjects
-       boost::intrusive_ptr<DisplayObject> ch1 ( new DummyCharacter(root) );
-       boost::intrusive_ptr<DisplayObject> ch2 ( new DummyCharacter(root) );
+    as_object* ob1 = getGlobal(*getObject(root)).createObject();
+    as_object* ob2 = getGlobal(*getObject(root)).createObject();
+
+       boost::intrusive_ptr<DisplayObject> ch1 ( new DummyCharacter(ob1, root) 
);
+       boost::intrusive_ptr<DisplayObject> ch2 ( new DummyCharacter(ob2, root) 
);
 
        dlist1.placeDisplayObject( ch1.get(), 1);
        dlist1.placeDisplayObject( ch2.get(), 2);

=== modified file 'testsuite/misc-ming.all/DefineTextTest-Runner.cpp'
--- a/testsuite/misc-ming.all/DefineTextTest-Runner.cpp 2009-04-09 11:41:59 
+0000
+++ b/testsuite/misc-ming.all/DefineTextTest-Runner.cpp 2009-10-28 13:33:35 
+0000
@@ -79,7 +79,7 @@
 
        string_table& st = VM::get().getStringTable();
        as_value eot;
-       bool endOfTestFound = root->get_member(st.find("endoftest"), &eot);
+       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
        check(endOfTestFound);
        check(eot.is_bool());
        check(eot.to_bool());

=== modified file 'testsuite/misc-ming.all/DragDropTestRunner.cpp'
--- a/testsuite/misc-ming.all/DragDropTestRunner.cpp    2009-07-14 06:16:40 
+0000
+++ b/testsuite/misc-ming.all/DragDropTestRunner.cpp    2009-10-28 13:33:35 
+0000
@@ -53,7 +53,7 @@
        assert(root);
 
        // for variables lookup (consistency checking)
-       string_table& st = getStringTable(*root);
+       string_table& st = getStringTable(*getObject(root));
 
        rgba white(255, 255, 255, 255); // background color
        rgba blue(0, 0, 255, 255);      // blue circles fill color
@@ -97,7 +97,7 @@
                const MovieClip* loadedTarget = 0;
                //const DisplayObject* ch = tester.findDisplayItemByName(*root, 
"loadedTarget");
                const DisplayObject* ch = tester.findDisplayItemByDepth(*root, 
30);
-               if ( ch ) loadedTarget = ch->to_movie();
+               if ( ch ) loadedTarget = 
const_cast<DisplayObject*>(ch)->to_movie();
                if ( loadedTarget )
                {
                        const DisplayObject* target100 = 
tester.findDisplayItemByName(*loadedTarget, "target100");
@@ -170,7 +170,7 @@
        // Consistency check !!
        as_value eot;
        // It's an swf6, so lowercase 'ENDOFTEST'
-       bool endOfTestFound = root->get_member(st.find("endoftest"), &eot);
+       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
        check(endOfTestFound);
        if ( endOfTestFound )
        {

=== modified file 'testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp'
--- a/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp      2009-07-14 
06:16:40 +0000
+++ b/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp      2009-10-28 
13:33:35 +0000
@@ -46,7 +46,7 @@
        MovieClip* root = tester.getRootMovie();
        assert(root);
 
-    VM& vm = getVM(*root);
+    VM& vm = getVM(*getObject(root));
     string_table& st = vm.getStringTable();
 
     const size_t framecount = root->get_frame_count();
@@ -62,7 +62,7 @@
         }
     }
     as_value eot;
-    xcheck(root->get_member(st.find("finished"), &eot));
+    xcheck(getObject(root)->get_member(st.find("finished"), &eot));
 
 }
 

=== modified file 'testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp'
--- a/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp    2009-04-03 
09:29:19 +0000
+++ b/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp    2009-10-28 
13:33:35 +0000
@@ -68,7 +68,7 @@
        string_table& st = VM::get().getStringTable();
        string_table::key k = st.find("startNotified");
        as_value tmp;
-       while (! root->get_member(k, &tmp) )
+       while (!getObject(root)->get_member(k, &tmp) )
        {
                tester.advance();
 
@@ -97,7 +97,7 @@
 
        // Consistency check 
        as_value eot;
-       bool endOfTestFound = root->get_member(st.find("end_of_test"), &eot);
+       bool endOfTestFound = 
getObject(root)->get_member(st.find("end_of_test"), &eot);
        check(endOfTestFound);
 
 }

=== modified file 
'testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp'
--- a/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp     
2009-07-14 06:16:40 +0000
+++ b/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp     
2009-10-28 13:33:35 +0000
@@ -51,7 +51,7 @@
        assert(root);
 
        // for variables lookup (consistency checking)
-       string_table& st = getStringTable(*root);
+       string_table& st = getStringTable(*getObject(root));
 
        check_equals(root->get_frame_count(), 2);
        check_equals(root->get_current_frame(), 0);
@@ -72,7 +72,7 @@
        // Consistency check !!
        as_value eot;
        // It's an swf6, so lowercase 'ENDOFTEST'
-       bool endOfTestFound = root->get_member(st.find("endoftest"), &eot);
+       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
        check(endOfTestFound);
 
        if ( endOfTestFound )

=== modified file 'testsuite/misc-ming.all/attachMovieTestRunner.cpp'
--- a/testsuite/misc-ming.all/attachMovieTestRunner.cpp 2009-04-09 11:41:59 
+0000
+++ b/testsuite/misc-ming.all/attachMovieTestRunner.cpp 2009-10-28 13:33:35 
+0000
@@ -81,23 +81,23 @@
 
        string_table& st = VM::get().getStringTable();
 
-       root->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(st.find("mousedown"), &tmp);
        check(tmp.is_undefined());
-       root->get_member(st.find("mouseup"), &tmp);
+       getObject(root)->get_member(st.find("mouseup"), &tmp);
        check(tmp.is_undefined());
 
        // Note that we are *not* on an active entity !
        tester.pressMouseButton();
 
-       root->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(st.find("mousedown"), &tmp);
        check_equals(tmp.to_number(), 1);
-       check ( ! root->get_member(st.find("mouseup"), &tmp) );
+       check ( ! getObject(root)->get_member(st.find("mouseup"), &tmp) );
 
        tester.depressMouseButton();
 
-       root->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(st.find("mousedown"), &tmp);
        check_equals(tmp.to_number(), 1);
-       root->get_member(st.find("mouseup"), &tmp);
+       getObject(root)->get_member(st.find("mouseup"), &tmp);
        check_equals(tmp.to_number(), 1);
 
        tester.advance();
@@ -154,7 +154,7 @@
        // Note that we are *not* on an active entity !
        tester.pressMouseButton();
 
-       root->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(st.find("mousedown"), &tmp);
        check_equals(tmp.to_number(), 5);
 
 }

=== modified file 'testsuite/misc-ming.all/eventSoundTest1-Runner.cpp'
--- a/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp        2009-07-14 
06:16:40 +0000
+++ b/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp        2009-10-28 
13:33:35 +0000
@@ -65,7 +65,7 @@
        MovieClip* root = tester.getRootMovie();
        assert(root);
 
-       VM& vm = getVM(*root);
+       VM& vm = getVM(*getObject(root));
        string_table& st = vm.getStringTable();
 
        //check_equals(root->get_frame_count(), 20);
@@ -104,9 +104,9 @@
        int test = 0;
        while (frame <= totalFrames) {
                as_value testReady;
-               if (root->get_member(st.find("testReady"), &testReady))
+               if (getObject(root)->get_member(st.find("testReady"), 
&testReady))
                {
-                       root->delProperty(st.find("testReady"));
+                       getObject(root)->delProperty(st.find("testReady"));
                        
                        // When a test is ready, check the result of the 
previous test.
                        if (testPasses[test]) {
@@ -134,7 +134,7 @@
 
     // Consistency checking
     as_value eot;
-    bool endOfTestFound = root->get_member(st.find("endoftest"), &eot);
+    bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
     check(endOfTestFound);
 
 }

=== modified file 'testsuite/misc-ming.all/intervalTestRunner.cpp'
--- a/testsuite/misc-ming.all/intervalTestRunner.cpp    2009-04-09 11:41:59 
+0000
+++ b/testsuite/misc-ming.all/intervalTestRunner.cpp    2009-10-28 13:33:35 
+0000
@@ -63,75 +63,75 @@
 
        VM& vm = VM::get();
        string_table& st = vm.getStringTable();
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 0);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 0);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 1);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 0);
 
        tester.advanceClock(600); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 2);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 1);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 3);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 1);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 4);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 2);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 4);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 3);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 4);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 4);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(st.find("this_counter"), &tmp);
        check_equals(tmp.to_number(), 5);
-       root->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(st.find("that_counter"), &tmp);
        check_equals(tmp.to_number(), 4);
 
-       root->get_member(st.find("pushed_args"), &tmp);
+       getObject(root)->get_member(st.find("pushed_args"), &tmp);
        as_environment env(vm); // needed for proper to_string()
        check_equals(tmp.to_string(), std::string("8,9,10"));
 
        tester.advanceClock(100); // "sleep" another 100 milliseconds
        tester.advance(); // run expired timers
 
-       root->get_member(st.find("test_completed"), &tmp);
+       getObject(root)->get_member(st.find("test_completed"), &tmp);
        check_equals(tmp.to_number(), 1);
 
 

=== modified file 'testsuite/misc-ming.all/loadMovieTestRunner.cpp'
--- a/testsuite/misc-ming.all/loadMovieTestRunner.cpp   2009-07-14 06:16:40 
+0000
+++ b/testsuite/misc-ming.all/loadMovieTestRunner.cpp   2009-10-28 13:33:35 
+0000
@@ -38,7 +38,7 @@
 using namespace std;
 
 std::auto_ptr<MovieTester> tester;
-boost::intrusive_ptr<MovieClip> root;
+MovieClip* root;
 
 MovieClip*
 getCoverArt()
@@ -94,7 +94,7 @@
 
 
        root = tester->getRootMovie();
-       assert(root.get());
+       assert(root);
 
        check_equals(root->get_frame_count(), 2);
        check_equals(root->get_current_frame(), 0);
@@ -173,10 +173,10 @@
        tester->releaseKey(key::SHIFT);
 
        // Consistency checking
-       string_table& st = getStringTable(*root);
+       string_table& st = getStringTable(*getObject(root));
        as_value eot;
        // It's an swf6, so lowercase 'END_OF_TEST'
-       bool endOfTestFound = root->get_member(st.find("end_of_test"), &eot);
+       bool endOfTestFound = 
getObject(root)->get_member(st.find("end_of_test"), &eot);
        check(endOfTestFound);
        if ( endOfTestFound )
        {

=== modified file 'testsuite/misc-swfc.all/button_test1runner.cpp'
--- a/testsuite/misc-swfc.all/button_test1runner.cpp    2009-07-14 06:18:11 
+0000
+++ b/testsuite/misc-swfc.all/button_test1runner.cpp    2009-11-04 13:29:39 
+0000
@@ -64,7 +64,7 @@
        tester.advance();
 
        MovieClip* root = tester.getRootMovie();
-       VM& vm = getVM(*root);
+       VM& vm = getVM(*getObject(root));
        string_table& st = vm.getStringTable();
 
        check_equals(root->get_frame_count(), 1);
@@ -158,7 +158,7 @@
 
        as_value eot;
         
-        root->get_member(st.find("testcompleted"), &eot);
+    getObject(root)->get_member(st.find("testcompleted"), &eot);
         
        //cerr << "EOT is " << eot.to_debug_string() << endl;
        check(eot.to_bool());

=== modified file 'testsuite/movies.all/gravity_embedded-TestRunner.cpp'
--- a/testsuite/movies.all/gravity_embedded-TestRunner.cpp      2009-10-21 
07:10:41 +0000
+++ b/testsuite/movies.all/gravity_embedded-TestRunner.cpp      2009-11-04 
13:40:12 +0000
@@ -71,7 +71,7 @@
        string_table::key yscale = st.find("_yscale");
        // we need a const_cast as get_member *might* eventually
        // change the DisplayObject (fetching _x shouldn't change it though)
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(getObject(const_cast<DisplayObject*>(loaded))->get_member(xscale, 
&tmp));
        check(tmp.strictly_equals(50));
 
        check_equals(loaded->getBounds().height(), 2056);
@@ -87,31 +87,32 @@
        check(!tester.isMouseOverMouseEntity());
 
        // click some on the "smaller" button
+    as_object* obj = getObject(const_cast<DisplayObject*>(loaded));
        tester.movePointerTo(474, 18);
        check(tester.isMouseOverMouseEntity());
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "50");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "48");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 48);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 48);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "46");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 46);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 46);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "44");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 44);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 44);
 
        // click some on the "larger" button
@@ -121,33 +122,33 @@
        check_equals(string(text->get_text_value()), "44");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "46");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 46);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 46);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "48");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 48);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 48);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "50");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 50);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 50);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "50");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "52");
-       check(const_cast<DisplayObject*>(loaded)->get_member(xscale, &tmp));
+       check(obj->get_member(xscale, &tmp));
        check_equals(round(tmp.to_number()), 52);
-       check(const_cast<DisplayObject*>(loaded)->get_member(yscale, &tmp));
+       check(obj->get_member(yscale, &tmp));
        check_equals(round(tmp.to_number()), 52);
 
 


reply via email to

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