gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11662: Fixes and cleanups to functi


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11662: Fixes and cleanups to function execution and construction.
Date: Mon, 30 Nov 2009 17:49:34 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11662 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Mon 2009-11-30 17:49:34 +0100
message:
  Fixes and cleanups to function execution and construction.
added:
  testsuite/misc-swfmill.all/trace-as2/arguments.trace
  testsuite/misc-swfmill.all/trace-as2/arguments.xml
  testsuite/misc-swfmill.all/trace-as2/this.trace
  testsuite/misc-swfmill.all/trace-as2/this.xml
modified:
  libcore/MovieClip.cpp
  libcore/TextField.cpp
  libcore/as_environment.cpp
  libcore/as_environment.h
  libcore/as_function.cpp
  libcore/as_function.h
  libcore/as_value.cpp
  libcore/asobj/Color_as.cpp
  libcore/asobj/Date_as.cpp
  libcore/asobj/Globals.cpp
  libcore/asobj/Object.cpp
  libcore/asobj/String_as.cpp
  libcore/asobj/flash/display/BitmapData_as.cpp
  libcore/asobj/flash/display/MovieClip_as.cpp
  libcore/asobj/flash/filters/BitmapFilter_as.cpp
  libcore/asobj/flash/geom/Matrix_as.cpp
  libcore/asobj/flash/geom/Point_as.cpp
  libcore/asobj/flash/geom/Rectangle_as.cpp
  libcore/asobj/flash/geom/Transform_as.cpp
  libcore/asobj/flash/net/SharedObject_as.cpp
  libcore/asobj/flash/net/XMLSocket_as.cpp
  libcore/asobj/flash/ui/ContextMenuItem_as.cpp
  libcore/asobj/flash/ui/ContextMenu_as.cpp
  libcore/asobj/flash/ui/Mouse_as.cpp
  libcore/asobj/flash/xml/XMLDocument_as.cpp
  libcore/builtin_function.h
  libcore/swf_function.cpp
  libcore/swf_function.h
  libcore/vm/ASHandlers.cpp
  libcore/vm/ActionExec.cpp
  libcore/vm/CallStack.cpp
  libcore/vm/CallStack.h
  libcore/vm/Machine.cpp
  testsuite/misc-swfmill.all/trace-as2/Makefile.am
  testsuite/misc-swfmill.all/trace-as2/PASSING
  testsuite/misc-swfmill.all/trace-as2/super.xml
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-11-29 09:24:30 +0000
+++ b/libcore/MovieClip.cpp     2009-11-30 13:09:55 +0000
@@ -991,17 +991,16 @@
     // and stop at that frame. 
     setPlayState(PLAYSTATE_STOP);
 
-    if ( target_frame_number > _def->get_frame_count() - 1)
-    {
+    if (target_frame_number > _def->get_frame_count() - 1) {
+
         target_frame_number = _def->get_frame_count() - 1;
 
-        if ( ! _def->ensure_frame_loaded(target_frame_number+1) )
-        {
+        if (!_def->ensure_frame_loaded(target_frame_number + 1)) {
             log_error(_("Target frame of a gotoFrame(%d) was never loaded,"
                         "although frame count in header (%d) said we "
                         "should have found it"),
                         target_frame_number+1, _def->get_frame_count());
-            return; // ... I guess, or not ?
+            return; 
         }
 
         // Just set _currentframe and return.
@@ -1011,25 +1010,23 @@
         return;
     }
 
-    if (target_frame_number == _currentFrame)
-    {
+    if (target_frame_number == _currentFrame) {
         // don't push actions
         return;
     }
 
     // Unless the target frame is the next one, stop playback of soundstream
-    if (target_frame_number != _currentFrame+1 )
-    {
+    if (target_frame_number != _currentFrame + 1) {
         stopStreamSound();
     }
 
-    size_t loaded_frames = get_loaded_frames();
+    const size_t loaded_frames = get_loaded_frames();
+
     // target_frame_number is 0-based, get_loaded_frames() is 1-based
     // so in order to goto_frame(3) loaded_frames must be at least 4
     // if goto_frame(4) is called, and loaded_frames is 4 we're jumping
     // forward
-    if ( target_frame_number >= loaded_frames )
-    {
+    if (target_frame_number >= loaded_frames) {
         IF_VERBOSE_ASCODING_ERRORS(
             log_aserror(_("GotoFrame(%d) targets a yet "
             "to be loaded frame (%d) loaded). "
@@ -1039,13 +1036,12 @@
             loaded_frames);
 
         );
-        if ( ! _def->ensure_frame_loaded(target_frame_number+1) )
-        {
+        if (!_def->ensure_frame_loaded(target_frame_number + 1)) {
             log_error(_("Target frame of a gotoFrame(%d) was never loaded, "
                         "although frame count in header (%d) said we should"
                         " have found it"),
-                        target_frame_number+1, _def->get_frame_count());
-            return; // ... I guess, or not ?
+                        target_frame_number + 1, _def->get_frame_count());
+            return;
         }
     }
 
@@ -1054,8 +1050,8 @@
     // Construct the DisplayList of the target frame
     //
 
-    if (target_frame_number < _currentFrame)
-    {
+    if (target_frame_number < _currentFrame) {
+
         // Go backward to a previous frame
         // NOTE: just in case we're being called by code in a called frame
         // we'll backup and resume the _callingFrameActions flag
@@ -1068,13 +1064,11 @@
         assert(_currentFrame == target_frame_number);
         _callingFrameActions = callingFrameActionsBackup;
     }
-    else
-    // Go forward to a later frame
-    {
+    else {
+        // Go forward to a later frame
         // We'd immediately return if target_frame_number == _currentFrame
         assert(target_frame_number > _currentFrame);
-        while (++_currentFrame < target_frame_number)
-        {
+        while (++_currentFrame < target_frame_number) {
             //for (size_t f = _currentFrame+1; f<target_frame_number; ++f) 
             // Second argument requests that only "DisplayList" tags
             // are executed. This means NO actions will be
@@ -1084,7 +1078,6 @@
         }
         assert(_currentFrame == target_frame_number);
 
-
         // Now execute target frame tags (queuing actions)
         // NOTE: just in case we're being called by code in a called frame
         //             we'll backup and resume the _callingFrameActions flag
@@ -1107,17 +1100,16 @@
     if (!_def) return false;
 
     size_t target_frame;
-    if (_def->get_labeled_frame(label, target_frame))
-    {
+    if (_def->get_labeled_frame(label, target_frame)) {
         goto_frame(target_frame);
         return true;
     }
 
-        IF_VERBOSE_MALFORMED_SWF(
+    IF_VERBOSE_MALFORMED_SWF(
         log_swferror(_("MovieClip::goto_labeled_frame('%s') "
             "unknown label"), label);
-        );
-        return false;
+    );
+    return false;
 }
 
 void
@@ -1867,98 +1859,42 @@
 void
 MovieClip::constructAsScriptObject()
 {
-#ifdef GNASH_DEBUG
-    log_debug(_("constructAsScriptObject called for movieclip %s"), 
-            getTarget());
-#endif
-
-    if (!isAS3(getVM(*getObject(this))) && !get_parent()) {
-        getObject(this)->init_member("$version", 
getVM(*getObject(this)).getPlayerVersion(), 0); 
-    }
-
-    bool eventHandlersInvoked = false;
-
-    do {
-
-        if ( _name.empty() )
-        {
-            // instance name will be needed for properly setting up
-            // a reference to 'this' object for ActionScript actions.
-            // If the instance doesn't have a name, it will NOT be
-            // an ActionScript referenceable object so we don't have
-            // anything more to do.
-            break;
-        }
-
-        const sprite_definition* def = 
-            dynamic_cast<const sprite_definition*>(_def.get());
-
-        // We won't "construct" top-level movies
-        if (!def) break;
-
-        as_function* ctor = def->getRegisteredClass();
-#ifdef GNASH_DEBUG
-        log_debug(_("Attached movieclips %s registered class is %p"),
-                getTarget(), (void*)ctor); 
-#endif
-
-        // TODO: builtin constructors are different from user-defined ones
-        // we should likely change that. See also vm/ASHandlers.cpp 
-        // (construct_object)
-        if ( ctor && ! ctor->isBuiltin() )
-        {
-            // Set the new prototype *after* the constructor was called
-            as_value proto = ctor->getMember(NSV::PROP_PROTOTYPE);
-            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(*getObject(this));
-
-            // Set the '__constructor__' and 'constructor' members, as well
-            // as calling the actual constructor.
-            //
-            // TODO: this would be best done by an
-            // as_function::constructInstance() method. We have one but it
-            // returns a new object rather then initializing a given object.
-            // We just need to add another one...
-            if ( swfversion > 5 )
-            {
-
-                const int flags = PropFlags::dontEnum;
-
-                getObject(this)->set_member(NSV::PROP_uuCONSTRUCTORuu, ctor);
-                getObject(this)->set_member_flags(NSV::PROP_uuCONSTRUCTORuu, 
flags);
-                if ( swfversion == 6 )
-                {
-                    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 = getObject(this)->get_super();
-
-                as_environment& env = get_environment();
-                fn_call call(getObject(this), env);
-                call.super = super;
-
-                    // we don't use the constructor return (should we?)
-                ctor->call(call);
-            }
-        }
-
-    } while (0);
-
-    /// Invoke event handlers if not done yet
-    if ( ! eventHandlersInvoked )
-    {
-        notifyEvent(event_id::CONSTRUCT);
+    as_object* mc = getObject(this);
+
+    // A MovieClip should always have an associated object.
+    assert(mc);
+
+    if (!isAS3(getVM(*mc)) && !get_parent()) {
+        mc->init_member("$version", getVM(*mc).getPlayerVersion(), 0); 
+    }
+
+    const sprite_definition* def = 
+        dynamic_cast<const sprite_definition*>(_def.get());
+
+    // We won't "construct" top-level movies
+    as_function* ctor = def ? def->getRegisteredClass() : 0;
+
+#ifdef GNASH_DEBUG
+    log_debug(_("Attached movieclips %s registered class is %p"),
+            getTarget(), (void*)ctor); 
+#endif
+
+    // Set this MovieClip object to be an instance of the class.
+    if (ctor) {
+        Property* proto = ctor->getOwnProperty(NSV::PROP_PROTOTYPE);
+        if (proto) mc->set_prototype(proto->getValue(*ctor));
+    }
+
+    // Send the construct event. This must be done after the __proto__ 
+    // member is set. It is always done.
+    notifyEvent(event_id::CONSTRUCT);
+        
+    if (ctor) {
+        const int swfversion = getSWFVersion(*mc);
+        if (swfversion > 5) {
+            fn_call::Args args;
+            ctor->construct(*mc, get_environment(), args);
+        }
     }
 }
 

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2009-11-18 11:51:35 +0000
+++ b/libcore/TextField.cpp     2009-11-30 11:12:37 +0000
@@ -134,7 +134,7 @@
     if (!ctor) return 0;
     fn_call::Args args;
     as_environment env(getVM(gl));
-    return ctor->constructInstance(env, args);
+    return constructInstance(*ctor, env, args);
 }
 
 
@@ -3289,7 +3289,7 @@
     if (!ctor) return as_value();
 
     fn_call::Args args;
-    as_object* textformat = ctor->constructInstance(fn.env(), args);
+    as_object* textformat = constructInstance(*ctor, fn.env(), args);
     TextFormat_as* tf;
 
     if (!isNativeType(textformat, tf)) {

=== modified file 'libcore/as_environment.cpp'
--- a/libcore/as_environment.cpp        2009-11-13 09:02:34 +0000
+++ b/libcore/as_environment.cpp        2009-11-30 15:59:02 +0000
@@ -57,10 +57,10 @@
 ///
 /// @return true if the variable was found, false otherwise
 bool
-getLocal(as_object* locals, const std::string& name, as_value& ret)
+getLocal(as_object& locals, const std::string& name, as_value& ret)
 {
-    string_table& st = getStringTable(*locals);
-    return locals->get_member(st.find(name), &ret);
+    string_table& st = getStringTable(locals);
+    return locals.get_member(st.find(name), &ret);
 }
 
 /// Delete a local variable
@@ -69,12 +69,30 @@
 /// Name of the local variable
 ///
 /// @return true if the variable was found and deleted, false otherwise
-///
-bool
-deleteLocal(as_object* locals, const std::string& varname)
-{
-    string_table& st = getStringTable(*locals);
-    return locals->delProperty(st.find(varname)).second;
+bool
+deleteLocal(as_object& locals, const std::string& varname)
+{
+    string_table& st = getStringTable(locals);
+    return locals.delProperty(st.find(varname)).second;
+}
+
+/// Set a variable of the given object, if it exists.
+//
+/// @param varname
+/// Name of the local variable
+///
+/// @param val
+/// Value to assign to the variable
+///
+/// @return true if the variable was found, false otherwise
+bool
+setLocal(as_object& locals, const std::string& varname, const as_value& val)
+{
+    string_table& st = getStringTable(locals);
+    Property* prop = locals.getOwnProperty(st.find(varname));
+    if (!prop) return false;
+    prop->setValue(locals, val);
+    return true;
 }
 
 as_object*
@@ -431,10 +449,10 @@
     else
     {
         // Not in frame; create a new local var.
-        assert( ! varname.empty() ); // null varnames are invalid!
-        as_object* locals = _localFrames.back().locals;
+        assert(!varname.empty()); // null varnames are invalid!
+        as_object& locals = _localFrames.back().locals();
         //locals.push_back(as_environment::frame_slot(varname, val));
-        locals->set_member(varkey, val);
+        locals.set_member(varkey, val);
     }
 }
     
@@ -446,10 +464,10 @@
     if ( ! findLocal(varname, tmp) )
     {
         // Not in frame; create a new local var.
-        assert( ! _localFrames.empty() );
+        assert(!_localFrames.empty());
         assert( ! varname.empty() );    // null varnames are invalid!
-        as_object* locals = _localFrames.back().locals;
-        locals->set_member(_vm.getStringTable().find(varname), as_value());
+        as_object& locals = _localFrames.back().locals();
+        locals.set_member(_vm.getStringTable().find(varname), as_value());
     }
 }
 
@@ -744,45 +762,28 @@
     return _vm.getSWFVersion();
 }
 
-static void
-dump(const as_environment::Registers& r, std::ostream& out) 
-{
-    for (size_t i=0; i<r.size(); ++i)
-    {
-        if (i) out << ", ";
-        out << i << ':' << '"' << r[i] << '"';
-    }
-}
-
 void
 as_environment::dump_local_registers(std::ostream& out) const
 {
     if ( _localFrames.empty() ) return;
     out << "Local registers: ";
-#ifndef DUMP_LOCAL_REGISTERS_IN_ALL_CALL_FRAMES
-    dump(_localFrames.back().registers, out);
-#else
     for (CallStack::const_iterator it=_localFrames.begin(),
-            itEnd=_localFrames.end();
-            it != itEnd; ++it)
-    {
-        if ( it != _localFrames.begin() ) out << " | ";
-        dump(it->registers, out);
+            itEnd=_localFrames.end(); it != itEnd; ++it) {
+        if (it != _localFrames.begin()) out << " | ";
+        out << *it;
     }
-#endif
     out << std::endl;
 }
 
 static void
-dump(const as_object* locals, std::ostream& out)
+dump(as_object& locals, std::ostream& out)
 {
     typedef std::map<std::string, as_value> PropMap;
     PropMap props;
-    const_cast<as_object*>(locals)->dump_members(props);
+    locals.dump_members(props);
     
     int count = 0;
-    for (PropMap::iterator i=props.begin(), e=props.end(); i!=e; ++i)
-    {
+    for (PropMap::iterator i=props.begin(), e=props.end(); i!=e; ++i) {
         if (count++) out << ", ";
         // TODO: define output operator for as_value !
         out << i->first << "==" << i->second;
@@ -795,17 +796,12 @@
 {
     if ( _localFrames.empty() ) return;
     out << "Local variables: ";
-#ifndef DUMP_LOCAL_VARIABLES_IN_ALL_CALL_FRAMES
-    dump(_localFrames.back().locals, out);
-#else
-    for (CallStack::const_iterator it=_localFrames.begin(),
-            itEnd=_localFrames.end();
-            it != itEnd; ++it)
-    {
+    for (CallStack::iterator it=_localFrames.begin(),
+            itEnd=_localFrames.end(); it != itEnd; ++it) {
+
         if ( it != _localFrames.begin() ) out << " | ";
-        dump(it->locals, out);
+        dump(it->locals(), out);
     }
-#endif
     out << std::endl;
 }
 
@@ -818,7 +814,7 @@
 
     ss << "Global registers: ";
     int defined=0;
-    for (unsigned int i=0; i<numGlobalRegisters; ++i)
+    for (unsigned int i = 0; i < numGlobalRegisters; ++i)
     {
         if ( m_global_register[i].is_undefined() ) continue;
 
@@ -836,9 +832,10 @@
 {
     if (_localFrames.empty()) return false;
 
-    if (getLocal(_localFrames.back().locals, varname, ret)) {
+    as_object& locals = _localFrames.back().locals();
 
-        if (retTarget) *retTarget = _localFrames.back().locals;
+    if (getLocal(locals, varname, ret)) {
+        if (retTarget) *retTarget = &locals;
         return true;
     }
 
@@ -849,28 +846,21 @@
 as_environment::delLocal(const std::string& varname)
 {
     if (_localFrames.empty()) return false;
-    return deleteLocal(_localFrames.back().locals, varname);
+    return deleteLocal(_localFrames.back().locals(), varname);
 }
 
 bool
 as_environment::setLocal(const std::string& varname, const as_value& val)
 {
     if (_localFrames.empty()) return false;
-    return setLocal(_localFrames.back().locals, varname, val);
-}
 
-bool
-as_environment::setLocal(as_object* locals, const std::string& varname,
-        const as_value& val)
-{
-    Property* prop = 
locals->getOwnProperty(_vm.getStringTable().find(varname));
-    if (!prop) return false;
-    prop->setValue(*locals, val);
-    return true;
+    // If this name is not qualified, the compiler fails to look beyond
+    // as_environment::setLocal.
+    return gnash::setLocal(_localFrames.back().locals(), varname, val);
 }
 
 void
-as_environment::pushCallFrame(as_function* func)
+as_environment::pushCallFrame(as_function& func)
 {
 
     // The stack size can be changed by the ScriptLimits
@@ -878,7 +868,7 @@
     // TODO: override from gnashrc.
     
     // A stack size of 0 is apparently legitimate.
-    const boost::uint16_t recursionLimit = getRoot(*func).getRecursionLimit();
+    const boost::uint16_t recursionLimit = getRoot(func).getRecursionLimit();
 
     // Don't proceed if local call frames would reach the recursion limit.
     if (_localFrames.size() + 1 >= recursionLimit) {
@@ -890,7 +880,7 @@
         throw ActionLimitException(ss.str()); 
     }
 
-    _localFrames.push_back(CallFrame(func));
+    _localFrames.push_back(CallFrame(&func));
 
 }
 
@@ -904,15 +894,7 @@
 void
 as_environment::set_target(DisplayObject* target)
 {
-    //assert(target);
-    if ( ! _original_target )
-    {
-        //assert(target); // we assume any as_environment creator sets a 
target too I guess..
-        // WRONG ASSUMPTION: ^^^^^^^^^ : as_value::to_primitive doesn't care 
about setting a target here
-
-        //log_debug("as_environment(%p)::set_target(%p): setting original 
target to %s", this, target, target ? target->getTarget() : "<null>");
-        _original_target = target;
-    }
+    if (!_original_target) _original_target = target;
     m_target = target;
 }
 
@@ -922,8 +904,8 @@
     assert(!varname.empty());   
     assert(!_localFrames.empty());
 
-    as_object* locals = _localFrames.back().locals;
-    locals->set_member(_vm.getStringTable().find(varname), val);
+    as_object& locals = _localFrames.back().locals();
+    locals.set_member(_vm.getStringTable().find(varname), val);
 }
 
 void
@@ -953,36 +935,43 @@
 unsigned int
 as_environment::setRegister(unsigned int regnum, const as_value& v)
 {
-    if (_localFrames.empty() || _localFrames.back().registers.empty()) {
-        if ( regnum >= numGlobalRegisters ) return 0;
+    // If there is a call frame and it has registers, the value must be
+    // set there.
+    if (!_localFrames.empty()) {
+        CallFrame& fr = _localFrames.back();
+        if (fr.hasRegisters()) {
+            if (_localFrames.back().setRegister(regnum, v)) return 2;
+            return 0;
+        }
+    }
+
+    if (regnum < numGlobalRegisters) {
         m_global_register[regnum] = v;
         return 1;
     }
 
-    Registers& registers = _localFrames.back().registers;
-    if (regnum < registers.size()) {
-        registers[regnum] = v;
-        return 2;
-    }
-
     return 0;
 }
 
 unsigned int
 as_environment::getRegister(unsigned int regnum, as_value& v)
 {
-    if (_localFrames.empty() || _localFrames.back().registers.empty()) {
-        if ( regnum >= numGlobalRegisters ) return 0;
+    // If there is a call frame and it has registers, the value must be
+    // sought there.
+    if (!_localFrames.empty()) {
+        const CallFrame& fr = _localFrames.back();
+        if (fr.hasRegisters()) {
+            if (fr.getRegister(regnum, v)) return 2;
+            return 0;
+        }
+    }
+
+    // Otherwise it can be in the global registers.
+    if (regnum < numGlobalRegisters) {
         v = m_global_register[regnum];
         return 1;
     }
 
-    Registers& registers = _localFrames.back().registers;
-    if (regnum < registers.size()) {
-        v = registers[regnum];
-        return 2;
-    }
-
     return 0;
 }
 

=== modified file 'libcore/as_environment.h'
--- a/libcore/as_environment.h  2009-11-13 08:18:42 +0000
+++ b/libcore/as_environment.h  2009-11-30 15:59:02 +0000
@@ -47,8 +47,6 @@
     /// A stack of objects used for variables/members lookup
     typedef std::vector<as_object*> ScopeStack;
 
-    typedef std::vector<as_value> Registers;
-
     as_environment(VM& vm);
 
     VM& getVM() const { return _vm; }
@@ -219,7 +217,7 @@
     ///
     void add_local_registers(unsigned int register_count) {
         assert(!_localFrames.empty());
-        return _localFrames.back().registers.resize(register_count);
+        return _localFrames.back().resizeRegisters(register_count);
     }
 
     /// Set value of a register (local or global).
@@ -275,22 +273,10 @@
     ///
     unsigned int getRegister(unsigned int regnum, as_value& v);
 
-    /// Return a reference to the Nth local register.
-    //
-    /// Local registers are only meaningful within a function2 context.
-    ///
-    as_value& local_register(boost::uint8_t n) {
-        assert(!_localFrames.empty());
-        return _localFrames.back().registers[n];
-    }
-
     /// Set the Nth local register to something
     void set_local_register(boost::uint8_t n, as_value &val) {
         if (! _localFrames.empty()) {
-            Registers& registers = _localFrames.back().registers;
-            if (n < registers.size()) {
-                registers[n] = val;
-            }
+            _localFrames.back().setRegister(n, val);
         }
     }
 
@@ -416,8 +402,9 @@
     class FrameGuard
     {
         as_environment& _env;
+
     public:
-        FrameGuard(as_environment& env, as_function* func)
+        FrameGuard(as_environment& env, as_function& func)
             :
             _env(env)
         {
@@ -474,7 +461,7 @@
     /// @param func
     /// The function being called
     ///
-    void pushCallFrame(as_function* func);
+    void pushCallFrame(as_function& func);
 
     /// Remove current call frame from the stack
     //
@@ -545,18 +532,6 @@
     ///
     bool setLocal(const std::string& varname, const as_value& val);
 
-    /// Set a variable of the given object, if it exists.
-    //
-    /// @param varname
-    /// Name of the local variable
-    ///
-    /// @param val
-    /// Value to assign to the variable
-    ///
-    /// @return true if the variable was found, false otherwise
-    ///
-    bool setLocal(as_object* locals, const std::string& varname, const 
as_value& val);
-
     static as_value undefVal;
         
 };

=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp   2009-11-29 09:24:30 +0000
+++ b/libcore/as_function.cpp   2009-11-30 12:06:32 +0000
@@ -30,6 +30,7 @@
 #include "namedStrings.h"
 #include "NativeFunction.h"
 #include "Object.h"
+#include "DisplayObject.h"
 
 #include <iostream>
 
@@ -90,40 +91,41 @@
 }
 
 as_object*
-as_function::constructInstance(const as_environment& env, fn_call::Args& args)
+constructInstance(as_function& ctor, const as_environment& env,
+        fn_call::Args& args)
 {
-
-#ifndef GNASH_USE_GC
-       assert(get_ref_count() > 0);
-#endif // GNASH_USE_GC
-
-       int swfversion = getSWFVersion(env);
-
-    Property* proto = getOwnProperty(NSV::PROP_PROTOTYPE);
-               
+    Global_as& gl = getGlobal(ctor);
+
     // Create an empty object, with a ref to the constructor's prototype.
     // The function's prototype property always becomes the new object's
     // __proto__ member, regardless of whether it is an object and regardless
     // of its visibility.
-    as_object* newobj = new as_object();
-    if (proto) newobj->set_prototype(proto->getValue(*this));
+    as_object* newobj = new as_object(gl);
+    Property* proto = ctor.getOwnProperty(NSV::PROP_PROTOTYPE);
+    if (proto) newobj->set_prototype(proto->getValue(ctor));
+
+    return ctor.construct(*newobj, env, args);
+}
+
+as_object*
+as_function::construct(as_object& newobj, const as_environment& env,
+        fn_call::Args& args)
+{
+       const int swfversion = getSWFVersion(env);
+
+    // Add a __constructor__ member to the new object visible from version 6.
+    const int flags = PropFlags::dontEnum | 
+                      PropFlags::onlySWF6Up; 
+
+    newobj.init_member(NSV::PROP_uuCONSTRUCTORuu, this, flags);
+
+    if (swfversion < 7) {
+        newobj.init_member(NSV::PROP_CONSTRUCTOR, this, PropFlags::dontEnum);
+    }
     
-    // Add a __constructor__ member to the new object, but only for SWF6 up
-    // (to be checked). NOTE that we assume the builtin constructors
-    // won't set __constructor__ to some other value...
-    int flags = PropFlags::dontEnum | 
-                PropFlags::onlySWF6Up; 
-
-    newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this), flags);
-
-    if (swfversion < 7) {
-        newobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this),
-               PropFlags::dontEnum);
-    }
-
     // Don't set a super so that it will be constructed only if required
     // by the function.
-    fn_call fn(newobj, env, args, 0, true);
+    fn_call fn(&newobj, env, args, 0, true);
     as_value ret;
 
     try {
@@ -149,19 +151,20 @@
     // 'this' pointer. Others return a new object. This is to handle those
     // cases.
     if (isBuiltin() && ret.is_object()) {
-        newobj = ret.to_object(getGlobal(env));
+        as_object* fakeobj = ret.to_object(getGlobal(env));
 
-        newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this),
+        fakeobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this),
                 flags);
 
         // Also for SWF5+ only?
         if (swfversion < 7) {
-            newobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this),
+            fakeobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this),
                     PropFlags::dontEnum);
         }
+        return fakeobj;
     }
 
-       return newobj;
+       return &newobj;
 }
 
 
@@ -334,24 +337,15 @@
                }
                else {
                        new_fn_call.this_ptr = this_ptr;
-                       as_object* proto = this_ptr->get_prototype();
-            if (proto) {
-                // Note: do not override fn_call::super by creating a super
-                // object, as it may not be needed. Doing so can have a very
-                // detrimental effect on memory usage!
-                // Normal supers will be created when needed in the function
-                // call.
+            // Note: do not override fn_call::super by creating a super
+            // object, as it may not be needed. Doing so can have a very
+            // detrimental effect on memory usage!
+            // Normal supers will be created when needed in the function
+            // call.
 
-                // TODO: it seems pointless to copy the old fn_call and
-                // then change almost everything...
-                new_fn_call.super = 0;
-            }
-            else {
-                // TODO: check this !
-                log_debug("No prototype in 'this' pointer "
-                        "passed to Function.call");
-                new_fn_call.super = function_obj->get_super();
-                       }
+            // TODO: it seems pointless to copy the old fn_call and
+            // then change almost everything...
+            new_fn_call.super = 0;
                }
                new_fn_call.drop_bottom();
        }

=== modified file 'libcore/as_function.h'
--- a/libcore/as_function.h     2009-11-29 09:27:07 +0000
+++ b/libcore/as_function.h     2009-11-30 12:32:56 +0000
@@ -67,27 +67,33 @@
        // Avoid RTTI
        as_function* to_function() { return this; }
 
-       /// Function dispatch.
-    //
+       /// Function dispatch.  //
     /// Override from as_object, although as_objects cannot generally 
     /// be called.
        virtual as_value call(const fn_call& fn) = 0;
 
-       /// Construct an instance of this class
-       // 
-       ///  Post-conditions:
-       ///      - The returned object is an instance of this class.
-       ///        See as_object::instanceOf
-       ///  
-       /// @param env
-       ///     The environment to use for stack, local variables,
-       ///     registers and scope chain.
-       /// 
-       /// @param args
-       ///     Arguments for the constructor invocation
-       ///
-       as_object* constructInstance(const as_environment& env,
-                       fn_call::Args& args);
+       /// Run this function as a constructor on an object
+    //
+    /// This function assigns various constructor properties and runs the
+    /// constructor.
+    //
+    /// NB: This function does not make the object an 'instance of' the
+    /// constructor, i.e. it does not assign a __proto__ property. For
+    /// ActionScript compatibility, callers should ensure this is already
+    /// done. 
+    //
+    /// @param newobj   The object to construct. This will be used as the
+    ///                 'this' object in the constructor.
+       /// @param env      The environment to use for stack, local variables,
+       ///                     registers and scope chain.
+       /// @param args     Arguments for the constructor invocation
+    /// @return         The constructed object. TODO: return void; currently
+    ///                 there is a hack to cope with some remaining bogus
+    ///                 constructors (Microphone and Camera), which
+    ///                 necessitates returning a different object from the
+    ///                 passed 'this' pointer.
+    as_object* construct(as_object& newobj, const as_environment& env,
+            fn_call::Args& args);
 
        /// Return true if this is a built-in class.
        virtual bool isBuiltin() { return false; }
@@ -105,6 +111,21 @@
 
 };
 
+
+/// Construct a new object from the given constructor
+//
+/// This function takes care of creating the new object and assigning the
+/// __proto__ property. The construct() function is then called with the
+/// new object as its 'this' object.
+//
+/// @param ctor     The constructor to run.
+/// @param env      The environment to use for the function call.
+/// @param arg      The arguments to pass to the constructor function.
+/// @return         A newly-created object constructed by the specified
+///                 function.
+as_object* constructInstance(as_function& ctor, const as_environment& env,
+        fn_call::Args& args);
+
 /// Initialize the global Function constructor
 void function_class_init(as_object& global, const ObjectURI& uri);
 void registerFunctionNative(as_object& global);

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2009-11-27 10:30:36 +0000
+++ b/libcore/as_value.cpp      2009-11-30 11:12:37 +0000
@@ -2186,7 +2186,7 @@
             if (ctor) {
                 fn_call::Args args;
                 args += dub;
-                ret.set_as_object(ctor->constructInstance(as_environment(vm),
+                ret.set_as_object(constructInstance(*ctor, as_environment(vm),
                             args));
             }
 

=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp        2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Color_as.cpp        2009-11-30 10:31:53 +0000
@@ -103,9 +103,9 @@
 as_value
 color_getrgb(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+       as_object* obj = ensure<ValidThis>(fn);
 
-    MovieClip* sp = getTarget(obj.get(), fn);
+    MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
        const cxform& trans = sp->get_user_cxform();
@@ -122,9 +122,9 @@
 as_value
 color_gettransform(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+       as_object* obj = ensure<ValidThis>(fn);
 
-    MovieClip* sp = getTarget(obj.get(), fn);
+    MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
        const cxform& cx = sp->get_user_cxform();
@@ -150,7 +150,7 @@
 as_value
 color_setrgb(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+       as_object* obj = ensure<ValidThis>(fn);
        
     if (!fn.nargs) {
                IF_VERBOSE_ASCODING_ERRORS(
@@ -159,7 +159,7 @@
                return as_value();
        }
 
-    MovieClip* sp = getTarget(obj.get(), fn);
+    MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
        boost::int32_t color = fn.arg(0).to_int();
@@ -183,7 +183,7 @@
 as_value
 color_settransform(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+       as_object* obj = ensure<ValidThis>(fn);
 
        if (!fn.nargs) {
                IF_VERBOSE_ASCODING_ERRORS(
@@ -192,7 +192,7 @@
                return as_value();
        }
 
-       boost::intrusive_ptr<as_object> trans = 
fn.arg(0).to_object(getGlobal(fn));
+       as_object* trans = fn.arg(0).to_object(getGlobal(fn));
 
     if (!trans) {
                IF_VERBOSE_ASCODING_ERRORS(
@@ -203,7 +203,7 @@
                return as_value();
        }
 
-    MovieClip* sp = getTarget(obj.get(), fn);
+    MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
        string_table& st = getStringTable(*obj);

=== modified file 'libcore/asobj/Date_as.cpp'
--- a/libcore/asobj/Date_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Date_as.cpp 2009-11-30 11:12:37 +0000
@@ -419,7 +419,7 @@
         as_function* ctor = gl.getMember(NSV::CLASS_DATE).to_function();
         if (!ctor) return as_value();
         fn_call::Args args;
-        return ctor->constructInstance(fn.env(), args);
+        return constructInstance(*ctor, fn.env(), args);
     }
 
     // Reject all date specifications containing Infinities and NaNs.

=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-11-30 07:43:29 +0000
+++ b/libcore/asobj/Globals.cpp 2009-11-30 16:49:34 +0000
@@ -1268,7 +1268,7 @@
         as_function* ctor = gl.getMember(NSV::CLASS_ERROR).to_function();
         if (ctor) {
             fn_call::Args args;
-            as_object* proto = ctor->constructInstance(fn.env(), args);
+            as_object* proto = constructInstance(*ctor, fn.env(), args);
 
             // Not really sure what the point of this is.
             gl.createClass(local_errorConstructor, proto);
@@ -1488,7 +1488,7 @@
     args += arg;
 
     as_environment env(getVM(gl));
-    as_object* ret = ctor->constructInstance(env, args);
+    as_object* ret = constructInstance(*ctor, env, args);
 
     return ret;
 

=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp  2009-11-29 08:57:58 +0000
+++ b/libcore/asobj/Object.cpp  2009-11-30 13:44:18 +0000
@@ -63,16 +63,16 @@
 {
     VM& vm = getVM(global);
 
-       vm.registerNative(object_watch, 101, 0); 
-       vm.registerNative(object_unwatch, 101, 1); 
-       vm.registerNative(object_addproperty, 101, 2); 
-       vm.registerNative(object_valueOf, 101, 3); 
-       vm.registerNative(object_toString, 101, 4); 
-       vm.registerNative(object_hasOwnProperty, 101, 5); 
-       vm.registerNative(object_isPrototypeOf, 101, 6); 
-       vm.registerNative(object_isPropertyEnumerable, 101, 7); 
-       vm.registerNative(object_registerClass, 101, 8);
-       vm.registerNative(object_ctor, 101, 9);
+    vm.registerNative(object_watch, 101, 0); 
+    vm.registerNative(object_unwatch, 101, 1); 
+    vm.registerNative(object_addproperty, 101, 2); 
+    vm.registerNative(object_valueOf, 101, 3); 
+    vm.registerNative(object_toString, 101, 4); 
+    vm.registerNative(object_hasOwnProperty, 101, 5); 
+    vm.registerNative(object_isPrototypeOf, 101, 6); 
+    vm.registerNative(object_isPropertyEnumerable, 101, 7); 
+    vm.registerNative(object_registerClass, 101, 8);
+    vm.registerNative(object_ctor, 101, 9);
 }
 
 // extern (used by Global.cpp)
@@ -83,8 +83,13 @@
     assert(proto);
     attachObjectInterface(*proto);
 
-    Global_as& gl = getGlobal(where);
-    as_object* cl = gl.createClass(object_ctor, proto);
+    // Object is a native constructor.
+    VM& vm = getVM(where);
+    as_object* cl = vm.getNative(101, 9);
+    cl->init_member(NSV::PROP_PROTOTYPE, proto);
+    proto->init_member(NSV::PROP_CONSTRUCTOR, cl);
+
+    attachObjectInterface(*proto);
 
     // The as_function ctor takes care of initializing these, but they
     // are different for the Object class.
@@ -93,13 +98,12 @@
     cl->set_member_flags(NSV::PROP_CONSTRUCTOR, readOnly);
     cl->set_member_flags(NSV::PROP_PROTOTYPE, readOnly);
 
-    VM& vm = getVM(where);
     const int readOnlyFlags = as_object::DefaultFlags | PropFlags::readOnly;
     cl->init_member("registerClass", vm.getNative(101, 8), readOnlyFlags);
-                    
-       // Register _global.Object (should only be visible in SWF5 up)
-       int flags = PropFlags::dontEnum; 
-       where.init_member(getName(uri), cl, flags, getNamespace(uri));
+             
+    // Register _global.Object (should only be visible in SWF5 up)
+    int flags = PropFlags::dontEnum; 
+    where.init_member(getName(uri), cl, flags, getNamespace(uri));
 
 }
 
@@ -109,25 +113,25 @@
 void
 attachObjectInterface(as_object& o)
 {
-       VM& vm = getVM(o);
+    VM& vm = getVM(o);
 
-       // We register natives despite swf version,
+    // We register natives despite swf version,
     Global_as& gl = getGlobal(o);
 
-       o.init_member("valueOf", vm.getNative(101, 3));
-       o.init_member("toString", vm.getNative(101, 4));
-       o.init_member("toLocaleString", 
gl.createFunction(object_toLocaleString));
+    o.init_member("valueOf", vm.getNative(101, 3));
+    o.init_member("toString", vm.getNative(101, 4));
+    o.init_member("toLocaleString", gl.createFunction(object_toLocaleString));
 
-       int swf6flags = PropFlags::dontEnum | 
+    int swf6flags = PropFlags::dontEnum | 
         PropFlags::dontDelete | 
         PropFlags::onlySWF6Up;
 
-       o.init_member("addProperty", vm.getNative(101, 2), swf6flags);
-       o.init_member("hasOwnProperty", vm.getNative(101, 5), swf6flags);
-       o.init_member("isPropertyEnumerable", vm.getNative(101, 7), swf6flags);
-       o.init_member("isPrototypeOf", vm.getNative(101, 6), swf6flags);
-       o.init_member("watch", vm.getNative(101, 0), swf6flags);
-       o.init_member("unwatch", vm.getNative(101, 1), swf6flags);
+    o.init_member("addProperty", vm.getNative(101, 2), swf6flags);
+    o.init_member("hasOwnProperty", vm.getNative(101, 5), swf6flags);
+    o.init_member("isPropertyEnumerable", vm.getNative(101, 7), swf6flags);
+    o.init_member("isPrototypeOf", vm.getNative(101, 6), swf6flags);
+    o.init_member("watch", vm.getNative(101, 0), swf6flags);
+    o.init_member("unwatch", vm.getNative(101, 1), swf6flags);
 }
 
 
@@ -136,16 +140,16 @@
 {
     Global_as& gl = getGlobal(fn);
 
-       if (fn.nargs == 1) {
+    if (fn.nargs == 1) {
         as_object* obj = fn.arg(0).to_object(gl);
         if (obj) return as_value(obj);
-       }
+    }
 
-       if (fn.nargs > 1) {
-               IF_VERBOSE_ASCODING_ERRORS(
-                   log_aserror(_("Too many args to Object constructor"));
-               );
-       }
+    if (fn.nargs > 1) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Too many args to Object constructor"));
+        );
+    }
 
     if (!fn.isInstantiation()) {
         return new as_object();
@@ -160,7 +164,7 @@
 as_value
 object_toString(const fn_call& fn)
 {
-    as_object* obj = fn.this_ptr;
+    as_object* obj = ensure<ValidThis>(fn);
 
     if (obj && obj->to_function()) {
         return as_value("[type Function]");
@@ -171,7 +175,7 @@
 as_value
 object_valueOf(const fn_call& fn)
 {
-       return fn.this_ptr;
+    return fn.this_ptr;
 }
 
 
@@ -180,252 +184,241 @@
 as_value
 object_addproperty(const fn_call& fn)
 {
-       assert(fn.this_ptr);
-       boost::intrusive_ptr<as_object> obj = fn.this_ptr;
+    as_object* obj = ensure<ValidThis>(fn);
 
     /// Extra arguments are just ignored.
-       if ( fn.nargs < 3 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss;
-               fn.dump_args(ss);
-               log_aserror(_("Invalid call to Object.addProperty(%s) - "
-                       "expected 3 arguments (<name>, <getter>, <setter>)"),
-                       ss.str());
-               );
-
-               // if we've been given more args then needed there's
-               // no need to abort here
-               if ( fn.nargs < 3 )
-               {
-                       return as_value(false);
-               }
-       }
-
-       const std::string& propname = fn.arg(0).to_string();
-       if (propname.empty())
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Invalid call to Object.addProperty() - "
-                       "empty property name"));
-               );
-               return as_value(false);
-       }
-
-       as_function* getter = fn.arg(1).to_function();
-       if (!getter)
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Invalid call to Object.addProperty() - "
-                       "getter is not an AS function"));
-               );
-               return as_value(false);
-       }
-
-       as_function* setter = NULL;
-       const as_value& setterval = fn.arg(2);
-       if (!setterval.is_null())
-       {
-               setter = setterval.to_function();
-               if (!setter)
-               {
-                       IF_VERBOSE_ASCODING_ERRORS(
-                       log_aserror(_("Invalid call to Object.addProperty() - "
-                               "setter is not null and not an AS function 
(%s)"),
-                               setterval);
-                       );
-                       return as_value(false);
-               }
-       }
-
-       // Now that we checked everything, let's call the as_object
-       // interface for getter/setter properties :)
-       obj->add_property(propname, *getter, setter);
-
-       return as_value(true);
+    if ( fn.nargs < 3 )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss;
+        fn.dump_args(ss);
+        log_aserror(_("Invalid call to Object.addProperty(%s) - "
+            "expected 3 arguments (<name>, <getter>, <setter>)"),
+                   ss.str());
+        );
+
+        // if we've been given more args then needed there's
+        // no need to abort here
+        if ( fn.nargs < 3 )
+        {
+            return as_value(false);
+        }
+    }
+
+    const std::string& propname = fn.arg(0).to_string();
+    if (propname.empty())
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Invalid call to Object.addProperty() - "
+            "empty property name"));
+        );
+        return as_value(false);
+    }
+
+    as_function* getter = fn.arg(1).to_function();
+    if (!getter)
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Invalid call to Object.addProperty() - "
+            "getter is not an AS function"));
+        );
+        return as_value(false);
+    }
+
+    as_function* setter = NULL;
+    const as_value& setterval = fn.arg(2);
+    if (!setterval.is_null())
+    {
+        setter = setterval.to_function();
+        if (!setter)
+        {
+            IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Invalid call to Object.addProperty() - "
+                "setter is not null and not an AS function (%s)"),
+                setterval);
+            );
+            return as_value(false);
+        }
+    }
+
+    // Now that we checked everything, let's call the as_object
+    // interface for getter/setter properties :)
+    obj->add_property(propname, *getter, setter);
+
+    return as_value(true);
 }
 
 
 as_value
 object_registerClass(const fn_call& fn)
 {
-       assert(fn.this_ptr);
-
-       if ( fn.nargs != 2 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss;
-               fn.dump_args(ss);
-               log_aserror(_("Invalid call to Object.registerClass(%s) - "
-                       "expected 2 arguments (<symbol>, <constructor>)"),
-                       ss.str());
-               );
-
-               // if we've been given more args then needed there's
-               // no need to abort here
-               if ( fn.nargs < 2 )
-               {
-                       return as_value(false);
-               }
-       }
-
-       const std::string& symbolid = fn.arg(0).to_string();
-       if ( symbolid.empty() )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss;
-               fn.dump_args(ss);
-               log_aserror(_("Invalid call to Object.registerClass(%s) - "
-                       "first argument (symbol id) evaluates to empty 
string"), ss.str());
-               );
-               return as_value(false);
-       }
-
-       as_function* theclass = fn.arg(1).to_function();
-       if ( ! theclass )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss;
-               fn.dump_args(ss);
-               log_aserror(_("Invalid call to Object.registerClass(%s) - "
-                       "second argument (class) is not a function)"), 
ss.str());
-               );
-               return as_value(false);
-       }
-
-       // Find the exported resource
-
-       // Using definition of current target fixes the youtube beta case
-       // https://savannah.gnu.org/bugs/index.php?23130
-       DisplayObject* tgt = fn.env().get_target();
-       if ( ! tgt ) {
-               log_error("current environment has no target, wouldn't know 
where to look for symbol required for registerClass"); 
-               return as_value(false);
-       }
-       Movie* relRoot = tgt->get_root();
-       assert(relRoot);
-       const movie_definition* def = relRoot->definition();
-       
-    boost::intrusive_ptr<ExportableResource> exp_res =
-        def->get_exported_resource(symbolid);
-       if ( ! exp_res )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Object.registerClass(%s, %s): "
-                       "can't find exported symbol"),
-                       symbolid, 
-                       typeid(theclass).name());
-               );
-               return as_value(false);
-       }
-
-       // Check that the exported resource is a sprite_definition
-       // (we're looking for a MovieClip symbol)
-
-       boost::intrusive_ptr<sprite_definition> exp_clipdef(
-            dynamic_cast<sprite_definition*>(exp_res.get()));
-
-
-       if ( ! exp_clipdef )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Object.registerClass(%s, %s): "
-                       "exported symbol is not a MovieClip symbol "
-                       "(sprite_definition), but a %s"),
-                       symbolid, typeName(theclass), typeName(exp_res));
-               );
-               return as_value(false);
-       }
-
-       exp_clipdef->registerClass(theclass);
-       return as_value(true);
+
+    if (fn.nargs != 2) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            std::stringstream ss;
+            fn.dump_args(ss);
+            log_aserror(_("Invalid call to Object.registerClass(%s) - "
+                "expected 2 arguments (<symbol>, <constructor>)"),
+                ss.str());
+        );
+
+        // if we've been given more args then needed there's
+        // no need to abort here
+        if (fn.nargs < 2) {
+            return as_value(false);
+        }
+    }
+
+    const std::string& symbolid = fn.arg(0).to_string();
+    if (symbolid.empty())
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+            std::stringstream ss;
+            fn.dump_args(ss);
+            log_aserror(_("Invalid call to Object.registerClass(%s) - "
+                "first argument (symbol id) evaluates to empty string"),
+                ss.str());
+        );
+        return as_value(false);
+    }
+
+    as_function* theclass = fn.arg(1).to_function();
+    if (!theclass) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            std::stringstream ss;
+            fn.dump_args(ss);
+            log_aserror(_("Invalid call to Object.registerClass(%s) - "
+                "second argument (class) is not a function)"), ss.str());
+            );
+        return as_value(false);
+    }
+
+    // Find the exported resource
+
+    // Using definition of current target fixes the youtube beta case
+    // https://savannah.gnu.org/bugs/index.php?23130
+    DisplayObject* tgt = fn.env().get_target();
+    if (!tgt) {
+        log_error("current environment has no target, wouldn't know "
+                "where to look for symbol required for registerClass"); 
+        return as_value(false);
+    }
+
+    Movie* relRoot = tgt->get_root();
+    assert(relRoot);
+    const movie_definition* def = relRoot->definition();
+    
+    ExportableResource* exp_res = def->get_exported_resource(symbolid).get();
+    if (!exp_res) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Object.registerClass(%s, %s): "
+                "can't find exported symbol"),
+                symbolid, typeName(theclass));
+            );
+        return as_value(false);
+    }
+
+    // Check that the exported resource is a sprite_definition
+    // (we're looking for a MovieClip symbol)
+
+    sprite_definition* exp_clipdef(
+            dynamic_cast<sprite_definition*>(exp_res));
+
+
+    if (!exp_clipdef) {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Object.registerClass(%s, %s): "
+            "exported symbol is not a MovieClip symbol "
+            "(sprite_definition), but a %s"),
+            symbolid, typeName(theclass), typeName(exp_res));
+        );
+        return as_value(false);
+    }
+
+    exp_clipdef->registerClass(theclass);
+    return as_value(true);
 }
 
 
 as_value
 object_hasOwnProperty(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
-
-       //assert(fn.result->is_undefined());
-       if ( fn.nargs < 1 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Object.hasOwnProperty() requires one arg"));
-               );
-               return as_value(false);
-       }
-       const as_value& arg = fn.arg(0);
-       const std::string& propname = arg.to_string();
-       if ( arg.is_undefined() || propname.empty() )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Invalid call to Object.hasOwnProperty('%s')"), 
arg);
-               );
-               return as_value(false);
-       }
-       //log_debug("%p.hasOwnProperty", fn.this_ptr);
-    const bool found =
-        fn.this_ptr->hasOwnProperty(getStringTable(fn).find(propname));
+    as_object* obj = ensure<ValidThis>(fn);
+
+    if ( fn.nargs < 1 )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Object.hasOwnProperty() requires one arg"));
+        );
+        return as_value(false);
+    }
+    const as_value& arg = fn.arg(0);
+    const std::string& propname = arg.to_string();
+    if (arg.is_undefined() || propname.empty())
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Invalid call to Object.hasOwnProperty('%s')"), arg);
+        );
+        return as_value(false);
+    }
+
+    const bool found = obj->hasOwnProperty(getStringTable(fn).find(propname));
     return as_value(found);
 }
 
 as_value
 object_isPropertyEnumerable(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
-
-       //assert(fn.result->is_undefined());
-       if ( fn.nargs < 1 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Object.isPropertyEnumerable() requires one 
arg"));
-               );
-               return as_value();
-       }
-       const as_value& arg = fn.arg(0);
-       const std::string& propname = arg.to_string();
-       if ( arg.is_undefined() || propname.empty() )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Invalid call to 
Object.isPropertyEnumerable('%s')"), arg);
-               );
-               return as_value();
-       }
-
-       Property* prop =
-        fn.this_ptr->getOwnProperty(getStringTable(fn).find(propname));
-       if ( ! prop )
-       {
-               return as_value(false);
-       }
-
-       return as_value( ! prop->getFlags().get_dont_enum() );
+    as_object* obj = ensure<ValidThis>(fn);
+
+    if (fn.nargs < 1) {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Object.isPropertyEnumerable() requires one arg"));
+        );
+        return as_value();
+    }
+    const as_value& arg = fn.arg(0);
+    const std::string& propname = arg.to_string();
+    if (arg.is_undefined() || propname.empty()) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Invalid call to Object.isPropertyEnumerable('%s')"),
+                arg);
+            );
+        return as_value();
+    }
+
+    Property* prop = obj->getOwnProperty(getStringTable(fn).find(propname));
+
+    if (!prop) {
+        return as_value(false);
+    }
+
+    return as_value(!prop->getFlags().get_dont_enum());
 }
 
 
 as_value
 object_isPrototypeOf(const fn_call& fn)
 {
-       //assert(fn.result->is_undefined());
-       if ( fn.nargs < 1 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("Object.isPrototypeOf() requires one arg"));
-               );
-               return as_value(false); 
-       }
-
-       boost::intrusive_ptr<as_object> obj = 
fn.arg(0).to_object(getGlobal(fn));
-       if ( ! obj )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("First arg to Object.isPrototypeOf(%s) is not an 
object"), fn.arg(0));
-               );
-               return as_value(false);
-       }
-
-       return as_value(fn.this_ptr->prototypeOf(*obj));
+    as_object* obj = ensure<ValidThis>(fn);
+
+    if (fn.nargs < 1) {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Object.isPrototypeOf() requires one arg"));
+        );
+        return as_value(false); 
+    }
+
+    as_object* arg = fn.arg(0).to_object(getGlobal(fn));
+    if (!arg) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("First arg to Object.isPrototypeOf(%s) is "
+                    "not an object"), fn.arg(0));
+            );
+        return as_value(false);
+    }
+
+    return as_value(obj->prototypeOf(*arg));
 
 }
 
@@ -433,62 +426,62 @@
 as_value
 object_watch(const fn_call& fn)
 {
-       as_object* obj = fn.this_ptr;
-
-       if ( fn.nargs < 2 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Object.watch(%s): missing arguments"));
-               );
-               return as_value(false);
-       }
-
-       const as_value& propval = fn.arg(0);
-       const as_value& funcval = fn.arg(1);
-
-       if ( ! funcval.is_function() )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Object.watch(%s): second argument is not a 
function"));
-               );
-               return as_value(false);
-       }
-
-       string_table& st = getStringTable(fn);
-
-       std::string propname = propval.to_string();
-       string_table::key propkey = st.find(propname);
-       as_function* trig = funcval.to_function();
-       as_value cust; if ( fn.nargs > 2 ) cust = fn.arg(2);
-
-       return as_value(obj->watch(propkey, *trig, cust));
+    as_object* obj = ensure<ValidThis>(fn);
+
+    if ( fn.nargs < 2 )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror(_("Object.watch(%s): missing arguments"));
+        );
+        return as_value(false);
+    }
+
+    const as_value& propval = fn.arg(0);
+    const as_value& funcval = fn.arg(1);
+
+    if ( ! funcval.is_function() )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror(_("Object.watch(%s): second argument is not a function"));
+        );
+        return as_value(false);
+    }
+
+    string_table& st = getStringTable(fn);
+
+    std::string propname = propval.to_string();
+    string_table::key propkey = st.find(propname);
+    as_function* trig = funcval.to_function();
+    as_value cust; if ( fn.nargs > 2 ) cust = fn.arg(2);
+
+    return as_value(obj->watch(propkey, *trig, cust));
 }
 
 
 as_value
 object_unwatch(const fn_call& fn)
 {
-       as_object* obj = fn.this_ptr;
-
-       if ( fn.nargs < 1 )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Object.unwatch(%s): missing argument"));
-               );
-               return as_value(false);
-       }
-
-       const as_value& propval = fn.arg(0);
-
-       string_table& st = getStringTable(fn);
-
-       std::string propname = propval.to_string();
-       string_table::key propkey = st.find(propname);
-
-       return as_value(obj->unwatch(propkey));
+    as_object* obj = ensure<ValidThis>(fn);
+
+    if ( fn.nargs < 1 )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror(_("Object.unwatch(%s): missing argument"));
+        );
+        return as_value(false);
+    }
+
+    const as_value& propval = fn.arg(0);
+
+    string_table& st = getStringTable(fn);
+
+    std::string propname = propval.to_string();
+    string_table::key propkey = st.find(propname);
+
+    return as_value(obj->unwatch(propkey));
 }
 
 
@@ -496,7 +489,7 @@
 object_toLocaleString(const fn_call& fn)
 {
     as_object* obj = ensure<ValidThis>(fn);
-       return callMethod(obj, NSV::PROP_TO_STRING);
+    return callMethod(obj, NSV::PROP_TO_STRING);
 }
   
 } // anonymous namespace

=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp       2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/String_as.cpp       2009-11-30 10:19:02 +0000
@@ -156,7 +156,6 @@
 as_value
 string_concat(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
 
     std::string str;
@@ -174,7 +173,6 @@
 as_value
 string_slice(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -230,7 +228,6 @@
 as_value
 string_split(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -346,7 +343,6 @@
 as_value
 string_lastIndexOf(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -383,7 +379,6 @@
 as_value
 string_substr(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -422,7 +417,6 @@
 as_value
 string_substring(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -475,7 +469,6 @@
 as_value
 string_indexOf(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
  
     /// Do not return before this, because the toString method should always
@@ -567,7 +560,6 @@
 as_value
 string_charCodeAt(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -604,7 +596,6 @@
 as_value
 string_charAt(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -639,7 +630,6 @@
 as_value
 string_toUpperCase(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
 
     std::string str;
@@ -677,7 +667,6 @@
 as_value
 string_toLowerCase(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
     
     std::string str;
@@ -714,7 +703,6 @@
 as_value
 string_oldToLower(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
 
     // This should use the C locale; extended DisplayObjects are
@@ -727,7 +715,6 @@
 as_value
 string_oldToUpper(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
     as_value val(fn.this_ptr);
 
     // This should use the C locale; extended DisplayObjects are

=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp     2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp     2009-11-30 11:12:37 
+0000
@@ -594,7 +594,7 @@
     args += 0.0, 0.0, ptr->getWidth(), ptr->getHeight();
 
     boost::intrusive_ptr<as_object> newRect =
-            rectCtor->constructInstance(fn.env(), args);
+            constructInstance(*rectCtor, fn.env(), args);
 
     return as_value(newRect.get());
 }

=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp      2009-11-18 12:32:41 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp      2009-11-30 11:12:37 
+0000
@@ -1239,7 +1239,7 @@
     args += getObject(movieclip);
 
     boost::intrusive_ptr<as_object> ts =
-        tsCtor->constructInstance(fn.env(), args);
+        constructInstance(*tsCtor, fn.env(), args);
 
     return as_value(ts.get());
 }
@@ -2330,7 +2330,7 @@
     args += getObject(ptr);
 
     boost::intrusive_ptr<as_object> newTrans =
-        transCtor->constructInstance(fn.env(), args);
+        constructInstance(*transCtor, fn.env(), args);
 
     return as_value(newTrans.get());
 }

=== modified file 'libcore/asobj/flash/filters/BitmapFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-11-30 11:12:37 
+0000
@@ -85,7 +85,7 @@
     if (constructor) {
         fn_call::Args args;
         VM& vm = getVM(where);
-        proto = constructor->constructInstance(as_environment(vm), args);
+        proto = constructInstance(*constructor, as_environment(vm), args);
     }
     else proto = 0;
 

=== modified file 'libcore/asobj/flash/geom/Matrix_as.cpp'
--- a/libcore/asobj/flash/geom/Matrix_as.cpp    2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp    2009-11-30 11:12:37 +0000
@@ -130,10 +130,10 @@
 as_object*
 instanceOfMatrix(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+    as_object* obj = ensure<ValidThis>(fn);
 
     as_function* ctor = getClassConstructor(fn, "flash.geom.Matrix");
-    if (obj->instanceOf(ctor)) return obj.get();
+    if (obj->instanceOf(ctor)) return obj;
     return 0;
 }
 
@@ -143,7 +143,7 @@
 {
     // It doesn't matter whether it is a matrix or not; a new Matrix
     // is created using any Matrix properties the object may have.
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value a, b, c, d, tx, ty;
     ptr->get_member(NSV::PROP_A, &a);
@@ -163,7 +163,7 @@
         return as_value();
     }
 
-    as_object* o = ctor->constructInstance(fn.env(), args);
+    as_object* o = constructInstance(*ctor, fn.env(), args);
 
     return as_value(o);
 }
@@ -173,7 +173,7 @@
 matrix_concat(const fn_call& fn)
 {
     // Doesn't have to be a Matrix.
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     if (fn.nargs < 1)
     {
@@ -241,7 +241,7 @@
 matrix_createBox(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     if (fn.nargs < 2)
     {
@@ -374,7 +374,7 @@
 matrix_deltaTransformPoint(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     if (fn.nargs < 1)
     {
@@ -406,7 +406,7 @@
     as_object* obj = arg.to_object(getGlobal(fn));
     assert(obj);
 
-    const PointType& point = transformPoint(obj, ptr.get());
+    const PointType& point = transformPoint(obj, ptr);
 
     // Construct a Point and set its properties.
     as_value pointClass(fn.env().find_object("flash.geom.Point"));
@@ -421,7 +421,7 @@
     fn_call::Args args;
     args += point(0), point(1);
 
-    as_value ret = pointCtor->constructInstance(fn.env(), args);
+    as_value ret = constructInstance(*pointCtor, fn.env(), args);
 
     return as_value(ret);
 }
@@ -437,7 +437,7 @@
 matrix_identity(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     ptr->set_member(NSV::PROP_A, 1.0);
     ptr->set_member(NSV::PROP_B, 0.0);
@@ -461,7 +461,7 @@
 {
 
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     MatrixType currentMatrix;
     
@@ -651,7 +651,7 @@
 matrix_toString(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value a, b, c, d, tx, ty;
 
@@ -680,7 +680,7 @@
 matrix_transformPoint(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     if (fn.nargs < 1)
     {
@@ -722,7 +722,7 @@
     ptr->get_member(NSV::PROP_TX, &tx);
     ptr->get_member(NSV::PROP_TY, &ty);
     
-    const PointType& point = transformPoint(obj, ptr.get());
+    const PointType& point = transformPoint(obj, ptr);
 
     // Construct a Point and set its properties.
     as_value pointClass(fn.env().find_object("flash.geom.Point"));
@@ -737,7 +737,7 @@
     fn_call::Args args;
     args += point(0) + tx.to_number(), point(1) + ty.to_number();
 
-    as_value ret = pointCtor->constructInstance(fn.env(), args);
+    as_value ret = constructInstance(*pointCtor, fn.env(), args);
 
     return as_value(ret);
 }
@@ -746,7 +746,7 @@
 matrix_translate(const fn_call& fn)
 {
     // Doesn't have to be a Matrix
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
     
     if (fn.nargs < 2)
     {
@@ -863,7 +863,7 @@
 as_value
 matrix_ctor(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = ensure<ThisIs<as_object> >(fn);
+    as_object* obj = ensure<ValidThis>(fn);
     
     as_value a, b, c, d, tx, ty;
 

=== modified file 'libcore/asobj/flash/geom/Point_as.cpp'
--- a/libcore/asobj/flash/geom/Point_as.cpp     2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/geom/Point_as.cpp     2009-11-30 11:12:37 +0000
@@ -71,7 +71,7 @@
     fn_call::Args args;
     args += x, y;
 
-    return ctor->constructInstance(fn.env(), args);
+    return constructInstance(*ctor, fn.env(), args);
 }
 
 void
@@ -103,7 +103,7 @@
 as_value
 point_add(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value x, y;
     ptr->get_member(NSV::PROP_X, &x);
@@ -166,7 +166,7 @@
 as_value
 point_clone(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value x, y;
     ptr->get_member(NSV::PROP_X, &x);
@@ -178,7 +178,7 @@
 as_value
 point_equals(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     if ( ! fn.nargs )
     {
@@ -224,7 +224,7 @@
 as_value
 point_normalize(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value argval;
 
@@ -278,7 +278,7 @@
 as_value
 point_offset(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     as_value x, y;
     ptr->get_member(NSV::PROP_X, &x);

=== modified file 'libcore/asobj/flash/geom/Rectangle_as.cpp'
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-11-30 11:12:37 +0000
@@ -138,7 +138,7 @@
     fn_call::Args args;
     args += x, y, w, h;
 
-    return ctor->constructInstance(fn.env(), args);
+    return constructInstance(*ctor, fn.env(), args);
 }
 
 as_value
@@ -430,7 +430,7 @@
         fn_call::Args args;
         args += x, y;
 
-        as_value ret = pointCtor->constructInstance(fn.env(), args);
+        as_value ret = constructInstance(*pointCtor, fn.env(), args);
         return ret;
     }
 
@@ -524,7 +524,7 @@
         fn_call::Args args;
         args += w, h;
 
-        ret = pointCtor->constructInstance(fn.env(), args);
+        ret = constructInstance(*pointCtor, fn.env(), args);
     }
     else // setter
     {
@@ -589,7 +589,7 @@
         fn_call::Args args;
         args += x, y;
 
-        ret = pointCtor->constructInstance(fn.env(), args);
+        ret = constructInstance(*pointCtor, fn.env(), args);
 
     }
     else // setter

=== modified file 'libcore/asobj/flash/geom/Transform_as.cpp'
--- a/libcore/asobj/flash/geom/Transform_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/geom/Transform_as.cpp 2009-11-30 11:12:37 +0000
@@ -145,7 +145,7 @@
              c.rb, c.gb, c.bb, c.ab;
 
         as_object* colorTransformObj =
-            colorTransformCtor->constructInstance(fn.env(), args);
+            constructInstance(*colorTransformCtor, fn.env(), args);
 
         return as_value(colorTransformObj);
     }
@@ -231,7 +231,7 @@
              c.rb, c.gb, c.bb, c.ab;
 
         as_object* colorTransformObj =
-            colorTransformCtor->constructInstance(fn.env(), args);
+            constructInstance(*colorTransformCtor, fn.env(), args);
 
         return as_value(colorTransformObj);
     }
@@ -270,7 +270,7 @@
                 twipsToPixels(m.tx),
                 twipsToPixels(m.ty);
 
-        as_object* matrixObj = matrixCtor->constructInstance(fn.env(), args);
+        as_object* matrixObj = constructInstance(*matrixCtor, fn.env(), args);
 
         return as_value(matrixObj);
     }
@@ -314,7 +314,7 @@
                 twipsToPixels(m.tx),
                 twipsToPixels(m.ty);
 
-        as_object* matrixObj = matrixCtor->constructInstance(fn.env(), args);
+        as_object* matrixObj = constructInstance(*matrixCtor, fn.env(), args);
 
         return as_value(matrixObj);
     }

=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp       2009-11-27 11:41:17 
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp       2009-11-30 11:12:37 
+0000
@@ -1303,7 +1303,7 @@
     if (!ctor) return 0;
     as_environment env(getVM(gl));
     fn_call::Args args;
-    as_object* o = ctor->constructInstance(env, args);
+    as_object* o = constructInstance(*ctor, env, args);
 
     std::auto_ptr<SharedObject_as> sh(new SharedObject_as(*o));
     o->setRelay(sh.release());

=== modified file 'libcore/asobj/flash/net/XMLSocket_as.cpp'
--- a/libcore/asobj/flash/net/XMLSocket_as.cpp  2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/net/XMLSocket_as.cpp  2009-11-30 11:12:37 +0000
@@ -547,7 +547,7 @@
 
     as_value xml;
     if (ctor) {
-        xml = ctor->constructInstance(fn.env(), args);
+        xml = constructInstance(*ctor, fn.env(), args);
     }
 
     // The built-in function calls:

=== modified file 'libcore/asobj/flash/ui/ContextMenuItem_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenuItem_as.cpp     2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/ui/ContextMenuItem_as.cpp     2009-11-30 11:12:37 
+0000
@@ -62,7 +62,7 @@
 as_value
 contextmenuitem_copy(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     Global_as& gl = getGlobal(fn);
     string_table& st = getStringTable(fn);
@@ -79,7 +79,7 @@
         ptr->getMember(NSV::PROP_ENABLED),
         ptr->getMember(st.find("visible"));
 
-    return ctor->constructInstance(fn.env(), args);
+    return constructInstance(*ctor, fn.env(), args);
 }
 
 

=== modified file 'libcore/asobj/flash/ui/ContextMenu_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-11-30 11:12:37 +0000
@@ -108,7 +108,7 @@
 as_value
 contextmenu_hideBuiltInItems(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
     string_table& st = getStringTable(fn);
 
     Global_as& gl = getGlobal(fn);
@@ -122,7 +122,7 @@
 as_value
 contextmenu_copy(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+    as_object* ptr = ensure<ValidThis>(fn);
 
     Global_as& gl = getGlobal(fn);
 
@@ -132,7 +132,7 @@
     }
 
     fn_call::Args args;
-    as_object* o = ctor->constructInstance(fn.env(), args);
+    as_object* o = constructInstance(*ctor, fn.env(), args);
 
     if (!o) return as_value();
     
@@ -158,7 +158,7 @@
     as_function* arrayctor = getClassConstructor(fn, "Array");
     if (arrayctor) {
         fn_call::Args args;
-        as_object* arr = arrayctor->constructInstance(fn.env(), args);
+        as_object* arr = constructInstance(*arrayctor, fn.env(), args);
         if (arr) {
             as_object* customs;
             if (customItems.is_object() &&

=== modified file 'libcore/asobj/flash/ui/Mouse_as.cpp'
--- a/libcore/asobj/flash/ui/Mouse_as.cpp       2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/ui/Mouse_as.cpp       2009-11-30 13:14:56 +0000
@@ -77,6 +77,10 @@
     // Mouse is always initialized as an AsBroadcaster, even for
     // SWF5.   
     AsBroadcaster::initialize(o);
+
+    Global_as& gl = getGlobal(o);
+    as_object* null = 0;
+    callMethod(&gl, NSV::PROP_AS_SET_PROP_FLAGS, &o, null, 7);
 }
 
 /// Returns whether the mouse was visible before the call.

=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-11-27 12:59:50 
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-11-30 11:12:37 
+0000
@@ -687,7 +687,7 @@
         fn_call::Args args;
         args += 1, "";
         as_object* proto =
-            ctor->constructInstance(as_environment(getVM(where)), args);
+            constructInstance(*ctor, as_environment(getVM(where)), args);
         attachXMLInterface(*proto);
         cl->init_member(NSV::PROP_PROTOTYPE, proto);
     }

=== modified file 'libcore/builtin_function.h'
--- a/libcore/builtin_function.h        2009-11-23 07:42:51 +0000
+++ b/libcore/builtin_function.h        2009-11-30 15:59:02 +0000
@@ -50,7 +50,6 @@
        /// @param func
        ///     The C function to call when this as_function is invoked.
        ///     For classes, the function pointer is the constructor.
-       ///
        builtin_function(Global_as& gl, ASFunction func)
                :
                as_function(gl),
@@ -61,20 +60,8 @@
        /// Invoke this function or this Class constructor
        virtual as_value call(const fn_call& fn)
        {
-               // Real native functions don't put self on the CallStack
-               // (they never end up in an arguments.caller).
-               // This is, for example, the case for Array.sort when
-               // calling a custom comparator.
-               // Unfortunately gnash implements all builtin as natives
-               // while the proprietary player doesn't (for example
-               // MovieClip.meth does end up in arguments.caller).
-               //
-               // A possible short-term solution to this could be
-               // specifying for a builtin_function whether or not
-               // it should be considered 'native'.
-               // If not 'native', we'd push a CallFrame on stack...
         as_environment env = fn.env();
-               as_environment::FrameGuard guard(env, this);
+               as_environment::FrameGuard guard(env, *this);
 
                assert(_func);
                return _func(fn);

=== modified file 'libcore/swf_function.cpp'
--- a/libcore/swf_function.cpp  2009-11-29 09:27:07 +0000
+++ b/libcore/swf_function.cpp  2009-11-30 15:59:02 +0000
@@ -34,18 +34,12 @@
 
 namespace {
 
-       /// Return an 'arguments' object.
+       /// Add properties to an 'arguments' object.
        //
        /// The 'arguments' variable is an array with an additional
        /// 'callee' member, set to the function being called.
-       ///
-       /// NOTE: the callee as_object will be stored in an as_value, thus
-       ///       getting wrapped into an intrusive_ptr. Make sure you have
-       ///       a reference on it!
-       ///       
-       ///
-       as_object* getArguments(swf_function& callee, const fn_call& fn,
-            as_object* caller);
+       as_object* getArguments(swf_function& callee, as_object& args, 
+            const fn_call& fn, as_object* caller);
 }
 
 swf_function::swf_function(const action_buffer& ab, as_environment& env,
@@ -53,15 +47,15 @@
        :
        as_function(getGlobal(env)),
        m_action_buffer(ab),
-       m_env(env),
+       _env(env),
        _scopeStack(scopeStack),
-       m_start_pc(start),
-       m_length(0),
-       m_is_function2(false),
-       m_local_register_count(0),
-       m_function2_flags(0)
+       _startPC(start),
+       _length(0),
+       _isFunction2(false),
+       _registerCount(0),
+       _function2Flags(0)
 {
-       assert( m_start_pc < m_action_buffer.size() );
+       assert( _startPC < m_action_buffer.size() );
 
     // We're stuck initializing our own prototype at the moment.
     as_object* proto = getGlobal(env).createObject();
@@ -109,19 +103,19 @@
 swf_function::call(const fn_call& fn)
 {
     // Extract caller before pushing ourself on the call stack
-    as_object* caller = 0;
     VM& vm = getVM(fn); 
     CallStack& cs = vm.getCallStack();
-    if ( ! cs.empty() ) caller = cs.back().func;
+
+    as_object* caller = cs.empty() ? 0 : &cs.back().function();
 
        // Set up local stack frame, for parameters and locals.
-       as_environment::FrameGuard guard(m_env, this);
+       as_environment::FrameGuard guard(_env, *this);
 
-       DisplayObject* target = m_env.get_target();
-       DisplayObject* orig_target = m_env.get_original_target();
+       DisplayObject* target = _env.get_target();
+       DisplayObject* orig_target = _env.get_original_target();
 
        // Some features are version-dependant.
-       const int swfversion = vm.getSWFVersion();
+       const int swfversion = getSWFVersion(fn);
 
        if (swfversion < 6) {
                // In SWF5, when 'this' is a DisplayObject it becomes
@@ -144,128 +138,138 @@
        ///       the one set now (rather then the really original one)
        /// TODO: test scope when calling functions defined in another timeline
        ///       (target, in particular).
-       ///
-       TargetGuard targetGuard(m_env, target, orig_target);
-
-       if (!m_is_function2)
-       {
+       TargetGuard targetGuard(_env, target, orig_target);
+
+       if (!_isFunction2) {
+
                // Conventional function.
 
                // Push the arguments onto the local frame.
-               for (size_t i=0, n=m_args.size(); i<n; ++i)
+               for (size_t i=0, n=_args.size(); i<n; ++i)
                {
-                       assert(m_args[i].m_register == 0);
+                       assert(_args[i].reg == 0);
                        if (i < fn.nargs) {
-                               m_env.add_local(m_args[i].m_name, fn.arg(i));
+                               _env.add_local(_args[i].name, fn.arg(i));
                        }
                        else {
                                // Still declare named arguments, even if
                                // they are not passed from caller
                                // See bug #22203
-                               m_env.declare_local(m_args[i].m_name);
+                               _env.declare_local(_args[i].name);
                        }
                }
 
                // Add 'this'
-               m_env.set_local("this", fn.this_ptr ? fn.this_ptr : as_value());
+               _env.set_local("this", fn.this_ptr ? fn.this_ptr : as_value());
 
         as_object* super = fn.super ? fn.super :
             fn.this_ptr ? fn.this_ptr->get_super() : 0;
 
                // Add 'super' (SWF6+ only)
                if (super && swfversion > 5) {
-                       m_env.set_local("super", super);
+                       _env.set_local("super", super);
                }
 
                // Add 'arguments'
-               m_env.set_local("arguments", getArguments(*this, fn, caller));
+        as_object* args = getGlobal(fn).createArray();
+               _env.set_local("arguments", getArguments(*this, *args, fn, 
caller));
        }
        else
        {
                // function2: most args go in registers; any others get pushed.
                
                // Create local registers.
-               m_env.add_local_registers(m_local_register_count);
+               _env.add_local_registers(_registerCount);
 
                // Handle the implicit args.
                // @@ why start at 1 ? Note that starting at 0 makes    
                // intro.swf movie fail to play correctly.
-               unsigned int current_reg = 1;
-               if ((m_function2_flags & PRELOAD_THIS) &&
-                !(m_function2_flags & SUPPRESS_THIS)) {
-                       // preload 'this' into a register.
-            // TODO: check whether it should be undefined or null if this_ptr
-            // is null.
-                       m_env.setRegister(current_reg, fn.this_ptr); 
-                       ++current_reg;
-               }
-
-               if (!(m_function2_flags & SUPPRESS_THIS)) {
-                       // Put 'this' in a local var.
-                       m_env.add_local("this", fn.this_ptr ? fn.this_ptr : 
as_value());
-               }
-
-               // Init arguments array, if it's going to be needed.
-        as_object* arg_array = 0;
-
-               if ((m_function2_flags & PRELOAD_ARGUMENTS) || 
-                !(m_function2_flags & SUPPRESS_ARGUMENTS)) {
-                       arg_array = getArguments(*this, fn, caller);
-               }
-
-               if (m_function2_flags & PRELOAD_ARGUMENTS) {
-                       // preload 'arguments' into a register.
-                       m_env.setRegister(current_reg, as_value(arg_array));
-                       current_reg++;
-               }
-
-               if (!(m_function2_flags & SUPPRESS_ARGUMENTS)) {
-                       // Put 'arguments' in a local var.
-                       m_env.add_local("arguments", arg_array);
-               }
+        size_t current_reg(1);
+
+        // If this is not suppressed it is either placed in a register
+        // or set as a local variable, but not both.
+               if (!(_function2Flags & SUPPRESS_THIS)) {
+            if (_function2Flags & PRELOAD_THIS) {
+                // preload 'this' into a register.
+                // TODO: check whether it should be undefined or null
+                // if this_ptr is null.
+                _env.setRegister(current_reg, fn.this_ptr); 
+                ++current_reg;
+            }
+            else {
+                // Put 'this' in a local var.
+                _env.add_local("this", fn.this_ptr ? fn.this_ptr : as_value());
+            }
+        }
+
+        // This works slightly differently from 'super' and 'this'. The
+        // arguments are only ever either placed in the register or a
+        // local variable, but if both preload and suppress arguments flags
+        // are set, an empty array is still placed to the register.
+        // This seems like a bug in the reference player.
+        if (!(_function2Flags & SUPPRESS_ARGUMENTS) ||
+                (_function2Flags & PRELOAD_ARGUMENTS)) {
+            
+            as_object* args = getGlobal(fn).createArray();
+
+            if (!(_function2Flags & SUPPRESS_ARGUMENTS)) {
+                getArguments(*this, *args, fn, caller);
+            }
+
+            if (_function2Flags & PRELOAD_ARGUMENTS) {
+                // preload 'arguments' into a register.
+                _env.setRegister(current_reg, args);
+                ++current_reg;
+            }
+            else {
+                // Put 'arguments' in a local var.
+                _env.add_local("arguments", args);
+            }
+
+        }
 
         // If super is not suppressed it is either placed in a register
         // or set as a local variable, but not both.
-        if (swfversion > 5 && !(m_function2_flags & SUPPRESS_SUPER)) {
+        if (swfversion > 5 && !(_function2Flags & SUPPRESS_SUPER)) {
             
             // Put 'super' in a register (SWF6+ only).
             // TOCHECK: should we still set it if not available ?
             as_object* super = fn.super ? fn.super :
                 fn.this_ptr ? fn.this_ptr->get_super() : 0;
 
-            if (super && (m_function2_flags & PRELOAD_SUPER)) {
-                               m_env.setRegister(current_reg, super);
+            if (super && (_function2Flags & PRELOAD_SUPER)) {
+                               _env.setRegister(current_reg, super);
                                current_reg++;
                        }
             else if (super) {
-                m_env.add_local("super", super);
+                _env.add_local("super", super);
             }
                }
 
-               if (m_function2_flags & PRELOAD_ROOT) {
+               if (_function2Flags & PRELOAD_ROOT) {
                        // Put '_root' (if any) in a register.
-                       DisplayObject* tgtch = m_env.get_target();
+                       DisplayObject* tgtch = _env.get_target();
                        if (tgtch) {
                                // NOTE: _lockroot will be handled by 
getAsRoot()
                                as_object* r = getObject(tgtch->getAsRoot());
-                               m_env.setRegister(current_reg, r);
+                               _env.setRegister(current_reg, r);
                                ++current_reg;
                        }
                }
 
-               if (m_function2_flags & PRELOAD_PARENT) {
-                       DisplayObject* tgtch = m_env.get_target();
+               if (_function2Flags & PRELOAD_PARENT) {
+                       DisplayObject* tgtch = _env.get_target();
             if (tgtch) {
                 as_object* parent = getObject(tgtch->get_parent());
-                m_env.setRegister(current_reg, parent);
+                _env.setRegister(current_reg, parent);
                 ++current_reg;
             }
                }
 
-               if (m_function2_flags & PRELOAD_GLOBAL) {
+               if (_function2Flags & PRELOAD_GLOBAL) {
                        // Put '_global' in a register.
                        as_object* global = vm.getGlobal();
-                       m_env.setRegister(current_reg, global);
+                       _env.setRegister(current_reg, global);
                        ++current_reg;
                }
 
@@ -273,25 +277,25 @@
                // This must be done after implicit ones,
                // as the explicit override the implicits:
         // see swfdec/definefunction2-override
-               for (size_t i = 0, n = m_args.size(); i < n; ++i) {
+               for (size_t i = 0, n = _args.size(); i < n; ++i) {
             // not a register, declare as local
-                       if (!m_args[i].m_register) {
+                       if (!_args[i].reg) {
                                if (i < fn.nargs) {
                                        // Conventional arg passing: create a 
local var.
-                                       m_env.add_local(m_args[i].m_name, 
fn.arg(i));
+                                       _env.add_local(_args[i].name, 
fn.arg(i));
                                }
                                else {
                                        // Still declare named arguments, even 
if
                                        // they are not passed from caller
                                        // See bug #22203
-                                       m_env.declare_local(m_args[i].m_name);
+                                       _env.declare_local(_args[i].name);
                                }
                        }
                        else {
                                if (i < fn.nargs) {
                                        // Pass argument into a register.
-                                       const int reg = m_args[i].m_register;
-                                       m_env.setRegister(reg, fn.arg(i));
+                                       const int reg = _args[i].reg;
+                                       _env.setRegister(reg, fn.arg(i));
                                }
                 // If no argument was passed, no need to setup a register
                 // I guess.
@@ -299,42 +303,28 @@
                }
        }
 
-       as_value result;
-
        // Execute the actions.
        // Do this in a try block to proper drop the pushed call frame 
        // in case of problems (most interesting action limits)
        try 
        {
-               ActionExec exec(*this, m_env, &result, fn.this_ptr);
+        as_value result;
+               ActionExec exec(*this, _env, &result, fn.this_ptr);
                exec();
+        return result;
        }
        catch (ActionLimitException& ale) // expected and sane 
        {
-               //log_debug("ActionLimitException got from swf_function 
execution: %s", ale.what());
-               throw;
-       }
-       catch (std::exception& ex) // unexpected but we can tell what it is
-       {
-               log_debug("Unexpected exception from swf_function execution: 
%s",
-                ex.what());
-               throw;
-       }
-       catch (...) // unexpected, unknown, but why not cleaning up...
-       {
-               log_debug("Unknown exception got from swf_function execution");
-               throw;
-       }
-
-        return result;
+               throw;
+       }
 }
 
 void
 swf_function::set_length(int len)
 {
        assert(len >= 0);
-       assert(m_start_pc+len <= m_action_buffer.size());
-       m_length = len;
+       assert(_startPC+len <= m_action_buffer.size());
+       _length = len;
 }
 
 #ifdef GNASH_USE_GC
@@ -348,7 +338,7 @@
                (*i)->setReachable();
        }
 
-       m_env.markReachableResources();
+       _env.markReachableResources();
 
        // Invoke parent class marker
        markAsObjectReachable(); 
@@ -357,21 +347,18 @@
 
 namespace {
 
-as_object* 
-getArguments(swf_function& callee, const fn_call& fn,
+as_object*
+getArguments(swf_function& callee, as_object& args, const fn_call& fn,
         as_object* caller)
 { 
 
-       as_object* arguments = getGlobal(fn).createArray();
        for (size_t i = 0; i < fn.nargs; ++i) {
-               callMethod(arguments, NSV::PROP_PUSH, fn.arg(i));
+               callMethod(&args, NSV::PROP_PUSH, fn.arg(i));
        }
 
-       arguments->init_member(NSV::PROP_CALLEE, &callee);
-
-       arguments->init_member(NSV::PROP_CALLER, caller);
-
-       return arguments;
+       args.init_member(NSV::PROP_CALLEE, &callee);
+       args.init_member(NSV::PROP_CALLER, caller);
+    return &args;
 
 }
 

=== modified file 'libcore/swf_function.h'
--- a/libcore/swf_function.h    2009-11-29 09:27:07 +0000
+++ b/libcore/swf_function.h    2009-11-30 09:19:50 +0000
@@ -76,7 +76,7 @@
                //
                /// TODO: check this.
         /// See:
-        /// 
http://sswf.sourceforge.net/SWFalexref.html#action_declare_function2
+        /// http://www.m2osw.com/swf_alexref.html#action_declare_function2
                ///       Looks like flags would look swapped
                PRELOAD_GLOBAL = 256 // 0x100
 
@@ -103,37 +103,35 @@
 
        size_t getStartPC() const
        {
-               return m_start_pc;
+               return _startPC;
        }
 
        size_t getLength() const
        {
-               return m_length;
+               return _length;
        }
 
        bool isFunction2() const
        {
-               return m_is_function2;
+               return _isFunction2;
        }
 
-       void set_is_function2() { m_is_function2 = true; }
+       void set_is_function2() { _isFunction2 = true; }
 
        void set_local_register_count(boost::uint8_t ct) {
-        assert(m_is_function2);
-        m_local_register_count = ct;
+        assert(_isFunction2);
+        _registerCount = ct;
     }
 
        void set_function2_flags(boost::uint16_t flags) {
-        assert(m_is_function2);
-        m_function2_flags = flags;
+        assert(_isFunction2);
+        _function2Flags = flags;
     }
 
        void add_arg(int arg_register, const char* name)
        {
-               assert(arg_register == 0 || m_is_function2 == true);
-               m_args.resize(m_args.size() + 1);
-               m_args.back().m_register = arg_register;
-               m_args.back().m_name = PROPNAME(name);
+               assert(arg_register == 0 || _isFunction2 == true);
+        _args.push_back(Argument(arg_register, name));
        }
 
        void set_length(int len);
@@ -156,7 +154,7 @@
        const action_buffer& m_action_buffer;
 
        /// @@ might need some kind of ref count here, but beware cycles
-       as_environment& m_env;
+       as_environment& _env;
 
        /// Scope stack on function definition.
        ScopeStack _scopeStack;
@@ -164,28 +162,31 @@
        /// \brief
        /// Offset within the action_buffer where
        /// start of the function is found.
-       size_t  m_start_pc;
+       size_t  _startPC;
 
        /// Length of the function within the action_buffer
        //
        /// This is currently expressed in bytes as the
-       /// action_buffer is just a blog of memory corresponding
+       /// action_buffer is just a blocḱ of memory corresponding
        /// to a DoAction block
-       size_t m_length;
+       size_t _length;
 
-       struct arg_spec
+       struct Argument
        {
-               int m_register;
-               std::string m_name;
+        Argument(int r, const std::string& n) : reg(r), name(n) {}
+               int reg;
+               std::string name;
        };
-       std::vector<arg_spec>   m_args;
-       bool m_is_function2;
-       boost::uint8_t m_local_register_count;
+
+       std::vector<Argument> _args;
+       bool _isFunction2;
+       boost::uint8_t _registerCount;
 
        /// used by function2 to control implicit arg register assignments
        // 
-       /// See 
http://sswf.sourceforge.net/SWFalexref.html#action_declare_function2
-       boost::uint16_t m_function2_flags;
+       /// See
+    /// http://sswf.sourceforge.net/SWFalexref.html#action_declare_function2
+       boost::uint16_t _function2Flags;
 
 };
 

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-11-29 09:07:59 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-11-30 15:59:02 +0000
@@ -518,14 +518,17 @@
     assert(thread.atActionTag(SWF::ACTION_GOTOFRAME));
 #endif
 
-    size_t frame = code.read_int16(thread.getCurrentPC()+3);
+    size_t frame = code.read_int16(thread.getCurrentPC() + 3);
 
     DisplayObject* tgtch = env.get_target();
     MovieClip* tgt = tgtch ? tgtch->to_movie() : 0;
 
     // frame number within this tag is hard-coded and 0-based
-    if ( tgt ) tgt->goto_frame(frame);
-    else log_debug(_("ActionGotoFrame: as_environment target is null or not a 
sprite"));
+    if (tgt) tgt->goto_frame(frame);
+    else {
+        log_debug(_("ActionGotoFrame: as_environment target is null "
+                "or not a sprite"));
+    }
 }
 
 void
@@ -1982,14 +1985,14 @@
             {
                 unsigned int reg = code[3 + i];
                 ++i;
-               as_value v;
-               if ( ! env.getRegister(reg, v) )
-               {
-                        IF_VERBOSE_MALFORMED_SWF(
-                        log_swferror(_("Invalid register %d in ActionPush"), 
reg);
-                        );
-               }
-               env.push(v);
+                as_value v;
+                if (!env.getRegister(reg, v)) {
+                    IF_VERBOSE_MALFORMED_SWF(
+                        log_swferror(_("Invalid register %d in ActionPush"),
+                            reg);
+                    );
+                }
+                env.push(v);
                 break;
             }
 
@@ -3684,36 +3687,44 @@
 
     const action_buffer& code = thread.code;
 
-    unsigned int reg = code[thread.getCurrentPC() + 3];
+    const size_t reg = code[thread.getCurrentPC() + 3];
 
     // Save top of stack in specified register.
-    int ret = env.setRegister(reg, env.top(0));
-    if ( ! ret )
-    {
-        IF_VERBOSE_MALFORMED_SWF(
-        log_swferror(_("Invalid register %d in ActionSetRegister"), reg);
-        );
-    }
-    else if ( ret == 1 )
-    {
-        IF_VERBOSE_ACTION (
-        log_action(_("-------------- global register[%d] = '%s'"),
-            reg, env.top(0));
-        );
-    }
-    else
-    {
-        IF_VERBOSE_ACTION (
-        log_action(_("-------------- local register[%d] = '%s'"),
-            reg, env.top(0));
-        );
+    const int ret = env.setRegister(reg, env.top(0));
+
+    switch (ret) {
+        default:
+        case 0:
+        {
+            IF_VERBOSE_MALFORMED_SWF(
+                log_swferror(_("Invalid register %d in ActionSetRegister"),
+                    reg);
+            );
+            break;
+        }
+        case 1:
+        {
+            IF_VERBOSE_ACTION (
+                log_action(_("-------------- global register[%d] = '%s'"),
+                    reg, env.top(0));
+            );
+            break;
+        }
+        case 2:
+        {
+            IF_VERBOSE_ACTION (
+                log_action(_("-------------- local register[%d] = '%s'"),
+                    reg, env.top(0));
+            );
+            break;
+        }
     }
 }
 
 const char*
 SWFHandlers::action_name(ActionType x) const
 {
-    if ( static_cast<size_t>(x) > get_handlers().size() )
+    if (static_cast<size_t>(x) > get_handlers().size())
     {
         log_error(_("at SWFHandlers::action_name(%d) call time, "
                     "_handlers size is %d"),
@@ -3757,7 +3768,7 @@
     for (size_t i = 0; i < nargs; ++i) {
         args += env.pop();
     } 
-    return ctor_as_func->constructInstance(env, args);
+    return constructInstance(*ctor_as_func, env, args);
 }
 
 // Common code for GetUrl and GetUrl2. See:

=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2009-11-13 08:18:42 +0000
+++ b/libcore/vm/ActionExec.cpp 2009-11-30 15:59:02 +0000
@@ -41,7 +41,7 @@
 
 #ifndef DEBUG_STACK
 
-// temporarly disabled as will produce lots of output with -v
+// temporarily disabled as will produce lots of output with -v
 // we'd need another switch maybe, as -va does also produce
 // too much information for my tastes. I really want just
 // to see how stack changes while executing actions...
@@ -52,7 +52,7 @@
 # define STACK_DUMP_LIMIT 32
 
 // Define to get debugging messages for try / catch
-//#define GNASH_DEBUG_TRY 1
+#define GNASH_DEBUG_TRY 1
 
 #endif
 
@@ -64,11 +64,11 @@
 static Debugger& debugger = Debugger::getDefaultInstance();
 #endif
 
-ActionExec::ActionExec(const swf_function& func, as_environment& newEnv, 
as_value* nRetVal, as_object* this_ptr)
+ActionExec::ActionExec(const swf_function& func, as_environment& newEnv,
+        as_value* nRetVal, as_object* this_ptr)
     :
     _withStack(),
     _scopeStack(func.getScopeStack()),
-    // See comment in header
     _withStackLimit(7),
     _func(&func),
     _this_ptr(this_ptr),
@@ -81,7 +81,7 @@
     _abortOnUnload(false),
     pc(func.getStartPC()),
     next_pc(pc),
-    stop_pc(pc+func.getLength()),
+    stop_pc(pc + func.getLength()),
     code(func.getActionBuffer()),
     env(newEnv),
     retval(nRetVal)
@@ -105,25 +105,23 @@
     //              set local var: i=[number:0]
     //              push 'i' getvariable
     //              get var: i=[undefined] 
-    // 
-    if ( code.getDefinitionVersion() > 5 )
-    //if ( env.get_version() > 5 )
-    {
-        // We assume that the swf_function () operator already initialized its 
environment
-        // so that it's activation object is now in the top element of the 
CallFrame stack
-        //
+    if (code.getDefinitionVersion() > 5) {
+        // We assume that the swf_function () operator already initialized
+        // its environment so that its activation object is now in the
+        // top element of the CallFrame stack
         CallFrame& topFrame = newEnv.topCallFrame();
-        assert(topFrame.func == &func);
-        _scopeStack.push_back(topFrame.locals);
+        assert(&topFrame.function() == &func);
+        _scopeStack.push_back(&topFrame.locals());
     }
 }
 
-ActionExec::ActionExec(const action_buffer& abuf, as_environment& newEnv, bool 
abortOnUnloaded)
+ActionExec::ActionExec(const action_buffer& abuf, as_environment& newEnv,
+        bool abortOnUnloaded)
     :
     _withStack(),
     _scopeStack(), // TODO: initialize the scope stack somehow
     _withStackLimit(7),
-    _func(NULL),
+    _func(0),
     _initialStackSize(0),
     _initialCallStackDepth(0),
     _originalTarget(0),
@@ -138,25 +136,24 @@
     env(newEnv),
     retval(0)
 {
-    //GNASH_REPORT_FUNCTION;
-
     /// See comment in header
     // TODO: stack limit dependent on function version or VM version ?
-    if ( env.get_version() > 5 ) {
+    if (env.get_version() > 5) {
         _withStackLimit = 15;
     }
 }
 
 void
-ActionExec::operator() ()
+ActionExec::operator()()
 {
     VM& vm = getVM(env);
 
     // Do not execute if scripts are disabled
-    if ( vm.getRoot().scriptsDisabled() ) return;
+    if (vm.getRoot().scriptsDisabled()) return;
 
     _origExecSWFVersion = vm.getSWFVersion();
-    int codeVersion = code.getDefinitionVersion();
+
+    const int codeVersion = code.getDefinitionVersion();
     vm.setSWFVersion(codeVersion);
 
     static const SWF::SWFHandlers& ash = SWF::SWFHandlers::instance();
@@ -184,8 +181,6 @@
     // TODO: specify in the .gnashrc !!
     static const size_t maxBranchCount = 65536; // what's enough ?
 
-    //WallClockTimer timer;
-
     // stop_pc: set to the code boundary at which we should check
     // for exceptions. If there is no exception in a TryBlock, it
     // is set to the end of that block; all the code (including catch
@@ -200,18 +195,19 @@
 
     size_t branchCount = 0;
     try {
-        while (1) // We might not stop at stop_pc, if we are trying.
-        {
-            if (pc >= stop_pc)
-            {
+        log_debug("Try list size: %s", _tryList.size());
+
+        // We might not stop at stop_pc, if we are trying.
+        while (1) {
+
+            if (pc >= stop_pc) {
                 // No try blocks
                 if (_tryList.empty()) {
                 
                     // Check for any uncaught exceptions.
-                    if (env.stack_size() && env.top(0).is_exception())
-                    {
+                    if (env.stack_size() && env.top(0).is_exception()) {
                         log_debug ("Exception on stack, no handlers left.");
-                        // Stop execution (for how long?) if an exception
+                        // Stop execution if an exception
                         // is still on the stack and there is nothing
                         // left to catch it.
                         throw ActionScriptException();
@@ -222,7 +218,7 @@
                 // If we are in a try block, check to see if we have thrown.
                 TryBlock& t = _tryList.back();
                 
-                if (! processExceptions(t)) break;
+                if (!processExceptions(t)) break;
 
                 continue;
             }
@@ -248,28 +244,26 @@
 
             // Set default next_pc offset, control flow action handlers
             // will be able to reset it.
-            if ((action_id & 0x80) == 0)
-            {
+            if ((action_id & 0x80) == 0) {
                 // action with no extra data
                 next_pc = pc+1;
             }
-            else
-            {
+            else {
                 // action with extra data
-                boost::uint16_t length = boost::uint16_t(code.read_int16(pc + 
1));
+                // Note this converts from int to uint!
+                boost::uint16_t length(code.read_int16(pc + 1));
+
                 next_pc = pc + length + 3;
-                if ( next_pc > stop_pc )
-                {
+                if (next_pc > stop_pc) {
                     IF_VERBOSE_MALFORMED_SWF(
                     log_swferror(_("Length %u (%d) of action tag"
                                    " id %u at pc %d"
                                    " overflows actions buffer size %d"),
-                      length, static_cast<int>(length),
-                      static_cast<unsigned>(action_id), pc,
-                      stop_pc);
+                          length, static_cast<int>(length),
+                          static_cast<unsigned>(action_id), pc,
+                          stop_pc);
                     );
                     
-                    //throw ActionException(ss.str());
                     // no way to recover from this actually...
                     // Give this action handler a chance anyway.
                     // Maybe it will be able to do something about
@@ -279,30 +273,28 @@
             }
 
             // Do we still need this ?
-            if ( action_id == SWF::ACTION_END )
-            {
+            if (action_id == SWF::ACTION_END) {
                 break;
             }
 
             ash.execute(static_cast<SWF::ActionType>(action_id), *this);
 
-#if 1 // See bugs: #20974, #21069, #20996.
-
-#if 0
-            // curveball.swf and feed.swf break with this
-            DisplayObject* guardedChar = env.get_original_target(); // watch 
out : _originalTarget is not necessarely the same
-#else
-            // curveball.swf and feed.swf suggest that it is the *current* 
target,
-            // not the *original* one that matters.
+            // Code round here has to do with bugs: #20974, #21069, #20996,
+            // but since there is so much disabled code it's not clear exactly
+            // what part.
+            
+            // curveball.swf and feed.swf suggest that it is the
+            // *current* target, not the *original* one that matters.
             DisplayObject* guardedChar = env.get_target();
-#endif
 
-            if ( _abortOnUnload && guardedChar && guardedChar->unloaded() )
-            // action_execution_order_test8.c shows that the opcode guard is 
not SWF version based (TODO: automate it!)
-            {
+            if (_abortOnUnload && guardedChar && guardedChar->unloaded()) {
+                // action_execution_order_test8.c shows that the opcode
+                // guard is not SWF version based (TODO: automate it!)
                 std::stringstream ss;
                 ss << "Target of action_buffer (" << guardedChar->getTarget() 
-                    << " of type " << typeName(*guardedChar) << ") unloaded by 
execution of opcode: " << std::endl;
+                    << " of type " << typeName(*guardedChar) << ") unloaded "
+                    "by execution of opcode: " << std::endl;
+
                 dumpActions(pc, next_pc, ss);
                 ss << "Discarding " << stop_pc-next_pc
                     << " bytes of remaining opcodes: " << std::endl;
@@ -310,7 +302,6 @@
                 log_debug("%s", ss.str());
                 break;
             }
-#endif
 
 
 #ifdef USE_DEBUGGER
@@ -324,7 +315,8 @@
         
 #if DEBUG_STACK
             IF_VERBOSE_ACTION (
-                log_action(_("After execution: PC %d, next PC %d, stack 
follows"), pc, next_pc);
+                log_action(_("After execution: PC %d, next PC %d, "
+                        "stack follows"), pc, next_pc);
                 std::stringstream ss;
                 env.dump_stack(ss, STACK_DUMP_LIMIT);
                 env.dump_global_registers(ss);
@@ -339,51 +331,33 @@
 
             // Check for script limits hit. 
             // See: http://www.gnashdev.org/wiki/index.php/ScriptLimits
-            // 
-#if 0
-            // TODO: only check on branch-back ? (would be less aggressive..)
-            // WARNING: if the movie is stopped, the wall clock continues to 
run !
-            if ( timeLimit && timer.elapsed() > timeLimit )
-            {
-                throw ActionLimitException("Script exceeded time limit");
-            }
-#else
-            if ( pc <= oldPc )
-            {
-                if ( ++branchCount > maxBranchCount )
-                {
+            if (pc <= oldPc) {
+                if (++branchCount > maxBranchCount) {
                     boost::format fmt(_("Loop iterations count exceeded "
                                 "limit of %d. Last branch was from pc %d "
                                 "to %d"));
                     fmt % maxBranchCount % oldPc % pc;
                     throw ActionLimitException(fmt.str());
                 }
-                //log_debug("Branch count: %u", branchCount);
             }
-#endif
-
         }
-
     }
-    catch (ActionLimitException& ex)
-    {
+    catch (ActionLimitException& ex) {
         // Script execution should stop (for this frame only?)
         // Here's were we should pop-up a window to prompt user about
         // what to do next (abort or not ?)
-        //log_error("Script aborted due to exceeded limit: %s - cleaning up 
after run", ex.what());
         cleanupAfterRun(true); // we expect inconsistencies here
         throw;
     }
-    catch (ActionScriptException& ex)
-    {
+    catch (ActionScriptException& ex) {
         // An unhandled ActionScript exception was thrown.
         cleanupAfterRun(true);
 
-       // Forceably clear the stack.
-       // - Fixes misc-mtasc.all/exception.swf
-       // By commenting the line above, we get an XPASS in
-       // - swfdec/catch-in-caller.swf
-       env.drop(env.stack_size());
+        // Forceably clear the stack.
+        // - Fixes misc-mtasc.all/exception.swf
+        // By commenting the line above, we get an XPASS in
+        // - swfdec/catch-in-caller.swf
+        env.drop(env.stack_size());
 
         return;
     }

=== modified file 'libcore/vm/CallStack.cpp'
--- a/libcore/vm/CallStack.cpp  2009-08-27 06:21:01 +0000
+++ b/libcore/vm/CallStack.cpp  2009-11-30 15:59:02 +0000
@@ -14,19 +14,22 @@
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
+
 #include "CallStack.h"
 #include "as_object.h"
 #include "as_function.h" 
 #include "Global_as.h" 
 
+#include <ostream>
+
 namespace gnash {
 
-CallFrame::CallFrame(as_function* funcPtr)
-       :
-       locals(new as_object),
-       func(funcPtr)
+CallFrame::CallFrame(as_function* f)
+    :
+    _locals(new as_object(getGlobal(*f))),
+    _func(f)
 {
+    assert(_func);
 }
 
 /// Mark all reachable resources
@@ -36,13 +39,26 @@
 void
 CallFrame::markReachableResources() const
 {
-       if ( func ) func->setReachable();
-       for (Registers::const_iterator i=registers.begin(), e=registers.end(); 
i!=e; ++i)
-       {
-               i->setReachable();
-       }
-       if (locals)
-               locals->setReachable();
-}
-
+    // Func is always valid.
+    assert(_func);
+    _func->setReachable();
+
+    std::for_each(_registers.begin(), _registers.end(),
+            std::mem_fun_ref(&as_value::setReachable));
+
+    if (_locals) _locals->setReachable();
+}
+
+std::ostream&
+operator<<(std::ostream& o, const CallFrame& fr)
+{
+    CallFrame::Registers r = fr._registers;
+
+    for (size_t i = 0; i < r.size(); ++i) {
+        if (i) o << ", ";
+        o << i << ':' << '"' << r[i] << '"';
+    }
+    return o;
+    
+}
 } // namespace gnash

=== modified file 'libcore/vm/CallStack.h'
--- a/libcore/vm/CallStack.h    2009-02-25 22:33:03 +0000
+++ b/libcore/vm/CallStack.h    2009-11-30 15:59:02 +0000
@@ -19,6 +19,7 @@
 #define GNASH_VM_CALL_STACK_H
 
 #include <vector>
+
 #include "as_value.h"
 
 // Forward declarations
@@ -30,27 +31,61 @@
 namespace gnash {
 
 /// An element of a CallStack
-struct CallFrame
+class CallFrame 
 {
+public:
+
     typedef std::vector<as_value> Registers;
 
-
-    CallFrame(as_function* funcPtr);
+    CallFrame(as_function* func);
 
     CallFrame(const CallFrame& other)
         :
-        locals(other.locals),
-        registers(other.registers),
-        func(other.func)
-    {/**/}
+        _locals(other._locals),
+        _registers(other._registers),
+        _func(other._func)
+    {}
+
+    as_object& locals() {
+        return *_locals;
+    }
+
+    as_function& function() {
+        return *_func;
+    }
+
+    bool getRegister(size_t i, as_value& val) const {
+        if (i >= _registers.size()) return false;
+        val = _registers[i];
+        return true;
+    }
+
+    bool setRegister(size_t i, const as_value& val) {
+        if (i >= _registers.size()) return false;
+        _registers[i] = val;
+        return true;
+    }
+
+    void resizeRegisters(size_t i) {
+        _registers.resize(i);
+    }
+
+    bool hasRegisters() const {
+        return !_registers.empty();
+    }
+
+
+private:
+
+    friend std::ostream& operator<<(std::ostream&, const CallFrame&);
 
     /// function use this 
-    as_object* locals;
+    as_object* _locals;
 
     /// function2 also use this
-    Registers registers;
+    Registers _registers;
 
-    as_function* func;
+    as_function* _func;
 
     /// Mark all reachable resources
     //
@@ -61,6 +96,7 @@
 
 typedef std::vector<CallFrame> CallStack;
 
+std::ostream& operator<<(std::ostream& o, const CallFrame& fr);
 
 } // namespace gnash
 

=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp    2009-11-20 08:00:47 +0000
+++ b/libcore/vm/Machine.cpp    2009-11-30 11:12:37 +0000
@@ -1587,7 +1587,7 @@
                     
                     if (ctor) {
                         boost::intrusive_ptr<as_object> newobj =
-                            ctor->constructInstance(env, args);
+                            constructInstance(*ctor, env, args);
                         push_stack(as_value(newobj));
                     }
 

=== modified file 'testsuite/misc-swfmill.all/trace-as2/Makefile.am'
--- a/testsuite/misc-swfmill.all/trace-as2/Makefile.am  2009-11-25 15:11:59 
+0000
+++ b/testsuite/misc-swfmill.all/trace-as2/Makefile.am  2009-11-30 07:53:30 
+0000
@@ -25,10 +25,14 @@
 
 TRACE_TESTS = \
        super.xml \
+       this.xml \
+       arguments.xml \
        $(NULL) 
 
 TRACE_TRACES = \
        super.trace \
+       this.trace \
+       arguments.trace \
        $(NULL) 
 
 EXTRA_DIST = \

=== modified file 'testsuite/misc-swfmill.all/trace-as2/PASSING'
--- a/testsuite/misc-swfmill.all/trace-as2/PASSING      2009-11-25 11:19:40 
+0000
+++ b/testsuite/misc-swfmill.all/trace-as2/PASSING      2009-11-30 09:00:24 
+0000
@@ -1,1 +1,3 @@
+arguments
 super
+this

=== added file 'testsuite/misc-swfmill.all/trace-as2/arguments.trace'
--- a/testsuite/misc-swfmill.all/trace-as2/arguments.trace      1970-01-01 
00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/trace-as2/arguments.trace      2009-11-30 
08:01:47 +0000
@@ -0,0 +1,8 @@
+6.5
+undefined
+undefined
+undefined
+6.5
+undefined
+
+6.5

=== added file 'testsuite/misc-swfmill.all/trace-as2/arguments.xml'
--- a/testsuite/misc-swfmill.all/trace-as2/arguments.xml        1970-01-01 
00:00:00 +0000
+++ b/testsuite/misc-swfmill.all/trace-as2/arguments.xml        2009-11-30 
08:01:47 +0000
@@ -0,0 +1,372 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+
+<!-- Tests when and where super is preloaded -->
+<!-- The answer is:
+       If it's suppressed, it's not available at all.
+       If it's preloaded, it is only available in a register, not as
+       a local variable.
+-->
+
+  <Header framerate="12" frames="1">
+    <size>
+      <Rectangle left="0" right="12800" top="0" bottom="9600"/>
+    </size>
+    <tags>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="o"/>
+              <String value="ns"/>
+              <String value="arguments"/>
+              <String value="nr"/>
+              <String value="sss"/>
+              <String value="pss"/>
+              <String value="psr"/>
+              <String value="psss"/>
+              <String value="pssr"/>
+              <String value="__proto__"/>
+              <String value="oo"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+              <StackInteger value="0"/>
+            </items>
+          </PushData>
+          <DeclareObject/>
+          <SetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+
+         <!-- Check arguments for a normal function -->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="3"/>
+            </items>
+          </PushData>
+
+          <!-- Check what's in register 1 for a normal function (nothing)-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="4"/>
+            </items>
+          </PushData>
+
+          <!-- Check what arguments is when it's suppressed-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="1" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="5"/>
+            </items>
+          </PushData>
+
+          <!-- Check what arguments is when it's preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="1" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="6"/>
+            </items>
+          </PushData>
+
+          <!-- Check what register 1 is when arguments is preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="1" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="7"/>
+            </items>
+          </PushData>
+
+          <!-- Check what arguments is when it's suppressed and preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="1" 
preloadArguments="1" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="8"/>
+            </items>
+          </PushData>
+
+          <!-- Check what register 1 is when arguments suppressed and 
preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="1" 
preloadArguments="1" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="9"/>
+              <StackInteger value="0"/>
+            </items>
+          </PushData>
+          <DeclareObject/>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="10"/>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <New/>
+         <SetLocalVariable/>
+
+         <!-- Start function calls -->
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="3"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="4"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="5"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="6"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="7"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="8"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackDouble value="6.5"/>
+              <StackInteger value="1"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>

=== modified file 'testsuite/misc-swfmill.all/trace-as2/super.xml'
--- a/testsuite/misc-swfmill.all/trace-as2/super.xml    2009-11-25 11:19:40 
+0000
+++ b/testsuite/misc-swfmill.all/trace-as2/super.xml    2009-11-30 07:37:35 
+0000
@@ -27,7 +27,6 @@
               <String value="psss"/>
               <String value="pssr"/>
               <String value="__proto__"/>
-              <String value="oo"/>
             </strings>
           </Dictionary>
           <PushData>
@@ -49,6 +48,8 @@
               <StackDictionaryLookup index="1"/>
             </items>
           </PushData>
+
+          <!-- ns(): Check super for a normal function (nothing)-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -74,7 +75,8 @@
             </items>
           </PushData>
 
-          <!-- Check what's in register 0 for a normal function (nothing)-->
+          <!-- nr(): Check what's in register 1 for a normal function
+          (nothing)-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -99,7 +101,7 @@
             </items>
           </PushData>
 
-          <!-- Check what super is when it's suppressed-->
+          <!-- sss(): Check what super is when it's suppressed-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="1" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -125,7 +127,7 @@
             </items>
           </PushData>
 
-          <!-- Check what super is when it's preloaded-->
+          <!-- pss(): Check what super is when it's preloaded-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="1" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -151,7 +153,7 @@
             </items>
           </PushData>
 
-          <!-- Check what register 0 is when super is preloaded-->
+          <!-- psr(): Check what register 1 is when super is preloaded-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="1" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -176,7 +178,7 @@
             </items>
           </PushData>
 
-          <!-- Check what super is when it's suppressed and preloaded-->
+          <!-- psss(): Check what super is when it's suppressed and 
preloaded-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="1" preloadSuper="1" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -202,7 +204,8 @@
             </items>
           </PushData>
 
-          <!-- Check what super is when it's suppressed and preloaded-->
+          <!-- pssr(): Check what register 1 is when it's suppressed and
+          preloaded-->
           <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="1" preloadSuper="1" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
             <args/>
             <actions>
@@ -229,15 +232,6 @@
           </PushData>
           <DeclareObject/>
           <SetMember/>
-          <PushData>
-            <items>
-              <StackDictionaryLookup index="10"/>
-              <StackInteger value="0"/>
-              <StackDictionaryLookup index="0"/>
-            </items>
-          </PushData>
-          <New/>
-         <SetLocalVariable/>
 
          <!-- Start function calls -->
           <PushData>

=== added file 'testsuite/misc-swfmill.all/trace-as2/this.trace'
--- a/testsuite/misc-swfmill.all/trace-as2/this.trace   1970-01-01 00:00:00 
+0000
+++ b/testsuite/misc-swfmill.all/trace-as2/this.trace   2009-11-29 21:29:59 
+0000
@@ -0,0 +1,8 @@
+[object Object]
+undefined
+_level0
+_level0
+[object Object]
+_level0
+undefined
+[object Object]

=== added file 'testsuite/misc-swfmill.all/trace-as2/this.xml'
--- a/testsuite/misc-swfmill.all/trace-as2/this.xml     1970-01-01 00:00:00 
+0000
+++ b/testsuite/misc-swfmill.all/trace-as2/this.xml     2009-11-30 07:48:37 
+0000
@@ -0,0 +1,355 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+
+<!-- Tests when and where super is preloaded -->
+<!-- The answer is:
+       If it's suppressed, it's not available at all.
+       If it's preloaded, it is only available in a register, not as
+       a local variable.
+-->
+
+  <Header framerate="12" frames="1">
+    <size>
+      <Rectangle left="0" right="12800" top="0" bottom="9600"/>
+    </size>
+    <tags>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="o"/>
+              <String value="ns"/>
+              <String value="this"/>
+              <String value="nr"/>
+              <String value="sss"/>
+              <String value="pss"/>
+              <String value="psr"/>
+              <String value="psss"/>
+              <String value="pssr"/>
+              <String value="__proto__"/>
+              <String value="oo"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+              <StackInteger value="0"/>
+            </items>
+          </PushData>
+          <DeclareObject/>
+          <SetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+
+         <!-- ns(): Check this for a normal function -->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="3"/>
+            </items>
+          </PushData>
+
+          <!-- nr(): Check what's in register 1 for a normal function 
(nothing)-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="4"/>
+            </items>
+          </PushData>
+
+          <!-- sss(): Check what this is when it's suppressed-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="1" preloadThis="0" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="5"/>
+            </items>
+          </PushData>
+
+          <!-- pss(): Check what this is when it's preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="1" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="6"/>
+            </items>
+          </PushData>
+
+          <!-- psr(): Check what register 1 is when this is preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="0" preloadThis="1" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="7"/>
+            </items>
+          </PushData>
+
+          <!-- psss(): Check what this is when it's suppressed and preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="1" preloadThis="1" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="2"/>
+                </items>
+              </PushData>
+              <GetVariable/>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="8"/>
+            </items>
+          </PushData>
+
+          <!-- pssr(): Check what register 1 is when this suppressed and 
preloaded-->
+          <DeclareFunction2 name="" argc="0" regc="2" preloadParent="0" 
preloadRoot="0" suppressSuper="0" preloadSuper="0" suppressArguments="0" 
preloadArguments="0" suppressThis="1" preloadThis="1" reserved="0" 
preloadGlobal="0">
+            <args/>
+            <actions>
+              <PushData>
+                <items>
+                  <StackRegister reg="1"/>
+                </items>
+              </PushData>
+              <Return/>
+            </actions>
+          </DeclareFunction2>
+          <SetMember/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="9"/>
+              <StackInteger value="0"/>
+            </items>
+          </PushData>
+          <DeclareObject/>
+          <SetMember/>
+
+         <!-- Start function calls -->
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="3"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="4"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="5"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="6"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="7"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="8"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+          <CallMethod/>
+          <Trace/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>


reply via email to

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