gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r12282: Fix the long-standing proper


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r12282: Fix the long-standing property case problem. The string_table is always
Date: Fri, 09 Jul 2010 08:22:44 +0200
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 12282 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2010-07-09 08:22:44 +0200
message:
  Fix the long-standing property case problem. The string_table is always
  case-sensitive. Properties are looked up differently according to version.
  
  Tests pass in swfdec and actionscript.all.
  
  Drop core code that misused AVM1 facilities, including the PropertyList,
  to try and implement AVM2. Disable AVM2 by default.
  
  Gnash will currently fail to compile when AVM2 is enabled. This may be fixed
  in later commits.
modified:
  configure.ac
  libbase/GnashAlgorithm.h
  libbase/string_table.cpp
  libbase/string_table.h
  libcore/Button.cpp
  libcore/DisplayList.cpp
  libcore/DisplayList.h
  libcore/DisplayObject.cpp
  libcore/DisplayObject.h
  libcore/MovieClip.cpp
  libcore/Property.cpp
  libcore/Property.h
  libcore/PropertyList.cpp
  libcore/PropertyList.h
  libcore/as_object.cpp
  libcore/as_object.h
  libcore/asobj/Globals.cpp
  libcore/asobj/Globals.h
  libcore/asobj/flash/display/MovieClip_as.cpp
  libcore/asobj/flash/text/TextField_as.cpp
  libcore/movie_root.cpp
  libcore/namedStrings.cpp
  libcore/namedStrings.h
  libcore/vm/ASHandlers.cpp
  libcore/vm/ActionExec.cpp
  libcore/vm/ActionExec.h
  libcore/vm/VM.cpp
  testsuite/MovieTester.cpp
  testsuite/actionscript.all/case.as
  testsuite/libbase.all/string_tableTest.cpp
  testsuite/libcore.all/PropertyListTest.cpp
  testsuite/swfdec/PASSING
=== modified file 'configure.ac'
--- a/configure.ac      2010-06-22 18:14:10 +0000
+++ b/configure.ac      2010-07-03 10:06:04 +0000
@@ -277,7 +277,7 @@
     yes) avm2=yes ;;
     no)  avm2=no ;;
     *)   AC_MSG_ERROR([bad value ${enableval} for enable-avm2 option]) ;;
-  esac], avm2=yes
+  esac], avm2=no
 )
 AM_CONDITIONAL(ENABLE_AVM2, [test x"$avm2" = xyes])
 if test x$avm2 = xyes; then

=== modified file 'libbase/GnashAlgorithm.h'
--- a/libbase/GnashAlgorithm.h  2010-03-11 01:47:08 +0000
+++ b/libbase/GnashAlgorithm.h  2010-07-05 10:05:40 +0000
@@ -39,6 +39,17 @@
     }
 };
 
+/// Retrieve the first element of a container with std::pairs.
+template<typename T>
+struct FirstElement
+{
+    typedef typename T::first_type result_type;
+
+    const result_type& operator()(const T& pair) const {
+        return pair.first;
+    }
+};
+
 /// Return a pointer to a type
 template<typename T>
 struct CreatePointer
@@ -150,6 +161,22 @@
     std::for_each(begin, end, boost::bind(op, boost::bind(S(), _1)));
 }
 
+/// Call a functor on the first element of each element in a range.
+//
+/// @tparam T           An iterator type satisfying the requirements of a
+///                     forward iterator
+/// @tparam U           The type of the functor op.
+/// @param begin        The start of the range to call op on.
+/// @param end          The end of the range to call op on.
+/// @param op           The function to call on each second element.
+template<typename T, typename U>
+void
+foreachFirst(T begin, T end, U op)
+{
+    typedef FirstElement<typename std::iterator_traits<T>::value_type> S;
+    std::for_each(begin, end, boost::bind(op, boost::bind(S(), _1)));
+}
+
 /// Safely call delete on each element in a range.
 //
 /// This checks that the type is fully known, but cannot check whether the

=== modified file 'libbase/string_table.cpp'
--- a/libbase/string_table.cpp  2010-01-25 18:52:20 +0000
+++ b/libbase/string_table.cpp  2010-07-05 12:29:23 +0000
@@ -20,103 +20,106 @@
 #include "string_table.h"
 #include <boost/algorithm/string/case_conv.hpp>
 
-using namespace gnash;
+namespace gnash {
 
-const std::string string_table::mEmpty;
+const std::string string_table::_empty;
 
 string_table::key
 string_table::find(const std::string& t_f, bool insert_unfound)
 {
-       std::string t_fcase;
-       const std::string *to_find = NULL;
-
-       if (mCaseInsensitive)
-       {
-               t_fcase = t_f;
-               boost::to_lower(t_fcase);
-               to_find = &t_fcase;
-       }
-       else
-               to_find = &t_f;
-               
-       // Empty strings all map to 0
-       if (to_find->empty()) return 0;
-
-       table::nth_index<0>::type::iterator i = mTable.get<0>().find(*to_find);
-
-       if (i == mTable.end())
-       {
-               if (insert_unfound)
-               {
-                       svt theSvt;
-
+    if (t_f.empty()) return 0;
+
+       table::index<StringValue>::type::iterator i = 
+        _table.get<StringValue>().find(t_f);
+
+       if (i == _table.get<StringValue>().end()) {
+
+               if (insert_unfound) {
                        // First we lock.
-                       boost::mutex::scoped_lock aLock(mLock);
+                       boost::mutex::scoped_lock aLock(_lock);
                        // Then we see if someone else managed to sneak past us.
-                       i = mTable.get<0>().find(*to_find);
+                       i = _table.get<StringValue>().find(t_f);
                        // If they did, use that value.
-                       if (i != mTable.end())
-                               return i->mId;
+                       if (i != _table.end()) return i->id;
 
-                       // Otherwise, insert it.
-                       theSvt.mValue = t_f;
-                       theSvt.mComp = *to_find;
-                       theSvt.mId = ++mHighestKey;
-                       mTable.insert(theSvt);
-                       return theSvt.mId;
+            return already_locked_insert(t_f);
                }
-               else
-                       return 0;
+        return 0;
        }
 
-       return i->mId;
-}
-
-string_table::key
-string_table::find_dot_pair(string_table::key left, string_table::key right, 
-       bool insert_unfound)
-{
-       if (!right)
-               return left;
-
-       std::string isit = value(left) + "." + value(right);
-       return find(isit, insert_unfound);
+       return i->id;
 }
 
 string_table::key
 string_table::insert(const std::string& to_insert)
 {
-       boost::mutex::scoped_lock aLock(mLock);
-       svt theSvt(to_insert, ++mHighestKey);
-
-       return mTable.insert(theSvt).first->mId;
+       boost::mutex::scoped_lock aLock(_lock);
+    return already_locked_insert(to_insert);
 }
 
 void
 string_table::insert_group(const svt* l, std::size_t size)
 {
-       boost::mutex::scoped_lock aLock(mLock);
-
-       for (std::size_t i = 0; i < size; ++i)
-       {
+       boost::mutex::scoped_lock aLock(_lock);
+    for (std::size_t i = 0; i < size; ++i) {
         // Copy to avoid changing the original table.
-        svt s = l[i];
-        if (mCaseInsensitive) boost::to_lower(s.mComp);
+        const svt s = l[i];
 
-               // The keys don't have to be consecutive, so any time we find a 
key
-               // that is too big, jump a few keys to avoid rewriting this on 
every
+        // The keys don't have to be consecutive, so any time we find a key
+        // that is too big, jump a few keys to avoid rewriting this on every
         // item.
-               if (s.mId > mHighestKey) mHighestKey = s.mId + 256;
-               mTable.insert(s);
-       }
-}
-
-string_table::key
-string_table::already_locked_insert(const std::string& to_insert, 
boost::mutex&)
-{
-       svt theSvt (to_insert, ++mHighestKey);
-       if (mCaseInsensitive)
-               boost::to_lower(theSvt.mComp);
-       return mTable.insert(theSvt).first->mId;
-}
-
+       if (s.id > _highestKey) _highestKey = s.id + 256;
+       _table.insert(s);
+    }
+    
+    for (std::size_t i = 0; i < size; ++i) {
+        const svt s = l[i];
+        const std::string& t = boost::to_lower_copy(s.value);
+        if (t != s.value) {
+            _caseTable[s.id] = already_locked_insert(t);
+        }
+    }
+
+}
+
+string_table::key
+string_table::already_locked_insert(const std::string& to_insert)
+{
+       const key ret = _table.insert(svt(to_insert, ++_highestKey)).first->id;
+
+    const std::string lower = boost::to_lower_copy(to_insert);
+
+    // Insert the caseless equivalent if it's not there. We're locked for
+    // the whole of this function, so we can do what we like.
+    if (lower != to_insert) {
+
+        // Find the caseless value in the table
+        table::index<StringValue>::type::iterator it = 
+            _table.get<StringValue>().find(lower);
+
+        const key nocase = (it == _table.end()) ? 
+            _table.insert(svt(lower, ++_highestKey)).first->id : it->id;
+
+        _caseTable[ret] = nocase;
+
+    }
+
+    return ret;
+}
+
+string_table::key
+string_table::noCase(key a) const
+{
+    std::map<key, key>::const_iterator i = _caseTable.find(a);
+    return i == _caseTable.end() ? a : i->second;
+}
+
+bool
+equal(string_table& st, string_table::key a, string_table::key b,
+        bool caseless)
+{
+    if (a == b) return true;
+    return caseless && (st.noCase(a) == st.noCase(b));
+}
+          
+}

=== modified file 'libbase/string_table.h'
--- a/libbase/string_table.h    2010-03-11 01:47:08 +0000
+++ b/libbase/string_table.h    2010-07-05 07:14:31 +0000
@@ -32,10 +32,7 @@
 #include <string>
 #include "dsodefs.h"
 
-namespace gnash
-{
-
-class string_table;
+namespace gnash {
 
 // So many strings are duplicated (such as standard property names)
 // that a string table could give significant memory savings.
@@ -43,119 +40,131 @@
 class DSOEXPORT string_table
 {
 public:
+
        /// A little helper for indexing.
        struct svt
        {
-               std::string mValue;
-               std::size_t mId;
-               std::string mComp;
-
-               svt() : mValue(""), mId(0), mComp("") {/**/}
-
-               svt(const std::string &val, std::size_t id) :
-                       mValue(val), mId(id), mComp(val) {/**/}
+               svt(const std::string& val, std::size_t i)
+            :
+                       value(val),
+            id(i)
+        {}
+
+               std::string value;
+               std::size_t id;
        };
-
-public:
+    
+    /// A tag to identify the key index.   
+    struct StringID {};
+
+    /// A tag to identify the string index.
+    struct StringValue {};
+
+    /// The container for indexing the strings
+    //
+    /// This contains two indices with no duplicate values:
+    /// 1. An index of unique, case-sensitive strings.
+    /// 2. An index of unique numeric keys.
        typedef boost::multi_index_container<svt,
                boost::multi_index::indexed_by<
-                       boost::multi_index::hashed_non_unique<
-                               boost::multi_index::member<svt, std::string, 
&svt::mComp> >,
-                       boost::multi_index::hashed_non_unique< // caseless
-                               boost::multi_index::member<svt, std::size_t, 
&svt::mId> > 
+
+                       boost::multi_index::hashed_unique<
+                boost::multi_index::tag<StringValue>,
+                               boost::multi_index::member<svt, std::string, 
&svt::value> >,
+
+                       boost::multi_index::hashed_unique<
+                boost::multi_index::tag<StringID>,
+                               boost::multi_index::member<svt, std::size_t, 
&svt::id>
+
+        > 
        > > table;
 
        typedef std::size_t key;
 
-       /// \brief
-       /// Find a string. If insert_unfound is true, the string will
-       /// be inserted if the value is not found in the table already.
-       /// @param to_find
-       /// The string to be found. Case-sensitive comparison using < operator
-       ///
-       /// @param insert_unfound
-       /// If this is set to false, a search is performed, but no update.
-       /// By update, any unfound string is added to the table.
-       ///
-       /// @return
-       /// A key which can be used in value or 0 if the string is
-       /// not yet in the table and insert_unfound was false.
+       /// Find a key for a string.
+    //
+    /// By default a key will be created for a string that isn't present.
+    //
+       /// @param to_find          The string to be found. 
+       /// @param insert_unfound   If this is set to false, a search is
+    ///                         performed, but no update.
+       /// @return                 A key which can be used in value or 0 if the
+    ///                         string is not yet in the table and
+    ///                         insert_unfound was false.
        key find(const std::string& to_find, bool insert_unfound = true);
 
-       /// \brief
-       /// Find a string which is the concatentation of two known strings
-       /// with a dot between them. (Used for namespaces.)
-       /// Otherwise, just like find.
-       key find_dot_pair(key left, key right, bool insert_unfound = true);
-
        /// Find a string by its key.
-       ///
-       /// @return
-       /// The string which matches key or "" if an invalid key is given.
+       //
+    /// @param key  The key of the string to return. 
+       /// @return     The string which matches key or "" if an invalid key is
+    ///             given.
        const std::string& value(key to_find)
        {
-               if (mTable.empty() || !to_find)
-                       return mEmpty;
-               table::nth_index<1>::type::iterator r = 
-                       mTable.get<1>().find(to_find);
-               return (r == mTable.get<1>().end()) ? mEmpty : r->mValue;
+               if (_table.empty() || !to_find) return _empty;
+
+               table::index<StringID>::type::iterator r =
+            _table.get<StringID>().find(to_find);
+               return (r == _table.get<StringID>().end()) ? _empty : r->value;
        }
 
-       /// \brief
-       /// Force insert a string with auto-assigned id. Does not prevent
-       /// duplicate insertions.
-       ///
+       /// Insert a string with auto-assigned id. 
+       //
        /// @return The assigned key
        key insert(const std::string& to_insert);
 
        /// Insert a group of strings with their ids preset.
     //
-    /// This allows
-       /// for switches and enums and such, but be careful you don't set two
-       /// strings with the same id, as this does not check for such 
occurrences.
-       ///
-       /// @param pList
-       /// An array of svt objects, these should be fully constructed, 
including
-       /// their ids.
-    ///
-       /// @param size
-    /// Number of elements in the svt objects array
-    ///
+       /// @param pList    An array of svt objects, these should be fully
+    ///                 constructed, including their ids. If any id is
+    ///                 duplicated, the insertion will fail.
+       /// @param size      Number of elements in the svt objects array
        void insert_group(const svt* pList, std::size_t size);
 
        /// Insert a string when you will handle the locking yourself.
     //
-       /// @param to_insert
-    /// String to insert
-    ///
-       /// @param lock
-       /// Use lock_mutex to obtain the correct mutex to use for this -- using
-       /// a different mutex will not be thread safe.
-       ///
-       /// @return The assigned key
-       key already_locked_insert(const std::string& to_insert, boost::mutex& 
lock);
-
-       /// @return A mutex which can be used to lock the string table to 
inserts.
-       boost::mutex& lock_mutex() { return mLock; }
-
-       /// Make the comparisons case-insensitive.
-       void set_insensitive() { mCaseInsensitive = true; }
+       /// @param to_insert    The string to insert
+       /// @return             The assigned key
+       key already_locked_insert(const std::string& to_insert);
 
        /// Construct the empty string_table
-       string_table() :
-               mTable(),
-               mLock(),
-               mHighestKey(0),
-               mCaseInsensitive(false)
-       {/**/}
+       string_table()
+        :
+               _highestKey(0)
+       {}
+
+    /// Return a caseless equivalent of the passed key.
+    //
+    /// @param a    The key to find a caseless equivalent for. The key
+    ///             may be its own caseless equivalent, in which case the
+    ///             same key will be returned.
+    key noCase(key a) const;
 
 private:
-       table mTable;
-       static const std::string mEmpty; // The empty string, universally.
-       boost::mutex mLock;
-       std::size_t mHighestKey;
-       bool mCaseInsensitive;
+
+       table _table;
+       static const std::string _empty;
+       boost::mutex _lock;
+       std::size_t _highestKey;
+
+    std::map<key, key> _caseTable;
 };
 
-} /* namespace gnash */
-#endif /* GNASH_STRING_TABLE_H */
+/// Check whether two keys are equivalent
+//
+/// This function provides a simple way to check for equivalence either in
+/// a case sensitive or case-insensitive way. It is mainly for convenience, to
+/// reduce conditionals in the code.
+//
+/// If the comparison is case-sensitive, the keys are equivalent if they are
+/// equal.
+//
+/// @param st       The string table to use
+/// @param a        One key to check
+/// @param b        The other key to check
+/// @param caseless Whether to compare in a case-insensitive way.
+/// @return         True if the keys are equivalent.
+bool equal(string_table& st, string_table::key a, string_table::key b,
+        bool caseless);
+
+}
+#endif 

=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp        2010-06-22 06:03:32 +0000
+++ b/libcore/Button.cpp        2010-07-05 08:32:15 +0000
@@ -226,16 +226,16 @@
 namespace {
     void addInstanceProperty(Button& b, DisplayObject* d) {
         if (!d) return;
-        const std::string& name = d->get_name();
-        if (name.empty()) return;
+        const string_table::key name = d->get_name();
+        if (!name) return;
         getObject(&b)->init_member(name, getObject(d), 0);
     }
 
     void removeInstanceProperty(Button& b, DisplayObject* d) {
         if (!d) return;
-        const std::string& name = d->get_name();
-        if (name.empty()) return;
-        getObject(&b)->delProperty(getStringTable(*getObject(&b)).find(name));
+        const string_table::key name = d->get_name();
+        if (!name) return;
+        getObject(&b)->delProperty(name);
     }
 }
 

=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp   2010-06-25 17:51:25 +0000
+++ b/libcore/DisplayList.cpp   2010-07-05 08:32:15 +0000
@@ -106,43 +106,34 @@
 class NameEquals
 {
 public:
-    NameEquals(const std::string& name) : _name(name) {}
-
-    bool operator() (const DisplayObject* item) {
-        assert (item);
-        // TODO: this is necessary because destroy() is called in
-        // movie_root, leaving destroyed items on the DisplayList. They
-        // shouldn't be found. A better fix would be to stop destroying
-        // objects there and add to the invariant that there are never
-        // destroyed DisplayObjects in the DisplayList.
-        if (item->isDestroyed()) return false;
-        return item->get_name() == _name;
-    }
-
-private:
-    const std::string& _name;
-};
-
-
-class NameEqualsNoCase
-{
-public:
-    NameEqualsNoCase(const std::string& name) : _name(name) {}
-
-    bool operator() (const DisplayObject* item) {
-        assert (item);
-        // TODO: this is necessary because destroy() is called in
-        // movie_root, leaving destroyed items on the DisplayList. They
-        // shouldn't be found. A better fix would be to stop destroying
-        // objects there and add to the invariant that there are never
-        // destroyed DisplayObjects in the DisplayList.
-        if (item->isDestroyed()) return false;
-        return _noCaseEquals(item->get_name(), _name);
-    }
-
-private:
-    const std::string& _name;
-    StringNoCaseEqual _noCaseEquals;
+    NameEquals(string_table& st, string_table::key name, bool caseless)
+        :
+        _st(st),
+        _caseless(caseless),
+        _name(caseless ? _st.noCase(name) : name)
+    {}
+
+    bool operator() (const DisplayObject* item) {
+        assert (item);
+
+        // TODO: this is necessary because destroy() is called in
+        // movie_root, leaving destroyed items on the DisplayList. They
+        // shouldn't be found. A better fix would be to stop destroying
+        // objects there and add to the invariant that there are never
+        // destroyed DisplayObjects in the DisplayList.
+        if (item->isDestroyed()) return false;
+        
+        const string_table::key itname =
+            _caseless ? _st.noCase(item->get_name()) : item->get_name();
+
+        return itname == _name;
+
+    }
+
+private:
+    string_table& _st;
+    const bool _caseless;
+    const string_table::key _name;
 };
 
 } // anonymous namespace
@@ -167,11 +158,11 @@
 }
 
 DisplayObject*
-DisplayList::getDisplayObjectAtDepth(int depth)
+DisplayList::getDisplayObjectAtDepth(int depth) const
 {
     testInvariant();
 
-    for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end();
+    for (const_iterator it = _charsByDepth.begin(), itEnd = 
_charsByDepth.end();
         it != itEnd; ++it) {
 
         DisplayObject* ch = *it;
@@ -192,14 +183,15 @@
 
 
 DisplayObject*
-DisplayList::getDisplayObjectByName(const std::string& name)
+DisplayList::getDisplayObjectByName(string_table& st, string_table::key name,
+        bool caseless) const
 {
     testInvariant();
 
-    const container_type::iterator e = _charsByDepth.end();
+    const container_type::const_iterator e = _charsByDepth.end();
 
     container_type::const_iterator it =
-        std::find_if( _charsByDepth.begin(), e, NameEquals(name));
+        std::find_if(_charsByDepth.begin(), e, NameEquals(st, name, caseless));
 
     if (it == e) return 0;
     
@@ -207,21 +199,6 @@
 
 }
 
-DisplayObject*
-DisplayList::getDisplayObjectByName_i(const std::string& name)
-{
-    testInvariant();
-
-    const container_type::iterator e = _charsByDepth.end();
-
-    container_type::const_iterator it =
-        std::find_if( _charsByDepth.begin(), e, NameEqualsNoCase(name));
-
-    if ( it == e ) return NULL;
-    
-    return *it;
-}
-
 void
 DisplayList::placeDisplayObject(DisplayObject* ch, int depth)
 {

=== modified file 'libcore/DisplayList.h'
--- a/libcore/DisplayList.h     2010-06-25 17:51:25 +0000
+++ b/libcore/DisplayList.h     2010-07-05 08:32:15 +0000
@@ -244,25 +244,11 @@
        void omit_display();
 
        /// May return NULL.
-       DisplayObject* getDisplayObjectAtDepth(int depth);
-
-       const DisplayObject* getDisplayObjectAtDepth(int depth) const {
-               return 
const_cast<DisplayList*>(this)->getDisplayObjectAtDepth(depth);
-       }
-
-       /// \brief
-       /// May return NULL.
-       /// If there are multiples, returns the *first* match only!
-       DisplayObject* getDisplayObjectByName(const std::string& name);
-
-       const DisplayObject* getDisplayObjectByName(const std::string& name) 
const {
-               return 
const_cast<DisplayList*>(this)->getDisplayObjectByName(name);
-       }
-
-       /// \brief
-       /// May return NULL.
-       /// If there are multiples, returns the *first* match only!
-       DisplayObject* getDisplayObjectByName_i(const std::string& name);
+       DisplayObject* getDisplayObjectAtDepth(int depth) const;
+
+       /// If there are multiples, returns the *first* match only!
+       DisplayObject* getDisplayObjectByName(string_table& st,
+            string_table::key name, bool caseless) const;
 
        /// \brief 
        /// Visit each DisplayObject in the list in depth order

=== modified file 'libcore/DisplayObject.cpp'
--- a/libcore/DisplayObject.cpp 2010-06-25 18:21:57 +0000
+++ b/libcore/DisplayObject.cpp 2010-07-05 08:32:15 +0000
@@ -134,14 +134,16 @@
     UNUSED(extern_movie);
 }
 
-std::string
+string_table::key
 DisplayObject::getNextUnnamedInstanceName()
 {
     assert(_object);
     movie_root& mr = getRoot(*_object);
        std::ostringstream ss;
        ss << "instance" << mr.nextUnnamedInstance();
-       return ss.str();
+
+    string_table& st = getStringTable(*_object);
+       return st.find(ss.str());
 }
 
 
@@ -189,9 +191,14 @@
     as_object* obj = getObject(this);
     if (!obj) return 0;
 
-       string_table& st = getStringTable(*obj);
+    string_table& st = stage().getVM().getStringTable();
     if (key == st.find("..")) return getObject(get_parent());
-       if (key == st.find(".") || key == st.find("this")) return obj;
+       if (key == st.find(".")) return obj;
+    
+    // The check is case-insensitive for SWF6 and below.
+    if (equal(st, key, NSV::PROP_THIS, caseless(*obj))) {
+        return obj;
+    }
        return 0;
 }
 
@@ -502,10 +509,8 @@
 DisplayObject::queueEvent(const event_id& id, int lvl)
 {
     if (!_object) return;
-    assert(_object);
-       movie_root& root = getRoot(*_object);
        std::auto_ptr<ExecutableCode> event(new QueuedEvent(this, id));
-       root.pushAction(event, lvl);
+       stage().pushAction(event, lvl);
 }
 
 bool
@@ -611,7 +616,6 @@
 }
 
 
-/*public*/
 std::string
 DisplayObject::getTargetPath() const
 {
@@ -625,6 +629,8 @@
        // Build parents stack
        const DisplayObject* topLevel = 0;
        const DisplayObject* ch = this;
+
+    string_table& st = getStringTable(*getObject(this));
        for (;;)
        {
                const DisplayObject* parent = ch->get_parent();
@@ -635,14 +641,14 @@
                        break;
                }
 
-               path.push_back(ch->get_name());
+               path.push_back(st.value(ch->get_name()));
                ch = parent;
        } 
 
        assert(topLevel);
 
        if (path.empty()) {
-               if (&getRoot(*_object).getRootMovie() == this) return "/";
+               if (&stage().getRootMovie() == this) return "/";
                std::stringstream ss;
                ss << "_level" << _depth-DisplayObject::staticDepthOffset;
                return ss.str();
@@ -650,7 +656,7 @@
 
        // Build the target string from the parents stack
        std::string target;
-       if (topLevel != &getRoot(*_object).getRootMovie()) {
+       if (topLevel != &stage().getRootMovie()) {
                std::stringstream ss;
                ss << "_level" << 
             topLevel->get_depth() - DisplayObject::staticDepthOffset;
@@ -664,7 +670,6 @@
 }
 
 
-/*public*/
 std::string
 DisplayObject::getTarget() const
 {
@@ -678,6 +683,7 @@
 
        // Build parents stack
        const DisplayObject* ch = this;
+    string_table& st = stage().getVM().getStringTable();
        for (;;)
        {
                const DisplayObject* parent = ch->get_parent();
@@ -703,7 +709,7 @@
                        break;
                }
 
-               path.push_back(ch->get_name());
+               path.push_back(st.value(ch->get_name()));
                ch = parent;
        } 
 
@@ -947,7 +953,7 @@
     const std::string& propname = st.value(key);
 
     // Check _level0.._level9
-    movie_root& mr = getRoot(*o);
+    movie_root& mr = getRoot(*getObject(&obj));
     unsigned int levelno;
     if (isLevelTarget(getSWFVersion(*o), propname, levelno)) {
         MovieClip* mo = mr.getLevel(levelno);
@@ -967,10 +973,12 @@
         }
     }
 
+    const string_table::key noCaseKey = st.noCase(key);
+
     // These properties have normal case-sensitivity.
     // They are tested to exist for TextField, MovieClip, and Button
     // but do not belong to the inheritance chain.
-    switch (key)
+    switch (caseless(*o) ? noCaseKey : key)
     {
         default:
             break;
@@ -987,8 +995,6 @@
     }
 
     // These magic properties are case insensitive in all versions!
-    const string_table::key noCaseKey = 
st.find(boost::to_lower_copy(propname));
-
     if (doGet(noCaseKey, obj, val)) return true;
 
     // Check MovieClip such as TextField variables.
@@ -1005,9 +1011,7 @@
 {
     // These magic properties are case insensitive in all versions!
     string_table& st = getStringTable(*getObject(&obj));
-    const std::string& propname = st.value(key);
-    const string_table::key noCaseKey = 
st.find(boost::to_lower_copy(propname));
-    return doSet(noCaseKey, obj, val);
+    return doSet(st.noCase(key), obj, val);
 }
 
 namespace {
@@ -1368,7 +1372,8 @@
 as_value
 getNameProperty(DisplayObject& o)
 {
-    const std::string& name = o.get_name();
+    string_table& st = getStringTable(*getObject(&o));
+    const std::string& name = st.value(o.get_name());
     if (getSWFVersion(*getObject(&o)) < 6 && name.empty()) return as_value(); 
     return as_value(name);
 }
@@ -1376,7 +1381,8 @@
 void
 setName(DisplayObject& o, const as_value& val)
 {
-    o.set_name(val.to_string().c_str());
+    string_table& st = getStringTable(*getObject(&o));
+    o.set_name(st.find(val.to_string().c_str()));
 }
 
 void
@@ -1518,6 +1524,10 @@
 //
 /// Return true if the property is a DisplayObject property, regardless of
 /// whether it was successfully set or not.
+//
+/// @param prop     The property to search for. Note that all special
+///                 properties are lower-case, so for a caseless check
+///                 it is sufficient for prop to be caseless.
 bool
 doSet(string_table::key prop, DisplayObject& o, const as_value& val)
 {

=== modified file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h   2010-06-25 18:21:57 +0000
+++ b/libcore/DisplayObject.h   2010-07-05 08:32:15 +0000
@@ -421,12 +421,11 @@
     }
 
     /// Set DisplayObject name, initializing the original target member
-    void set_name(const std::string& name)
-    {
+    void set_name(string_table::key name) {
         _name = name;
     }
 
-    const std::string& get_name() const { return _name; }
+    string_table::key get_name() const { return _name; }
 
     /// \brief
     /// Get our concatenated SWFMatrix (all our ancestor transforms,
@@ -906,7 +905,7 @@
 #endif
     
     /// Used to assign a name to unnamed instances
-    std::string getNextUnnamedInstanceName();
+    string_table::key getNextUnnamedInstanceName();
 
     enum BlendMode
     {
@@ -990,7 +989,7 @@
     virtual bool unloadChildren() { return false; }
 
     /// Get the movie_root to which this DisplayObject belongs.
-    movie_root& stage() {
+    movie_root& stage() const {
         return _stage;
     }
 
@@ -1014,7 +1013,7 @@
     void set_event_handlers(const Events& copyfrom);
 
     /// Name of this DisplayObject (if any)
-    std::string _name;
+    string_table::key _name;
 
     DisplayObject* _parent;
 

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2010-06-29 14:41:42 +0000
+++ b/libcore/MovieClip.cpp     2010-07-05 08:38:28 +0000
@@ -559,7 +559,9 @@
             NSV::CLASS_MOVIE_CLIP);
 
     MovieClip* newmovieclip = new MovieClip(o, _def.get(), _swf, parent);
-    newmovieclip->set_name(newname);
+
+    const string_table::key nn = 
getStringTable(*getObject(this)).find(newname);
+    newmovieclip->set_name(nn);
 
     newmovieclip->setDynamic();
 
@@ -1160,10 +1162,12 @@
     Global_as& gl = getGlobal(*getObject(this));
     DisplayObject* ch = cdef->createDisplayObject(gl, this);
 
-    if (tag->hasName()) ch->set_name(tag->getName());
+    string_table& st = getStringTable(*getObject(this));
+
+    if (tag->hasName()) ch->set_name(st.find(tag->getName()));
     else if (isReferenceable(*ch))
     {
-        std::string instance_name = getNextUnnamedInstanceName();
+        const string_table::key instance_name = getNextUnnamedInstanceName();
         ch->set_name(instance_name);
     }
 
@@ -1241,14 +1245,16 @@
 
     Global_as& gl = getGlobal(*getObject(this));
     DisplayObject* ch = cdef->createDisplayObject(gl, this);
+    
 
     // TODO: check if we can drop this for REPLACE!
     // should we rename the DisplayObject when it's REPLACE tag?
-    if(tag->hasName()) {
-        ch->set_name(tag->getName());
+    if (tag->hasName()) {
+        string_table& st = getStringTable(*getObject(this));
+        ch->set_name(st.find(tag->getName()));
     }
     else if (isReferenceable(*ch)) {
-        std::string instance_name = getNextUnnamedInstanceName();
+        const string_table::key instance_name = getNextUnnamedInstanceName();
         ch->set_name(instance_name);
     }
     if (tag->hasRatio()) {
@@ -1652,14 +1658,15 @@
 MovieClip::getDisplayListObject(string_table::key key)
 {
 
-    const std::string& name = getStringTable(*getObject(this)).value(key);
+    as_object* obj = getObject(this);
+    assert(obj);
+
+    string_table& st = getStringTable(*obj);
 
     // Try items on our display list.
-    DisplayObject* ch;
-    if (getSWFVersion(*getObject(this)) >= 7 ) {
-        ch = _displayList.getDisplayObjectByName(name);
-    }
-    else ch = _displayList.getDisplayObjectByName_i(name);
+    DisplayObject* ch = _displayList.getDisplayObjectByName(st, key,
+            caseless(*obj));
+
     if (!ch) return 0;
 
     // Found object.
@@ -1888,8 +1895,8 @@
 
         // Copy own name
         // TODO: check empty != none...
-        const std::string& name = get_name();
-        if( !name.empty() ) extern_movie->set_name(name);
+        const string_table::key name = get_name();
+        if (name) extern_movie->set_name(name);
 
         // Copy own clip depth (TODO: check this)
         extern_movie->set_clip_depth(get_clip_depth());
@@ -2069,16 +2076,21 @@
         _env(env)
     {}
 
-    void operator() (DisplayObject* ch)
-    {
+    void operator() (DisplayObject* ch) {
+
+        if (!isReferenceable(*ch)) return;
+
         // Don't enumerate unloaded DisplayObjects
         if (ch->unloaded()) return;
         
-        const std::string& name = ch->get_name();
+        string_table::key name = ch->get_name();
         // Don't enumerate unnamed DisplayObjects
-        if (name.empty()) return;
+        if (!name) return;
         
-        _env.push(name);
+        // Referenceable DisplayObject always have an object.
+        assert(getObject(ch));
+        string_table& st = getStringTable(*getObject(ch));
+        _env.push(st.value(name));
     }
 };
 

=== modified file 'libcore/Property.cpp'
--- a/libcore/Property.cpp      2010-01-11 06:41:38 +0000
+++ b/libcore/Property.cpp      2010-07-05 15:43:51 +0000
@@ -81,7 +81,7 @@
 }
 
 void
-Property::setDelayedValue(as_object& this_ptr, const as_value& value)
+Property::setDelayedValue(as_object& this_ptr, const as_value& value) const
 {
        GetterSetter* a = boost::get<GetterSetter>(&_bound);
 
@@ -173,7 +173,7 @@
 }
 
 void
-Property::setValue(as_object& this_ptr, const as_value &value)
+Property::setValue(as_object& this_ptr, const as_value &value) const
 {
        switch (_bound.which())
        {

=== modified file 'libcore/Property.h'
--- a/libcore/Property.h        2010-03-11 17:03:04 +0000
+++ b/libcore/Property.h        2010-07-05 15:43:51 +0000
@@ -249,6 +249,12 @@
 };
 
 /// An abstract property
+//
+/// A Property is a holder for a value or a getter-setter.
+//
+/// Properties have special const semantics: the value of a Property does
+/// not affect its outward state, so the value of a const Property can be
+/// changed.
 class Property
 {
 public:
@@ -257,8 +263,7 @@
         : 
                _bound(as_value()),
         _destructive(false),
-        _uri(uri),
-               _orderID(0)
+        _uri(uri)
        {}
 
        /// Copy constructor
@@ -267,8 +272,7 @@
                _flags(p._flags),
         _bound(p._bound),
         _destructive(p._destructive),
-        _uri(p._uri),
-        _orderID(p._orderID)
+        _uri(p._uri)
        {}
 
        Property(const ObjectURI& uri, const as_value& value,
@@ -277,8 +281,7 @@
                _flags(flags),
         _bound(value),
         _destructive(false),
-               _uri(uri),
-               _orderID(0)
+               _uri(uri)
        {}
 
        Property(const ObjectURI& uri,
@@ -288,8 +291,7 @@
                _flags(flags), 
         _bound(GetterSetter(getter, setter)),
                _destructive(destroy),
-        _uri(uri),
-               _orderID(0)
+        _uri(uri)
        {}
 
        Property(const ObjectURI& uri, as_function *getter, as_function *setter,
@@ -298,8 +300,7 @@
                _flags(),
         _bound(GetterSetter(getter, setter)),
         _destructive(destroy),
-        _uri(uri),
-               _orderID(0)
+        _uri(uri)
        {}
 
        Property(const ObjectURI& uri, as_c_function_ptr getter,
@@ -309,8 +310,7 @@
                _flags(flags),
         _bound(GetterSetter(getter, setter)),
         _destructive(destroy),
-        _uri(uri),
-               _orderID(0)
+        _uri(uri)
        {}
 
        /// Set a user-defined setter
@@ -321,7 +321,11 @@
 
        /// accessor to the properties flags
        const PropFlags& getFlags() const { return _flags; }
-       PropFlags& getFlags() { return _flags; }
+
+    /// Set the flags of the property
+    void setFlags(const PropFlags& flags) const {
+        _flags = flags;
+    }
 
        /// Get value of this property
        //
@@ -351,7 +355,6 @@
        /// to watch for infinitely recurse on calling the getter
        /// or setter; Native getter-setter has no cache,
        /// nothing would happen for them.
-       ///
        void setCache(const as_value& v);
 
        /// Set value of this property
@@ -370,21 +373,7 @@
        ///     argument of the 'setter' function if this is a Getter/Setter
        ///     property. @see isGetterSetter().
        ///
-       void setValue(as_object& this_ptr, const as_value &value);
-
-       /// Set the order id
-       //
-       /// NOTE: this field is used by one of the indexes
-       ///       in the boost::multi_index used by PropertyList,
-       ///       so changing this value on an instance which was
-       ///       put in that index might result in corruption of
-       ///       the index invariant. (at least this is what happens
-       ///       with standard containers indexed on an element's member).
-       ///
-       void setOrder(int order) { _orderID = order; }
-
-       /// Get the order id
-       int getOrder() const { return _orderID; }
+       void setValue(as_object& this_ptr, const as_value &value) const;
 
        /// is this a read-only member ?
        bool isReadOnly() const { return _flags.get_read_only(); }
@@ -417,9 +406,12 @@
        void setReachable() const;
 
 private:
+       
+    /// Get a value from a getter function.
+       as_value getDelayedValue(const as_object& this_ptr) const;
 
-       /// Properties flags
-       PropFlags _flags;
+       /// Set a value using a setter function.
+       void setDelayedValue(as_object& this_ptr, const as_value& value) const;
 
     enum Type {
         TYPE_EMPTY,
@@ -427,11 +419,13 @@
         TYPE_GETTER_SETTER
     };
 
+       /// Properties flags
+       mutable PropFlags _flags;
+
        // Store the various types of things that can be held.
        typedef boost::variant<boost::blank, as_value, GetterSetter> BoundType;
 
-       // Changing this doesn't change the identity of the property, so it is
-       // mutable.
+    /// The value of the property.
        mutable BoundType _bound;
 
        // If true, as soon as getValue has been invoked once, the
@@ -442,16 +436,6 @@
     // TODO: this should be const, but the assignment operator is still needed 
     ObjectURI _uri;
 
-       // An ordering number, for access by order
-       // (AS3 enumeration and slots, AS2 arrays)
-       int _orderID;
-
-       /// Get a value from a getter function.
-       as_value getDelayedValue(const as_object& this_ptr) const;
-
-       /// Set a value using a setter function.
-       void setDelayedValue(as_object& this_ptr, const as_value& value);
-
 };
 
 } // namespace gnash

=== modified file 'libcore/PropertyList.cpp'
--- a/libcore/PropertyList.cpp  2010-01-25 18:52:20 +0000
+++ b/libcore/PropertyList.cpp  2010-07-09 05:14:26 +0000
@@ -26,6 +26,7 @@
 #include "as_value.h" // for enumerateValues
 #include "VM.h" // For string_table
 #include "string_table.h"
+#include "GnashAlgorithm.h"
 
 #include <utility> // for std::make_pair
 #include <boost/bind.hpp> 
@@ -41,79 +42,37 @@
 namespace {
 
 inline
-PropertyList::container::iterator
-iterator_find(const PropertyList::container &p, const ObjectURI& uri)
-{
-    return p.find(uri);
-}
-
-}
-
-typedef PropertyList::container::index<PropertyList::OrderTag>::type::iterator
-    order_iterator;
-
-order_iterator
-iterator_find(PropertyList::container &p, int order)
-{
-       return p.get<1>().find(order);
-}
-
-const Property*
-PropertyList::getPropertyByOrder(int order)
-{
-    order_iterator i = iterator_find(_props, order);
-       if (i == _props.get<1>().end()) return 0;
-
-       return &(*i);
-}
-
-const Property*
-PropertyList::getOrderAfter(int order)
-{
-    order_iterator i = iterator_find(_props, order);
-
-       if (i == _props.get<1>().end()) return 0;
-
-       do {
-               ++i;
-               if (i == _props.get<1>().end()) return 0;
-       } while (i->getFlags().get_dont_enum());
-
-       return &(*i);
-}
-
-bool
-PropertyList::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
-{
-    order_iterator found = iterator_find(_props, slotId + 1);
-       if (found != _props.get<1>().end()) return false;
-
-       Property a(uri, as_value());
-       a.setOrder(slotId + 1);
-       _props.insert(a);
-
-#ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(getStringTable(_owner));
-       log_debug("Slot for AS property %s inserted with flags %s", l(uri)
-            a.getFlags());
-#endif
-
-       return true;
+PropertyList::const_iterator
+iterator_find(const PropertyList::container& p, const ObjectURI& uri, VM& vm)
+{
+    
+    const bool caseless = vm.getSWFVersion() < 7;
+
+    if (!caseless) {
+        return p.project<0>(p.get<1>().find(uri));
+    }
+        
+    string_table& st = vm.getStringTable();
+    const string_table::key nocase = st.noCase(uri.name);
+    return p.project<0>(p.get<2>().find(nocase));
+}
+
 }
 
 bool
 PropertyList::setValue(const ObjectURI& uri, const as_value& val,
         const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, uri);
+       const_iterator found = iterator_find(_props, uri, getVM(_owner));
        
+    string_table& st = getStringTable(_owner);
+
        if (found == _props.end())
        {
                // create a new member
                Property a(uri, val, flagsIfMissing);
                // Non slot properties are negative ordering in insertion order
-               a.setOrder(- ++_defaultOrder - 1);
-               _props.insert(a);
+               _props.push_back(std::make_pair(a, st.noCase(uri.name)));
 #ifdef GNASH_DEBUG_PROPERTY
         ObjectURI::Logger l(getStringTable(_owner));
                log_debug("Simple AS property %s inserted with flags %s",
@@ -122,7 +81,7 @@
                return true;
        }
 
-       const Property& prop = *found;
+       const Property& prop = found->first;
        if (prop.isReadOnly() && ! prop.isDestructive())
        {
         ObjectURI::Logger l(getStringTable(_owner));
@@ -131,61 +90,51 @@
                return false;
        }
 
-       // 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(_owner, val);
+       prop.setValue(_owner, val);
 
        return true;
 }
 
-bool
+void
 PropertyList::setFlags(const ObjectURI& uri, int setFlags, int clearFlags)
 {
-       container::iterator found = iterator_find(_props, uri);
-       if ( found == _props.end() ) return false;
-
-       PropFlags oldFlags = found->getFlags();
-
-       PropFlags& f = const_cast<PropFlags&>(found->getFlags());
-       return f.set_flags(setFlags, clearFlags);
-
-#ifdef GNASH_DEBUG_PROPERTY
-    ObjectURI::Logger l(getStringTable(_owner));
-       log_debug("Flags of property %s changed from %s to  %s",
-               l(uri), oldFlags, found->getFlags());
-#endif
+       iterator found = iterator_find(_props, uri, getVM(_owner));
+       if (found == _props.end()) return;
+    PropFlags f = found->first.getFlags();
+    f.set_flags(setFlags, clearFlags);
+       found->first.setFlags(f);
+
 }
 
 void
 PropertyList::setFlagsAll(int setFlags, int clearFlags)
 {
-    PropertyList::container::iterator it;
-    for (it=_props.begin(); it != _props.end(); ++it) {
-               PropFlags& f = const_cast<PropFlags&>(it->getFlags());
-               f.set_flags(setFlags, clearFlags);
+    for (const_iterator it = _props.begin(); it != _props.end(); ++it) {
+        PropFlags f = it->first.getFlags();
+        f.set_flags(setFlags, clearFlags);
+        it->first.setFlags(f);
     }
 }
 
 Property*
 PropertyList::getProperty(const ObjectURI& uri) const
 {
-       container::iterator found = iterator_find(_props, uri);
+       iterator found = iterator_find(_props, uri, getVM(_owner));
        if (found == _props.end()) return 0;
-       return const_cast<Property*>(&(*found));
+       return const_cast<Property*>(&(found->first));
 }
 
 std::pair<bool,bool>
 PropertyList::delProperty(const ObjectURI& uri)
 {
        //GNASH_REPORT_FUNCTION;
-       container::iterator found = iterator_find(_props, uri);
+       iterator found = iterator_find(_props, uri, getVM(_owner));
        if (found == _props.end()) {
                return std::make_pair(false, false);
        }
 
        // check if member is protected from deletion
-       if (found->getFlags().get_dont_delete()) {
+       if (found->first.getFlags().get_dont_delete()) {
                return std::make_pair(true, false);
        }
 
@@ -193,18 +142,15 @@
        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();
+       for (const_iterator i=_props.begin(), ie=_props.end();
             i != ie; ++i)
        {
-               to.insert(std::make_pair(l(i->uri()), i->getValue(_owner)));
+               to.insert(std::make_pair(l(i->first.uri()), 
i->first.getValue(_owner)));
        }
 }
 
@@ -215,14 +161,12 @@
        string_table& st = getStringTable(_owner);
 
     // We should enumerate in order of creation, not lexicographically.
-    typedef container::nth_index<1>::type ContainerByOrder;
-
-       for (ContainerByOrder::const_reverse_iterator 
i=_props.get<1>().rbegin(),
-            ie=_props.get<1>().rend(); i != ie; ++i) {
-
-               if (i->getFlags().get_dont_enum()) continue;
-
-        const ObjectURI& uri = i->uri();
+       for (const_iterator i = _props.begin(),
+            ie = _props.end(); i != ie; ++i) {
+
+               if (i->first.getFlags().get_dont_enum()) continue;
+
+        const ObjectURI& uri = i->first.uri();
 
                if (donelist.insert(uri).second) {
 
@@ -239,9 +183,9 @@
 PropertyList::dump()
 {
     ObjectURI::Logger l(getStringTable(_owner));
-       for (container::const_iterator it=_props.begin(), itEnd=_props.end();
+       for (const_iterator it=_props.begin(), itEnd=_props.end();
             it != itEnd; ++it) {
-               log_debug("  %s: %s", l(it->uri()), it->getValue(_owner));
+               log_debug("  %s: %s", l(it->first.uri()), 
it->first.getValue(_owner));
        }
 }
 
@@ -251,16 +195,15 @@
        const PropFlags& flagsIfMissing)
 {
        Property a(uri, &getter, setter, flagsIfMissing);
-       a.setOrder(- ++_defaultOrder - 1);
-
-       container::iterator found = iterator_find(_props, uri);
+       iterator found = iterator_find(_props, uri, getVM(_owner));
+    
+    string_table& st = getStringTable(_owner);
        if (found != _props.end())
        {
                // copy flags from previous member (even if it's a normal 
member ?)
-               PropFlags& f = a.getFlags();
-               f = found->getFlags();
-               a.setCache(found->getCache());
-               _props.replace(found, a);
+               a.setFlags(found->first.getFlags());
+               a.setCache(found->first.getCache());
+               _props.replace(found, std::make_pair(a, st.noCase(uri.name)));
 
 #ifdef GNASH_DEBUG_PROPERTY
         ObjectURI::Logger l(getStringTable(_owner));
@@ -272,7 +215,7 @@
        else
        {
                a.setCache(cacheVal);
-               _props.insert(a);
+               _props.push_back(std::make_pair(a, st.noCase(uri.name)));
 #ifdef GNASH_DEBUG_PROPERTY
         ObjectURI::Logger l(getStringTable(_owner));
                log_debug("AS GetterSetter %s inserted with flags %s", l(uri),
@@ -288,15 +231,14 @@
        as_c_function_ptr setter, const PropFlags& flagsIfMissing)
 {
        Property a(uri, getter, setter, flagsIfMissing);
-       a.setOrder(- ++_defaultOrder - 1);
 
-       container::iterator found = iterator_find(_props, uri);
+    string_table& st = getStringTable(_owner);
+       const_iterator found = iterator_find(_props, uri, getVM(_owner));
        if (found != _props.end())
        {
                // copy flags from previous member (even if it's a normal 
member ?)
-               PropFlags& f = a.getFlags();
-               f = found->getFlags();
-               _props.replace(found, a);
+               a.setFlags(found->first.getFlags());
+               _props.replace(found, std::make_pair(a, st.noCase(uri.name)));
 
 #ifdef GNASH_DEBUG_PROPERTY
         ObjectURI::Logger l(getStringTable(_owner));
@@ -307,7 +249,7 @@
        }
        else
        {
-               _props.insert(a);
+               _props.push_back(std::make_pair(a, st.noCase(uri.name)));
 #ifdef GNASH_DEBUG_PROPERTY
                string_table& st = getStringTable(_owner);
                log_debug("Native GetterSetter %s in namespace %s inserted with 
"
@@ -322,7 +264,7 @@
 PropertyList::addDestructiveGetter(const ObjectURI& uri, as_function& getter, 
        const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, uri);
+       const_iterator found = iterator_find(_props, uri, getVM(_owner));
        if (found != _props.end())
        {
         ObjectURI::Logger l(getStringTable(_owner));
@@ -333,8 +275,9 @@
 
        // destructive getter don't need a setter
        Property a(uri, &getter, (as_function*)0, flagsIfMissing, true);
-       a.setOrder(- ++_defaultOrder - 1);
-       _props.insert(a);
+
+    string_table& st = getStringTable(_owner);
+       _props.push_back(std::make_pair(a, st.noCase(uri.name)));
 
 #ifdef GNASH_DEBUG_PROPERTY
     ObjectURI::Logger l(getStringTable(_owner));
@@ -349,13 +292,13 @@
 PropertyList::addDestructiveGetter(const ObjectURI& uri,
        as_c_function_ptr getter, const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, uri);
+       iterator found = iterator_find(_props, uri, getVM(_owner));
        if (found != _props.end()) return false; 
 
        // destructive getter don't need a setter
        Property a(uri, getter, (as_c_function_ptr)0, flagsIfMissing, true);
-       a.setOrder(- ++_defaultOrder - 1);
-       _props.insert(a);
+    string_table& st = getStringTable(_owner);
+       _props.push_back(std::make_pair(a, st.noCase(uri.name)));
 
 #ifdef GNASH_DEBUG_PROPERTY
     ObjectURI::Logger l(getStringTable(_owner));
@@ -374,7 +317,7 @@
 void
 PropertyList::setReachable() const
 {
-    std::for_each(_props.begin(), _props.end(),
+    foreachFirst(_props.begin(), _props.end(),
             boost::mem_fn(&Property::setReachable));
 }
 

=== modified file 'libcore/PropertyList.h'
--- a/libcore/PropertyList.h    2010-06-05 09:29:30 +0000
+++ b/libcore/PropertyList.h    2010-07-09 05:14:26 +0000
@@ -29,6 +29,7 @@
 #include <boost/cstdint.hpp> 
 #include <boost/multi_index_container.hpp>
 #include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
 #include <boost/multi_index/key_extractors.hpp>
 #include <boost/noncopyable.hpp>
 
@@ -59,34 +60,36 @@
 /// owner.
 class PropertyList : boost::noncopyable
 {
+
 public:
 
     typedef std::set<ObjectURI> PropertyTracker;
-
-    /// A tag for identifying an index in the container.
-    struct OrderTag {};
-
-    /// The actual container
-    /// index 0 is the fully indexed name/namespace pairs, which are unique
-    /// Because of the way searching works, this index can also be
-    /// used to search for the names alone (composite keys are sorted
-    /// lexographically, beginning with the first element specified)
-    ///
-    /// index 1 is an ordered sequence, and it is used for the AS3 style
-    /// enumeration (which requires an order number for each property),
-    /// for slot access, and for array access.
+    typedef std::pair<Property, string_table::key> value_type;
+
+    struct NameExtractor
+    {
+        typedef const ObjectURI& result_type;
+        const result_type operator()(const value_type& r) const {
+            return r.first.uri();
+        }
+        const result_type operator()(value_type& r) {
+            return r.first.uri();
+        }
+    };
+    
+    typedef boost::multi_index::member<value_type, value_type::second_type,
+            &value_type::second> KeyExtractor;
+
     typedef boost::multi_index_container<
-        Property,
+        value_type,
         boost::multi_index::indexed_by<
-            boost::multi_index::ordered_unique<
-                boost::multi_index::const_mem_fun<Property,const 
ObjectURI&,&Property::uri>
-            >,
-            boost::multi_index::ordered_unique<
-                boost::multi_index::tag<OrderTag>,
-                
boost::multi_index::const_mem_fun<Property,int,&Property::getOrder>
+            boost::multi_index::sequenced<>,
+            boost::multi_index::ordered_unique<NameExtractor>,
+            boost::multi_index::ordered_non_unique<KeyExtractor>
             >
-        >
-    > container;
+        > container;
+    typedef container::iterator iterator;
+    typedef container::const_iterator const_iterator;
 
     /// Construct the PropertyList 
     //
@@ -96,7 +99,6 @@
     PropertyList(as_object& obj)
         :
         _props(),
-        _defaultOrder(0),
         _owner(obj)
     {
     }
@@ -119,18 +121,15 @@
     template <class U, class V>
     void visitValues(V& visitor, U cmp = U()) const
     {
-        typedef container::nth_index<1>::type ContainerByOrder;
-
         // The template keyword is not required by the Standard here, but the
         // OpenBSD compiler needs it. Use of the template keyword where it is
         // not necessary is not an error.
-        for (ContainerByOrder::const_reverse_iterator
-                it = _props.template get<1>().rbegin(),
-                ie = _props.template get<1>().rend(); it != ie; ++it)
+        for (const_iterator it = _props.begin(), ie = _props.end();
+                it != ie; ++it)
         {
-            if (!cmp(*it)) continue;
-            as_value val = it->getValue(_owner);
-            if (!visitor.accept(it->uri(), val)) return;
+            if (!cmp(it->first)) continue;
+            as_value val = it->first.getValue(_owner);
+            if (!visitor.accept(it->first.uri(), val)) return;
         }
     }
 
@@ -145,14 +144,6 @@
     ///                     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
-    ///                 should be returned, otherwise, this should be the
-    ///                 result of a previous call to getOrderAfter
-    /// @return         A value which can be used for ordered access. 
-    const Property* getOrderAfter(int order);
-
     /// Set the value of a property, creating a new one if it doesn't exist.
     //
     /// If the named property is a getter/setter one it's setter
@@ -174,16 +165,6 @@
     bool setValue(const ObjectURI& uri, const as_value& value,
             const PropFlags& flagsIfMissing = 0);
 
-    /// Reserves a slot number for a property
-    ///
-    /// @param slotId
-    /// The slot id to use. (Note that getOrder() on this property will return
-    /// this slot number + 1 if the assignment was successful.)
-    /// @param key      Name of the property.
-    /// @param nsId     The namespace in which the property should be found.
-    /// @return         true if the slot did not previously exist.
-    bool reserveSlot(const ObjectURI& uri, boost::uint16_t slotId);
-
     /// Get a property if it exists.
     //
     /// @param key  Name of the property. Search is case-*sensitive*
@@ -194,11 +175,6 @@
     Property* getProperty(const ObjectURI& uri)
         const;
 
-    /// Get a property, if existing, by order
-    //
-    /// @param order    The ordering id
-    const Property* getPropertyByOrder(int order);
-    
     /// Delete a Property, if existing and not protected from deletion.
     //
     ///
@@ -271,9 +247,7 @@
     /// @param key      Name of the property. Search is case-*sensitive*
     /// @param setTrue  The set of flags to set
     /// @param setFalse The set of flags to clear
-    /// @return         true if the value was successfully set, false
-    ///                 otherwise (either not found or protected)
-    bool setFlags(const ObjectURI& uri, int setTrue, int setFalse);
+    void setFlags(const ObjectURI& uri, int setTrue, int setFalse);
 
     /// Set the flags of all properties.
     //
@@ -310,8 +284,6 @@
 
     container _props;
 
-    boost::uint32_t _defaultOrder;
-    
     as_object& _owner;
 
 };

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2010-05-08 21:33:27 +0000
+++ b/libcore/as_object.cpp     2010-07-09 05:14:26 +0000
@@ -450,23 +450,6 @@
 }
 
 
-const Property*
-as_object::getByIndex(int index)
-{
-    // The low byte is used to contain the depth of the property.
-    unsigned char depth = index & 0xFF;
-    index /= 256; // Signed
-    as_object *obj = this;
-    while (depth--)
-       {
-            obj = obj->get_prototype();
-            if (!obj)
-                return NULL;
-       }
-
-    return obj->_members.getPropertyByOrder(index);
-}
-
 as_object*
 as_object::get_super(string_table::key fname)
 {
@@ -489,44 +472,6 @@
     return super;
 }
 
-int
-as_object::nextIndex(int index, as_object **owner)
-{
-  skip_duplicates:
-    unsigned char depth = index & 0xFF;
-    unsigned char i = depth;
-    index /= 256; // Signed
-    as_object *obj = this;
-    while (i--)
-       {
-            obj = obj->get_prototype();
-            if (!obj)
-                return 0;
-       }
-       
-    const Property *p = obj->_members.getOrderAfter(index);
-    if (!p)
-       {
-            obj = obj->get_prototype();
-            if (!obj)
-                return 0;
-            p = obj->_members.getOrderAfter(0);
-            ++depth;
-       }
-    if (p)
-       {
-            if (findProperty(p->uri()) != p)
-               {
-                    index = p->getOrder() * 256 | depth;
-                    goto skip_duplicates; // Faster than recursion.
-               }
-            if (owner)
-                *owner = obj;
-            return p->getOrder() * 256 | depth;
-       }
-    return 0;
-}
-
 /*private*/
 Property*
 as_object::findProperty(const ObjectURI& uri, as_object **owner)
@@ -581,33 +526,6 @@
 }
 
 void
-as_object::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
-{
-    _members.reserveSlot(uri, slotId);
-}
-
-bool
-as_object::get_member_slot(int order, as_value* val){
-       
-    const Property* prop = _members.getPropertyByOrder(order);
-    if (prop) {
-        return get_member(prop->uri(), val);
-    }
-    return false;
-}
-
-
-bool
-as_object::set_member_slot(int order, const as_value& val, bool ifFound)
-{
-    const Property* prop = _members.getPropertyByOrder(order);
-    if (prop) {
-        return set_member(prop->uri(), val, ifFound);
-    }
-    return false;
-}
-
-void
 as_object::executeTriggers(Property* prop, const ObjectURI& uri,
                            const as_value& val)
 {
@@ -757,17 +675,9 @@
 }
 
 void
-as_object::init_member(const ObjectURI& uri, const as_value& val, int flags,
-                       int order)
+as_object::init_member(const ObjectURI& uri, const as_value& val, int flags)
 {
 
-    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 "
-                    "which already exists."));
-        return;
-    }
-               
     // Set (or create) a SimpleProperty 
     if (!_members.setValue(uri, val, flags)) {
         ObjectURI::Logger l(getStringTable(*this));
@@ -873,10 +783,10 @@
 }
 
 
-bool
+void
 as_object::set_member_flags(const ObjectURI& uri, int setTrue, int setFalse)
 {
-    return _members.setFlags(uri, setTrue, setFalse);
+    _members.setFlags(uri, setTrue, setFalse);
 }
 
 void
@@ -1016,15 +926,7 @@
         }
 
         // set_member_flags will take care of case conversion
-        if (!set_member_flags(getStringTable(*this).find(prop), set_true,
-                              set_false) )
-            {
-                IF_VERBOSE_ASCODING_ERRORS(
-                    log_aserror(_("Can't set propflags on object "
-                                  "property %s "
-                                  "(either not found or protected)"),  prop);
-                    );
-            }
+        set_member_flags(getStringTable(*this).find(prop), set_true, 
set_false);
 
         if (next_comma == std::string::npos) {
             break;

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2010-03-31 08:08:58 +0000
+++ b/libcore/as_object.h       2010-07-09 05:14:26 +0000
@@ -42,10 +42,6 @@
 
 // Forward declarations
 namespace gnash {
-    namespace abc {
-        class Machine;
-        class Class;
-    }
     class as_function;
     class MovieClip;
     class DisplayObject;
@@ -301,7 +297,7 @@
     ///                 an unsigned short, this is used as the slotId and
     ///                 can be subsequently found with get_slot
     void init_member(const ObjectURI& uri, const as_value& val, 
-        int flags = DefaultFlags, int slotId = -1);
+        int flags = DefaultFlags);
 
     /// Initialize a getter/setter property by name
     //
@@ -566,28 +562,6 @@
     /// @return         true if the object has the property, false otherwise.
     bool hasOwnProperty(const ObjectURI& uri);
 
-    /// Get a property from this object (or a prototype) by ordering index.
-    ///
-    /// @param index    An index returned by nextIndex
-    /// @return         The property associated with the order index.
-    const Property* getByIndex(int index);
-
-    /// Get the next index after the one whose index was used as a parameter.
-    ///
-    /// @param index
-    /// 0 is a starter index -- use it to get the first index. Using the
-    /// return value in subsequent calls will walk through all enumerable
-    /// properties in the list.
-    ///
-    /// @param owner
-    /// If owner is not NULL, it will be set to the exact object to which
-    /// the property used for the value of index belongs, if such a property
-    /// exists, and left untouched otherwise.
-    ///
-    /// @return
-    /// A value which can be fed to getByIndex, or 0 if there are no more.
-    int nextIndex(int index, as_object **owner = NULL);
-
     /// Set member flags (probably used by ASSetPropFlags)
     //
     /// @param name     Name of the property. Must be all lowercase
@@ -595,9 +569,7 @@
     ///                 up to SWF6.
     /// @param setTrue  The set of flags to set
     /// @param setFalse The set of flags to clear
-    /// @return         true on success, false on failure (non-existent or
-    ///                 protected member)
-    bool set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
+    void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
 
     /// Cast to a as_function, or return NULL
     virtual as_function* to_function() { return 0; }
@@ -767,33 +739,6 @@
         _displayObject = d;
     }
 
-    /// Get a member value at a given slot.
-    //
-    /// Note it is quite likely that slots only apply to static properties.
-    //
-    /// @param order    The slot index of the property.
-    /// @param val      The as_value to store a found variable's value in.
-    /// @return         true if a member exists at the given slot, 
-    ///                 and the member's value is successfully retrieved,
-    ///                 false otherwise.
-    bool get_member_slot(int order, as_value* val);
-
-    /// Set a member value at a given slot.
-    //
-    /// Note it is quite likely that slots only apply to static properties.
-    //
-    /// @param order    The slot index of the property.
-    /// @param val      Value to assign to the named property.
-    /// @param ifFound  If true, don't create a new member, but only update
-    ///                 an existing one.
-    /// @return true    if the member exists at the given slot, 
-    ///                 false otherwise.
-    ///    
-    /// NOTE: the return doesn't tell if the member exists after
-    ///       the call, as watch triggers might have deleted it
-    ///       after setting.
-    bool set_member_slot(int order, const as_value& val, bool ifFound = false);
-
 protected:
 
     /// Construct an as_object associated with a VM.
@@ -992,6 +937,10 @@
 /// Return whether the object is an AS3 object.
 bool isAS3(const as_object& o);
 
+/// Return whether property matching is caseless
+inline bool caseless(const as_object& o) {
+    return getSWFVersion(o) < 7;
+}
 
 } // namespace gnash
 

=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2010-06-22 06:03:51 +0000
+++ b/libcore/asobj/Globals.cpp 2010-07-09 05:14:26 +0000
@@ -135,10 +135,6 @@
 
     const ClassHierarchy::NativeClasses& avm1Classes();
 
-    // These functions are for AVM2 only.
-    const ClassHierarchy::NativeClasses& avm2Classes();
-    ObjectURI knownClass(string_table::key key);
-
     as_value global_trace(const fn_call& fn);
     as_value global_isNaN(const fn_call& fn);
     as_value global_isfinite(const fn_call& fn);
@@ -388,107 +384,6 @@
 
 }
 
-#ifdef ENABLE_AVM2
-
-AVM2Global::AVM2Global(abc::Machine& /*machine*/, VM& vm)
-    :
-    Global_as(vm),
-    _classes(this, 0),
-    _objectProto(new as_object(*this))
-{
-}
-
-void
-AVM2Global::registerClasses()
-{
-   
-    const string_table::key NS_GLOBAL(0);
-    
-    initObjectClass(_objectProto, *this,
-            ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
-
-    function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
-    string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
-    array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
-    
-    init_member("trace", createFunction(global_trace));
-    init_member("escape", createFunction(global_escape));
-
-    _classes.declareAll(avm2Classes());
-    _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
-    _classes.getGlobalNs()->getScript(NSV::CLASS_FUNCTION)->setDeclared();
-    _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
-    _classes.getGlobalNs()->getScript(NSV::CLASS_OBJECT)->setDeclared();
-    _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
-    _classes.getGlobalNs()->getScript(NSV::CLASS_ARRAY)->setDeclared();
-    _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_STRING);
-    _classes.getGlobalNs()->getScript(NSV::CLASS_STRING)->setDeclared();       
 
-
-}
-
-as_object*
-AVM2Global::createObject()
-{
-    as_object* obj = new as_object(*this);
-    obj->set_prototype(_objectProto);
-    return obj;
-}
-
-builtin_function*
-AVM2Global::createFunction(Global_as::ASFunction function)
-{
-    builtin_function* f = new builtin_function(*this, function);
-    f->init_member(NSV::PROP_CONSTRUCTOR,
-            as_function::getFunctionConstructor());
-    return f;
-}
-
-as_object*
-AVM2Global::createClass(Global_as::ASFunction ctor, as_object* prototype)
-{
-    // TODO: this should attach the function to the prototype as its
-    as_object* cl = new builtin_function(*this, ctor);
-    
-    if (prototype) {
-        prototype->init_member(NSV::PROP_CONSTRUCTOR, cl); 
-        cl->init_member(NSV::PROP_PROTOTYPE, prototype);
-    }
-    return cl;
-}
-
-as_object*
-AVM2Global::createString(const std::string& s)
-{
-    // What AVM2 does for createString is untested, so we do the same
-    // as AVM1 for now.
-    return constructObject(*this, s, NSV::CLASS_STRING);
-}
-
-as_object*
-AVM2Global::createNumber(double d)
-{
-    return constructObject(*this, d, NSV::CLASS_NUMBER);
-}
-
-as_object*
-AVM2Global::createBoolean(bool b)
-{
-    return constructObject(*this, b, NSV::CLASS_BOOLEAN);
-}
-
-/// This serves the purpose of hiding the Array_as type from the
-/// implementation, which at least enforces good behaviour from users.
-as_object*
-AVM2Global::createArray()
-{
-    as_object* array = new as_object(*this);
-    array->setArray();
-    array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
-    return array;
-}
-
-#endif
-
 namespace {
 
 const ClassHierarchy::NativeClasses&
@@ -541,209 +436,6 @@
 
 }
 
-#ifdef ENABLE_AVM2
-
-const ClassHierarchy::NativeClasses&
-avm2Classes()
-{
-
-    typedef ClassHierarchy::NativeClass N;
-
-    ObjectURI(*c)(string_table::key) = knownClass;
-
-    static const ClassHierarchy::NativeClasses s = boost::assign::list_of
-
-        // Global classes
-        (N(math_class_init, c(NSV::CLASS_MATH), c(NSV::CLASS_OBJECT), 4))
-        (N(boolean_class_init, c(NSV::CLASS_BOOLEAN), c(NSV::CLASS_OBJECT), 5))
-        (N(number_class_init, c(NSV::CLASS_NUMBER), c(NSV::CLASS_OBJECT), 5))
-        (N(int_class_init, c(NSV::CLASS_INT), c(NSV::CLASS_OBJECT), 5))
-        (N(namespace_class_init, c(NSV::CLASS_NAMESPACE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(qname_class_init, c(NSV::CLASS_QNAME), c(NSV::CLASS_OBJECT), 5))
-        (N(date_class_init, c(NSV::CLASS_DATE), c(NSV::CLASS_OBJECT), 5))
-        (N(Error_class_init, c(NSV::CLASS_ERROR), c(NSV::CLASS_OBJECT), 5))
-
-        // System classes
-        (N(system_class_init, c(NSV::CLASS_SYSTEM), c(NSV::CLASS_OBJECT), 1))
-
-        // Display classes
-        (N(shape_class_init, c(NSV::CLASS_SHAPE),
-           c(NSV::CLASS_DISPLAYOBJECT), 3))
-        (N(displayobject_class_init, c(NSV::CLASS_DISPLAYOBJECT),
-           c(NSV::CLASS_EVENTDISPATCHER), 3))
-        (N(interactiveobject_class_init, c(NSV::CLASS_INTERACTIVEOBJECT),
-           c(NSV::CLASS_DISPLAYOBJECT), 3))
-        (N(displayobjectcontainer_class_init,
-           c(NSV::CLASS_DISPLAYOBJECTCONTAINER),
-           c(NSV::CLASS_INTERACTIVEOBJECT), 3))
-        (N(sprite_class_init, c(NSV::CLASS_SPRITE),
-           c(NSV::CLASS_DISPLAYOBJECTCONTAINER), 3))
-        (N(bitmap_class_init, c(NSV::CLASS_BITMAP),
-           c(NSV::CLASS_DISPLAYOBJECT), 3))
-        (N(movieclip_class_init, c(NSV::CLASS_MOVIE_CLIP),
-           c(NSV::CLASS_SPRITE), 3))
-        (N(stage_class_init, c(NSV::CLASS_STAGE),
-           c(NSV::CLASS_MOVIE_CLIP), 1))
-        (N(button_class_init, c(NSV::CLASS_SIMPLE_BUTTON),
-           c(NSV::CLASS_INTERACTIVEOBJECT), 5))
-
-        // Text classes
-        (N(textfield_class_init, c(NSV::CLASS_TEXT_FIELD),
-           c(NSV::CLASS_INTERACTIVEOBJECT), 3))
-        (N(textformat_class_init, c(NSV::CLASS_TEXT_FORMAT),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textsnapshot_class_init, c(NSV::CLASS_TEXT_SNAPSHOT),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textfieldautosize_class_init, c(NSV::CLASS_TEXTFIELDAUTOSIZE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(font_class_init, c(NSV::CLASS_FONT), c(NSV::CLASS_OBJECT), 5))
-        (N(fontstyle_class_init, c(NSV::CLASS_FONTSTYLE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(antialiastype_class_init, c(NSV::CLASS_ANTIALIASTYPE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(csmsettings_class_init, c(NSV::CLASS_CSMTEXTSETTINGS),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(gridfittype_class_init, c(NSV::CLASS_GRIDFITTYPE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(statictext_class_init, c(NSV::CLASS_STATICTEXT),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(stylesheet_class_init, c(NSV::CLASS_STYLESHEET),
-           c(NSV::CLASS_OBJECT), 5))
-#if 0
-        // This one isn't stubbed for some reason.
-        (N(textcolor_class_init, c(NSV::CLASS_TEXTCOLOR),
-           c(NSV::CLASS_OBJECT), 5))
-#endif
-        (N(textcolortype_class_init, c(NSV::CLASS_TEXTCOLORTYPE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textdisplaymode_class_init, c(NSV::CLASS_TEXTDISPLAYMODE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textfieldtype_class_init, c(NSV::CLASS_TEXTFIELDTYPE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textformatalign_class_init, c(NSV::CLASS_TEXTFORMATALIGN),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textlinemetrics_class_init, c(NSV::CLASS_TEXTLINEMETRICS),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(textrenderer_class_init, c(NSV::CLASS_TEXTRENDERER),
-           c(NSV::CLASS_OBJECT), 5))
-
-        // Media classes
-        (N(sound_class_init, c(NSV::CLASS_SOUND), c(NSV::CLASS_OBJECT), 5))
-        (N(video_class_init, c(NSV::CLASS_VIDEO),
-           c(NSV::CLASS_DISPLAYOBJECT), 6))
-        (N(camera_class_init, c(NSV::CLASS_CAMERA), c(NSV::CLASS_OBJECT), 6))
-        (N(microphone_class_init, c(NSV::CLASS_MICROPHONE),
-           c(NSV::CLASS_OBJECT), 6))
-        // Net classes
-        (N(xmlsocket_class_init, c(NSV::CLASS_XMLSOCKET),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(sharedobject_class_init, c(NSV::CLASS_SHARED_OBJECT),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(localconnection_class_init, c(NSV::CLASS_LOCALCONNECTION),
-           c(NSV::CLASS_OBJECT), 6))
-        (N(netconnection_class_init, c(NSV::CLASS_NET_CONNECTION),
-           c(NSV::CLASS_OBJECT), 6))
-        (N(netstream_class_init, c(NSV::CLASS_NET_STREAM),
-           c(NSV::CLASS_OBJECT), 6))
-        // Error classes
-        // XML classes
-        (N(xmlnode_class_init, c(NSV::CLASS_XMLNODE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(xml_class_init, c(NSV::CLASS_XML_DOCUMENT),
-           c(NSV::CLASS_OBJECT), 5))
-        // UI classes
-        (N(mouse_class_init, c(NSV::CLASS_MOUSE),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(keyboard_class_init, c(NSV::CLASS_KEYBOARD),
-           c(NSV::CLASS_OBJECT), 5))
-        (N(contextmenu_class_init, c(NSV::CLASS_CONTEXTMENU),
-           c(NSV::CLASS_OBJECT), 7))
-        (N(contextmenuitem_class_init, c(NSV::CLASS_CONTEXTMENUITEM),
-           c(NSV::CLASS_OBJECT), 5))
-        // Accessibility classes
-        (N(accessibility_class_init, c(NSV::CLASS_ACCESSIBILITY),
-           c(NSV::CLASS_OBJECT), 5))
-        // Event classes
-        (N(event_class_init, c(NSV::CLASS_EVENT), c(NSV::CLASS_OBJECT), 5))
-        (N(eventdispatcher_class_init, c(NSV::CLASS_EVENTDISPATCHER),
-           c(NSV::CLASS_OBJECT), 5));
-
-        return s;
-
-}
-
-ObjectURI
-knownClass(string_table::key key)
-{
-    typedef std::map<string_table::key, string_table::key> KnownClasses;
-
-    const string_table::key NS_GLOBAL(0);
-
-    static const KnownClasses knownClasses = boost::assign::map_list_of
-         (NSV::CLASS_OBJECT, NS_GLOBAL)
-         (NSV::CLASS_MATH, NS_GLOBAL)
-         (NSV::CLASS_BOOLEAN, NS_GLOBAL)
-         (NSV::CLASS_NUMBER, NS_GLOBAL)
-         (NSV::CLASS_INT, NS_GLOBAL)
-         (NSV::CLASS_NAMESPACE, NS_GLOBAL)
-         (NSV::CLASS_QNAME, NS_GLOBAL)
-         (NSV::CLASS_DATE, NS_GLOBAL)
-         (NSV::CLASS_ERROR, NS_GLOBAL)
-         (NSV::CLASS_SYSTEM, NSV::NS_FLASH_SYSTEM)
-         (NSV::CLASS_SHAPE, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_DISPLAYOBJECT, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_DISPLAYOBJECTCONTAINER, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_SPRITE, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_BITMAP, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_MOVIE_CLIP, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_STAGE, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_SIMPLE_BUTTON, NSV::NS_FLASH_DISPLAY)
-         (NSV::CLASS_TEXT_FIELD, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXT_FORMAT, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXT_SNAPSHOT, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTFIELDAUTOSIZE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_FONT, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_FONTSTYLE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_ANTIALIASTYPE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_CSMTEXTSETTINGS, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_GRIDFITTYPE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_STATICTEXT, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_STYLESHEET, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTCOLORTYPE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTDISPLAYMODE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTFIELDTYPE, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTFORMATALIGN, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTLINEMETRICS, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_TEXTRENDERER, NSV::NS_FLASH_TEXT)
-         (NSV::CLASS_SOUND, NSV::NS_FLASH_MEDIA)
-         (NSV::CLASS_VIDEO, NSV::NS_FLASH_MEDIA)
-         (NSV::CLASS_CAMERA, NSV::NS_FLASH_MEDIA)
-         (NSV::CLASS_MICROPHONE, NSV::NS_FLASH_MEDIA)
-         (NSV::CLASS_XMLSOCKET, NSV::NS_FLASH_NET)
-         (NSV::CLASS_SHARED_OBJECT, NSV::NS_FLASH_NET)
-         (NSV::CLASS_LOCALCONNECTION, NSV::NS_FLASH_NET)
-         (NSV::CLASS_NET_CONNECTION, NSV::NS_FLASH_NET)
-         (NSV::CLASS_NET_STREAM, NSV::NS_FLASH_NET)
-         (NSV::CLASS_XMLNODE, NSV::NS_FLASH_XML)
-         (NSV::CLASS_XML_DOCUMENT, NSV::NS_FLASH_XML)
-         (NSV::CLASS_MOUSE, NSV::NS_FLASH_UI)
-         (NSV::CLASS_KEYBOARD, NSV::NS_FLASH_UI)
-         (NSV::CLASS_SHAPE, NSV::NS_FLASH_UI)
-         (NSV::CLASS_CONTEXTMENU, NSV::NS_FLASH_UI)
-         (NSV::CLASS_CONTEXTMENUITEM, NSV::NS_FLASH_UI)
-         (NSV::CLASS_ACCESSIBILITY, NSV::NS_FLASH_ACCESSIBILITY)
-         (NSV::CLASS_EVENT, NSV::NS_FLASH_EVENTS)
-         (NSV::CLASS_EVENTDISPATCHER, NSV::NS_FLASH_EVENTS);
-
-    KnownClasses::const_iterator it = knownClasses.find(key);
-    assert(it != knownClasses.end());
-    return ObjectURI(key, it->second);
-}
-
-#endif
-
 as_value
 global_trace(const fn_call& fn)
 {

=== modified file 'libcore/asobj/Globals.h'
--- a/libcore/asobj/Globals.h   2010-03-31 08:08:58 +0000
+++ b/libcore/asobj/Globals.h   2010-07-09 05:14:26 +0000
@@ -117,69 +117,6 @@
 
 };
 
-#ifdef ENABLE_AVM2
-
-class AVM2Global : public Global_as
-{
-public:
-
-    /// Construct the AVM2 global object.
-    //
-    /// This takes a VM argument because most access to necessary
-    /// resources is still through the VM.
-       AVM2Global(abc::Machine& m, VM& vm);
-       ~AVM2Global() {}
-    
-    void registerClasses();
-    
-    /// Create an ActionScript function
-    virtual builtin_function* createFunction(Global_as::ASFunction function);
-
-    /// Create an ActionScript class
-    //
-    /// An AS3 class is generally an object (the prototype) with a constructor.
-    virtual as_object* createClass(Global_as::ASFunction ctor,
-            as_object* prototype);
-
-    virtual as_object* createString(const std::string& s);
-
-    virtual as_object* createNumber(double d);
-
-    virtual as_object* createBoolean(bool b);
-
-    virtual as_object* createObject();
-
-    virtual as_object* createArray();
-
-    virtual const ClassHierarchy& classHierarchy() const {
-        return _classes;
-    }
-    
-    virtual ClassHierarchy& classHierarchy() {
-        return _classes;
-    }
-    
-    virtual VM& getVM() const {
-        return vm();
-    }
-
-protected:
-
-    virtual void markReachableResources() const {
-        _classes.markReachableResources();
-        _objectProto->setReachable();
-        markAsObjectReachable();
-    }
-
-private:
-
-    ClassHierarchy _classes;
-    as_object* _objectProto;
-
-};
-
-#endif 
-
 } // namespace gnash
 
 #endif 

=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp      2010-06-10 13:43:34 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp      2010-07-05 08:32:15 
+0000
@@ -333,7 +333,8 @@
     as_object* o = getObjectWithPrototype(getGlobal(fn), 
NSV::CLASS_MOVIE_CLIP);
     MovieClip* mc = new MovieClip(o, 0, m, ptr);
 
-    mc->set_name(fn.arg(0).to_string());
+    string_table& st = getStringTable(fn);
+    mc->set_name(st.find(fn.arg(0).to_string()));
     mc->setDynamic();
 
     // Unlike other MovieClip methods, the depth argument of an empty movie 
clip
@@ -500,7 +501,8 @@
     Global_as& gl = getGlobal(fn);
     DisplayObject* newch = exported_movie->createDisplayObject(gl, movieclip);
 
-    newch->set_name(newname);
+    string_table& st = getStringTable(fn);
+    newch->set_name(st.find(newname));
     newch->setDynamic();
 
     boost::intrusive_ptr<as_object> initObj;

=== modified file 'libcore/asobj/flash/text/TextField_as.cpp'
--- a/libcore/asobj/flash/text/TextField_as.cpp 2010-04-21 22:07:20 +0000
+++ b/libcore/asobj/flash/text/TextField_as.cpp 2010-07-05 08:32:15 +0000
@@ -259,8 +259,10 @@
 
     DisplayObject* tf = new TextField(obj, ptr, bounds);
 
+    string_table& st = getStringTable(fn);
+
     // Give name and mark as dynamic
-    tf->set_name(name);
+    tf->set_name(st.find(name));
     tf->setDynamic();
 
     // Set _x and _y

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2010-06-18 03:28:37 +0000
+++ b/libcore/movie_root.cpp    2010-07-05 06:57:11 +0000
@@ -556,7 +556,7 @@
 
     if (_scaleMode == SCALEMODE_NOSCALE) {
         //log_debug("Rescaling disabled");
-        as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+        as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
         if (stage) {
             log_debug("notifying Stage listeners about a resize");
             callMethod(stage, NSV::PROP_BROADCAST_MESSAGE, "onResize");
@@ -1367,7 +1367,7 @@
     callInterface("Stage.align");    
 
     if (notifyResize) {
-        as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+        as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
         if (stage) {
             log_debug("notifying Stage listeners about a resize");
             callMethod(stage, NSV::PROP_BROADCAST_MESSAGE, "onResize");
@@ -1380,7 +1380,7 @@
 {
     _displayState = ds;
 
-    as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+    as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
     if (stage) {
         log_debug("notifying Stage listeners about fullscreen state");
         const bool fs = _displayState == DISPLAYSTATE_FULLSCREEN;

=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp  2010-01-25 18:52:20 +0000
+++ b/libcore/namedStrings.cpp  2010-07-05 06:48:13 +0000
@@ -44,7 +44,7 @@
     string_table::svt( "c", NSV::PROP_C ),
     string_table::svt( "callee", NSV::PROP_CALLEE ),
     string_table::svt( "caller", NSV::PROP_CALLER ),
-    //string_table::svt( "color", NSV::PROP_COLOR ), // clashes with 
CLASS_COLOR in case-insensitive mode
+    string_table::svt( "color", NSV::PROP_COLOR ),
     string_table::svt( "concat", NSV::PROP_CONCAT ),    
     string_table::svt( "constructor", NSV::PROP_CONSTRUCTOR ),
     string_table::svt( "__constructor__", NSV::PROP_uuCONSTRUCTORuu ),
@@ -131,7 +131,6 @@
     string_table::svt( "size", NSV::PROP_SIZE ),
     string_table::svt( "_soundbuftime", NSV::PROP_uSOUNDBUFTIME ),
     string_table::svt( "splice", NSV::PROP_SPLICE ),
-    string_table::svt( "Stage", NSV::PROP_iSTAGE ),
     string_table::svt( "status", NSV::PROP_STATUS ),
     string_table::svt( "super", NSV::PROP_SUPER ),
     string_table::svt( "target", NSV::PROP_TARGET ),
@@ -140,6 +139,7 @@
     string_table::svt( "textColor", NSV::PROP_TEXT_COLOR ),
     string_table::svt( "textWidth", NSV::PROP_TEXT_WIDTH ),
     string_table::svt( "textHeight", NSV::PROP_TEXT_HEIGHT ),
+    string_table::svt( "this", NSV::PROP_THIS ),
     string_table::svt( "toString", NSV::PROP_TO_STRING ),
     string_table::svt( "toLowerCase", NSV::PROP_TO_LOWER_CASE ),
     string_table::svt( "_totalframes", NSV::PROP_uTOTALFRAMES ),
@@ -174,7 +174,7 @@
     string_table::svt( "TextFormatAlign", NSV::CLASS_TEXTFORMATALIGN),
     string_table::svt( "TextLineMetrics", NSV::CLASS_TEXTLINEMETRICS),
     string_table::svt( "TextRenderer", NSV::CLASS_TEXTRENDERER),
-//  string_table::svt( "Stage", NSV::CLASS_STAGE ), // Identical to PROP_iSTAGE
+    string_table::svt( "Stage", NSV::CLASS_STAGE ),
     string_table::svt( "MovieClip", NSV::CLASS_MOVIE_CLIP ),
     string_table::svt( "TextField", NSV::CLASS_TEXT_FIELD ),
     string_table::svt( "Button", NSV::CLASS_BUTTON ),
@@ -247,12 +247,8 @@
 };
 
 void
-loadStrings(string_table& table, int version)
+loadStrings(string_table& table)
 {
-    if (version < 7) {
-        table.set_insensitive();
-    }
-
     table.insert_group(preload_names, arraySize(preload_names));
 }
 

=== modified file 'libcore/namedStrings.h'
--- a/libcore/namedStrings.h    2010-01-01 17:48:26 +0000
+++ b/libcore/namedStrings.h    2010-07-05 06:48:13 +0000
@@ -32,8 +32,6 @@
 ///
 /// Lowercase letters in the enum value signal the format of the string
 /// literals associated with these enums.
-/// i: Initial capital for groups which are normally initial lower case.
-/// For example: PROP_iSTAGE is "Stage";
 /// u: An underscore
 /// For example: PROP_uuPROTOuu is "__proto__"
 /// _: The next letter is capitalized
@@ -96,7 +94,6 @@
         CLASS_SOUND,
         CLASS_SPRITE,
         CLASS_STAGE,
-        PROP_iSTAGE = CLASS_STAGE,
         CLASS_STATICTEXT,
         CLASS_STRING,
         CLASS_STYLESHEET,
@@ -144,7 +141,7 @@
         PROP_C,
         PROP_CALLEE,
         PROP_CALLER,
-        //PROP_COLOR, // clashes with CLASS_COLOR in case-insensitive mode
+        PROP_COLOR,
         PROP_CONCAT,
         PROP_CONSTRUCTOR,
         PROP_CONTENT_TYPE,
@@ -219,6 +216,7 @@
         PROP_TEXT_COLOR,
         PROP_TEXT_HEIGHT,
         PROP_TEXT_WIDTH,
+        PROP_THIS,
         PROP_TO_LOWER_CASE,
         PROP_TO_STRING,
         PROP_TX,
@@ -267,8 +265,7 @@
     };
 
 /// Load the prenamed strings.
-/// version controls case
-void loadStrings(string_table &table, int version);
+void loadStrings(string_table &table);
 
 } // namespace NSV
 } // namespace gnash

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2010-06-15 06:40:04 +0000
+++ b/libcore/vm/ASHandlers.cpp 2010-07-07 09:19:47 +0000
@@ -53,6 +53,7 @@
 #include "as_value.h"
 #include "RunResources.h"
 #include "with_stack_entry.h"
+#include "ObjectURI.h"
 
 #include <string>
 #include <vector>
@@ -98,7 +99,6 @@
     /// @param thread           The current execution thread.
     void commonSetTarget(ActionExec& thread, const std::string& target_name);
 
-
     enum as_encoding_guess_t {
         ENCGUESS_UNICODE = 0,
         ENCGUESS_JIS = 1,
@@ -2645,11 +2645,12 @@
 
     as_object* ao = gl.createArray();
 
+    string_table& st = getStringTable(env);
     // Fill the elements with the initial values from the stack.
     for (int i = 0; i < array_size; i++) {
-        // @@ TODO a set_member that takes an int or as_value?
-        thread.setObjectMember(*ao, boost::lexical_cast<std::string>(i),
-                env.pop());
+        const string_table::key k = 
+            st.find(boost::lexical_cast<std::string>(i));
+        ao->set_member(k, env.pop());
     }
 
     env.push(ao);
@@ -2678,12 +2679,13 @@
 
     obj->init_member(NSV::PROP_CONSTRUCTOR, gl.getMember(NSV::CLASS_OBJECT));
 
+    string_table& st = getStringTable(env);
+
     // Set provided members
     for (int i = 0; i < nmembers; ++i) {
-        as_value member_value = env.top(0);
+        const as_value& member_value = env.top(0);
         std::string member_name = env.top(1).to_string();
-
-        thread.setObjectMember(*obj, member_name, member_value);
+        obj->set_member(st.find(member_name), member_value);
         env.drop(2);
     }
 
@@ -2873,8 +2875,11 @@
                target, static_cast<void *>(obj.get()));
     );
 
-    if (!thread.getObjectMember(*obj, member_name.to_string(), env.top(1)))
-    {
+    string_table& st = getStringTable(env);
+    const string_table::key k = st.find(member_name.to_string());
+
+    if (!obj->get_member(k, &env.top(1))) {
+
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror("Reference to undefined member %s of object %s",
             member_name,
@@ -2913,7 +2918,8 @@
         );
     }
     else if (obj) {
-        thread.setObjectMember(*(obj.get()), member_name, member_value);
+        string_table& st = getStringTable(env);
+        obj->set_member(st.find(member_name), member_value);
 
         IF_VERBOSE_ACTION (
             log_action(_("-- set_member %s.%s=%s"),
@@ -3042,11 +3048,7 @@
         // The method value
         as_value method_value; 
 
-        // Alright, not using 'thread' object here is kind of
-        // a policy break, but saves a duplicated string_table::find
-        // call so for now I'm fine like this ...
-        //if (!thread.getObjectMember(*obj, method_string, method_value)) {
-        if ( ! obj->get_member(method_key, &method_value) ) {
+        if (!obj->get_member(method_key, &method_value) ) {
             IF_VERBOSE_ASCODING_ERRORS(
             log_aserror(_("ActionCallMethod: "
                 "Can't find method %s of object %s"),
@@ -3172,7 +3174,9 @@
         method_val = obj_val;
     }
     else {
-        if (!thread.getObjectMember(*obj, method_string, method_val)) {
+        string_table& st = getStringTable(env);
+        const string_table::key k = st.find(method_string);
+        if (!obj->get_member(k, &method_val)) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("ActionNewMethod: can't find method %s of "
                         "object %s"), method_string, obj_val);
@@ -4160,7 +4164,6 @@
     return ENCGUESS_OTHER;
 }
 
-
 }
 
 

=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2010-05-19 07:45:49 +0000
+++ b/libcore/vm/ActionExec.cpp 2010-07-07 09:19:47 +0000
@@ -713,22 +713,6 @@
     }
 }
 
-void
-ActionExec::setObjectMember(as_object& obj, const std::string& var,
-        const as_value& val)
-{
-    string_table& st = getStringTable(env);
-    obj.set_member(st.find(var), val);
-}
-
-bool
-ActionExec::getObjectMember(as_object& obj, const std::string& var,
-        as_value& val)
-{
-    string_table& st = getStringTable(env);
-    return obj.get_member(st.find(var), &val);
-}
-
 as_object*
 ActionExec::getTarget()
 {

=== modified file 'libcore/vm/ActionExec.h'
--- a/libcore/vm/ActionExec.h   2010-03-12 03:52:58 +0000
+++ b/libcore/vm/ActionExec.h   2010-07-07 09:19:47 +0000
@@ -369,37 +369,6 @@
        ///
        as_value getVariable(const std::string& name, as_object** target);
 
-       /// Set an object's member.
-       //
-       /// @param obj
-       ///     The object we want to set the member of.
-       ///
-       /// @param name
-       ///     Name of the variable. Supports slash and dot syntax.
-       ///     Name is converted to lowercase if SWF version is < 7.
-       ///
-       /// @param val
-       ///     The value to assign to the object's member.
-       ///
-       void setObjectMember(as_object& obj, const std::string& name, const 
as_value& val);
-
-       /// Get an object's member.
-       //
-       /// @param obj
-       ///     The object we want to set the member of.
-       ///
-       /// @param name
-       ///     Name of the variable. Supports slash and dot syntax.
-       ///     Name is converted to lowercase if SWF version is < 7.
-       ///
-       /// @param val
-       ///     The as_value to write member value into.
-       ///
-       /// @returns
-       ///     True if the member was found, false otherwise.
-       ///
-       bool getObjectMember(as_object& obj, const std::string& name, as_value& 
val);
-
        /// Get current target.
        //
        /// This function returns top 'with' stack entry, if any.

=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2010-01-13 09:10:35 +0000
+++ b/libcore/vm/VM.cpp 2010-07-04 12:57:34 +0000
@@ -66,7 +66,7 @@
        _singleton.reset(new VM(version, root, clock));
 
        assert(_singleton.get());
-       NSV::loadStrings(_singleton->_stringTable, _singleton->getSWFVersion());
+       NSV::loadStrings(_singleton->_stringTable);
 
     AVM1Global* gl(new AVM1Global(*_singleton));
 

=== modified file 'testsuite/MovieTester.cpp'
--- a/testsuite/MovieTester.cpp 2010-05-21 01:26:20 +0000
+++ b/testsuite/MovieTester.cpp 2010-07-05 08:32:15 +0000
@@ -316,7 +316,8 @@
                const std::string& name) 
 {
     const DisplayList& dlist = mc.getDisplayList();
-    return dlist.getDisplayObjectByName(name);
+    string_table& st = getStringTable(*getObject(&mc));
+    return dlist.getDisplayObjectByName(st, st.find(name), false);
 }
 
 const DisplayObject*

=== modified file 'testsuite/actionscript.all/case.as'
--- a/testsuite/actionscript.all/case.as        2010-01-01 17:48:26 +0000
+++ b/testsuite/actionscript.all/case.as        2010-07-02 13:33:51 +0000
@@ -209,7 +209,7 @@
 propRecorder.sort(); // case sensitive sort
 check_equals(propRecorder.length, 2);
 #if OUTPUT_VERSION < 7
-xcheck_equals(propRecorder[0], 'A')
+check_equals(propRecorder[0], 'A')
 #else
 check_equals(propRecorder[0], 'A')
 #endif
@@ -224,7 +224,7 @@
 propRecorder.sort(); //case sensitive sort
 #if OUTPUT_VERSION < 7
     check_equals(propRecorder.length, 2);
-    xcheck_equals(propRecorder[0], 'A')
+    check_equals(propRecorder[0], 'A')
     check_equals(propRecorder[1], 'b')
 #else
     check_equals(propRecorder.length, 3);
@@ -242,7 +242,7 @@
 propRecorder.sort(); //case sensitive sort
 #if OUTPUT_VERSION < 7
     check_equals(propRecorder.length, 2);
-    xcheck_equals(propRecorder[0], 'A')
+    check_equals(propRecorder[0], 'A')
     check_equals(propRecorder[1], 'b')
 #else
     check_equals(propRecorder.length, 4);
@@ -292,8 +292,8 @@
  // gnash fails here because 'B' will point to a previously used 'b'
  // and 'a' will point to a previously used 'A'
  // in the global string_table
- xcheck_equals(propRecorder[0], 'B');
- xcheck_equals(propRecorder[1], 'a');
+ check_equals(propRecorder[0], 'B');
+ check_equals(propRecorder[1], 'a');
 #else
  // The problem above is a non-issue in SWF7 or higher, as 'b' and
  // 'B' will be separate entries in the string_table

=== modified file 'testsuite/libbase.all/string_tableTest.cpp'
--- a/testsuite/libbase.all/string_tableTest.cpp        2010-01-11 06:41:38 
+0000
+++ b/testsuite/libbase.all/string_tableTest.cpp        2010-07-05 10:35:12 
+0000
@@ -36,19 +36,26 @@
 int
 main(int /*argc*/, char** /*argv*/)
 {
-       string_table testTable;
+       string_table st;
        
        LogFile& lgf = LogFile::getDefaultInstance();
        lgf.setVerbosity(2);
 
-       testTable.insert("A");
-       testTable.insert("B");
-       testTable.insert("C");
-
-       check_equals(testTable.find("D",false),0);
-       check_equals(testTable.find("D"),4);
-       check_equals(testTable.find("A",false),1);
-       check_equals(testTable.find("B",false),2);
-       check_equals(testTable.find("C",false),3);
-       check_equals(testTable.find("D",false),4);
+       st.insert("A");
+       st.insert("B");
+       st.insert("C");
+
+       check_equals(st.find("D",false),0);
+       check(st.find("D") > 0);
+       check(st.find("A") > 0);
+       check(st.find("B") > 0);
+       check(st.find("C") > 0);
+
+    const bool nocase = true;
+    check(equal(st, st.find("AbAb"), st.find("abaB"), nocase));
+    check(equal(st, st.find("AbAb"), st.find("ABAB"), nocase));
+    check(!equal(st, st.find("AbAb"), st.find("abaB"), false));
+    check(!equal(st, st.find("AbAb"), st.find("ABAB"), false));
+
+
 }

=== modified file 'testsuite/libcore.all/PropertyListTest.cpp'
--- a/testsuite/libcore.all/PropertyListTest.cpp        2010-05-21 01:26:20 
+0000
+++ b/testsuite/libcore.all/PropertyListTest.cpp        2010-07-05 15:43:30 
+0000
@@ -142,7 +142,8 @@
                check_equals(props.size(), 4);
 
                // Set property var2 as protected from deletion!
-               check(props.setFlags(st.find("var2"), PropFlags::dontDelete, 
0));
+               props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
+        check(props.getProperty(st.find("var2")));
                // this fails (protected from deletion)
                std::pair<bool, bool> delpair = 
props.delProperty(st.find("var2"));
                check_equals(delpair.first, true); // property was found
@@ -197,7 +198,8 @@
                check_equals(props.size(), 3);
 
                // Set property var2 as protected from deletion!
-               check(props.setFlags(st.find("var2"), PropFlags::dontDelete, 
0));
+               props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
+        check(props.getProperty(st.find("var2")));
                // this fails (protected from deletion)
                std::pair<bool, bool> delpair = 
props.delProperty(st.find("var2"));
                check_equals(delpair.first, true); // property was found

=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING  2010-06-29 10:22:08 +0000
+++ b/testsuite/swfdec/PASSING  2010-07-02 15:36:43 +0000
@@ -711,6 +711,7 @@
 loadobject-sendandload-8.swf:75cc0c0c435987ef63b0abc9a327a2b2
 loadvariables-5.swf:a24997be9ca59d8da2216f9527d0279a
 loadvars-5.swf:378a93e3fc7821a72f61332dcfa6cbf7
+loadvars-decode-6.swf:9c41bfc273298905ba56dfa0308212b7
 loadvars-decode-7.swf:c56b42214f26888edba5d991f711c209
 loadvars-decode-8.swf:ed7cb98e1a1ec7f7e6a6730a3d884f9a
 loadvars-decode-return-5.swf:7d961f35feb3d46db0725e93c26bb90a
@@ -898,6 +899,7 @@
 object-properties-6.swf:c34734222b0c6eef649ab3b92b1b830f
 object-properties-7.swf:71ebb1f47408d993409748dae8d32d5e
 object-properties-8.swf:992fafbfd6ae4927116892eb205aac0f
+object-resolve-5.swf:5ec01818d35026f5ec889416fbbf8320
 object-resolve-propflags-9.swf:db769008cba912cd906834a4722fdb95
 object-valueof-5.swf:2520f058ac5a1af3db81ba9b3002e6ab
 object-valueof-6.swf:68d80a5ba580357d1dfeb3b515691e7e
@@ -1421,6 +1423,8 @@
 text-field-variable-5.swf:20821d0f34ab14b27bbc55f27c70c57f
 textformat-init-5.swf:52dec30885359d5bdda450588076eb10
 textformat-init-5.swf:d45b857148b96635af7d18855cb067ae
+textformat-properties-5.swf:a879a08351954d91c45d4f67e5ba2edd
+textformat-properties-6.swf:15e2a52688f6b11796dabf9d26061276
 textformat-properties-7.swf:390495b699f387f9647c8cf47afa2175
 text-snapshot-properties-5.swf:caf502463913e8aa1959715f629b92aa
 text-snapshot-properties-6.swf:b17d4634477fa1e2a5a095fba489d3ed
@@ -1501,6 +1505,9 @@
 xml-cdata-6.swf:d7559375e07591033d7739671a8c4d42
 xml-cdata-7.swf:5e51dafbe7f6af8206041ecabf0016f8
 xml-cdata-8.swf:d5537f4fb83eaf49d615eecb89b2ae95
+xml-errors-5.swf:d97d4e6fd3a604ff845c7cbdee144003
+xml-errors-6.swf:147e755000980143b5c145867523da
+xml-errors-6.swf:147e755000980143b5c145867523da51
 xml-errors-7.swf:0f90a1e9ae561ecc4c3206bb1e966ca1
 xml-errors-8.swf:321a6535952813fadeaef64c99fa467d
 xml-escape-6.swf:302349505514bd60239c7019355f6ab8


reply via email to

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