gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11677: Tidy up function signatures


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11677: Tidy up function signatures by using ObjectURI.
Date: Fri, 04 Dec 2009 14:03:51 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11677 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2009-12-04 14:03:51 +0100
message:
  Tidy up function signatures by using ObjectURI.
  
  Clean up and restrict some class interfaces.
  
  Implement more of AS3 class objects. Some passing tests (after an additional
  temporary hack for value equality).
modified:
  libbase/extension.cpp
  libbase/sharedlib.h
  libbase/shm.h
  libcore/Button.cpp
  libcore/MovieClip.cpp
  libcore/MovieClip.h
  libcore/ObjectURI.h
  libcore/PropertyList.cpp
  libcore/PropertyList.h
  libcore/TextField.cpp
  libcore/Video.cpp
  libcore/abc/Class.cpp
  libcore/abc/Method.cpp
  libcore/abc/as_class.cpp
  libcore/abc/as_class.h
  libcore/as_environment.cpp
  libcore/as_function.cpp
  libcore/as_object.cpp
  libcore/as_object.h
  libcore/asobj/Array_as.cpp
  libcore/asobj/Array_as.h
  libcore/asobj/Boolean_as.cpp
  libcore/asobj/Date_as.cpp
  libcore/asobj/Global_as.h
  libcore/asobj/LoadVars_as.cpp
  libcore/asobj/MovieClipLoader.cpp
  libcore/asobj/Number_as.cpp
  libcore/asobj/Object.cpp
  libcore/asobj/QName_as.cpp
  libcore/asobj/String_as.cpp
  libcore/asobj/flash/accessibility/Accessibility_as.cpp
  libcore/asobj/flash/display/DisplayObjectContainer_as.cpp
  libcore/asobj/flash/display/DisplayObject_as.cpp
  libcore/asobj/flash/display/Graphics_as.cpp
  libcore/asobj/flash/display/LoaderInfo_as.cpp
  libcore/asobj/flash/display/MovieClip_as.cpp
  libcore/asobj/flash/filters/BitmapFilter_as.cpp
  libcore/asobj/flash/media/Camera_as.cpp
  libcore/asobj/flash/media/Microphone_as.cpp
  libcore/asobj/flash/media/Sound_as.cpp
  libcore/asobj/flash/net/SharedObject_as.cpp
  libcore/asobj/flash/system/Security_as.cpp
  libcore/asobj/flash/text/TextFormat_as.cpp
  libcore/asobj/flash/xml/XMLDocument_as.cpp
  libcore/asobj/flash/xml/XMLNode_as.cpp
  libcore/asobj/flash/xml/XMLNode_as.h
  libcore/asobj/int_as.cpp
  libcore/vm/ASHandlers.cpp
  libcore/vm/Machine.cpp
  libcore/vm/Machine.h
  testsuite/as3compile.all/Object.as
  testsuite/as3compile.all/QName.as
  testsuite/as3compile.all/Sprite.as
  testsuite/as3compile.all/class.as
  testsuite/as3compile.all/function.as
  testsuite/libcore.all/PropertyListTest.cpp
=== modified file 'libbase/extension.cpp'
--- a/libbase/extension.cpp     2009-11-05 09:17:23 +0000
+++ b/libbase/extension.cpp     2009-12-03 11:49:20 +0000
@@ -44,7 +44,10 @@
 #include "ltdl.h"
 #include "sharedlib.h"
 #include "extension.h"
-#include "as_object.h"
+
+namespace gnash {
+    class as_object;
+}
 
 #if defined(WIN32) || defined(_WIN32)
 int        lt_dlsetsearchpath   (const char *search_path);

=== modified file 'libbase/sharedlib.h'
--- a/libbase/sharedlib.h       2009-11-05 09:16:59 +0000
+++ b/libbase/sharedlib.h       2009-12-03 11:49:20 +0000
@@ -25,7 +25,6 @@
 #include <boost/thread/mutex.hpp>
 #include <string>
 #include <map>
-#include "as_object.h"
 #include "dsodefs.h" // DSOEXPORT
 
 #ifdef _WIN32
@@ -40,9 +39,11 @@
 #include <libgen.h>
 #endif
 
-namespace gnash 
-{
+namespace gnash {
+    class as_object;
+}
 
+namespace gnash {
 
 /// TODO: document this class
 class SharedLib

=== modified file 'libbase/shm.h'
--- a/libbase/shm.h     2009-06-15 14:46:41 +0000
+++ b/libbase/shm.h     2009-12-03 11:49:20 +0000
@@ -24,8 +24,6 @@
 
 #include <string>
 
-#include "as_object.h" // for inheritance
-
 #include <sys/types.h>
 #if !defined(HAVE_WINSOCK_H) && !defined(__riscos__) && !defined(__OS2__)
 # include <sys/ipc.h>
@@ -168,17 +166,6 @@
     void destroy(pointer __p)   { __p->~_Tp(); }
 };
 
-class shm_as_object : public as_object
-{
-public:
-    Shm obj;
-};
-
-as_value shm_getname(const fn_call& fn);
-as_value shm_getsize(const fn_call& fn);
-as_value shm_getallocated(const fn_call& fn);
-as_value shm_exists(const fn_call& fn);
-
 } // end of gnash namespace
 
 // end of __SHM_H__

=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp        2009-11-18 11:51:35 +0000
+++ b/libcore/Button.cpp        2009-12-04 09:20:14 +0000
@@ -925,8 +925,7 @@
     attachButtonInterface(*proto);
 
     // Register _global.MovieClip
-    global.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    global.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 void

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-12-02 14:27:13 +0000
+++ b/libcore/MovieClip.cpp     2009-12-04 09:20:14 +0000
@@ -445,8 +445,9 @@
 /// The TextField variables should probably be handled in a more generic
 /// way.
 bool
-MovieClip::getTextFieldVariables(string_table::key name_key, as_value& val)
+MovieClip::getTextFieldVariables(const ObjectURI& uri, as_value& val)
 {
+    const string_table::key name_key = getName(uri);
 
     const std::string& name = getStringTable(*getObject(this)).value(name_key);
 
@@ -748,10 +749,11 @@
 }
 
 bool
-MovieClip::setTextFieldVariables(string_table::key name, const as_value& val,
-        string_table::key /*nsname*/)
+MovieClip::setTextFieldVariables(const ObjectURI& uri, const as_value& val)
 {
 
+    const string_table::key name = getName(uri);
+
     // Try textfield variables
     //
     // FIXME: Turn textfield variables into Getter/Setters (Properties)

=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h       2009-11-13 12:54:06 +0000
+++ b/libcore/MovieClip.h       2009-12-04 09:20:14 +0000
@@ -490,13 +490,12 @@
     //
     /// TODO: this is unlikely to be the best way of doing it, and it would
     /// simplify things if this function could be dropped.
-    bool getTextFieldVariables(string_table::key name, as_value& val);
+    bool getTextFieldVariables(const ObjectURI& uri, as_value& val);
 
     // Set TextField variables
     //
     /// TODO: this is also unlikely to be the best way to do it.
-    bool setTextFieldVariables(string_table::key name, const as_value& val,
-        string_table::key nsname = 0);
+    bool setTextFieldVariables(const ObjectURI& uri, const as_value& val);;
 
     /// Search for a named object on the DisplayList
     //

=== modified file 'libcore/ObjectURI.h'
--- a/libcore/ObjectURI.h       2009-12-02 14:25:11 +0000
+++ b/libcore/ObjectURI.h       2009-12-04 09:20:14 +0000
@@ -32,6 +32,13 @@
 
 };
 
+/// ObjectURIs are equal if both name and namespace are equal.
+inline bool
+operator==(const ObjectURI& a, const ObjectURI& b)
+{
+    return a.name == b.name && a.ns == b.ns;
+}
+
 /// Comparator for ObjectURI so it can serve as a key in stdlib containers.
 inline bool
 operator<(const ObjectURI& a, const ObjectURI& b)
@@ -69,7 +76,10 @@
                " %3%(%4%)") % _st.value(name) % name % _st.value(ns) % ns;
         return f.str();
 #else
-        return _st.value(getNamespace(uri)) + "." + _st.value(getName(uri));
+        const string_table::key ns = getNamespace(uri);
+        const string_table::key name = getName(uri);
+        if (ns) return _st.value(ns) + "." + _st.value(name);
+        return _st.value(name);
 #endif
 
     }

=== modified file 'libcore/PropertyList.cpp'
--- a/libcore/PropertyList.cpp  2009-12-02 14:52:22 +0000
+++ b/libcore/PropertyList.cpp  2009-12-03 13:36:04 +0000
@@ -41,27 +41,6 @@
 
 namespace gnash {
 
-PropertyList::PropertyList(const PropertyList& pl)
-       :
-       _defaultOrder(pl._defaultOrder),
-    _vm(pl._vm)
-{
-       import(pl);
-}
-
-PropertyList&
-PropertyList::operator=(const PropertyList& pl)
-{
-       if ( this != &pl )
-       {
-               clear();
-               _defaultOrder = pl._defaultOrder;
-               import(pl);
-       }
-       return *this;
-}
-
-
 namespace {
 
 inline
@@ -121,7 +100,7 @@
        _props.insert(a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(_vm.getStringTable());
+    ObjectURI::Logger l(getStringTable(_owner));
        log_debug("Slot for AS property %s inserted with flags %s", l(uri)
             a.getFlags());
 #endif
@@ -131,7 +110,7 @@
 
 bool
 PropertyList::setValue(const ObjectURI& uri, const as_value& val,
-               as_object& this_ptr, const PropFlags& flagsIfMissing)
+        const PropFlags& flagsIfMissing)
 {
        container::iterator found = iterator_find(_props, uri);
        
@@ -143,7 +122,7 @@
                a.setOrder(- ++_defaultOrder - 1);
                _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_debug("Simple AS property %s inserted with flags %s",
                        l(uri), a.getFlags());
 #endif
@@ -153,7 +132,7 @@
        const Property& prop = *found;
        if (prop.isReadOnly() && ! prop.isDestructive())
        {
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_error(_("Property %s is read-only %s, not setting it to 
%s"), 
                        l(uri), prop.getFlags(), val);
                return false;
@@ -162,7 +141,7 @@
        // Property is const because the container uses its members
        // for indexing. We don't use value (only name and namespace)
        // so this const_cast is safe
-       const_cast<Property&>(prop).setValue(this_ptr, val);
+       const_cast<Property&>(prop).setValue(_owner, val);
 
        return true;
 }
@@ -179,7 +158,7 @@
        return f.set_flags(setFlags, clearFlags);
 
 #ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(_vm.getStringTable());
+    ObjectURI::Logger l(getStringTable(_owner));
        log_debug("Flags of property %s changed from %s to  %s",
                l(uri), oldFlags, found->getFlags());
 #endif
@@ -208,25 +187,39 @@
 {
        //GNASH_REPORT_FUNCTION;
        container::iterator found = iterator_find(_props, uri);
-       if (found == _props.end())
-       {
-               return std::make_pair(false,false);
+       if (found == _props.end()) {
+               return std::make_pair(false, false);
        }
 
        // check if member is protected from deletion
-       if (found->getFlags().get_dont_delete())
-       {
-               return std::make_pair(true,false);
+       if (found->getFlags().get_dont_delete()) {
+               return std::make_pair(true, false);
        }
 
        _props.erase(found);
-       return std::make_pair(true,true);
-}
-
-void
-PropertyList::enumerateKeys(as_environment& env, PropTracker& donelist) const
-{
-       string_table& st = getStringTable(env);
+       return std::make_pair(true, true);
+}
+
+
+/// This does not reflect the normal enumeration order. It is sorted
+/// lexicographically by property.
+void
+PropertyList::dump(std::map<std::string, as_value>& to) 
+{
+    ObjectURI::Logger l(getStringTable(_owner));
+
+       for (container::const_iterator i=_props.begin(), ie=_props.end();
+            i != ie; ++i)
+       {
+               to.insert(std::make_pair(l(i->uri()), i->getValue(_owner)));
+       }
+}
+
+void
+PropertyList::enumerateKeys(as_environment& env, PropertyTracker& donelist)
+    const
+{
+       string_table& st = getStringTable(_owner);
 
     // We should enumerate in order of creation, not lexicographically.
     typedef container::nth_index<1>::type ContainerByOrder;
@@ -250,80 +243,12 @@
 }
 
 void
-PropertyList::enumerateKeyValue(const as_object& this_ptr,
-        SortedPropertyList& to) const
-{
-    VM& vm = getVM(this_ptr);
-       string_table& st = vm.getStringTable();
-    typedef container::nth_index<1>::type ContainerByOrder;
-
-       for (ContainerByOrder::const_iterator i=_props.get<1>().begin(),
-            ie=_props.get<1>().end(); i != ie; ++i)
-       {
-               if (i->getFlags().get_dont_enum()) continue;
-
-        // Undefined values should be "undefined" for SWF7 and
-        // empty for SWF6.
-        const int version = vm.getSWFVersion();
-               to.push_back(std::make_pair(st.value(getName(i->uri())),
-                               
i->getValue(this_ptr).to_string_versioned(version)));
-       }
-}
-
-/// This does not reflect the normal enumeration order. It is sorted
-/// lexicographically by property.
-void
-PropertyList::dump(as_object& this_ptr, std::map<std::string, as_value>& to) 
-{
-    ObjectURI::Logger l(_vm.getStringTable());
-
-       for (container::const_iterator i=_props.begin(), ie=_props.end();
-            i != ie; ++i)
-       {
-               to.insert(std::make_pair(l(i->uri()), i->getValue(this_ptr)));
-       }
-}
-
-void
-PropertyList::dump(as_object& this_ptr)
-{
-    ObjectURI::Logger l(_vm.getStringTable());
+PropertyList::dump()
+{
+    ObjectURI::Logger l(getStringTable(_owner));
        for (container::const_iterator it=_props.begin(), itEnd=_props.end();
             it != itEnd; ++it) {
-               log_debug("  %s: %s", l(it->uri()), it->getValue(this_ptr));
-       }
-}
-
-void
-PropertyList::import(const PropertyList& o) 
-{
-       for (container::const_iterator it = o._props.begin(),
-               itEnd = o._props.end(); it != itEnd; ++it)
-       {
-               // overwrite any previous property with this name
-               container::iterator found = iterator_find(_props, it->uri());
-               if (found != _props.end())
-               {
-                       Property a = *it;
-                       a.setOrder(found->getOrder());
-                       _props.replace(found, a);
-#ifdef GNASH_DEBUG_PROPERTY
-            ObjectURI::Logger l(_vm.getStringTable());
-                       log_debug("Property %s replaced on import: new flags 
%s",
-                               l(a.uri()), a.getFlags());
-#endif
-               }
-               else
-               {
-                       Property a = *it;
-                       a.setOrder(- ++_defaultOrder - 1);
-                       _props.insert(a);
-#ifdef GNASH_DEBUG_PROPERTY
-            ObjectURI::Logger l(_vm.getStringTable());
-                       log_debug("Property %s imported with flags %s",
-                               l(a.uri()), a.getFlags());
-#endif
-               }
+               log_debug("  %s: %s", l(it->uri()), it->getValue(_owner));
        }
 }
 
@@ -345,7 +270,7 @@
                _props.replace(found, a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_debug("AS GetterSetter %s replaced copying flags %s", 
l(uri),
                 a.getFlags());
 #endif
@@ -356,7 +281,7 @@
                a.setCache(cacheVal);
                _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_debug("AS GetterSetter %s inserted with flags %s", l(uri),
                 a.getFlags());
 #endif
@@ -381,7 +306,7 @@
                _props.replace(found, a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_debug("Native GetterSetter %s replaced copying flags %s", 
l(uri),
                 a.getFlags());
 #endif
@@ -391,7 +316,7 @@
        {
                _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-               string_table& st = _vm.getStringTable();
+               string_table& st = getStringTable(_owner);
                log_debug("Native GetterSetter %s in namespace %s inserted with 
"
                 "flags %s", st.value(key), st.value(nsId), a.getFlags());
 #endif
@@ -407,7 +332,7 @@
        container::iterator found = iterator_find(_props, uri);
        if (found != _props.end())
        {
-        ObjectURI::Logger l(_vm.getStringTable());
+        ObjectURI::Logger l(getStringTable(_owner));
                log_error("Property %s already exists, can't 
addDestructiveGetter",
                 l(uri));
                return false; // Already exists.
@@ -419,7 +344,7 @@
        _props.insert(a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(_vm.getStringTable());
+    ObjectURI::Logger l(getStringTable(_owner));
        log_debug("Destructive AS property %s inserted with flags %s",
             l(uri), a.getFlags());
 #endif
@@ -440,7 +365,7 @@
        _props.insert(a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(_vm.getStringTable());
+    ObjectURI::Logger l(getStringTable(_owner));
        log_debug("Destructive native property %s with flags %s", l(uri),
             a.getFlags());
 #endif

=== modified file 'libcore/PropertyList.h'
--- a/libcore/PropertyList.h    2009-12-02 14:27:13 +0000
+++ b/libcore/PropertyList.h    2009-12-03 13:36:04 +0000
@@ -24,16 +24,16 @@
 #include "string_table.h"
 #include "ObjectURI.h"
 
+#include <set> 
 #include <map> 
 #include <string> // for use within map 
 #include <cassert> // for inlines
 #include <utility> // for std::pair
-#include <set>
 #include <boost/cstdint.hpp> 
 #include <boost/multi_index_container.hpp>
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index/key_extractors.hpp>
-
+#include <boost/noncopyable.hpp>
 
 // Forward declaration
 namespace gnash {
@@ -45,21 +45,25 @@
 
 namespace gnash {
 
-/// Set of properties associated to an ActionScript object.
+/// Set of properties associated with an ActionScript object.
 //
 /// The PropertyList container is the sole owner of the Property
 /// elements in it contained and has full responsibility of their
 /// construction and destruction.
-///
-class PropertyList
+//
+/// A PropertyList holds a reference to the as_object whose properties it
+/// contains. This reference will always be valid if the PropertyList
+/// is a member of as_object.
+//
+/// It is theoretically possible for a PropertyList to be used with any
+/// as_object, not just original as_object it was use with. Currently (as
+/// there is no use for this scenario) it is not possible to change the
+/// owner.
+class PropertyList : boost::noncopyable
 {
 public:
 
-    typedef std::pair<std::string, std::string> KeyValuePair;
-    typedef std::vector<KeyValuePair> SortedPropertyList;
-    
-    /// Used to keep track of which properties have been enumerated.
-    typedef std::set<ObjectURI> PropTracker;
+    typedef std::set<ObjectURI> PropertyTracker;
 
     /// A tag for identifying an index in the container.
     struct OrderTag {};
@@ -88,23 +92,17 @@
 
     /// Construct the PropertyList 
     //
-    /// The constructor takes a VM reference because PropertyList
-    /// conceptually needs access to Virtual Machine resources
-    /// (string_table) but not to the Stage.
-    PropertyList(VM& vm)
+    /// @param obj      The as_object to which this PropertyList belongs.
+    ///                 This object is not fully constructed at this stage,
+    ///                 so this constructor should not do anything with it!
+    PropertyList(as_object& obj)
         :
         _props(),
         _defaultOrder(0),
-        _vm(vm)
+        _owner(obj)
     {
     }
 
-    /// Copy constructor
-    PropertyList(const PropertyList& pl);
-
-    /// Assignment operator
-    PropertyList& operator=(const PropertyList&);
-
     /// Visit properties 
     //
     /// The method will invoke the given visitor method
@@ -120,11 +118,8 @@
     ///                     bool accept(const ObjectURI&, const as_value&);
     ///                 Scan is by enumeration order and stops when accept()
     ///                 returns false.
-    ///
-    /// @param this_ptr The object reference used to extract values from
-    ///                 properties.
     template <class U, class V>
-    void visitValues(V& visitor, const as_object& this_ptr, U cmp = U()) const
+    void visitValues(V& visitor, U cmp = U()) const
     {
         typedef container::nth_index<1>::type ContainerByOrder;
 
@@ -136,11 +131,22 @@
                 ie = _props.template get<1>().rend(); it != ie; ++it)
         {
             if (!cmp(*it)) continue;
-            as_value val = it->getValue(this_ptr);
+            as_value val = it->getValue(_owner);
             if (!visitor.accept(it->uri(), val)) return;
         }
     }
 
+    /// Enumerate all non-hidden properties to the given as_environment.
+    //
+    /// Follows enumeration order. Note that this enumeration does not
+    /// access the values. Accessing the values can result in changes to
+    /// the object if the value is a getter-setter, and key enumeration must
+    /// avoid this.
+    ///
+    /// @param donelist     Don't enumerate properties in donelist.
+    ///                     Enumerated properties are added to donelist.
+    void enumerateKeys(as_environment& env, PropertyTracker& donelist) const;
+
     /// Get the order number just after the passed order number.
     ///
     /// @param order    0 is a special value indicating the first order
@@ -160,14 +166,6 @@
     /// @param value
     ///    a const reference to the as_value to use for setting
     ///    or creating the property. 
-    /// @param this_ptr
-    ///     The as_object used to set the 'this' pointer
-    ///     for calling getter/setter function (GetterSetterProperty);
-    ///     it will be unused when getting or setting SimpleProperty
-    ///     properties.
-    ///    This parameter is non-const as nothing prevents an
-    ///    eventual "Setter" function from actually modifying it,
-    ///    so we can't promise constness.
     /// @param namespaceId
     ///    The namespace in which this should be entered. If 0 is given,
     ///    this will use the first value found, if it exists.
@@ -176,7 +174,7 @@
     /// @return true if the value was successfully set, false
     ///         otherwise (found a read-only property, most likely).
     bool setValue(const ObjectURI& uri, const as_value& value,
-            as_object& this_ptr, const PropFlags& flagsIfMissing = 0);
+            const PropFlags& flagsIfMissing = 0);
 
     /// Reserves a slot number for a property
     ///
@@ -203,7 +201,7 @@
     /// @param order    The ordering id
     const Property* getPropertyByOrder(int order);
     
-    /// Delete a propery, if exising and not protected from deletion.
+    /// Delete a Property, if existing and not protected from deletion.
     //
     ///
     /// @param key      Name of the property.
@@ -285,40 +283,6 @@
     /// @param setFalse     The set of flags to clear
     void setFlagsAll(int setTrue, int setFalse);
 
-    /// \brief
-    /// Copy all properties from the given PropertyList
-    /// instance.
-    //
-    /// Unexistent properties are created. Existing properties
-    /// are updated with the new value.
-    ///
-    /// @param props
-    ///    the properties to copy from
-    ///
-    void import(const PropertyList& props);
-
-    /// \brief
-    /// Enumerate all non-hidden properties pushing
-    /// their keys to the given as_environment.
-    /// Follows enumeration order.
-    ///
-    /// @param donelist
-    /// Don't enumerate those in donelist. Add those done to donelist.
-    void enumerateKeys(as_environment& env, PropTracker& donelist) const;
-
-    /// \brief
-    /// Enumerate all non-hidden properties inserting
-    /// their name/value pair to the given SortedPropertyList.
-    /// Follows enumeration order.
-    ///
-    /// @param this_ptr
-    ///     The as_object used to set the 'this' pointer
-    ///     for calling getter/setter function (GetterSetterProperty);
-    ///     it will be unused when getting or setting SimpleProperty
-    ///     properties.
-    void enumerateKeyValue(const as_object& this_ptr, SortedPropertyList& to)
-        const;
-
     /// Remove all entries in the container
     void clear();
 
@@ -329,41 +293,16 @@
 
     /// Dump all members (using log_debug)
     //
-    /// @param this_ptr
-    ///     The as_object used to set the 'this' pointer
-    ///     for calling getter/setter function (GetterSetterProperty);
-    ///     it will be unused when getting or setting SimpleProperty
-    ///     properties.
-    ///    This parameter is non-const as nothing prevents an
-    ///    eventual "Getter" function from actually modifying it,
-    ///    so we can't promise constness.
-    ///    Note that the PropertyList itself might be changed
-    ///    from this call, accessed trough the 'this' pointer,
-    ///    so this method too is non-const.
-    ///
     /// This does not reflect the normal enumeration order. It is sorted
     /// lexicographically by property.
-    ///
-    void dump(as_object& this_ptr);
+    void dump();
 
     /// Dump all members into the given map
     //
-    /// @param this_ptr
-    ///     The as_object used to set the 'this' pointer
-    ///     for calling getter/setter function (GetterSetterProperty);
-    ///     it will be unused when getting or setting SimpleProperty
-    ///     properties.
-    ///    This parameter is non-const as nothing prevents an
-    ///    eventual "Getter" function from actually modifying it,
-    ///    so we can't promise constness.
-    ///    Note that the PropertyList itself might be changed
-    ///    from this call, accessed trough the 'this' pointer,
-    ///    so this method too is non-const.
-    ///
     /// This does not reflect the normal enumeration order. It is sorted
     /// lexicographically by property.
     ///
-    void dump(as_object& this_ptr, std::map<std::string, as_value>& to);
+    void dump(std::map<std::string, as_value>& to);
 
     /// Mark all simple properties, getters and setters
     /// as being reachable (for the GC)
@@ -375,7 +314,7 @@
 
     boost::uint32_t _defaultOrder;
     
-    VM& _vm;
+    as_object& _owner;
 
 };
 

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2009-11-30 11:12:37 +0000
+++ b/libcore/TextField.cpp     2009-12-04 09:20:14 +0000
@@ -2350,8 +2350,7 @@
     attachTextFieldInterface(*proto);
     attachTextFieldStaticMembers(*cl);
              
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
     // ASSetPropFlags is called on the TextField class.
     as_object* null = 0;

=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/Video.cpp 2009-12-04 09:20:14 +0000
@@ -292,8 +292,7 @@
     attachVideoInterface(*proto);
 
        // Register _global.Video
-       global.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+       global.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 void

=== modified file 'libcore/abc/Class.cpp'
--- a/libcore/abc/Class.cpp     2009-12-02 15:57:58 +0000
+++ b/libcore/abc/Class.cpp     2009-12-04 10:56:27 +0000
@@ -57,11 +57,13 @@
        if (isstatic)
                flags |= PropFlags::staticProp;
 
-       if(slotId == 0){
-               _prototype->init_member(name, val, flags, nsname);
+    const ObjectURI uri(name, nsname);
+
+       if (slotId == 0) {
+               _prototype->init_member(uri, val, flags);
        }
-       else{
-               _prototype->init_member(name, val, flags, nsname, slotId);
+       else {
+               _prototype->init_member(uri, val, flags, slotId);
        }
        return true;
 }
@@ -70,7 +72,7 @@
 Class::initPrototype()
 {
     Global_as& gl = *VM::get().getGlobal();
-    _prototype = new as_class(gl);
+    _prototype = new as_class(gl, this);
 }
 
 bool
@@ -98,7 +100,7 @@
 
        //TODO: Set flags.
        if (slotId == 0) {
-               _prototype->init_member(name, as_value(), 0, nsname);
+               _prototype->init_member(ObjectURI(name, nsname), as_value(), 0);
        }
        else {
                _prototype->reserveSlot(ObjectURI(name, nsname), slotId);

=== modified file 'libcore/abc/Method.cpp'
--- a/libcore/abc/Method.cpp    2009-12-02 15:57:58 +0000
+++ b/libcore/abc/Method.cpp    2009-12-04 09:20:14 +0000
@@ -96,11 +96,13 @@
 
        if (isconst) flags |= PropFlags::readOnly;
 
+    const ObjectURI uri(name, nsname);
+
        if (slotId == 0) {
-               _prototype->init_member(name, val, flags, nsname);
+               _prototype->init_member(uri, val, flags);
        }
        else {
-               _prototype->init_member(name, val, flags, nsname, slotId);
+               _prototype->init_member(uri, val, flags, slotId);
        }
        return true;
 }
@@ -154,12 +156,12 @@
 
 bool
 Method::addSlot(string_table::key name, Namespace* ns, boost::uint32_t slotId,
-       Class */*type*/)
+       Class* /*type*/)
 {
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
        int flags = PropFlags::dontDelete;
 
-       _prototype->init_member(name, as_value(), flags, nsname, slotId);
+       _prototype->init_member(ObjectURI(name, nsname), as_value(), flags, 
slotId);
        return true;
 }
 

=== modified file 'libcore/abc/as_class.cpp'
--- a/libcore/abc/as_class.cpp  2009-12-01 08:45:59 +0000
+++ b/libcore/abc/as_class.cpp  2009-12-04 10:56:27 +0000
@@ -16,18 +16,25 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "as_class.h"
+#include "Class.h"
+#include "Global_as.h"
 #include <string>
 
 namespace gnash {
 namespace abc {
 
+as_class::as_class(Global_as& gl, Class* c)
+    :
+    as_object(gl),
+    _class(c),
+    _name("[class " + getStringTable(gl).value(c->getName()) + "]")
+{}
+
 const std::string&
 as_class::stringValue() const
 {
     assert(isAS3(*this));
-
-    static const std::string str("[class Class]");
-    return str;
+    return _name;
 }
 
 }

=== modified file 'libcore/abc/as_class.h'
--- a/libcore/abc/as_class.h    2009-12-01 08:45:59 +0000
+++ b/libcore/abc/as_class.h    2009-12-04 10:56:27 +0000
@@ -19,6 +19,11 @@
 #define GNASH_ABC_AS_CLASS_H
 
 #include "as_object.h"
+namespace gnash {
+    namespace abc {
+        class Class;
+    }
+}
 
 namespace gnash {
 namespace abc {
@@ -27,14 +32,30 @@
 //
 /// A Class is a first-class type, i.e. it can be referenced itself in
 /// ActionScript.
+//
+/// Although Classes are nominally 'dynamic' types, there seems to be no
+/// way to alter them in ActionScript, or to create them dynamically. In
+/// order to reference them, the Class must already be constructed and
+/// known in the execution scope, then retrieved by name.
+//
+/// Accordingly, all as_class objects have an associated Class, which is its
+/// static definition.
+//
+/// TODO: see how to implement "[class Class]", the prototype of all classes.
 class as_class : public as_object
 {
 public:
-    as_class(Global_as& gl) : as_object(gl) {}
+
+    as_class(Global_as& gl, Class* c);
     virtual ~as_class() {}
 
     virtual const std::string& stringValue() const;
 
+private:
+
+    Class* _class;
+
+    const std::string _name;
 };
 
 } // namespace abc

=== modified file 'libcore/as_environment.cpp'
--- a/libcore/as_environment.cpp        2009-11-30 15:59:02 +0000
+++ b/libcore/as_environment.cpp        2009-12-04 09:20:14 +0000
@@ -410,7 +410,7 @@
     for (size_t i = scopeStack.size(); i > 0; --i)
     {
         as_object* obj = scopeStack[i-1];
-        if (obj && obj->set_member(varkey, val, 0, true)) {
+        if (obj && obj->set_member(varkey, val, true)) {
             return;
         }
     }

=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp   2009-12-01 08:42:45 +0000
+++ b/libcore/as_function.cpp   2009-12-04 09:20:14 +0000
@@ -194,7 +194,7 @@
        int swf6flags = PropFlags::dontEnum | 
                     PropFlags::dontDelete | 
                     PropFlags::onlySWF6Up;
-       global.init_member(getName(uri), func, swf6flags, getNamespace(uri));
+       global.init_member(uri, func, swf6flags);
 }
 
 namespace {

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2009-12-02 14:27:13 +0000
+++ b/libcore/as_object.cpp     2009-12-04 09:20:14 +0000
@@ -240,20 +240,39 @@
                _tgt(tgt)
        {}
 
-       /// \brief
-       /// Use the set_member function to properly set *inherited* properties
-       /// of the given target object
-       ///
-       bool accept(const ObjectURI& uri, const as_value& val)
-       {
+       /// Set *inherited* properties of the given target object
+       bool accept(const ObjectURI& uri, const as_value& val) {
                if (getName(uri) == NSV::PROP_uuPROTOuu) return true;
-               _tgt.set_member(getName(uri), val);
+               _tgt.set_member(uri, val);
         return true;
        }
 private:
        as_object& _tgt;
 };
 
+class PropertyEnumerator : public AbstractPropertyVisitor
+{
+public:
+    PropertyEnumerator(const as_object& this_ptr,
+            as_object::SortedPropertyList& to)
+        :
+        _version(getSWFVersion(this_ptr)),
+        _st(getStringTable(this_ptr)),
+        _to(to)
+    {}
+
+    bool accept(const ObjectURI& uri, const as_value& val) {
+               _to.push_front(std::make_pair(_st.value(getName(uri)),
+                               val.to_string_versioned(_version)));
+        return true;
+    }
+
+private:
+    const int _version;
+    string_table& _st;
+    as_object::SortedPropertyList& _to;
+};
+
 } // end of anonymous namespace
 
 
@@ -265,7 +284,7 @@
     _array(false),
     _relay(0),
        _vm(getVM(gl)),
-       _members(_vm)
+       _members(*this)
 {
 }
 
@@ -275,7 +294,7 @@
     _array(false),
     _relay(0),
        _vm(VM::get()),
-       _members(_vm)
+       _members(*this)
 {
 }
 
@@ -414,8 +433,9 @@
                throw;
        }
        catch (ActionTypeError& exc) {
-               // TODO: check if this should be an 'as' error.. (log_aserror)
-               log_error(_("Caught exception: %s"), exc.what());
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Caught exception: %s"), exc.what());
+        );
                return false;
        }
 
@@ -562,8 +582,7 @@
     // getter/setter
        // TODO: check triggers !!
     // Note that this sets __proto__ in namespace 0
-       _members.setValue(NSV::PROP_uuPROTOuu, proto, *this,
-            as_object::DefaultFlags);
+       _members.setValue(NSV::PROP_uuPROTOuu, proto, as_object::DefaultFlags);
 }
 
 void
@@ -588,8 +607,7 @@
 {
        const Property* prop = _members.getPropertyByOrder(order);
        if (prop) {
-               return set_member(getName(prop->uri()), val, 
getNamespace(prop->uri()),
-                    ifFound);
+               return set_member(prop->uri(), val, ifFound);
        }
     return false;
 }
@@ -660,23 +678,20 @@
 /// 3. Visible own getter-setter properties of all __proto__ objects
 ///    (a DisplayObject ends the chain).
 bool
-as_object::set_member(string_table::key key, const as_value& val,
-       string_table::key nsname, bool ifFound)
+as_object::set_member(const ObjectURI& uri, const as_value& val, bool ifFound)
 {
 
     bool tfVarFound = false;
     if (displayObject()) {
         MovieClip* mc = dynamic_cast<MovieClip*>(displayObject());
-        if (mc) tfVarFound = mc->setTextFieldVariables(key, val, nsname);
+        if (mc) tfVarFound = mc->setTextFieldVariables(uri, val);
         // We still need to set the member.
     }
 
     // Handle the length property for arrays. NB: checkArrayLength() will
     // call this function again if the key is a valid index.
-    if (array()) checkArrayLength(*this, key, val, nsname);
+    if (array()) checkArrayLength(*this, uri, val);
 
-    const ObjectURI uri(key, nsname);
-    
     PrototypeRecursor<Exists> pr(this, uri);
 
        Property* prop = pr.getProperty();
@@ -687,7 +702,7 @@
 
         if (displayObject()) {
             DisplayObject* d = displayObject();
-            if (setDisplayObjectProperty(*d, key, val)) return true;
+            if (setDisplayObjectProperty(*d, getName(uri), val)) return true;
             // TODO: should we execute triggers?
         }
 
@@ -707,8 +722,9 @@
 
                if (prop->isReadOnly()) {
                        IF_VERBOSE_ASCODING_ERRORS(
-                    log_aserror(_("Attempt to set read-only property '%s'"),
-                    getStringTable(*this).value(key));
+                ObjectURI::Logger l(getStringTable(*this));
+                log_aserror(_("Attempt to set read-only property '%s'"),
+                    l(uri));
             );
                        return true;
                }
@@ -718,7 +734,7 @@
                }
                catch (ActionTypeError& exc) {
                        log_aserror(_("%s: Exception %s. Will create a new 
member"),
-                               getStringTable(*this).value(key), exc.what());
+                               getStringTable(*this).value(getName(uri)), 
exc.what());
                }
 
                return true;
@@ -728,11 +744,12 @@
        if (ifFound) return false;
 
        // Property does not exist, so it won't be read-only. Set it.
-       if (!_members.setValue(key, val, *this, nsname)) {
+       if (!_members.setValue(uri, val)) {
 
                IF_VERBOSE_ASCODING_ERRORS(
+            ObjectURI::Logger l(getStringTable(*this));
                        log_aserror(_("Unknown failure in setting property '%s' 
on "
-                       "object '%p'"), getStringTable(*this).value(key), 
(void*) this);
+                       "object '%p'"), l(uri), (void*) this);
            );
                return false;
        }
@@ -750,16 +767,15 @@
 as_object::init_member(const std::string& key1, const as_value& val, int flags,
        string_table::key nsname)
 {
-       init_member(getStringTable(*this).find(key1), val, flags, nsname);
+       const ObjectURI uri(getStringTable(*this).find(key1), nsname);
+       init_member(uri, val, flags);
 }
 
 void
-as_object::init_member(string_table::key key, const as_value& val, int flags,
-       string_table::key nsname, int order)
+as_object::init_member(const ObjectURI& uri, const as_value& val, int flags,
+       int order)
 {
 
-    const ObjectURI uri(key, nsname);
-
        if (order >= 0 && !_members.reserveSlot(uri,
                 static_cast<boost::uint16_t>(order))) {
                log_error(_("Attempt to set a slot for either a slot or a 
property "
@@ -768,11 +784,10 @@
        }
                
        // Set (or create) a SimpleProperty 
-       if (! _members.setValue(uri, val, *this, flags) )
-       {
+       if (!_members.setValue(uri, val, flags)) {
+        ObjectURI::Logger l(getStringTable(*this));
                log_error(_("Attempt to initialize read-only property ``%s''"
-                       " on object ``%p'' twice"),
-                       getStringTable(*this).value(key), (void*)this);
+                       " on object ``%p'' twice"), l(uri), (void*)this);
                // We shouldn't attempt to initialize a member twice, should we 
?
                abort();
        }
@@ -982,13 +997,13 @@
 {
        log_debug(_("%d members of object %p follow"),
                _members.size(), (const void*)this);
-       _members.dump(*this);
+       _members.dump();
 }
 
 void
 as_object::dump_members(std::map<std::string, as_value>& to)
 {
-       _members.dump(*this, to);
+       _members.dump(to);
 }
 
 void
@@ -1043,8 +1058,9 @@
 }
 
 void
-as_object::enumerateProperties(as_environment& env) const
+as_object::enumeratePropertyKeys(as_environment& env) const
 {
+
        assert(env.top(0).is_undefined());
 
     // Hack to handle MovieClips.
@@ -1054,35 +1070,31 @@
 
        // this set will keep track of visited objects,
        // to avoid infinite loops
-       std::set< const as_object* > visited;
-       PropertyList::PropTracker named;
+       std::set<const as_object*> visited;
 
-       boost::intrusive_ptr<const as_object> obj(this);
+    PropertyList::PropertyTracker doneList;
        
-       while ( obj && visited.insert(obj.get()).second )
-       {
-               obj->_members.enumerateKeys(env, named);
-               obj = obj->get_prototype();
+       const as_object* current(this);
+       while (current && visited.insert(current).second) {
+               current->_members.enumerateKeys(env, doneList);
+               current = current->get_prototype();
        }
-
-       // This happens always since top object in hierarchy
-       // is always Object, which in turn derives from itself
-       //if ( obj ) log_error(_("prototype loop during Enumeration"));
 }
 
 void
-as_object::enumerateProperties(SortedPropertyList& to) const
+enumerateProperties(as_object& obj, as_object::SortedPropertyList& to)
 {
 
        // this set will keep track of visited objects,
        // to avoid infinite loops
-       std::set< const as_object* > visited;
-
-       boost::intrusive_ptr<const as_object> obj(this);
-       while ( obj && visited.insert(obj.get()).second )
-       {
-               obj->_members.enumerateKeyValue(*this, to);
-               obj = obj->get_prototype();
+       std::set<as_object*> visited;
+
+    PropertyEnumerator e(obj, to);
+       as_object* current(&obj);
+
+       while (current && visited.insert(current).second) {
+               current->visitProperties<IsEnumerable>(e);
+               current = current->get_prototype();
        }
 
 }
@@ -1151,13 +1163,13 @@
 void
 getURLEncodedVars(as_object& o, std::string& data)
 {
-    PropertyList::SortedPropertyList props;
-    o.enumerateProperties(props);
+    as_object::SortedPropertyList props;
+    enumerateProperties(o, props);
 
     std::string del;
     data.clear();
     
-    for (PropertyList::SortedPropertyList::const_iterator i=props.begin(),
+    for (as_object::SortedPropertyList::const_iterator i=props.begin(),
             e=props.end(); i!=e; ++i) {
         std::string name = i->first;
         std::string value = i->second;

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2009-12-02 14:27:13 +0000
+++ b/libcore/as_object.h       2009-12-04 09:20:14 +0000
@@ -24,7 +24,6 @@
 
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "string_table.h"
-#include "ref_counted.h" // for inheritance  (to drop)
 #include "GC.h" // for inheritance from GcResource (to complete)
 #include "PropertyList.h"
 #include "as_value.h" // for return of get_primitive_value
@@ -39,6 +38,7 @@
 #include <set>
 #include <sstream>
 #include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
 
 // Forward declarations
 namespace gnash {
@@ -144,15 +144,23 @@
 /// Base-class for ActionScript script-defined objects.
 /// This would likely be ActionScript's 'Object' class.
 ///
-class as_object : public GcResource
+class as_object : public GcResource, boost::noncopyable
 {
-    friend class abc::Class;
-    friend class abc::Machine;
-
-    typedef PropertyList::SortedPropertyList SortedPropertyList;
 
 public:
     
+    typedef std::pair<std::string, std::string> KeyValuePair;
+
+    /// This is used to hold an intermediate copy of an as_object's properties.
+    //
+    /// AS enumerates in reverse order of creation. In order to make sure
+    /// that the properties are in the correct order, the first element of
+    /// a SortedPropertyList should hold the last created property.
+    //
+    /// We use a deque because we push to the front in order to preserve the
+    /// ordering for the copy.
+    typedef std::deque<KeyValuePair> SortedPropertyList;
+    
     /// Construct an ActionScript object with no prototype associated.
     //
     /// @param  global  A reference to the Global object the new
@@ -245,8 +253,8 @@
     ///          after setting.
     ///    
     ///
-    virtual bool set_member(string_table::key key, const as_value& val,
-        string_table::key nsname = 0, bool ifFound=false);
+    virtual bool set_member(const ObjectURI& uri, const as_value& val,
+        bool ifFound = false);
 
     /// Reserve a slot
     ///
@@ -305,9 +313,8 @@
     /// this is used as the slotId and can be subsequently found with
     /// get_slot
     ///
-    void init_member(string_table::key key, const as_value& val, 
-        int flags = DefaultFlags, string_table::key nsname = 0,
-        int slotId = -1);
+    void init_member(const ObjectURI& uri, const as_value& val, 
+        int flags = DefaultFlags, int slotId = -1);
 
     /// \brief
     /// Initialize a getter/setter property by name
@@ -544,6 +551,18 @@
     void init_readonly_property(const ObjectURI& uri,
             as_c_function_ptr getter, int flags = DefaultFlags);
 
+
+    /// Enumerate all non-hidden property keys to the given as_environment.
+    //
+    /// NB: this function does not access the property values, so callers
+    /// can be certain no values will be changed.
+    //
+    /// The enumeration recurses through the prototype chain. This
+    /// implementation will keep track of visited object to avoid infinite
+    /// loops in the prototype chain.  NOTE: the MM player just chokes in
+    /// this case.
+    void enumeratePropertyKeys(as_environment& env) const;
+
     /// \brief
     /// Add a watch trigger, overriding any other defined for same name.
     //
@@ -796,28 +815,6 @@
         _members.clear();
     }
 
-    /// \brief
-    /// Enumerate all non-hidden properties pushing
-    /// their value to the given as_environment.
-    //
-    /// The enumeration recurse in prototype.
-    /// This implementation will keep track of visited object
-    /// to avoid loops in prototype chain. 
-    /// NOTE: the MM player just chokes in this case (loop)
-    ///
-    void enumerateProperties(as_environment& env) const;
-
-    /// \brief
-    /// Enumerate all non-hidden properties inserting
-    /// their name/value pair to the given map.
-    //
-    /// The enumeration recurse in prototype.
-    /// This implementation will keep track of visited object
-    /// to avoid loops in prototype chain. 
-    /// NOTE: the MM player just chokes in this case (loop)
-    ///
-    void enumerateProperties(SortedPropertyList& to) const;
-
     /// Visit the properties of this object by key/as_value pairs
     //
     /// The method will invoke the given visitor method
@@ -832,7 +829,7 @@
     ///
     template<typename T>
     void visitProperties(AbstractPropertyVisitor& visitor) const {
-        _members.visitValues<T>(visitor, *this);
+        _members.visitValues<T>(visitor);
     }
 
     /// \brief
@@ -925,8 +922,6 @@
         _displayObject = d;
     }
 
-protected:
-
     ///Get a member value at a given slot.
     //
     /// @param order
@@ -961,7 +956,8 @@
     ///
     bool set_member_slot(int order, const as_value& val, bool ifFound = false);
 
-#ifdef GNASH_USE_GC
+protected:
+
     /// Mark all reachable resources, override from GcResource.
     //
     /// The default implementation marks all properties
@@ -970,25 +966,15 @@
     /// If a derived class provides access to more GC-managed
     /// resources, it should override this method and call 
     /// markAsObjectReachable() as the last step.
-    ///
-    virtual void markReachableResources() const
-    {
+    virtual void markReachableResources() const {
         markAsObjectReachable();
     }
 
     /// Mark properties and triggers list as reachable (for the GC)
     void markAsObjectReachable() const;
 
-#endif // GNASH_USE_GC
-
 private:
 
-    /// Do not allow copies.
-    as_object(const as_object& other);
-
-    /// Don't allow implicit assignment.
-    as_object& operator=(const as_object&);
-
     /// A utility class for processing this as_object's inheritance chain
     template<typename T> class PrototypeRecursor;
 
@@ -1124,6 +1110,16 @@
     return relay;
 }
 
+/// Enumerate all non-hidden properties to the passed container
+//
+/// NB: it is likely that this call will change the object, as accessing
+/// propertyproperty  values may call getter-setters.
+//
+/// The enumeration recurses through the prototype chain. This implementation
+/// will keep track of visited object to avoid infinite loops in the
+/// prototype chain.  NOTE: the MM player just chokes in this case.
+void enumerateProperties(as_object& o, as_object::SortedPropertyList& to);
+
 /// Get the VM from an as_object.
 VM& getVM(const as_object& o);
 

=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp        2009-12-02 14:27:13 +0000
+++ b/libcore/asobj/Array_as.cpp        2009-12-04 09:20:14 +0000
@@ -821,9 +821,9 @@
 }
 
 void
-checkArrayLength(as_object& array, string_table::key name, const as_value& val,
-        string_table::key /*nsname*/)
+checkArrayLength(as_object& array, const ObjectURI& uri, const as_value& val)
 {
+    const string_table::key name = getName(uri);
     if (name == NSV::PROP_LENGTH) {
         resizeArray(array, val.to_int());
         return;
@@ -888,7 +888,7 @@
     attachArrayStatics(*cl);
 
     const int flags = PropFlags::dontEnum; 
-    where.init_member(getName(uri), cl, flags, getNamespace(uri));
+    where.init_member(uri, cl, flags);
 }
 
 // Used by foreachArray, declared in Array_as.h

=== modified file 'libcore/asobj/Array_as.h'
--- a/libcore/asobj/Array_as.h  2009-12-02 14:27:13 +0000
+++ b/libcore/asobj/Array_as.h  2009-12-04 09:20:14 +0000
@@ -71,8 +71,8 @@
 /// The only distinction between Arrays and Objects is that the length
 /// property is changed when an element is added, and that changing the length
 /// can result in deleted properties.
-void checkArrayLength(as_object& array, string_table::key name,
-        const as_value& val, string_table::key nsname = 0);
+void checkArrayLength(as_object& array, const ObjectURI& uri,
+        const as_value& val);
 
 template<typename T>
 void foreachArray(as_object& array, T& pred)

=== modified file 'libcore/asobj/Boolean_as.cpp'
--- a/libcore/asobj/Boolean_as.cpp      2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Boolean_as.cpp      2009-12-04 09:20:14 +0000
@@ -75,8 +75,7 @@
     attachBooleanInterface(*proto);
     
     // Register _global.Boolean
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/Date_as.cpp'
--- a/libcore/asobj/Date_as.cpp 2009-11-30 11:12:37 +0000
+++ b/libcore/asobj/Date_as.cpp 2009-12-04 09:20:14 +0000
@@ -222,8 +222,7 @@
     attachDateStaticInterface(*cl);
 
     // Register _global.Date
-    global.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    global.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/Global_as.h'
--- a/libcore/asobj/Global_as.h 2009-11-23 08:58:01 +0000
+++ b/libcore/asobj/Global_as.h 2009-12-04 09:20:14 +0000
@@ -142,8 +142,7 @@
     as_object* obj = gl.createObject();
     if (p) p(*obj);
     
-    where.init_member(getName(uri), obj, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, obj, as_object::DefaultFlags);
 
     return obj;
 }
@@ -180,8 +179,7 @@
     if (p) p(*proto);
 
     // Register class with specified object.
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
     return cl;
 }
 

=== modified file 'libcore/asobj/LoadVars_as.cpp'
--- a/libcore/asobj/LoadVars_as.cpp     2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/LoadVars_as.cpp     2009-12-03 13:36:04 +0000
@@ -123,12 +123,12 @@
 as_value
 loadvars_tostring(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> ptr = ensure<ThisIs<as_object> >(fn);
+       as_object* ptr = ensure<ValidThis>(fn);
 
-       typedef PropertyList::SortedPropertyList VarMap;
+       typedef as_object::SortedPropertyList VarMap;
        VarMap vars;
 
-       ptr->enumerateProperties(vars);
+       enumerateProperties(*ptr, vars);
 
     as_object* global = &getGlobal(*ptr);
     std::ostringstream o;

=== modified file 'libcore/asobj/MovieClipLoader.cpp'
--- a/libcore/asobj/MovieClipLoader.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/MovieClipLoader.cpp 2009-12-04 09:20:14 +0000
@@ -82,8 +82,7 @@
     as_object* null = 0;
     callMethod(&gl, NSV::PROP_AS_SET_PROP_FLAGS, proto, null, 1027);
 
-       where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri)); 
+       where.init_member(uri, cl, as_object::DefaultFlags); 
 }
 
 

=== modified file 'libcore/asobj/Number_as.cpp'
--- a/libcore/asobj/Number_as.cpp       2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Number_as.cpp       2009-12-04 09:20:14 +0000
@@ -162,8 +162,7 @@
     attachNumberStaticInterface(*cl);
 
     // Register _global.Number
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp  2009-12-01 08:44:22 +0000
+++ b/libcore/asobj/Object.cpp  2009-12-04 09:20:14 +0000
@@ -103,7 +103,7 @@
              
     // Register _global.Object (should only be visible in SWF5 up)
     int flags = PropFlags::dontEnum; 
-    where.init_member(getName(uri), cl, flags, getNamespace(uri));
+    where.init_member(uri, cl, flags);
 
 }
 

=== modified file 'libcore/asobj/QName_as.cpp'
--- a/libcore/asobj/QName_as.cpp        2009-11-18 13:04:36 +0000
+++ b/libcore/asobj/QName_as.cpp        2009-12-04 09:20:14 +0000
@@ -51,8 +51,7 @@
     as_object* proto = gl.createObject();
     as_object* cl = gl.createClass(&qname_ctor, proto);
 
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 

=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp       2009-11-30 10:19:02 +0000
+++ b/libcore/asobj/String_as.cpp       2009-12-04 09:20:14 +0000
@@ -125,7 +125,7 @@
     cl->init_member("fromCharCode", vm.getNative(251, 14)); 
 
     const int flags = PropFlags::dontEnum; 
-    where.init_member(getName(uri), cl, flags, getNamespace(uri));
+    where.init_member(uri, cl, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/accessibility/Accessibility_as.cpp'
--- a/libcore/asobj/flash/accessibility/Accessibility_as.cpp    2009-11-18 
11:51:35 +0000
+++ b/libcore/asobj/flash/accessibility/Accessibility_as.cpp    2009-12-04 
09:20:14 +0000
@@ -63,8 +63,7 @@
     attachAccessibilityStaticInterface(*obj);
 
     // Register _global.Accessibility
-    where.init_member(getName(uri), obj, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, obj, as_object::DefaultFlags);
 }
 
 void

=== modified file 'libcore/asobj/flash/display/DisplayObjectContainer_as.cpp'
--- a/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-11-06 
07:54:33 +0000
+++ b/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-12-04 
09:20:14 +0000
@@ -69,8 +69,7 @@
     }
 
     // Register _global.DisplayObjectContainer
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl.get(), as_object::DefaultFlags);
 }
 
 as_object*

=== modified file 'libcore/asobj/flash/display/DisplayObject_as.cpp'
--- a/libcore/asobj/flash/display/DisplayObject_as.cpp  2009-11-18 13:05:53 
+0000
+++ b/libcore/asobj/flash/display/DisplayObject_as.cpp  2009-12-04 09:20:14 
+0000
@@ -60,8 +60,7 @@
     attachDisplayObjectStaticInterface(*cl);
 
     // Register _global.DisplayObject
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/Graphics_as.cpp'
--- a/libcore/asobj/flash/display/Graphics_as.cpp       2009-11-18 12:32:41 
+0000
+++ b/libcore/asobj/flash/display/Graphics_as.cpp       2009-12-04 09:20:14 
+0000
@@ -62,8 +62,7 @@
     attachGraphicsStaticInterface(*cl);
 
     // Register _global.Graphics
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/LoaderInfo_as.cpp'
--- a/libcore/asobj/flash/display/LoaderInfo_as.cpp     2009-11-18 12:32:41 
+0000
+++ b/libcore/asobj/flash/display/LoaderInfo_as.cpp     2009-12-04 09:20:14 
+0000
@@ -58,8 +58,7 @@
     attachLoaderInfoStaticInterface(*cl);
 
     // Register _global.LoaderInfo
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp      2009-11-30 11:12:37 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp      2009-12-04 09:20:14 
+0000
@@ -136,16 +136,14 @@
 
         log_debug("AVM2 MovieClip, proto %s", cl);
 
-        where.init_member(getName(uri), cl, as_object::DefaultFlags,
-                getNamespace(uri));
+        where.init_member(uri, cl, as_object::DefaultFlags);
         return;
     }
 
     as_object* cl = gl.createClass(&movieclip_as2_ctor, proto);
     attachMovieClipAS2Interface(*proto);
 
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 void

=== modified file 'libcore/asobj/flash/filters/BitmapFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-12-02 12:30:12 
+0000
+++ b/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-12-04 09:20:14 
+0000
@@ -95,8 +95,7 @@
     // so the new prototype doesn't have a constructor property. We do the
     // same here.
     cl->set_member(NSV::PROP_PROTOTYPE, proto);
-    where.init_member(getName(uri) , cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri , cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/media/Camera_as.cpp'
--- a/libcore/asobj/flash/media/Camera_as.cpp   2009-11-29 08:57:58 +0000
+++ b/libcore/asobj/flash/media/Camera_as.cpp   2009-12-04 09:20:14 +0000
@@ -639,8 +639,7 @@
     }
     
     // Register _global.Camera
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/media/Microphone_as.cpp'
--- a/libcore/asobj/flash/media/Microphone_as.cpp       2009-11-29 08:57:58 
+0000
+++ b/libcore/asobj/flash/media/Microphone_as.cpp       2009-12-04 09:20:14 
+0000
@@ -490,8 +490,7 @@
     }
         
        // Register _global.Microphone
-       where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+       where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/media/Sound_as.cpp'
--- a/libcore/asobj/flash/media/Sound_as.cpp    2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/media/Sound_as.cpp    2009-12-04 09:20:14 +0000
@@ -125,8 +125,7 @@
     proto->set_member_flags(NSV::PROP_uuPROTOuu, PropFlags::readOnly, 0);
 
     // Register _global.String
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp       2009-12-02 14:27:13 
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp       2009-12-04 09:20:14 
+0000
@@ -727,8 +727,7 @@
     attachSharedObjectStaticInterface(*cl);
     
     // Register _global.SharedObject
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));    
+    where.init_member(uri, cl, as_object::DefaultFlags);    
 }
 
 void

=== modified file 'libcore/asobj/flash/system/Security_as.cpp'
--- a/libcore/asobj/flash/system/Security_as.cpp        2009-10-23 06:25:25 
+0000
+++ b/libcore/asobj/flash/system/Security_as.cpp        2009-12-04 09:20:14 
+0000
@@ -58,8 +58,7 @@
     attachSecurityInterface(*proto);
 
     // Register _global.Security
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/text/TextFormat_as.cpp'
--- a/libcore/asobj/flash/text/TextFormat_as.cpp        2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/text/TextFormat_as.cpp        2009-12-04 09:20:14 
+0000
@@ -156,8 +156,7 @@
     as_object* proto = gl.createObject();;
     as_object* cl = gl.createClass(&textformat_new, proto);
 
-       global.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+       global.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-11-30 11:12:37 
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-12-04 09:20:14 
+0000
@@ -692,8 +692,7 @@
         cl->init_member(NSV::PROP_PROTOTYPE, proto);
     }
     
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 

=== modified file 'libcore/asobj/flash/xml/XMLNode_as.cpp'
--- a/libcore/asobj/flash/xml/XMLNode_as.cpp    2009-11-26 16:11:18 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.cpp    2009-12-04 09:20:14 +0000
@@ -47,11 +47,11 @@
 // Function Prototypes
 namespace {
     void enumerateAttributes(const XMLNode_as& node,
-            PropertyList::SortedPropertyList& attributes);
-    bool prefixMatches(const PropertyList::SortedPropertyList::value_type& val,
+            as_object::SortedPropertyList& attributes);
+    bool prefixMatches(const as_object::SortedPropertyList::value_type& val,
             const std::string& prefix);
     bool namespaceMatches(
-            const PropertyList::SortedPropertyList::value_type& val,
+            const as_object::SortedPropertyList::value_type& val,
             const std::string& ns);    
 
     as_value xmlnode_new(const fn_call& fn);
@@ -302,8 +302,8 @@
 XMLNode_as::getPrefixForNamespace(const std::string& ns, std::string& prefix)
 {
     XMLNode_as* node = this;
-    PropertyList::SortedPropertyList::const_iterator it; 
-    PropertyList::SortedPropertyList attrs;
+    as_object::SortedPropertyList::const_iterator it; 
+    as_object::SortedPropertyList attrs;
     
     while (node) {
         enumerateAttributes(*node, attrs);
@@ -339,8 +339,8 @@
 XMLNode_as::getNamespaceForPrefix(const std::string& prefix, std::string& ns)
 {
     XMLNode_as* node = this;
-    PropertyList::SortedPropertyList::const_iterator it; 
-    PropertyList::SortedPropertyList attrs;
+    as_object::SortedPropertyList::const_iterator it; 
+    as_object::SortedPropertyList attrs;
     
     while (node) {
 
@@ -414,11 +414,11 @@
         xmlout << "<" << nodeName;
     
         // Process the attributes, if any
-        PropertyList::SortedPropertyList attrs;
+        as_object::SortedPropertyList attrs;
         enumerateAttributes(xml, attrs);
         if (!attrs.empty()) {
 
-            for (PropertyList::SortedPropertyList::iterator i = 
+            for (as_object::SortedPropertyList::iterator i = 
                     attrs.begin(), e = attrs.end(); i != e; ++i) { 
                 escapeXML(i->second);
                 xmlout << " " << i->first << "=\"" << i->second << "\"";
@@ -501,8 +501,7 @@
     attachXMLNodeInterface(*proto);
     as_object* cl = gl.createClass(&xmlnode_new, proto);
 
-    where.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+    where.init_member(uri, cl, as_object::DefaultFlags);
 
 }
 
@@ -991,12 +990,12 @@
 
 void
 enumerateAttributes(const XMLNode_as& node,
-        PropertyList::SortedPropertyList& attrs)
+        as_object::SortedPropertyList& attrs)
 {
     attrs.clear();
-    const as_object* obj = node.getAttributes();
+    as_object* obj = node.getAttributes();
     if (obj) {
-        obj->enumerateProperties(attrs);
+        enumerateProperties(*obj, attrs);
     }
 
 }
@@ -1004,7 +1003,7 @@
 /// Return true if this attribute is a namespace specifier and the
 /// namespace matches.
 bool
-namespaceMatches(const PropertyList::SortedPropertyList::value_type& val,
+namespaceMatches(const as_object::SortedPropertyList::value_type& val,
         const std::string& ns)
 {
     StringNoCaseEqual noCaseCompare;
@@ -1014,7 +1013,7 @@
 
 
 bool
-prefixMatches(const PropertyList::SortedPropertyList::value_type& val,
+prefixMatches(const as_object::SortedPropertyList::value_type& val,
         const std::string& prefix)
 {
     const std::string& name = val.first;

=== modified file 'libcore/asobj/flash/xml/XMLNode_as.h'
--- a/libcore/asobj/flash/xml/XMLNode_as.h      2009-11-27 12:52:50 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.h      2009-12-03 13:36:04 +0000
@@ -186,10 +186,7 @@
     virtual void toString(std::ostream& str, bool encode = false) const;
 
     /// Return the attributes object associated with this node.
-    as_object* getAttributes() { return _attributes; }
-
-    /// Return a read-only version of this node's attributes object.
-    const as_object* getAttributes() const { return _attributes; }
+    as_object* getAttributes() const { return _attributes; }
 
     /// Set a named attribute to a value.
     //

=== modified file 'libcore/asobj/int_as.cpp'
--- a/libcore/asobj/int_as.cpp  2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/int_as.cpp  2009-12-04 09:20:14 +0000
@@ -68,8 +68,7 @@
     as_object* cl = gl.createClass(&int_ctor, proto);
 
        // Register _global.DisplayObject
-       global.init_member(getName(uri), cl, as_object::DefaultFlags,
-            getNamespace(uri));
+       global.init_member(uri, cl, as_object::DefaultFlags);
 }
 
 }

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-11-30 15:59:02 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-12-04 09:20:14 +0000
@@ -2692,7 +2692,7 @@
 enumerateObject(as_environment& env, const as_object& obj)
 {
     assert(env.top(0).is_undefined());
-    obj.enumerateProperties(env);
+    obj.enumeratePropertyKeys(env);
 }
 
 void
@@ -3440,7 +3440,6 @@
                         "starts at PC %d"), name, func->getStartPC());
         );
 
-        //env.set_member(name, function_value);
         thread.setVariable(name, function_value);
     }
 
@@ -3458,12 +3457,8 @@
     //          thing into the intrusive_ptr, so the debugger
     //          will be left with a deleted object !!
     //          Rob: we don't want to use void pointers here..
-    boost::intrusive_ptr<as_object> o = convertToObject(getGlobal(thread.env), 
function_value);
-#ifndef GNASH_USE_GC
-    o->add_ref(); // this will leak, but at least debugger won't end up
-                  // with a dangling reference...
-#endif //ndef GNASH_USE_GC
-        debugger.addSymbol(o.get(), name);
+    as_object* o = convertToObject(getGlobal(thread.env), function_value);
+    debugger.addSymbol(o.get(), name);
 #endif
 }
 
@@ -3649,7 +3644,6 @@
                         "PC %d", name, func->getStartPC());
         );
 
-        //env.set_member(name, function_value);
         thread.setVariable(name, function_value);
 #ifdef USE_DEBUGGER
         // WARNING: convertToObject(getGlobal(thread.env), new_obj) can return 
a newly allocated

=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp    2009-12-02 16:47:14 +0000
+++ b/libcore/vm/Machine.cpp    2009-12-04 12:34:34 +0000
@@ -252,6 +252,12 @@
 inline bool abstractEquality(const as_value& a, const as_value& b,
        bool strictness_on)
 {
+    // TODO: this is a very quick hack to fix some tests without touching
+    // as_value. Tamarin has a detailed algorithm for working out equality,
+    // which can be implemented as a separate member function of as_value.
+    if (a.is_object() && !b.is_object()) {
+        return a.to_string() == b.to_string();
+    }
     if ( strictness_on ) return a.strictly_equals(b);
     else return a.equals(b);
 }                                                              
@@ -1621,19 +1627,21 @@
                     
                     break;
                 }
-            /// 0x55 ABC_ACTION_NEWOBJECT
-            /// Stream: V32 'arg_count'
-            /// Stack In:
-            ///  prop_value_1 -- a value object
-            ///  prop_name_1 -- a string
-            ///  .
-            ///  . (arg_count value/name pairs in all)
-            ///  .
-            ///  prop_value_n -- a value object
-            ///  prop_name_n -- a string
-            /// Stack Out:
-            ///  obj -- A new object which contains all of the given 
properties.
-            /// NB: This builds an object from its properties, it's not a 
constructor.
+                /// 0x55 ABC_ACTION_NEWOBJECT
+                /// Stream: V32 'arg_count'
+                /// Stack In:
+                ///  prop_value_1 -- a value object
+                ///  prop_name_1 -- a string
+                ///  .
+                ///  . (arg_count value/name pairs in all)
+                ///  .
+                ///  prop_value_n -- a value object
+                ///  prop_name_n -- a string
+                /// Stack Out:
+                ///  obj -- A new object which contains all of the given
+                ///  properties.
+                /// NB: This builds an object from its properties, it's not
+                ///  a constructor.
                 case SWF::ABC_ACTION_NEWOBJECT:
                 {
                     as_object *obj = _global->createObject();
@@ -1885,7 +1893,7 @@
                         break;
                     }
 
-                    object->set_member(name, value, ns, false);
+                    object->set_member(ObjectURI(name, ns), value, false);
                     break;
                 }
 
@@ -2988,7 +2996,7 @@
        return size;
 }
 
-Class *
+Class*
 Machine::findSuper(as_value &v, bool find_for_primitive)
 {
        if (v.is_undefined() || v.is_null()) return NULL;

=== modified file 'libcore/vm/Machine.h'
--- a/libcore/vm/Machine.h      2009-12-02 16:47:14 +0000
+++ b/libcore/vm/Machine.h      2009-12-04 09:44:49 +0000
@@ -142,8 +142,7 @@
        /// This returns the value, but on the stack.
        /// (Since the return value is not known until after control has left
        /// the caller of this, it's impossible to return a meaningful value.
-       void getMember(Class* pDefinition, MultiName& name,
-            as_value& source);
+       void getMember(Class* pDefinition, MultiName& name, as_value& source);
 
        /// Set a member in an object.
        ///

=== modified file 'testsuite/as3compile.all/Object.as'
--- a/testsuite/as3compile.all/Object.as        2009-11-25 16:52:44 +0000
+++ b/testsuite/as3compile.all/Object.as        2009-12-04 11:18:59 +0000
@@ -39,7 +39,7 @@
         public function Main() {
 
             xcheck_equals(Object, "[class Object]");
-            xcheck_equals(Object.prototype, "[object Object]");
+            check_equals(Object.prototype, "[object Object]");
             xcheck_equals(Object.constructor, "[class Class]");
             
             xcheck_equals(typeof(Object), "object");
@@ -61,7 +61,7 @@
             check(Object.prototype.isPrototypeOf(this));
 
             var a = new Object();
-            xcheck_equals(a, "[object Object]");       
+            check_equals(a, "[object Object]");       
             check(!a.hasOwnProperty("constructor"));
             check(!a.hasOwnProperty("hasOwnProperty"));
             check(!a.hasOwnProperty("isPrototypeOf"));

=== modified file 'testsuite/as3compile.all/QName.as'
--- a/testsuite/as3compile.all/QName.as 2009-07-02 11:43:06 +0000
+++ b/testsuite/as3compile.all/QName.as 2009-12-04 11:18:59 +0000
@@ -32,12 +32,12 @@
             
             xcheck_equals(QName.prototype, "");    
             xcheck_equals(QName.constructor, "[class Class]");    
-            xcheck_equals(QName.constructor.prototype, "[object Object]");    
+            check_equals(QName.constructor.prototype, "[object Object]");    
 
             var q = new QName();
             xcheck_equals(q.constructor, "[class QName]");    
             xcheck_equals(q.constructor.constructor, "[class Class]");    
-            xcheck_equals(q.constructor.constructor.prototype,
+            check_equals(q.constructor.constructor.prototype,
                                 "[object Object]");    
             
             check(q.hasOwnProperty("uri"));

=== modified file 'testsuite/as3compile.all/Sprite.as'
--- a/testsuite/as3compile.all/Sprite.as        2009-06-18 11:20:51 +0000
+++ b/testsuite/as3compile.all/Sprite.as        2009-12-04 11:18:59 +0000
@@ -28,7 +28,7 @@
 
         public function Main() {
 
-            xcheck_equals(Sprite.prototype, "[object Object]");
+            check_equals(Sprite.prototype, "[object Object]");
             xcheck_equals(Sprite.constructor, "[class Class]");
             
             // The prototype seems really to be just an object. Just

=== modified file 'testsuite/as3compile.all/class.as'
--- a/testsuite/as3compile.all/class.as 2009-11-20 12:37:59 +0000
+++ b/testsuite/as3compile.all/class.as 2009-12-04 11:18:59 +0000
@@ -55,7 +55,7 @@
             xcheck_equals(this.constructor.constructor, "[class Class]");
             xcheck_equals(this.parent, "[object Stage]");
 
-            xcheck_equals(S, "[class S]");
+            check_equals(S, "[class S]");
             xcheck_equals(S.constructor, "[class Class]");
             check_equals(S.__constructor__, undefined);
             
@@ -67,10 +67,10 @@
 
             trace(Base);
 
-            xcheck_equals(Base, "[class Base]");
-            xcheck_equals(Base.prototype, "[object Object]");
-            xcheck_equals(Derived, "[class Derived]");
-            xcheck_equals(Base.prototype, "[object Object]");
+            check_equals(Base, "[class Base]");
+            check_equals(Base.prototype, "[object Object]");
+            check_equals(Derived, "[class Derived]");
+            check_equals(Base.prototype, "[object Object]");
 
             xcheck_equals(Derived.constructor, "[class Class]");
             xcheck_equals(Base.constructor, "[class Class]");

=== modified file 'testsuite/as3compile.all/function.as'
--- a/testsuite/as3compile.all/function.as      2009-06-25 08:28:00 +0000
+++ b/testsuite/as3compile.all/function.as      2009-12-04 11:18:59 +0000
@@ -62,7 +62,7 @@
         check_equals(typeof(A.bb()), "number");
         check_equals(A.cc(), 2.45);
         check_equals(typeof(A.cc()), "number");
-        xcheck_equals(A.dd(), "[object Object]");
+        check_equals(A.dd(), "[object Object]");
         check_equals(typeof(A.dd()), "object");
         check_equals(A.ee("f"), "f");
         check_equals(typeof(A.ee("f")), typeof("f"));
@@ -81,7 +81,7 @@
         check_equals(typeof(a.b()), "number");
         check_equals(a.c(), 5.65);
         check_equals(typeof(a.c()), "number");
-        xcheck_equals(a.d(), "[object Object]");
+        check_equals(a.d(), "[object Object]");
         check_equals(typeof(a.d()), "object");
         check_equals(a.e("f"), "f");
         check_equals(typeof(a.e("f")), typeof("f"));

=== modified file 'testsuite/libcore.all/PropertyListTest.cpp'
--- a/testsuite/libcore.all/PropertyListTest.cpp        2009-12-01 16:03:50 
+0000
+++ b/testsuite/libcore.all/PropertyListTest.cpp        2009-12-03 13:36:04 
+0000
@@ -87,7 +87,7 @@
        log_debug("VM version %d", vm.getSWFVersion());
 
        as_object obj;
-       PropertyList props(vm);
+       PropertyList props(obj);
 
        as_value val("value");
        as_value val2("value2");
@@ -99,7 +99,7 @@
        if (vm.getSWFVersion() > 6) // SWF 7 or higher is case sensitive.
        {
                check_equals(props.size(), 0);
-               check ( props.setValue(st.find("Var0"), val, obj) );
+               check ( props.setValue(st.find("Var0"), val) );
                check_equals(props.size(), 1);
 
                check (getVal(props, st.find("Var0"), ret, obj) );
@@ -109,22 +109,22 @@
                check (!getVal(props, st.find("var0"), ret, obj) );
 
                // new value overrides existing value
-               check ( props.setValue(st.find("Var0"), val2, obj) );
+               check ( props.setValue(st.find("Var0"), val2) );
                check_equals(props.size(), 1);
                check (getVal(props, st.find("Var0"), ret, obj) );
                check_strictly_equals ( ret, val2 );
 
                // case-sensitive setting value doesn't overrides existing value
-               check ( props.setValue(st.find("var0"), val3, obj) );
+               check ( props.setValue(st.find("var0"), val3) );
                check_equals(props.size(), 2);
                check (!getVal(props, st.find("vAr0"), ret, obj) );
 
                // Now add some new labels
-               check ( props.setValue(st.find("var1"), val, obj) );
+               check ( props.setValue(st.find("var1"), val) );
                check_equals(props.size(), 3);
-               check ( props.setValue(st.find("var2"), val, obj) );
+               check ( props.setValue(st.find("var2"), val) );
                check_equals(props.size(), 4);
-               check ( props.setValue(st.find("var3"), val, obj) );
+               check ( props.setValue(st.find("var3"), val) );
                check_equals(props.size(), 5);
 
                // Test deletion of properties
@@ -145,16 +145,6 @@
                check_equals(delpair.second, false); // property was NOT deleted
                check_equals(props.size(), 4);
 
-        PropertyList::SortedPropertyList vals;
-               props.enumerateKeyValue(obj, vals);
-               check_equals( vals.size(), 4 );
-               check_equals( vals[0].first, "var0");
-               check_equals( vals[0].second, "value3");
-               check_equals( vals[1].first, "Var0");
-               check_equals( vals[1].second, "value2");
-               check_equals( vals[2].first, "var1");
-               check_equals( vals[2].second, "value");
-
        }
        else
        {
@@ -162,7 +152,7 @@
                // Below SWF or is not case sensitive.
 
                check_equals(props.size(), 0);
-               check ( props.setValue(st.find("Var0"), val, obj) );
+               check ( props.setValue(st.find("Var0"), val) );
                check_equals(props.size(), 1);
 
                check (getVal(props, st.find("Var0"), ret, obj) );
@@ -173,23 +163,23 @@
                check_strictly_equals ( ret, val );
 
                // new value overrides existing value
-               check ( props.setValue(st.find("Var0"), val2, obj) );
+               check ( props.setValue(st.find("Var0"), val2) );
                check_equals(props.size(), 1);
                check (getVal(props, st.find("Var0"), ret, obj) );
                check_strictly_equals ( ret, val2 );
 
                // case-insensitive setting value should override existing value
-               check ( props.setValue(st.find("var0"), val3, obj) );
+               check ( props.setValue(st.find("var0"), val3) );
                check_equals(props.size(), 1);
                check (getVal(props, st.find("vAr0"), ret, obj) );
                check_strictly_equals ( ret, val3 );
 
                // Now add some new labels
-               check ( props.setValue(st.find("var1"), val, obj) );
+               check ( props.setValue(st.find("var1"), val) );
                check_equals(props.size(), 2);
-               check ( props.setValue(st.find("var2"), val, obj) );
+               check ( props.setValue(st.find("var2"), val) );
                check_equals(props.size(), 3);
-               check ( props.setValue(st.find("var3"), val, obj) );
+               check ( props.setValue(st.find("var3"), val) );
                check_equals(props.size(), 4);
 
                // Test deletion of properties
@@ -210,16 +200,6 @@
                check_equals(delpair.second, false); // property was NOT deleted
                check_equals(props.size(), 3);
 
-        PropertyList::SortedPropertyList vals;
-               props.enumerateKeyValue(obj, vals);
-               check_equals( vals.size(), 3 );
-               check_equals( vals[0].first, "var2");
-               check_equals( vals[0].second, "value");
-               check_equals( vals[1].first, "var1");
-               check_equals( vals[1].second, "value");
-               check_equals( vals[2].first, "Var0");
-               check_equals( vals[2].second, "value3");
-
        }
 }
 


reply via email to

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