gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11675: Improve ugly and verbose han


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11675: Improve ugly and verbose handling of namespaces by using ObjectURI much more.
Date: Wed, 02 Dec 2009 16:31:53 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11675 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-12-02 16:31:53 +0100
message:
  Improve ugly and verbose handling of namespaces by using ObjectURI much more.
  This now makes usage almost transparent, as using a string_table::key will
  automatically use the global namespace without the need for a namespace
  argument at an unpredictable place in the argument list for every single
  function.
  
  Be stricter about namespaces for AVM2.
added:
  libcore/ObjectURI.h
modified:
  extensions/mysql/mysql_db.cpp
  libcore/ClassHierarchy.cpp
  libcore/ClassHierarchy.h
  libcore/Makefile.am
  libcore/MovieClip.cpp
  libcore/Property.cpp
  libcore/Property.h
  libcore/PropertyList.cpp
  libcore/PropertyList.h
  libcore/abc/Method.cpp
  libcore/abc/Script.cpp
  libcore/abc/Script.h
  libcore/as_object.cpp
  libcore/as_object.h
  libcore/as_value.cpp
  libcore/asobj/Array_as.cpp
  libcore/asobj/Array_as.h
  libcore/asobj/Globals.cpp
  libcore/asobj/flash/display/BitmapData_as.cpp
  libcore/asobj/flash/display/display_pkg.cpp
  libcore/asobj/flash/external/ExternalInterface_as.cpp
  libcore/asobj/flash/external/external_pkg.cpp
  libcore/asobj/flash/filters/BitmapFilter_as.cpp
  libcore/asobj/flash/filters/filters_pkg.cpp
  libcore/asobj/flash/flash_pkg.cpp
  libcore/asobj/flash/geom/ColorTransform_as.cpp
  libcore/asobj/flash/geom/Matrix_as.cpp
  libcore/asobj/flash/geom/Point_as.cpp
  libcore/asobj/flash/geom/Rectangle_as.cpp
  libcore/asobj/flash/geom/Transform_as.cpp
  libcore/asobj/flash/geom/geom_pkg.cpp
  libcore/asobj/flash/net/SharedObject_as.cpp
  libcore/asobj/flash/net/net_pkg.cpp
  libcore/asobj/flash/text/text_pkg.cpp
  libcore/namedStrings.cpp
  libcore/namedStrings.h
  libcore/vm/Machine.cpp
=== modified file 'extensions/mysql/mysql_db.cpp'
--- a/extensions/mysql/mysql_db.cpp     2009-11-05 08:06:43 +0000
+++ b/extensions/mysql/mysql_db.cpp     2009-12-02 14:34:57 +0000
@@ -331,7 +331,7 @@
             row = qresult[i];
             for (size_t j=0; j< row.size(); j++) {
                 as_value entry = row[j];
-                arr->callMethod(NSV::PROP_PUSH, entry);
+                callMethod(arr, NSV::PROP_PUSH, entry);
             }
         }
         return as_value(true);
@@ -366,7 +366,7 @@
         as_value aaa = *res;       
         Global_as& gl = getGlobal(fn);
         as_object* arr = gl.createArray();
-        arr->callMethod(NSV::PROP_PUSH, aaa);
+        callMethod(arr, NSV::PROP_PUSH, aaa);
         return as_value(arr);
     }
     log_aserror("Mysql.fetch(): missing arguments");

=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp        2009-12-01 11:02:43 +0000
+++ b/libcore/ClassHierarchy.cpp        2009-12-02 14:27:13 +0000
@@ -58,7 +58,7 @@
 class declare_extension_function : public as_function
 {
 private:
-    ClassHierarchy::ExtensionClass mDeclaration;
+    ClassHierarchy::ExtensionClass _decl;
     as_object *mTarget;
     Extension *mExtension;
 
@@ -69,7 +69,7 @@
             Extension* e)
         :
         as_function(getGlobal(*g)),
-        mDeclaration(c),
+        _decl(c),
         mTarget(g),
         mExtension(e)
     {
@@ -78,19 +78,20 @@
     virtual as_value call(const fn_call& fn)
     {
         string_table& st = getStringTable(fn);
-        log_debug("Loading extension class %s", st.value(mDeclaration.name));
+        log_debug("Loading extension class %s", st.value(getName(_decl.uri)));
 
         as_value super;
-        if (mDeclaration.super_name)
+        if (getName(_decl.super))
         {
             // Check to be sure our super exists.
             // This will trigger its instantiation if necessary.
-            if (!mTarget->get_member(mDeclaration.super_name, &super))
-            {
+            if (!mTarget->get_member(_decl.super, &super)) {
                 // Error here -- doesn't exist.
-                log_error("Can't find %s (Superclass of %s)",
-                    st.value(mDeclaration.super_name),
-                    st.value(mDeclaration.name));
+                log_error("Can't find %s.%s (Superclass of %s.%s)",
+                    st.value(getNamespace(_decl.super)),
+                    st.value(getName(_decl.super)),
+                    st.value(getNamespace(_decl.uri)),
+                    st.value(getName(_decl.uri)));
                 super.set_undefined();
                 return super;
             }
@@ -98,22 +99,22 @@
             {
                 // Error here -- not an object.
                 log_error("%s (Superclass of %s) is not a function (%s)",
-                    st.value(mDeclaration.super_name),
-                    st.value(mDeclaration.name), super);
+                    st.value(getName(_decl.super)),
+                    st.value(getName(_decl.uri)), super);
                 super.set_undefined();
                 return super;
             }
         }
-        if (mExtension->initModuleWithFunc(mDeclaration.file_name,
-            mDeclaration.init_name, *mTarget))
+        if (mExtension->initModuleWithFunc(_decl.file_name,
+            _decl.init_name, *mTarget))
         {
             // Successfully loaded it, now find it, set its proto, and return.
             as_value us;
-            mTarget->get_member(mDeclaration.name, &us);
+            mTarget->get_member(_decl.uri, &us);
             return us;
         }
         // Error here -- not successful in loading.
-        log_error("Could not load class %s", st.value(mDeclaration.name));
+        log_error("Could not load class %s", st.value(getName(_decl.uri)));
         super.set_undefined();
         return super;
     }
@@ -123,13 +124,13 @@
 {
 
 public:
+
     bool isBuiltin() { return true; }
 
-    declare_native_function(const ClassHierarchy::NativeClass &c,
-        as_object *g)
+    declare_native_function(const ClassHierarchy::NativeClass &c, as_object *g)
         :
         as_function(getGlobal(*g)),
-        mDeclaration(c),
+        _decl(c),
         mTarget(g)
     {
     }
@@ -137,26 +138,25 @@
     virtual as_value call(const fn_call& fn)
     {
         string_table& st = getStringTable(fn);
-        log_debug("Loading native class %s", st.value(mDeclaration.name));
+        log_debug("Loading native class %s", st.value(getName(_decl.uri)));
 
-        mDeclaration.initializer(*mTarget,
-                ObjectURI(mDeclaration.name, mDeclaration.namespace_name));
+        _decl.initializer(*mTarget, _decl.uri);
         // Successfully loaded it, now find it, set its proto, and return.
         as_value us;
-        if (mTarget->get_member(mDeclaration.name, &us,
-                    mDeclaration.namespace_name)) {
+        if (mTarget->get_member(_decl.uri, &us)) {
 
             as_value super;
-            if (mDeclaration.super_name)
+            if (getName(_decl.super))
             {
                 // Check to be sure our super exists.
                 // This will trigger its instantiation if necessary.
-                if (!mTarget->get_member(mDeclaration.super_name, &super))
-                {
+                if (!mTarget->get_member(_decl.super, &super)) {
                     // Error here -- doesn't exist.
-                    log_error("Can't find %s (Superclass of %s)",
-                        st.value(mDeclaration.super_name),
-                        st.value(mDeclaration.name));
+                    log_error("Can't find %s.%s (Superclass of %s.%s)",
+                        st.value(getNamespace(_decl.super)),
+                        st.value(getName(_decl.super)),
+                        st.value(getNamespace(_decl.uri)),
+                        st.value(getName(_decl.uri)));
                     super.set_undefined();
                     return super;
                 }
@@ -164,8 +164,8 @@
                 {
                     // Error here -- not an object.
                     log_error("%s (Superclass of %s) is not a function (%s)",
-                        st.value(mDeclaration.super_name),
-                        st.value(mDeclaration.name), super);
+                        st.value(getName(_decl.super)),
+                        st.value(getName(_decl.uri)), super);
                     super.set_undefined();
                     return super;
                 }
@@ -176,19 +176,21 @@
 
             if (!us.to_object(gl)) {
                 log_error("Native class %s is not an object after "
-                        "initialization (%s)", st.value(mDeclaration.name), 
us);
+                        "initialization (%s)",
+                        st.value(getName(_decl.uri)), us);
             }
         }
         else
         {
             log_error("Native class %s is not found after initialization", 
-                st.value(mDeclaration.name));
+                st.value(getName(_decl.uri)));
         }
         return us;
     }
 
 private:
-    ClassHierarchy::NativeClass mDeclaration;
+
+    ClassHierarchy::NativeClass _decl;
     as_object *mTarget;
 
 };
@@ -206,17 +208,17 @@
 
 #ifdef ENABLE_AVM2
     if (isAS3(*mGlobal)) {
-        mGlobalNamespace->stubPrototype(*this, c.name);
-        mGlobalNamespace->getScript(c.name)->setDeclared();
-        mGlobalNamespace->getScript(c.name)->setSystem();
+        mGlobalNamespace->stubPrototype(*this, getName(c.uri));
+        mGlobalNamespace->getScript(getName(c.uri))->setDeclared();
+        mGlobalNamespace->getScript(getName(c.uri))->setSystem();
     }
 #endif
 
     as_function* getter(new declare_extension_function(c, mGlobal, 
mExtension));
 
-    int flags=PropFlags::dontEnum;
+    int flags = PropFlags::dontEnum;
     addVisibilityFlag(flags, c.version);
-    return mGlobal->init_destructive_property(c.name, *getter, flags);
+    return mGlobal->init_destructive_property(c.uri, *getter, flags);
 }
 
 bool
@@ -225,13 +227,13 @@
 
 #ifdef ENABLE_AVM2
     if (isAS3(*mGlobal)) {
-        abc::Namespace *nso = findNamespace(c.namespace_name);
-
-        if (!nso) nso = addNamespace(c.namespace_name);
-
-        nso->stubPrototype(*this, c.name);
-        nso->getScript(c.name)->setDeclared();
-        nso->getScript(c.name)->setSystem();
+        abc::Namespace *nso = findNamespace(getNamespace(c.uri));
+
+        if (!nso) nso = addNamespace(getNamespace(c.uri));
+
+        nso->stubPrototype(*this, getName(c.uri));
+        nso->getScript(getName(c.uri))->setDeclared();
+        nso->getScript(getName(c.uri))->setSystem();
     }
 #endif
 
@@ -239,8 +241,7 @@
     
     int flags = PropFlags::dontEnum;
     addVisibilityFlag(flags, c.version);
-    return mGlobal->init_destructive_property(c.name, *getter, flags,
-            c.namespace_name);
+    return mGlobal->init_destructive_property(c.uri, *getter, flags);
 }
 
 
@@ -266,9 +267,9 @@
     string_table& st = VM::get().getStringTable();
 
     os << "("
-        << " name:" << st.value(c.name)
-        << " super:" << st.value(c.super_name)
-        << " namespace:" << st.value(c.namespace_name)
+        << " name:" << st.value(getName(c.uri))
+        << " super:" << st.value(getName(c.super))
+        << " namespace:" << st.value(getNamespace(c.uri))
         << " version:" << c.version
         << ")";
 
@@ -282,9 +283,9 @@
 
     os << "(file:" << c.file_name
         << " init:" << c.init_name
-        << " name:" << st.value(c.name)
-        << " super:" << st.value(c.super_name)
-        << " namespace:" << st.value(c.namespace_name)
+        << " name:" << st.value(getName(c.uri))
+        << " super:" << st.value(getName(c.super))
+        << " namespace:" << st.value(getNamespace(c.uri))
         << " version:" << c.version
         << ")";
 

=== modified file 'libcore/ClassHierarchy.h'
--- a/libcore/ClassHierarchy.h  2009-12-01 11:02:43 +0000
+++ b/libcore/ClassHierarchy.h  2009-12-02 12:30:12 +0000
@@ -62,14 +62,8 @@
                /// mysql_class_init
                std::string init_name;
 
-               /// The name of the class.
-               string_table::key name;
-
-               /// The name of the inherited class. Ordinarily should be 
CLASS_OBJECT
-               string_table::key super_name;
-
-               /// The name of the namespace in which this belongs.
-               string_table::key namespace_name;
+        const ObjectURI uri;
+        const ObjectURI super;
 
                /// The version at which this should be added.
                int version;
@@ -81,13 +75,12 @@
         /// The type of function to use for initialization
                typedef void (*InitFunc)(as_object& obj, const ObjectURI& uri);
 
-        NativeClass(InitFunc init, string_table::key n,
-                string_table::key sc, string_table::key ns, int ver)
+        NativeClass(InitFunc init, const ObjectURI& u, const ObjectURI& s,
+                int ver)
             :
             initializer(init),
-            name(n),
-            super_name(sc),
-            namespace_name(ns),
+            uri(u),
+            super(s),
             version(ver)
         {}
 
@@ -97,14 +90,10 @@
                InitFunc initializer;
 
                /// The name of the class.
-               string_table::key name;
-
-               /// The name of the inherited class. Object is assumed if
-               /// none is given. (Unless name is itself Object)
-               string_table::key super_name;
-
-               /// The name of the namespace in which this belongs.
-               string_table::key namespace_name;
+               const ObjectURI uri;
+
+               /// The name of the inherited class.
+               const ObjectURI super;
 
                /// The version at which this should be visible.
                int version;

=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am       2009-12-01 11:02:43 +0000
+++ b/libcore/Makefile.am       2009-12-02 12:30:12 +0000
@@ -231,6 +231,7 @@
 EXTENSIONS_API = \
        Relay.h \
        as_object.h \
+       ObjectURI.h \
        Property.h \
        PropertyList.h \
        as_value.h \

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-11-30 13:09:55 +0000
+++ b/libcore/MovieClip.cpp     2009-12-02 14:27:13 +0000
@@ -733,7 +733,7 @@
 
     // See if it's a member
     as_value tmp;
-    if (!obj->as_object::get_member(key, &tmp, 0)) {
+    if (!obj->as_object::get_member(key, &tmp)) {
         return NULL;
     }
     if (!tmp.is_object()) {

=== added file 'libcore/ObjectURI.h'
--- a/libcore/ObjectURI.h       1970-01-01 00:00:00 +0000
+++ b/libcore/ObjectURI.h       2009-12-02 14:25:11 +0000
@@ -0,0 +1,81 @@
+
+#ifndef GNASH_OBJECTURI_H
+#define GNASH_OBJECTURI_H
+
+#include "string_table.h"
+#include <ostream>
+#include <boost/format.hpp>
+/// Define this for verbose logging of ObjectURIs
+//#define FULL_OBJECT_URI_LOGGING 1
+
+
+namespace gnash {
+
+/// A URI for describing as_objects.
+//
+/// This is used as a unique identifier for any object member, especially
+/// prototypes, class, constructors.
+struct ObjectURI
+{
+
+    class Logger;
+
+    /// Construct an ObjectURI from name and namespace.
+    ObjectURI(string_table::key name, string_table::key ns = 0)
+        :
+        name(name),
+        ns(ns)
+    {}
+
+    string_table::key name;
+    string_table::key ns;
+
+};
+
+/// Comparator for ObjectURI so it can serve as a key in stdlib containers.
+inline bool
+operator<(const ObjectURI& a, const ObjectURI& b)
+{
+    if (a.name < b.name) return true;
+    return (a.name == b.name) && a.ns < b.ns;
+}
+
+/// Get the name element of an ObjectURI
+inline string_table::key
+getName(const ObjectURI& o)
+{
+    return o.name;
+}
+
+/// Get the namespace element of an ObjectURI
+inline string_table::key
+getNamespace(const ObjectURI& o)
+{
+    return o.ns;
+}
+
+class ObjectURI::Logger
+{
+public:
+    Logger(string_table& st) : _st(st) {}
+
+    std::string operator()(const ObjectURI& uri) const {
+
+#ifdef FULL_OBJECT_URI_LOGGING
+        const string_table::key ns = getNamespace(uri);
+        const string_table::key name = getName(uri);
+
+        boost::format f = boost::format("URI: property %1%(%2%) in namespace "
+               " %3%(%4%)") % _st.value(name) % name % _st.value(ns) % ns;
+        return f.str();
+#else
+        return _st.value(getNamespace(uri)) + "." + _st.value(getName(uri));
+#endif
+
+    }
+private:
+    string_table& _st;
+};
+
+} // namespace gnash
+#endif

=== modified file 'libcore/Property.cpp'
--- a/libcore/Property.cpp      2009-11-23 07:42:51 +0000
+++ b/libcore/Property.cpp      2009-12-02 07:28:05 +0000
@@ -23,21 +23,55 @@
 
 namespace gnash {
 
+void
+GetterSetter::UserDefinedGetterSetter::markReachableResources() const
+{
+       if (_getter) _getter->setReachable();
+       if (_setter) _setter->setReachable();
+       _underlyingValue.setReachable();
+}
+
+as_value
+GetterSetter::UserDefinedGetterSetter::get(fn_call& fn) const
+{
+       ScopedLock lock(*this);
+       if (!lock.obtainedLock()) {
+               return _underlyingValue;
+       }
+
+       if (_getter) return _getter->call(fn);
+    
+    // should we return underlyingValue here ?
+       return as_value(); 
+}
+
+void
+GetterSetter::UserDefinedGetterSetter::set(fn_call& fn)
+{
+       ScopedLock lock(*this);
+       if (!lock.obtainedLock() || ! _setter) {
+               _underlyingValue = fn.arg(0);
+               return;
+       }
+
+       _setter->call(fn);
+}
+
 as_value
 Property::getDelayedValue(const as_object& this_ptr) const
 {
-       const GetterSetter* a = boost::get<const GetterSetter>(&mBound);
+       const GetterSetter* a = boost::get<const GetterSetter>(&_bound);
 
        as_environment env(getVM(this_ptr));
        fn_call fn(const_cast<as_object*>(&this_ptr), env);
-       if (mDestructive)
+       if (_destructive)
        {
                as_value ret = a->get(fn);
                // The getter might have called the setter, and we should not 
override.
-               if (mDestructive)
+               if (_destructive)
                {
-                       mBound = ret;
-                       mDestructive = false;
+                       _bound = ret;
+                       _destructive = false;
                }
                return ret;
        }
@@ -48,7 +82,7 @@
 void
 Property::setDelayedValue(as_object& this_ptr, const as_value& value)
 {
-       GetterSetter* a = boost::get<GetterSetter>(&mBound);
+       GetterSetter* a = boost::get<GetterSetter>(&_bound);
 
        as_environment env(getVM(this_ptr));
 
@@ -66,11 +100,11 @@
 {
        if (isGetterSetter())
        {
-               GetterSetter* a = boost::get<GetterSetter>(&mBound);
+               GetterSetter* a = boost::get<GetterSetter>(&_bound);
                a->setSetter(func);
        }
        else
-               mBound = GetterSetter(NULL, func);
+               _bound = GetterSetter(NULL, func);
 }
 
 void
@@ -78,83 +112,46 @@
 {
        if (isGetterSetter())
        {
-               GetterSetter* a = boost::get<GetterSetter>(&mBound);
+               GetterSetter* a = boost::get<GetterSetter>(&_bound);
                a->setGetter(func);
        }
-       else mBound = GetterSetter(func, 0);
+       else _bound = GetterSetter(func, 0);
 }
 
 void
 Property::setReachable() const
 {
-       switch (mBound.which())
+       switch (_bound.which())
        {
-           case 0: // Blank, nothing to do.
-                   break;
-           case 1: // Simple property, value
-           {
-                   boost::get<as_value>(mBound).setReachable();
-                   break;
-           }
-           case 2: // Getter/setter
-           {
-                   const GetterSetter& a = boost::get<GetterSetter>(mBound);
+           case TYPE_EMPTY: 
+                   break;
+
+        case TYPE_VALUE: 
+                   boost::get<as_value>(_bound).setReachable();
+                   break;
+
+           case TYPE_GETTER_SETTER: 
+           {
+                   const GetterSetter& a = boost::get<GetterSetter>(_bound);
                    a.markReachableResources();
                    break;
            }
-           default:
-               abort(); // Not here.
-                   break;
-       }
-}
-
-void
-GetterSetter::UserDefinedGetterSetter::markReachableResources() const
-{
-       if (mGetter) mGetter->setReachable();
-       if (mSetter) mSetter->setReachable();
-       underlyingValue.setReachable();
-}
-
-as_value
-GetterSetter::UserDefinedGetterSetter::get(fn_call& fn) const
-{
-       ScopedLock lock(*this);
-       if ( ! lock.obtained() )
-       {
-               return underlyingValue;
-       }
-
-       if (mGetter) return mGetter->call(fn);
-       else return as_value(); // should we return underlyingValue here ?
-}
-
-void
-GetterSetter::UserDefinedGetterSetter::set(fn_call& fn)
-{
-       ScopedLock lock(*this);
-       if ( ! lock.obtained() || ! mSetter )
-       {
-               underlyingValue = fn.arg(0);
-               return;
-       }
-
-       mSetter->call(fn);
+       }
 }
 
 as_value
 Property::getValue(const as_object& this_ptr) const
 {
-       switch (mBound.which())
+       switch (_bound.which())
        {
-       case 0: // blank, nothing to do.
-               return as_value();
-       case 1: // Bound value
-               return boost::get<as_value>(mBound);
-       case 2: // Getter/setter
-               return getDelayedValue(this_ptr);
-       } // end of switch
-       return as_value(); // Not reached.
+        case TYPE_EMPTY:
+            return as_value();
+        case TYPE_VALUE:
+            return boost::get<as_value>(_bound);
+        case TYPE_GETTER_SETTER: 
+            return getDelayedValue(this_ptr);
+       } 
+    return as_value();
 }
 
 const as_value&
@@ -162,51 +159,50 @@
 {
        static as_value undefVal;
 
-       switch (mBound.which())
+       switch (_bound.which())
        {
-       case 0: // blank, nothing to do.
-               return undefVal;
-       case 1: // Bound value
-               return boost::get<as_value&>(mBound);
-       case 2: // Getter/setter
-               return boost::get<GetterSetter&>(mBound).getCache();
-       } // end of switch
-       return undefVal; // not reached
+        case TYPE_EMPTY:
+            return undefVal;
+        case TYPE_VALUE:
+            return boost::get<as_value&>(_bound);
+        case TYPE_GETTER_SETTER:
+            return boost::get<GetterSetter&>(_bound).getCache();
+       } 
+    return undefVal;
 }
 
 void
 Property::setValue(as_object& this_ptr, const as_value &value)
 {
-       switch (mBound.which())
+       switch (_bound.which())
        {
-       case 0: // As yet unbound, so make it a simple
-       case 1: // Bound value, set. Trust our callers to check read-only.
-               mBound = value;
-               return;
-       case 2: // Getter/setter
-               // Destructive are always overwritten.
-               if (mDestructive)
-               {
-                       mDestructive = false;
-                       mBound = value;
-               }
-               else setDelayedValue(this_ptr, value);
-               return;
-       }
+        case TYPE_EMPTY: 
+        case TYPE_VALUE: 
+            _bound = value;
+            return;
+        case TYPE_GETTER_SETTER:
+            // Destructive are always overwritten.
+            if (_destructive) {
+                _destructive = false;
+                _bound = value;
+            }
+            else setDelayedValue(this_ptr, value);
+            return;
+        }
 }
 
 void
 Property::setCache(const as_value &value)
 {
-       switch (mBound.which())
+       switch (_bound.which())
        {
-       case 0: // As yet unbound, so make it a simple
-       case 1: // Bound value, set. Trust our callers to check read-only.
-               mBound = value;
-               return;
-       case 2: // Getter/setter
-               boost::get<GetterSetter&>(mBound).setCache(value);
-               return;
+        case TYPE_EMPTY:
+        case TYPE_VALUE: 
+            _bound = value;
+            return;
+        case TYPE_GETTER_SETTER: 
+            boost::get<GetterSetter&>(_bound).setCache(value);
+            return;
        }
 }
 

=== modified file 'libcore/Property.h'
--- a/libcore/Property.h        2009-07-16 08:53:33 +0000
+++ b/libcore/Property.h        2009-12-02 14:27:13 +0000
@@ -23,6 +23,7 @@
 #include "as_value.h"
 #include "string_table.h"
 #include "log.h"
+#include "ObjectURI.h"
 
 #include <boost/variant.hpp>
 #include <cassert>
@@ -47,13 +48,13 @@
        GetterSetter(as_function* getter, as_function* setter)
                :
                _getset(UserDefinedGetterSetter(getter, setter))
-       {/**/}
+       {}
 
        /// Construct a native getter-setter
        GetterSetter(as_c_function_ptr getter, as_c_function_ptr setter)
                :
                _getset(NativeGetterSetter(getter, setter))
-       {/**/}
+       {}
 
        /// Invoke the getter
        as_value get(fn_call& fn) const
@@ -101,10 +102,11 @@
        /// Get the cache value (for user-defined getter-setters)
        const as_value& getCache() const
        {
-               switch ( _getset.which() )
+               switch (_getset.which())
                {
                        case 0: // user-defined
-                               return 
boost::get<UserDefinedGetterSetter>(_getset).getUnderlying();
+                               return boost::get<UserDefinedGetterSetter>(
+                        _getset).getUnderlying();
                }
                static as_value undefVal;
                return undefVal;
@@ -113,8 +115,7 @@
        /// Set a user-defined getter
        void setGetter(as_function* fun)
        {
-               if ( _getset.which() == 0 )
-               {
+               if (_getset.which() == 0) {
                        
boost::get<UserDefinedGetterSetter>(_getset).setGetter(fun);
                }
        }
@@ -122,31 +123,32 @@
        /// Set a user-defined setter
        void setSetter(as_function* fun)
        {
-               if ( _getset.which() == 0 )
-               {
+               if (_getset.which() == 0) {
                        
boost::get<UserDefinedGetterSetter>(_getset).setSetter(fun);
                }
        }
 
        void markReachableResources() const
        {
-               if ( _getset.which() == 0 )
-               {
-                       
boost::get<UserDefinedGetterSetter>(_getset).markReachableResources();
+               if (_getset.which() == 0) {
+                       boost::get<UserDefinedGetterSetter>(
+                    _getset).markReachableResources();
                }
        }
 
 private:
 
        /// User-defined getter/setter
-       class UserDefinedGetterSetter {
+       class UserDefinedGetterSetter
+    {
        public:
+
                UserDefinedGetterSetter(as_function* get, as_function* set)
                        :
-                       mGetter(get),
-                       mSetter(set),
-                       underlyingValue(),
-                       beingAccessed(false)
+                       _getter(get),
+                       _setter(set),
+                       _underlyingValue(),
+                       _beingAccessed(false)
                {}
 
                /// Invoke the getter
@@ -156,49 +158,49 @@
                void set(fn_call& fn);
 
                /// Get the underlying value
-               const as_value& getUnderlying() const { return underlyingValue; 
}
+               const as_value& getUnderlying() const { return 
_underlyingValue; }
 
                /// Set the underlying value
-               void setUnderlying(const as_value& v) { underlyingValue=v; }
+               void setUnderlying(const as_value& v) { _underlyingValue = v; }
 
                /// Set the setter
-               void setSetter(as_function* setter) { mSetter = setter; }
+               void setSetter(as_function* setter) { _setter = setter; }
 
                /// Set the getter
-               void setGetter(as_function* getter) { mGetter = getter; }
+               void setGetter(as_function* getter) { _getter = getter; }
 
                void markReachableResources() const;
 
        private:
-               as_function* mGetter;
-               as_function* mSetter;
-
-               as_value underlyingValue;
-
-               mutable bool beingAccessed;
-
-               /// For SWF6 (not higher) a user-defined getter-setter would 
not be invoked
-               /// while being set. This ScopedLock helps marking a
-               /// Getter-Setter as being invoked in an exception-safe
-               /// manner.
-               class ScopedLock {
-                       const UserDefinedGetterSetter& a;
-                       bool obtainedLock;
-
-                       ScopedLock(ScopedLock&);
-                       ScopedLock& operator==(ScopedLock&);
+
+               as_function* _getter;
+               as_function* _setter;
+
+               as_value _underlyingValue;
+
+               mutable bool _beingAccessed;
+
+               /// For SWF6 (not higher) a user-defined getter-setter would not
+        /// be invoked while being set. This ScopedLock helps marking a
+        /// Getter-Setter as being invoked in an exception-safe manner.
+        //
+        /// Note this is not thread safe and does not attempt to provide 
+        /// thread safety.
+               class ScopedLock : boost::noncopyable
+        {
                public:
 
-                       ScopedLock(const UserDefinedGetterSetter& na) : a(na)
+                       ScopedLock(const UserDefinedGetterSetter& na)
+                :
+                _a(na),
+                _obtainedLock(_a._beingAccessed ? false : true)
                        {
-                               if ( a.beingAccessed ) obtainedLock=false;
-                               else {
-                                       a.beingAccessed = true;
-                                       obtainedLock = true;
-                               }
+                // If we didn't obtain the lock it would be true anyway,
+                // but it's probably polite to avoid touching it.
+                if (_obtainedLock) _a._beingAccessed = true;
                        }
 
-                       ~ScopedLock() { if ( obtainedLock) a.beingAccessed = 
false; }
+                       ~ScopedLock() { if ( _obtainedLock) _a._beingAccessed = 
false; }
 
                        /// Return true if the lock was obtained
                        //
@@ -206,12 +208,15 @@
                        /// which means we should set the underlyingValue 
instead
                        /// of calling the setter (for SWF6, again).
                        ///
-                       bool obtained() const { return obtainedLock; }
-               };
-
-               friend class ScopedLock;
-
-       };
+                       bool obtainedLock() const { return _obtainedLock; }
+
+        private:
+
+                       const UserDefinedGetterSetter& _a;
+                       bool _obtainedLock;
+
+        };
+    };
 
        /// Native GetterSetter
        class NativeGetterSetter {
@@ -220,25 +225,24 @@
 
                NativeGetterSetter(as_c_function_ptr get, as_c_function_ptr set)
                        :
-                       cGetter(get), cSetter(set) {}
+                       _getter(get), _setter(set) {}
 
                /// Invoke the getter
                as_value get(fn_call& fn) const
                {
-                       return cGetter(fn);
+                       return _getter(fn);
                }
 
                /// Invoke the setter
                void set(fn_call& fn)
                {
-                       cSetter(fn);
+                       _setter(fn);
                }
 
        private:
 
-               as_c_function_ptr cGetter;
-
-               as_c_function_ptr cSetter;
+               as_c_function_ptr _getter;
+               as_c_function_ptr _setter;
        };
 
        boost::variant<UserDefinedGetterSetter, NativeGetterSetter> _getset;
@@ -248,124 +252,66 @@
 /// An abstract property
 class Property
 {
-private:
-       friend class PropertyList; // For index access
-
-       /// Properties flags
-       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.
-       mutable boundType mBound;
-
-       // If true, as soon as getValue has been invoked once, the
-       // returned value becomes a fixed return (though it can be
-       // overwritten if not readOnly)
-       mutable bool mDestructive;
-       
-       string_table::key mName;
-       string_table::key mNamespace;
-       // An ordering number, for access by order
-       // (AS3 enumeration and slots, AS2 arrays)
-       int mOrderId;
-
-       /// 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);
-
 public:
        /// Default constructor
-       Property(string_table::key name = 0, string_table::key nsId = 0)
+       Property(const ObjectURI& uri)
         : 
-               mBound(as_value()),
-        mDestructive(false),
-        mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
+               _bound(as_value()),
+        _destructive(false),
+        _uri(uri),
+               _orderID(0)
        {}
 
        /// Copy constructor
        Property(const Property& p)
         :
                _flags(p._flags),
-        mBound(p.mBound),
-        mDestructive(p.mDestructive),
-               mName(p.mName),
-        mNamespace(p.mNamespace),
-        mOrderId(p.mOrderId)
-       {}
-
-       /// Constructor taking initial flags
-       Property(string_table::key name, string_table::key nsId,
-               const PropFlags& flags)
-        :
-        _flags(flags),
-               mBound(as_value()),
-        mDestructive(false),
-        mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
-       {}
-
-       Property(string_table::key name, string_table::key nsId, 
-               const as_value& value)
-        :
-        mBound(value),
-        mDestructive(false),
-               mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
-       {}
-
-       Property(string_table::key name, string_table::key nsId,
-               const as_value& value, const PropFlags& flags)
+        _bound(p._bound),
+        _destructive(p._destructive),
+        _uri(p._uri),
+        _orderID(p._orderID)
+       {}
+
+       Property(const ObjectURI& uri, const as_value& value,
+            const PropFlags& flags = PropFlags())
         :
                _flags(flags),
-        mBound(value),
-        mDestructive(false),
-               mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
+        _bound(value),
+        _destructive(false),
+               _uri(uri),
+               _orderID(0)
        {}
 
-       Property(string_table::key name, string_table::key nsId,
+       Property(const ObjectURI& uri,
                as_function *getter, as_function *setter, 
                const PropFlags& flags, bool destroy = false)
         :
                _flags(flags), 
-        mBound(GetterSetter(getter, setter)),
-               mDestructive(destroy),
-        mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
+        _bound(GetterSetter(getter, setter)),
+               _destructive(destroy),
+        _uri(uri),
+               _orderID(0)
        {}
 
-       Property(string_table::key name, string_table::key nsId,
-               as_function *getter, as_function *setter, bool destroy = false)
+       Property(const ObjectURI& uri, as_function *getter, as_function *setter,
+            bool destroy = false)
         :
                _flags(),
-        mBound(GetterSetter(getter, setter)),
-        mDestructive(destroy),
-               mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
+        _bound(GetterSetter(getter, setter)),
+        _destructive(destroy),
+        _uri(uri),
+               _orderID(0)
        {}
 
-       Property(string_table::key name, string_table::key nsId,
-               as_c_function_ptr getter, as_c_function_ptr setter,
-               const PropFlags& flags, bool destroy = false)
+       Property(const ObjectURI& uri, as_c_function_ptr getter,
+            as_c_function_ptr setter, const PropFlags& flags,
+            bool destroy = false)
                :
                _flags(flags),
-        mBound(GetterSetter(getter, setter)),
-        mDestructive(destroy),
-               mName(name),
-        mNamespace(nsId),
-               mOrderId(0)
+        _bound(GetterSetter(getter, setter)),
+        _destructive(destroy),
+        _uri(uri),
+               _orderID(0)
        {}
 
        /// Set a user-defined setter
@@ -436,19 +382,21 @@
        ///       the index invariant. (at least this is what happens
        ///       with standard containers indexed on an element's member).
        ///
-       void setOrder(int order) { mOrderId = order; }
+       void setOrder(int order) { _orderID = order; }
 
        /// Get the order id
-       int getOrder() const { return mOrderId; }
+       int getOrder() const { return _orderID; }
 
        /// is this a read-only member ?
        bool isReadOnly() const { return _flags.get_read_only(); }
 
        /// Is this a getter/setter property?
-       bool isGetterSetter() const { return mBound.which() == 2; }
+       bool isGetterSetter() const {
+        return _bound.which() == TYPE_GETTER_SETTER;
+    }
 
        /// is this a destructive property ?
-       bool isDestructive() const { return mDestructive; }
+       bool isDestructive() const { return _destructive; }
 
        /// Is this a static property?
        bool isStatic() const { return _flags.get_static(); }
@@ -461,14 +409,50 @@
        /// Clear visibility flags
        void clearVisible(int swfVersion) { _flags.clear_visible(swfVersion); }
 
-       /// What is the name of this property?
-       string_table::key getName() const { return mName; }
-
-       /// What is the namespace of this property?
-       string_table::key getNamespace() const { return mNamespace; }
+    /// The name-namespace pair (ObjectURI) of this Property
+    const ObjectURI& uri() const {
+        return _uri;
+    }
 
        /// Mark this property as being reachable (for the GC)
        void setReachable() const;
+
+private:
+
+       /// Properties flags
+       PropFlags _flags;
+
+    enum Type {
+        TYPE_EMPTY,
+        TYPE_VALUE,
+        TYPE_GETTER_SETTER
+    };
+
+       // 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.
+       mutable BoundType _bound;
+
+       // If true, as soon as getValue has been invoked once, the
+       // returned value becomes a fixed return (though it can be
+       // overwritten if not readOnly)
+       mutable bool _destructive;
+       
+    // 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  2009-12-01 16:03:50 +0000
+++ b/libcore/PropertyList.cpp  2009-12-02 14:52:22 +0000
@@ -43,7 +43,7 @@
 
 PropertyList::PropertyList(const PropertyList& pl)
        :
-       mDefaultOrder(pl.mDefaultOrder),
+       _defaultOrder(pl._defaultOrder),
     _vm(pl._vm)
 {
        import(pl);
@@ -55,57 +55,37 @@
        if ( this != &pl )
        {
                clear();
-               mDefaultOrder = pl.mDefaultOrder;
+               _defaultOrder = pl._defaultOrder;
                import(pl);
        }
        return *this;
 }
 
-// Should find in any namespace if nsId is 0, and any namespace should find
-// something in namespace 0.
-static inline
+
+namespace {
+
+inline
 PropertyList::container::iterator
-iterator_find(const PropertyList::container &p, string_table::key name,
-       string_table::key nsId)
+iterator_find(const PropertyList::container &p, const ObjectURI& uri)
 {
-       if (nsId)
-       {
-               PropertyList::container::iterator i =
-                       p.find(boost::make_tuple(name, nsId));
-               if (i != p.end())
-                       return i;
-               return p.find(boost::make_tuple(name, 0));
-       }
-
-       return p.find(boost::make_tuple(name));
-}
-
-typedef PropertyList::container::index<PropertyList::oType>::type::iterator
-       orderIterator;
-
-static inline
-orderIterator
+    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);
 }
 
-bool
-PropertyList::getValueByOrder(int order, as_value& val,
-       as_object& this_ptr)
-{
-       orderIterator i = iterator_find(_props, order);
-       if (i == _props.get<1>().end())
-               return false;
-
-       val = i->getValue(this_ptr);
-       return true;
-}
-
 const Property*
 PropertyList::getPropertyByOrder(int order)
 {
-       orderIterator i = iterator_find(_props, order);
+    order_iterator i = iterator_find(_props, order);
        if (i == _props.get<1>().end())
                return NULL;
 
@@ -115,7 +95,7 @@
 const Property*
 PropertyList::getOrderAfter(int order)
 {
-       orderIterator i = iterator_find(_props, order);
+    order_iterator i = iterator_find(_props, order);
 
        if (i == _props.get<1>().end())
                return NULL; // Not found at all.
@@ -133,39 +113,39 @@
 bool
 PropertyList::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
 {
-       orderIterator found = iterator_find(_props, slotId + 1);
-       if (found != _props.get<1>().end())
-               return false;
+    order_iterator found = iterator_find(_props, slotId + 1);
+       if (found != _props.get<1>().end()) return false;
 
-       Property a(getName(uri), getNamespace(uri), as_value());
+       Property a(uri, as_value());
        a.setOrder(slotId + 1);
        _props.insert(a);
+
 #ifdef GNASH_DEBUG_PROPERTY
-       string_table& st = _vm.getStringTable();
-       log_debug("Slot for AS property %s::%s inserted with flags %s",
-            getNamespace(uri), getName(uri), a.getFlags());
+    ObjectURI::Logger l(_vm.getStringTable());
+       log_debug("Slot for AS property %s inserted with flags %s", l(uri)
+            a.getFlags());
 #endif
+
        return true;
 }
 
 bool
-PropertyList::setValue(string_table::key key, const as_value& val,
-               as_object& this_ptr, string_table::key nsId,
-               const PropFlags& flagsIfMissing)
+PropertyList::setValue(const ObjectURI& uri, const as_value& val,
+               as_object& this_ptr, const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        
        if (found == _props.end())
        {
                // create a new member
-               Property a(key, nsId, val, flagsIfMissing);
+               Property a(uri, val, flagsIfMissing);
                // Non slot properties are negative ordering in insertion order
-               a.setOrder(- ++mDefaultOrder - 1);
+               a.setOrder(- ++_defaultOrder - 1);
                _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-               string_table& st = _vm.getStringTable();
-               log_debug("Simple AS property %s in namespace %s inserted with 
flags %s",
-                       st.value(key), st.value(nsId), a.getFlags());
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_debug("Simple AS property %s inserted with flags %s",
+                       l(uri), a.getFlags());
 #endif
                return true;
        }
@@ -173,9 +153,9 @@
        const Property& prop = *found;
        if (prop.isReadOnly() && ! prop.isDestructive())
        {
-               string_table& st = _vm.getStringTable();
-               log_error(_("Property %s (key %d) in namespace %s (key %d) is 
read-only %s, not setting it to %s"), 
-                       st.value(key), key, st.value(nsId), nsId, 
prop.getFlags(), val);
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_error(_("Property %s is read-only %s, not setting it to 
%s"), 
+                       l(uri), prop.getFlags(), val);
                return false;
        }
 
@@ -188,10 +168,9 @@
 }
 
 bool
-PropertyList::setFlags(string_table::key key,
-               int setFlags, int clearFlags, string_table::key nsId)
+PropertyList::setFlags(const ObjectURI& uri, int setFlags, int clearFlags)
 {
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        if ( found == _props.end() ) return false;
 
        PropFlags oldFlags = found->getFlags();
@@ -200,57 +179,35 @@
        return f.set_flags(setFlags, clearFlags);
 
 #ifdef GNASH_DEBUG_PROPERTY
-       string_table& st = _vm.getStringTable();
-       log_debug("Flags of property %s in namespace %s changed from %s to  %s",
-               st.value(key), st.value(nsId), oldFlags, found->getFlags());
+    ObjectURI::Logger l(_vm.getStringTable());
+       log_debug("Flags of property %s changed from %s to  %s",
+               l(uri), oldFlags, found->getFlags());
 #endif
 }
 
-std::pair<size_t,size_t>
+void
 PropertyList::setFlagsAll(int setFlags, int clearFlags)
 {
-       size_t success=0;
-       size_t failure=0;
-
-#ifdef GNASH_DEBUG_PROPERTY
-       string_table& st = _vm.getStringTable();
-#endif
-
-        PropertyList::container::iterator it;
-        for (it=_props.begin(); it != _props.end(); ++it)
-       {
-#ifdef GNASH_DEBUG_PROPERTY
-               PropFlags oldFlags = it->getFlags();
-#endif
-
+    PropertyList::container::iterator it;
+    for (it=_props.begin(); it != _props.end(); ++it) {
                PropFlags& f = const_cast<PropFlags&>(it->getFlags());
-               if (f.set_flags(setFlags, clearFlags))
-                       ++success;
-               else
-                       ++failure;
-
-#ifdef GNASH_DEBUG_PROPERTY
-               log_debug("Flags of property %s in namespace %s changed from %s 
to  %s",
-                       st.value(it->getName()), st.value(it->getNamespace()), 
oldFlags, it->getFlags());
-#endif
-       }
-
-       return std::make_pair(success,failure);
+               f.set_flags(setFlags, clearFlags);
+    }
 }
 
 Property*
-PropertyList::getProperty(string_table::key key, string_table::key nsId) const
+PropertyList::getProperty(const ObjectURI& uri) const
 {
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        if (found == _props.end()) return 0;
        return const_cast<Property*>(&(*found));
 }
 
 std::pair<bool,bool>
-PropertyList::delProperty(string_table::key key, string_table::key nsId)
+PropertyList::delProperty(const ObjectURI& uri)
 {
        //GNASH_REPORT_FUNCTION;
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        if (found == _props.end())
        {
                return std::make_pair(false,false);
@@ -266,28 +223,8 @@
        return std::make_pair(true,true);
 }
 
-std::pair<size_t,size_t>
-PropertyList::setFlagsAll(const PropertyList& props,
-               int flagsSet, int flagsClear)
-{
-       size_t success=0;
-       size_t failure=0;
-
-       for (container::const_iterator it = props._props.begin(),
-               itEnd = props._props.end(); it != itEnd; ++it )
-       {
-               string_table::key key = it->mName;
-
-               if (setFlags(key, flagsSet, flagsClear, it->mNamespace)) 
++success;
-               else ++failure;
-       }
-
-       return std::make_pair(success,failure);
-
-}
-
 void
-PropertyList::enumerateKeys(as_environment& env, propNameSet& donelist) const
+PropertyList::enumerateKeys(as_environment& env, PropTracker& donelist) const
 {
        string_table& st = getStringTable(env);
 
@@ -299,11 +236,13 @@
 
                if (i->getFlags().get_dont_enum()) continue;
 
-               if (donelist.insert(std::make_pair(i->mName, 
i->mNamespace)).second) {
-
-            const std::string& qname = i->mNamespace ?
-                st.value(i->mName) + "." + st.value(i->mNamespace) :
-                st.value(i->mName);
+        const ObjectURI& uri = i->uri();
+
+               if (donelist.insert(uri).second) {
+
+            const std::string& qname = getNamespace(uri) ?
+                st.value(getName(uri)) + "." + st.value(getNamespace(uri)) :
+                st.value(getName(uri));
 
                        env.push(qname);
                }
@@ -326,7 +265,7 @@
         // Undefined values should be "undefined" for SWF7 and
         // empty for SWF6.
         const int version = vm.getSWFVersion();
-               to.push_back(std::make_pair(st.value(i->mName),
+               to.push_back(std::make_pair(st.value(getName(i->uri())),
                                
i->getValue(this_ptr).to_string_versioned(version)));
        }
 }
@@ -336,25 +275,22 @@
 void
 PropertyList::dump(as_object& this_ptr, std::map<std::string, as_value>& to) 
 {
-       string_table& st = _vm.getStringTable();
+    ObjectURI::Logger l(_vm.getStringTable());
 
        for (container::const_iterator i=_props.begin(), ie=_props.end();
             i != ie; ++i)
        {
-               to.insert(std::make_pair(
-                    st.value(i->mNamespace) + "::" + st.value(i->mName),
-                    i->getValue(this_ptr)));
+               to.insert(std::make_pair(l(i->uri()), i->getValue(this_ptr)));
        }
 }
 
 void
 PropertyList::dump(as_object& this_ptr)
 {
-       string_table& st = _vm.getStringTable();
-       for (container::const_iterator it=_props.begin(), itEnd=_props.end(); 
it != itEnd; ++it )
-       {
-               log_debug("  %s::%s: %s", st.value(it->mNamespace), 
st.value(it->mName),
-                       it->getValue(this_ptr));
+    ObjectURI::Logger l(_vm.getStringTable());
+       for (container::const_iterator it=_props.begin(), itEnd=_props.end();
+            it != itEnd; ++it) {
+               log_debug("  %s: %s", l(it->uri()), it->getValue(this_ptr));
        }
 }
 
@@ -365,53 +301,53 @@
                itEnd = o._props.end(); it != itEnd; ++it)
        {
                // overwrite any previous property with this name
-               container::iterator found = iterator_find(_props, it->mName, 
it->mNamespace);
+               container::iterator found = iterator_find(_props, it->uri());
                if (found != _props.end())
                {
                        Property a = *it;
                        a.setOrder(found->getOrder());
                        _props.replace(found, a);
 #ifdef GNASH_DEBUG_PROPERTY
-                       string_table& st = _vm.getStringTable();
-                       log_debug("Property %s in namespace %s replaced on 
import: new flags %s",
-                               st.value(a.getName()), 
st.value(a.getNamespace()), a.getFlags());
+            ObjectURI::Logger l(_vm.getStringTable());
+                       log_debug("Property %s replaced on import: new flags 
%s",
+                               l(a.uri()), a.getFlags());
 #endif
                }
                else
                {
                        Property a = *it;
-                       a.setOrder(- ++mDefaultOrder - 1);
+                       a.setOrder(- ++_defaultOrder - 1);
                        _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-                       string_table& st = _vm.getStringTable();
-                       log_debug("Property %s in namespace %s imported with 
flags %s",
-                               st.value(a.getName()), 
st.value(a.getNamespace()), a.getFlags());
+            ObjectURI::Logger l(_vm.getStringTable());
+                       log_debug("Property %s imported with flags %s",
+                               l(a.uri()), a.getFlags());
 #endif
                }
        }
 }
 
 bool
-PropertyList::addGetterSetter(string_table::key key, as_function& getter,
+PropertyList::addGetterSetter(const ObjectURI& uri, as_function& getter,
        as_function* setter, const as_value& cacheVal,
-       const PropFlags& flagsIfMissing, string_table::key nsId)
+       const PropFlags& flagsIfMissing)
 {
-       Property a(key, nsId, &getter, setter, flagsIfMissing);
-       a.setOrder(- ++mDefaultOrder - 1);
+       Property a(uri, &getter, setter, flagsIfMissing);
+       a.setOrder(- ++_defaultOrder - 1);
 
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        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);
+
 #ifdef GNASH_DEBUG_PROPERTY
-               string_table& st = _vm.getStringTable();
-               log_debug("AS GetterSetter %s in namespace %s replaced copying "
-                "flags %s", st.value(key), st.value(nsId), a.getFlags());
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_debug("AS GetterSetter %s replaced copying flags %s", 
l(uri),
+                a.getFlags());
 #endif
 
        }
@@ -420,9 +356,9 @@
                a.setCache(cacheVal);
                _props.insert(a);
 #ifdef GNASH_DEBUG_PROPERTY
-               string_table& st = _vm.getStringTable();
-               log_debug("AS GetterSetter %s in namespace %s inserted with 
flags %s",
-                       st.value(key), st.value(nsId), a.getFlags());
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_debug("AS GetterSetter %s inserted with flags %s", l(uri),
+                a.getFlags());
 #endif
        }
 
@@ -430,26 +366,23 @@
 }
 
 bool
-PropertyList::addGetterSetter(string_table::key key, as_c_function_ptr getter,
-       as_c_function_ptr setter, const PropFlags& flagsIfMissing,
-       string_table::key nsId)
+PropertyList::addGetterSetter(const ObjectURI& uri, as_c_function_ptr getter,
+       as_c_function_ptr setter, const PropFlags& flagsIfMissing)
 {
-       Property a(key, nsId, getter, setter, flagsIfMissing);
-       a.setOrder(- ++mDefaultOrder - 1);
+       Property a(uri, getter, setter, flagsIfMissing);
+       a.setOrder(- ++_defaultOrder - 1);
 
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        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);
-               //assert ( iterator_find(_props, key, nsId) != _props.end() );
+
 #ifdef GNASH_DEBUG_PROPERTY
-               string_table& st = _vm.getStringTable();
-               log_debug("Native GetterSetter %s in namespace %s replaced "
-                "copying flags %s", st.value(key), st.value(nsId),
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_debug("Native GetterSetter %s replaced copying flags %s", 
l(uri),
                 a.getFlags());
 #endif
 
@@ -457,7 +390,6 @@
        else
        {
                _props.insert(a);
-               //assert ( iterator_find(_props, key, nsId) != _props.end() );
 #ifdef GNASH_DEBUG_PROPERTY
                string_table& st = _vm.getStringTable();
                log_debug("Native GetterSetter %s in namespace %s inserted with 
"
@@ -469,50 +401,48 @@
 }
 
 bool
-PropertyList::addDestructiveGetter(string_table::key key,
-       as_function& getter, string_table::key nsId,
+PropertyList::addDestructiveGetter(const ObjectURI& uri, as_function& getter, 
        const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        if (found != _props.end())
        {
-               string_table& st = _vm.getStringTable();
-               log_error("Property %s in namespace %s already exists, "
-                "can't addDestructiveGetter", st.value(key), st.value(nsId));
+        ObjectURI::Logger l(_vm.getStringTable());
+               log_error("Property %s already exists, can't 
addDestructiveGetter",
+                l(uri));
                return false; // Already exists.
        }
 
        // destructive getter don't need a setter
-       Property a(key, nsId, &getter, (as_function*)0, flagsIfMissing, true);
-       a.setOrder(- ++mDefaultOrder - 1);
+       Property a(uri, &getter, (as_function*)0, flagsIfMissing, true);
+       a.setOrder(- ++_defaultOrder - 1);
        _props.insert(a);
 
 #ifdef GNASH_DEBUG_PROPERTY
-       string_table& st = _vm.getStringTable();
-       log_debug("Destructive AS property %s (key %d) in namespace %s "
-            "(key %d) inserted with flags %s",
-                   st.value(key), key, st.value(nsId), nsId, a.getFlags());
+    ObjectURI::Logger l(_vm.getStringTable());
+       log_debug("Destructive AS property %s inserted with flags %s",
+            l(uri), a.getFlags());
 #endif
 
        return true;
 }
 
 bool
-PropertyList::addDestructiveGetter(string_table::key key,
-       as_c_function_ptr getter, string_table::key nsId,
-       const PropFlags& flagsIfMissing)
+PropertyList::addDestructiveGetter(const ObjectURI& uri,
+       as_c_function_ptr getter, const PropFlags& flagsIfMissing)
 {
-       container::iterator found = iterator_find(_props, key, nsId);
+       container::iterator found = iterator_find(_props, uri);
        if (found != _props.end()) return false; 
 
        // destructive getter don't need a setter
-       Property a(key, nsId, getter, (as_c_function_ptr)0, flagsIfMissing, 
true);
-       a.setOrder(- ++mDefaultOrder - 1);
+       Property a(uri, getter, (as_c_function_ptr)0, flagsIfMissing, true);
+       a.setOrder(- ++_defaultOrder - 1);
        _props.insert(a);
+
 #ifdef GNASH_DEBUG_PROPERTY
-       string_table& st = _vm.getStringTable();
-       log_debug("Destructive native property %s in namespace %s inserted "
-            "with flags %s", st.value(key), st.value(nsId), a.getFlags());
+    ObjectURI::Logger l(_vm.getStringTable());
+       log_debug("Destructive native property %s with flags %s", l(uri),
+            a.getFlags());
 #endif
        return true;
 }

=== modified file 'libcore/PropertyList.h'
--- a/libcore/PropertyList.h    2009-12-01 16:16:33 +0000
+++ b/libcore/PropertyList.h    2009-12-02 14:27:13 +0000
@@ -22,6 +22,7 @@
 #include "PropFlags.h" // for templated functions
 #include "as_value.h" // for templated functions
 #include "string_table.h"
+#include "ObjectURI.h"
 
 #include <map> 
 #include <string> // for use within map 
@@ -57,9 +58,11 @@
     typedef std::pair<std::string, std::string> KeyValuePair;
     typedef std::vector<KeyValuePair> SortedPropertyList;
     
+    /// Used to keep track of which properties have been enumerated.
+    typedef std::set<ObjectURI> PropTracker;
 
-    /// A tag type for multi-index
-    struct oType {};
+    /// 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
@@ -74,15 +77,11 @@
         Property,
         boost::multi_index::indexed_by<
             boost::multi_index::ordered_unique<
-                boost::multi_index::composite_key<
-                    Property,
-                    
boost::multi_index::member<Property,string_table::key,&Property::mName>,
-                    
boost::multi_index::member<Property,string_table::key,&Property::mNamespace>
-                >
+                boost::multi_index::const_mem_fun<Property,const 
ObjectURI&,&Property::uri>
             >,
             boost::multi_index::ordered_unique<
-                boost::multi_index::tag<PropertyList::oType>,
-                boost::multi_index::member<Property,int,&Property::mOrderId>
+                boost::multi_index::tag<OrderTag>,
+                
boost::multi_index::const_mem_fun<Property,int,&Property::getOrder>
             >
         >
     > container;
@@ -95,7 +94,7 @@
     PropertyList(VM& vm)
         :
         _props(),
-        mDefaultOrder(0),
+        _defaultOrder(0),
         _vm(vm)
     {
     }
@@ -118,7 +117,7 @@
     ///                 acceptable.
     //
     /// @param visitor  The visitor function. It must implement the function:
-    ///                     bool accept(string_table::key, const as_value&);
+    ///                     bool accept(const ObjectURI&, const as_value&);
     ///                 Scan is by enumeration order and stops when accept()
     ///                 returns false.
     ///
@@ -138,19 +137,10 @@
         {
             if (!cmp(*it)) continue;
             as_value val = it->getValue(this_ptr);
-            if (!visitor.accept(it->mName, val)) return;
+            if (!visitor.accept(it->uri(), val)) return;
         }
     }
 
-    /// Get the as_value value of an ordered property
-    //
-    /// getter/setter will be invoked, just as for getValue
-    ///
-    /// @param order    The order number: negative for default values, 
-    ///                 non-negative for properties which were specifically
-    ///                 positioned.
-    bool getValueByOrder(int order, as_value& val, as_object& this_ptr);
-    
     /// Get the order number just after the passed order number.
     ///
     /// @param order    0 is a special value indicating the first order
@@ -159,7 +149,7 @@
     /// @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 unexistent.
+    /// 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
     /// will be invoked using the given as_object as 'this' pointer.
@@ -167,11 +157,9 @@
     ///
     /// @param key
     ///    Name of the property. Search is case-*sensitive*
-    ///
     /// @param value
     ///    a const reference to the as_value to use for setting
     ///    or creating the property. 
-    ///
     /// @param this_ptr
     ///     The as_object used to set the 'this' pointer
     ///     for calling getter/setter function (GetterSetterProperty);
@@ -180,43 +168,34 @@
     ///    This parameter is non-const as nothing prevents an
     ///    eventual "Setter" function from actually modifying it,
     ///    so we can't promise constness.
-    ///
     /// @param namespaceId
     ///    The namespace in which this should be entered. If 0 is given,
     ///    this will use the first value found, if it exists.
-    ///
     /// @param flagsIfMissing
     ///    Flags to associate to the property if a new one is created.
-    ///
     /// @return true if the value was successfully set, false
     ///         otherwise (found a read-only property, most likely).
-    bool setValue(string_table::key key, const as_value& value,
-            as_object& this_ptr, string_table::key namespaceId = 0,
-            const PropFlags& flagsIfMissing = 0);
+    bool setValue(const ObjectURI& uri, const as_value& value,
+            as_object& this_ptr, 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*
-    ///
     /// @param nsId The id of the namespace to search
-    ///
     /// @return     A Property or 0, if no such property exists.
     ///             All Property objects are owned by this PropertyList. Do
     ///             not delete them.
-    Property* getProperty(string_table::key key, string_table::key nsId = 0)
+    Property* getProperty(const ObjectURI& uri)
         const;
 
     /// Get a property, if existing, by order
@@ -228,9 +207,7 @@
     //
     ///
     /// @param key      Name of the property.
-    ///
     /// @param nsId     Name of the namespace
-    ///
     /// @return         a pair of boolean values expressing whether the 
property
     ///                 was found (first) and whether it was deleted (second).
     ///                 Of course a pair(false, true) would be invalid (deleted
@@ -238,41 +215,36 @@
     ///                     - (false, false) : property not found
     ///                     - (true, false) : property protected from deletion
     ///                     - (true, true) : property successfully deleted
-    std::pair<bool,bool> delProperty(string_table::key key,
-        string_table::key nsId = 0);
+    std::pair<bool,bool> delProperty(const ObjectURI& uri);
 
     /// Add a getter/setter property, if not already existing
     //
     /// TODO: this function has far too many arguments.
     //
     /// @param key      Name of the property. Search is case-*sensitive*
-    ///
     /// @param getter   A function to invoke when this property value is
     ///                 requested. 
     /// @param setter   A function to invoke when setting this property's 
value.
-    ///
     /// @param cacheVal The value to use as a cache. If null uses any cache
     ///                 from pre-existing property with same name.
     /// @param flagsIfMissing Flags to associate to the property if a new one
     ///                       is created.
     /// @return         true if the property was successfully added, false
     ///                 otherwise.
-    bool addGetterSetter(string_table::key key, as_function& getter,
+    bool addGetterSetter(const ObjectURI& uri, as_function& getter,
         as_function* setter, const as_value& cacheVal,
-        const PropFlags& flagsIfMissing = 0, string_table::key ns = 0);
+        const PropFlags& flagsIfMissing = 0);
 
     /// Add a getter/setter property, if not already existing
     //
     /// @param key      Name of the property.
-    ///
     /// @param getter   A function to invoke when this property value is
     ///                 requested.
     /// @param setter   A function to invoke when setting this property's 
value.
     /// @return         true if the property was successfully added, false
     ///                 otherwise.
-    bool addGetterSetter(string_table::key key, as_c_function_ptr getter,
-        as_c_function_ptr setter, const PropFlags& flagsIfMissing,
-        string_table::key ns = 0);
+    bool addGetterSetter(const ObjectURI& uri, as_c_function_ptr getter,
+        as_c_function_ptr setter, const PropFlags& flagsIfMissing);
 
     /// Add a destructive getter property, if not already existant.
     //
@@ -282,9 +254,8 @@
     /// @param flagsIfMissing Flags to associate to the property if a new
     ///                             one is created.
     /// @return         true if the property was successfully added.
-    bool addDestructiveGetter(string_table::key key,
-        as_function& getter, string_table::key ns = 0,
-        const PropFlags& flagsIfMissing=0);
+    bool addDestructiveGetter(const ObjectURI& uri, as_function& getter,
+        const PropFlags& flagsIfMissing = 0);
 
     /// Add a destructive getter property, if not already existant.
     ///
@@ -296,9 +267,8 @@
     //                          one is created.
     /// @return         true if the property was successfully added, false
     ///                 otherwise.
-    bool addDestructiveGetter(string_table::key key,
-        as_c_function_ptr getter, string_table::key ns = 0,
-        const PropFlags& flagsIfMissing=0);
+    bool addDestructiveGetter(const ObjectURI& uri, as_c_function_ptr getter, 
+        const PropFlags& flagsIfMissing = 0);
 
     /// Set the flags of a property.
     //
@@ -307,36 +277,13 @@
     /// @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(string_table::key key, int setTrue, int setFalse,
-        string_table::key ns = 0);
+    bool setFlags(const ObjectURI& uri, int setTrue, int setFalse);
 
     /// Set the flags of all properties.
     //
-    /// Note: no one cares about the return, so it can be made void.
-    //
     /// @param setTrue      The set of flags to set
-    ///
     /// @param setFalse     The set of flags to clear
-    ///
-    /// @return             a pair containing number of successes 
-    ///                     (first) and number of failures (second).
-    ///                     Failures are due to protected properties,
-    ///                     on which flags cannot be set.
-    std::pair<size_t,size_t> setFlagsAll(int setTrue, int setFalse);
-
-    /// Set the flags of all properties whose name matches
-    /// any key in the given PropertyList object
-    //
-    /// @param props    The properties to use for finding names
-    /// @param setTrue  The set of flags to set
-    /// @param setFalse The set of flags to clear
-    /// @return         a pair containing number of successes 
-    ///                 (first) and number of failures (second).
-    ///                 Failures are due to either protected properties
-    ///                 of keys in the props argument not found in
-    ///                 this properties set.
-    std::pair<size_t,size_t> setFlagsAll( const PropertyList& props,
-            int setTrue, int setFalse);
+    void setFlagsAll(int setTrue, int setFalse);
 
     /// \brief
     /// Copy all properties from the given PropertyList
@@ -350,10 +297,6 @@
     ///
     void import(const PropertyList& props);
 
-    // Used to keep track of which properties have been enumerated.
-    typedef std::set<std::pair<string_table::key, string_table::key> >
-        propNameSet;
-
     /// \brief
     /// Enumerate all non-hidden properties pushing
     /// their keys to the given as_environment.
@@ -361,7 +304,7 @@
     ///
     /// @param donelist
     /// Don't enumerate those in donelist. Add those done to donelist.
-    void enumerateKeys(as_environment& env, propNameSet& donelist) const;
+    void enumerateKeys(as_environment& env, PropTracker& donelist) const;
 
     /// \brief
     /// Enumerate all non-hidden properties inserting
@@ -430,7 +373,7 @@
 
     container _props;
 
-    boost::uint32_t mDefaultOrder;
+    boost::uint32_t _defaultOrder;
     
     VM& _vm;
 

=== modified file 'libcore/abc/Method.cpp'
--- a/libcore/abc/Method.cpp    2009-12-01 11:02:43 +0000
+++ b/libcore/abc/Method.cpp    2009-12-02 14:27:13 +0000
@@ -110,15 +110,17 @@
 {
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
 
-       Property *getset = _prototype->getOwnProperty(name, nsname);
+    const ObjectURI uri(name, nsname);
+
+       Property *getset = _prototype->getOwnProperty(uri);
 
        if (getset)
                getset->setGetter(method->getPrototype());
        else
        {
                int flags = PropFlags::dontDelete | PropFlags::dontEnum;
-               _prototype->init_property(name, *method->getPrototype(), 
-                       *method->getPrototype(), flags, nsname);
+               _prototype->init_property(uri, *method->getPrototype(), 
+                       *method->getPrototype(), flags);
        }
        return true;
 }
@@ -127,16 +129,18 @@
 Method::addSetter(string_table::key name, Namespace *ns, Method *method)
 {
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
+    
+    const ObjectURI uri(name, nsname);
 
-       Property *getset = _prototype->getOwnProperty(name, nsname);
+       Property *getset = _prototype->getOwnProperty(uri);
 
        if (getset)
                getset->setSetter(method->getPrototype());
        else
        {
                int flags = PropFlags::dontDelete | PropFlags::dontEnum;
-               _prototype->init_property(name, *method->getPrototype(), 
-                       *method->getPrototype(), flags, nsname);
+               _prototype->init_property(uri, *method->getPrototype(), 
+                       *method->getPrototype(), flags);
        }
        return true;
 }

=== modified file 'libcore/abc/Script.cpp'
--- a/libcore/abc/Script.cpp    2009-12-01 11:02:43 +0000
+++ b/libcore/abc/Script.cpp    2009-12-02 14:27:13 +0000
@@ -46,8 +46,7 @@
     Global_as* g = VM::get().getGlobal();
 
     if (val.is_object()) {
-               val.to_object(*g)->set_member(NSV::INTERNAL_TYPE, 
-                       std::size_t(type->getName()));
+               val.to_object(*g)->set_member(NSV::INTERNAL_TYPE, 
type->getName());
     }
 
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
@@ -124,7 +123,9 @@
 {
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
 
-       Property *getset = _prototype->getOwnProperty(name, nsname);
+    const ObjectURI uri(name, nsname);
+
+       Property *getset = _prototype->getOwnProperty(uri);
 
        if (getset)
                getset->setGetter(method->getPrototype());
@@ -133,8 +134,8 @@
                int flags = PropFlags::dontDelete | PropFlags::dontEnum;
                if (isstatic)
                        flags |= PropFlags::staticProp;
-               _prototype->init_property(name, *method->getPrototype(), 
-                       *method->getPrototype(), flags, nsname);
+               _prototype->init_property(uri, *method->getPrototype(), 
+                       *method->getPrototype(), flags);
        }
        return true;
 }
@@ -144,18 +145,18 @@
        bool isstatic)
 {
        string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
+    const ObjectURI uri(name, nsname);
 
-       Property *getset = _prototype->getOwnProperty(name, nsname);
+       Property *getset = _prototype->getOwnProperty(uri);
 
        if (getset)
                getset->setSetter(method->getPrototype());
        else
        {
                int flags = PropFlags::dontDelete | PropFlags::dontEnum;
-               if (isstatic)
-                       flags |= PropFlags::staticProp;
-               _prototype->init_property(name, *method->getPrototype(), 
-                       *method->getPrototype(), flags, nsname);
+               if (isstatic) flags |= PropFlags::staticProp;
+               _prototype->init_property(uri, *method->getPrototype(), 
+                       *method->getPrototype(), flags);
        }
        return true;
 }

=== modified file 'libcore/abc/Script.h'
--- a/libcore/abc/Script.h      2009-12-01 11:11:21 +0000
+++ b/libcore/abc/Script.h      2009-12-02 14:27:13 +0000
@@ -248,10 +248,15 @@
 
     as_object *_prototype;
 
-       bool addBinding(string_table::key name, Binding b)
-       { _bindings[name] = b; return true; }
-       bool addStaticBinding(string_table::key name, Binding b)
-       { _staticBindings[name] = b; return true; }
+       bool addBinding(string_table::key name, const Binding& b) {
+        _bindings.insert(std::make_pair(name, b));
+        return true;
+    }
+
+       bool addStaticBinding(string_table::key name, const Binding& b) {
+        _staticBindings.insert(std::make_pair(name, b));
+        return true;
+    }
 
        Binding *getStaticBinding(string_table::key name)
        {

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2009-12-01 11:02:43 +0000
+++ b/libcore/as_object.cpp     2009-12-02 14:27:13 +0000
@@ -51,11 +51,10 @@
 as_object::PrototypeRecursor
 {
 public:
-    PrototypeRecursor(as_object* top, const ObjectURI& property, T cmp = T())
+    PrototypeRecursor(as_object* top, const ObjectURI& uri, T cmp = T())
         :
         _object(top),
-        _name(getName(property)),
-        _ns(getNamespace(property)),
+        _uri(uri),
         _iterations(0),
         _condition(cmp)
     {
@@ -92,7 +91,7 @@
     Property* getProperty(as_object** owner = 0) const {
 
         assert(_object);
-        Property* prop = _object->_members.getProperty(_name, _ns);
+        Property* prop = _object->_members.getProperty(_uri);
         
         if (prop && _condition(*prop)) {
             if (owner) *owner = _object;
@@ -103,8 +102,7 @@
 
 private:
     as_object* _object;
-    const string_table::key _name;
-    const string_table::key _ns;
+    const ObjectURI& _uri;
     std::set<const as_object*> _visited;
     size_t _iterations;
     T _condition;
@@ -140,11 +138,10 @@
        virtual as_object* get_super(string_table::key fname = 0);
 
        // Fetching members from 'super' yelds a lookup on the associated 
prototype
-       virtual bool get_member(string_table::key name, as_value* val,
-               string_table::key nsname = 0)
+       virtual bool get_member(const ObjectURI& uri, as_value* val)
        {
         as_object* proto = prototype();
-               if (proto) return proto->get_member(name, val, nsname);
+               if (proto) return proto->get_member(uri, val);
                log_debug("Super has no associated prototype");
                return false;
        }
@@ -204,7 +201,7 @@
     }
 
     as_object* owner = 0;
-    proto->findProperty(fname, 0, &owner);
+    proto->findProperty(fname, &owner);
     if (!owner) return 0;
 
     if (owner == proto) return new as_super(getGlobal(*this), proto);
@@ -229,9 +226,8 @@
 
 
 /// A PropertyList visitor copying properties to an object
-class PropsCopier : public AbstractPropertyVisitor {
-
-       as_object& _tgt;
+class PropsCopier : public AbstractPropertyVisitor
+{
 
 public:
 
@@ -248,13 +244,14 @@
        /// Use the set_member function to properly set *inherited* properties
        /// of the given target object
        ///
-       bool accept(string_table::key name, const as_value& val)
+       bool accept(const ObjectURI& uri, const as_value& val)
        {
-               if (name == NSV::PROP_uuPROTOuu) return true;
-               //log_debug(_("Setting member '%s' to value '%s'"), name, val);
-               _tgt.set_member(name, val);
+               if (getName(uri) == NSV::PROP_uuPROTOuu) return true;
+               _tgt.set_member(getName(uri), val);
         return true;
        }
+private:
+       as_object& _tgt;
 };
 
 } // end of anonymous namespace
@@ -303,9 +300,9 @@
 }
 
 std::pair<bool,bool>
-as_object::delProperty(string_table::key name, string_table::key nsname)
+as_object::delProperty(const ObjectURI& uri)
 {
-       return _members.delProperty(name, nsname);
+       return _members.delProperty(uri);
 }
 
 
@@ -371,21 +368,19 @@
 /// 4. __resolve property of this object and all __proto__ objects (a Display
 ///    Object ends the chain). This should ignore visibility but doesn't.
 bool
-as_object::get_member(string_table::key name, as_value* val,
-       string_table::key nsname)
+as_object::get_member(const ObjectURI& uri, as_value* val)
 {
        assert(val);
 
     const int version = getSWFVersion(*this);
 
-    PrototypeRecursor<IsVisible> pr(this, ObjectURI(name, nsname),
-        IsVisible(version));
+    PrototypeRecursor<IsVisible> pr(this, uri, IsVisible(version));
        
        Property* prop = pr.getProperty();
     if (!prop) {
         if (displayObject()) {
             DisplayObject* d = displayObject();
-            if (getDisplayObjectProperty(*d, name, *val)) return true;
+            if (getDisplayObjectProperty(*d, getName(uri), *val)) return true;
         }
         while (pr()) {
             if ((prop = pr.getProperty())) break;
@@ -396,13 +391,13 @@
     // inheritance chain, try the __resolve property.
     if (!prop) {
 
-        prop = findProperty(NSV::PROP_uuRESOLVE, nsname);
+        prop = findProperty(NSV::PROP_uuRESOLVE);
         if (!prop) return false;
 
         /// If __resolve exists, call it with the name of the undefined
         /// property.
         string_table& st = getStringTable(*this);
-        const std::string& undefinedName = st.value(name);
+        const std::string& undefinedName = st.value(getName(uri));
         log_debug("__resolve exists, calling with '%s'", undefinedName);
 
         // TODO: we've found the property, don't search for it again.
@@ -456,7 +451,7 @@
 
        if (fname && getSWFVersion(*this) > 6) {
                as_object* owner = 0;
-               findProperty(fname, 0, &owner);
+               findProperty(fname, &owner);
         // should be 0 if findProperty returned 0
                if (owner != this) proto = owner; 
        }
@@ -505,7 +500,7 @@
        }
        if (p)
        {
-               if (findProperty(p->getName(), p->getNamespace()) != p)
+               if (findProperty(p->uri()) != p)
                {
                        index = p->getOrder() * 256 | depth;
                        goto skip_duplicates; // Faster than recursion.
@@ -519,14 +514,12 @@
 
 /*private*/
 Property*
-as_object::findProperty(string_table::key key, string_table::key nsname, 
-       as_object **owner)
+as_object::findProperty(const ObjectURI& uri, as_object **owner)
 {
 
     const int version = getSWFVersion(*this);
 
-    PrototypeRecursor<IsVisible> pr(this, ObjectURI(key, nsname),
-        IsVisible(version));
+    PrototypeRecursor<IsVisible> pr(this, uri, IsVisible(version));
 
     do {
         Property* prop = pr.getProperty(owner);
@@ -534,7 +527,7 @@
     } while (pr());
 
        // No Property found
-       return NULL;
+       return 0;
 }
 
 Property*
@@ -568,7 +561,8 @@
        // TODO: check what happens if __proto__ is set as a user-defined 
     // getter/setter
        // TODO: check triggers !!
-       _members.setValue(NSV::PROP_uuPROTOuu, proto, *this, 0,
+    // Note that this sets __proto__ in namespace 0
+       _members.setValue(NSV::PROP_uuPROTOuu, proto, *this,
             as_object::DefaultFlags);
 }
 
@@ -583,7 +577,7 @@
        
        const Property* prop = _members.getPropertyByOrder(order);
        if (prop) {
-               return get_member(prop->getName(), val, prop->getNamespace());
+               return get_member(prop->uri(), val);
        }
     return false;
 }
@@ -594,7 +588,8 @@
 {
        const Property* prop = _members.getPropertyByOrder(order);
        if (prop) {
-               return set_member(prop->getName(), val, prop->getNamespace(), 
ifFound);
+               return set_member(getName(prop->uri()), val, 
getNamespace(prop->uri()),
+                    ifFound);
        }
     return false;
 }
@@ -763,17 +758,17 @@
        string_table::key nsname, int order)
 {
 
-       if (order >= 0 && !_members.
-               reserveSlot(ObjectURI(key, nsname),
-            static_cast<boost::uint16_t>(order)))
-       {
+    const ObjectURI uri(key, nsname);
+
+       if (order >= 0 && !_members.reserveSlot(uri,
+                static_cast<boost::uint16_t>(order))) {
                log_error(_("Attempt to set a slot for either a slot or a 
property "
                        "which already exists."));
                return;
        }
                
        // Set (or create) a SimpleProperty 
-       if (! _members.setValue(key, val, *this, nsname, flags) )
+       if (! _members.setValue(uri, val, *this, flags) )
        {
                log_error(_("Attempt to initialize read-only property ``%s''"
                        " on object ``%p'' twice"),
@@ -788,18 +783,18 @@
                as_function& setter, int flags, string_table::key nsname)
 {
        string_table::key k = getStringTable(*this).find(key);
-       init_property(k, getter, setter, flags, nsname);
+       init_property(ObjectURI(k, nsname), getter, setter, flags);
 }
 
 void
-as_object::init_property(string_table::key key, as_function& getter,
-               as_function& setter, int flags, string_table::key nsname)
+as_object::init_property(const ObjectURI& uri, as_function& getter,
+               as_function& setter, int flags)
 {
        as_value cacheValue;
 
     // PropertyList::addGetterSetter always returns true (used to be
     // an assert).
-       _members.addGetterSetter(key, getter, &setter, cacheValue, flags, 
nsname);
+       _members.addGetterSetter(uri, getter, &setter, cacheValue, flags);
 }
 
 void
@@ -807,33 +802,33 @@
                as_c_function_ptr setter, int flags, string_table::key nsname)
 {
        string_table::key k = getStringTable(*this).find(key);
-       init_property(k, getter, setter, flags, nsname);
+       init_property(ObjectURI(k, nsname), getter, setter, flags);
 }
 
 void
-as_object::init_property(string_table::key key, as_c_function_ptr getter,
-               as_c_function_ptr setter, int flags, string_table::key nsname)
+as_object::init_property(const ObjectURI& uri, as_c_function_ptr getter,
+               as_c_function_ptr setter, int flags)
 {
     // PropertyList::addGetterSetter always returns true (used to be
     // an assert).
-       _members.addGetterSetter(key, getter, setter, flags, nsname);
+       _members.addGetterSetter(uri, getter, setter, flags);
 }
 
 bool
-as_object::init_destructive_property(string_table::key key, as_function& 
getter,
-       int flags, string_table::key nsname)
+as_object::init_destructive_property(const ObjectURI& uri, as_function& getter,
+        int flags)
 {
        // No case check, since we've already got the key.
-       bool success = _members.addDestructiveGetter(key, getter, nsname, 
flags);
+       bool success = _members.addDestructiveGetter(uri, getter, flags);
        return success;
 }
 
 bool
-as_object::init_destructive_property(string_table::key key,
-        as_c_function_ptr getter, int flags, string_table::key nsname)
+as_object::init_destructive_property(const ObjectURI& uri,
+        as_c_function_ptr getter, int flags)
 {
        // No case check, since we've already got the key.
-       bool success = _members.addDestructiveGetter(key, getter, nsname, 
flags);
+       bool success = _members.addDestructiveGetter(uri, getter, flags);
        return success;
 }
 
@@ -843,18 +838,18 @@
 {
        string_table::key k = getStringTable(*this).find(key);
 
-       init_property(k, getter, getter, initflags | PropFlags::readOnly
-               | PropFlags::isProtected, nsname);
-       assert(_members.getProperty(k, nsname));
+       init_property(ObjectURI(k, nsname), getter, getter,
+            initflags | PropFlags::readOnly | PropFlags::isProtected);
+       assert(_members.getProperty(ObjectURI(k, nsname)));
 }
 
 void
-as_object::init_readonly_property(const string_table::key& k,
-        as_function& getter, int initflags, string_table::key nsname)
+as_object::init_readonly_property(const ObjectURI& uri, as_function& getter,
+        int initflags)
 {
-       init_property(k, getter, getter, initflags | PropFlags::readOnly
-               | PropFlags::isProtected, nsname);
-       assert(_members.getProperty(k, nsname));
+       init_property(uri, getter, getter,
+            initflags | PropFlags::readOnly | PropFlags::isProtected);
+       assert(_members.getProperty(uri));
 }
 
 void
@@ -863,26 +858,25 @@
 {
        string_table::key k = getStringTable(*this).find(key);
 
-       init_property(k, getter, getter, initflags | PropFlags::readOnly
-               | PropFlags::isProtected, nsname);
-       assert(_members.getProperty(k, nsname));
+       init_property(ObjectURI(k, nsname), getter, getter,
+            initflags | PropFlags::readOnly | PropFlags::isProtected);
+       assert(_members.getProperty(ObjectURI(k, nsname)));
 }
 
 void
-as_object::init_readonly_property(const string_table::key& k,
-        as_c_function_ptr getter, int initflags, string_table::key nsname)
+as_object::init_readonly_property(const ObjectURI& uri,
+        as_c_function_ptr getter, int initflags)
 {
-       init_property(k, getter, getter, initflags | PropFlags::readOnly
-               | PropFlags::isProtected, nsname);
-       assert(_members.getProperty(k, nsname));
+       init_property(uri, getter, getter, initflags | PropFlags::readOnly
+               | PropFlags::isProtected);
+       assert(_members.getProperty(uri));
 }
 
 
 bool
-as_object::set_member_flags(string_table::key name,
-               int setTrue, int setFalse, string_table::key nsname)
+as_object::set_member_flags(const ObjectURI& uri, int setTrue, int setFalse)
 {
-       return _members.setFlags(name, setTrue, setFalse, nsname);
+       return _members.setFlags(uri, setTrue, setFalse);
 }
 
 void
@@ -1061,7 +1055,7 @@
        // this set will keep track of visited objects,
        // to avoid infinite loops
        std::set< const as_object* > visited;
-       PropertyList::propNameSet named;
+       PropertyList::PropTracker named;
 
        boost::intrusive_ptr<const as_object> obj(this);
        
@@ -1095,15 +1089,15 @@
 
 
 Property*
-as_object::getOwnProperty(string_table::key key, string_table::key nsname)
+as_object::getOwnProperty(const ObjectURI& uri)
 {
-       return _members.getProperty(key, nsname);
+       return _members.getProperty(uri);
 }
 
 bool
-as_object::hasOwnProperty(string_table::key key, string_table::key nsname)
+as_object::hasOwnProperty(const ObjectURI& uri)
 {
-       return getOwnProperty(key, nsname) != NULL;
+       return getOwnProperty(uri);
 }
 
 as_object*
@@ -1121,10 +1115,10 @@
 }
 
 as_value
-as_object::getMember(string_table::key name, string_table::key nsname)
+as_object::getMember(const ObjectURI& uri)
 {
        as_value ret;
-       get_member(name, &ret, nsname);
+       get_member(uri, &ret);
        return ret;
 }
 
@@ -1177,40 +1171,39 @@
 }
 
 bool
-as_object::watch(string_table::key key, as_function& trig,
-               const as_value& cust, string_table::key ns)
+as_object::watch(const ObjectURI& uri, as_function& trig,
+               const as_value& cust)
 {
        
-       ObjectURI k(key, ns);
-       std::string propname = getStringTable(*this).value(key);
+       std::string propname = getStringTable(*this).value(getName(uri));
 
     if (!_trigs.get()) _trigs.reset(new TriggerContainer);
 
-       TriggerContainer::iterator it = _trigs->find(k);
+       TriggerContainer::iterator it = _trigs->find(uri);
        if (it == _trigs->end())
        {
                return _trigs->insert(
-                std::make_pair(k, Trigger(propname, trig, cust))).second;
+                std::make_pair(uri, Trigger(propname, trig, cust))).second;
        }
        it->second = Trigger(propname, trig, cust);
        return true;
 }
 
 bool
-as_object::unwatch(string_table::key key, string_table::key ns)
+as_object::unwatch(const ObjectURI& uri)
 {
     if (!_trigs.get()) return false; 
 
-       TriggerContainer::iterator trigIter = _trigs->find(ObjectURI(key, ns));
+       TriggerContainer::iterator trigIter = _trigs->find(uri);
        if (trigIter == _trigs->end()) {
                log_debug("No watch for property %s",
-                getStringTable(*this).value(key));
+                getStringTable(*this).value(getName(uri)));
                return false;
        }
-       Property* prop = _members.getProperty(key, ns);
+       Property* prop = _members.getProperty(uri);
        if (prop && prop->isGetterSetter()) {
                log_debug("Watch on %s not removed (is a getter-setter)",
-                getStringTable(*this).value(key));
+                getStringTable(*this).value(getName(uri)));
                return false;
        }
        trigIter->second.kill();

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2009-12-01 08:42:45 +0000
+++ b/libcore/as_object.h       2009-12-02 14:27:13 +0000
@@ -32,6 +32,7 @@
 #include "PropFlags.h" // for enum
 #include "GnashException.h"
 #include "Relay.h"
+#include "ObjectURI.h"
 
 #include <cmath>
 #include <utility> // for std::pair
@@ -64,7 +65,7 @@
 public:
 
     /// This function should return false if no further visits are needed.
-    virtual bool accept(string_table::key key, const as_value& val) = 0;
+    virtual bool accept(const ObjectURI& uri, const as_value& val) = 0;
     virtual ~AbstractPropertyVisitor() {}
 };
 
@@ -136,25 +137,6 @@
 
 };
 
-/// A URI for describing as_objects.
-//
-/// This is used as a unique identifier for any object member, especially
-/// prototypes, class, constructors.
-struct ObjectURI
-{
-
-    /// Construct an ObjectURI from name and namespace.
-    ObjectURI(string_table::key name, string_table::key ns)
-        :
-        name(name),
-        ns(ns)
-    {}
-
-    string_table::key name;
-    string_table::key ns;
-
-};
-
 
 /// \brief
 /// A generic bag of attributes. Base class for all ActionScript-able objects.
@@ -167,9 +149,6 @@
     friend class abc::Class;
     friend class abc::Machine;
 
-    typedef std::set<std::pair<string_table::key, string_table::key> >
-        propNameSet;
-
     typedef PropertyList::SortedPropertyList SortedPropertyList;
 
 public:
@@ -219,8 +198,7 @@
     /// @returns a Property if found, NULL if not found
     ///          or not visible in current VM version
     ///
-    Property* findProperty(string_table::key name, string_table::key nsname,
-        as_object **owner = NULL);
+    Property* findProperty(const ObjectURI& uri, as_object **owner = NULL);
 
     /// Return a reference to this as_object's global object.
     VM& vm() const {
@@ -416,9 +394,8 @@
     /// @param nsname
     /// The id of the namespace to which this member belongs. 0 is a wildcard
     /// and will be matched by anything not asking for a specific namespace.
-    void init_property(string_table::key key, as_function& getter,
-        as_function& setter, int flags = DefaultFlags,
-        string_table::key nsname = 0);
+    void init_property(const ObjectURI& uri, as_function& getter,
+        as_function& setter, int flags = DefaultFlags);
 
     /// \brief
     /// Initialize a getter/setter property by key
@@ -445,65 +422,63 @@
     /// @param nsname
     /// The id of the namespace to which this member belongs. 0 is a wildcard
     /// and will be matched by anything not asking for a specific namespace.
-    void init_property(string_table::key key, as_c_function_ptr getter,
-        as_c_function_ptr setter, int flags = DefaultFlags,
-        string_table::key nsname = 0);
-
-
-    /// \brief
-    /// Initialize a destructive getter property
-    ///
-    /// A destructive getter can be used as a place holder for the real
-    /// value of a property.  As soon as getValue is invoked on the getter,
-    /// it destroys itself after setting its property to the return value of
-    /// getValue.
-    ///
-    /// @param key
-    ///     Name of the property.
-    ///    Will be converted to lowercase if VM is initialized for SWF6 or 
lower.
-    ///
-    /// @param getter
-    ///    A function to invoke when this property value is requested.
-    ///    add_ref will be called on the function.
-    ///
-    /// @param flags
-    ///     Flags for the new member. By default dontDelete and dontEnum.
-    ///    See PropFlags::Flags.
-    ///
-    /// @param nsname
-    /// The id of the namespace to which this member belongs. 0 is a wildcard
-    /// and will be matched by anything not asking for a specific namespace.
-    ///
-    bool init_destructive_property(string_table::key key, as_function& getter,
-        int flags = PropFlags::dontEnum, string_table::key nsname = 0);
-
-    /// \brief
-    /// Initialize a destructive getter property
-    ///
-    /// A destructive getter can be used as a place holder for the real
-    /// value of a property.  As soon as getValue is invoked on the getter,
-    /// it destroys itself after setting its property to the return value of
-    /// getValue.
-    ///
-    /// @param key
-    ///     Name of the property.
-    ///    Will be converted to lowercase if VM is initialized for SWF6 or 
lower.
-    ///
-    /// @param getter
-    ///    A function to invoke when this property value is requested.
-    ///    add_ref will be called on the function.
-    ///
-    /// @param flags
-    ///     Flags for the new member. By default dontDelete and dontEnum.
-    ///    See PropFlags::Flags.
-    ///
-    /// @param nsname
-    /// The id of the namespace to which this member belongs. 0 is a wildcard
-    /// and will be matched by anything not asking for a specific namespace.
-    ///
-    bool init_destructive_property(string_table::key key,
-            as_c_function_ptr getter, int flags = PropFlags::dontEnum,
-            string_table::key nsname = 0);
+    void init_property(const ObjectURI& uri, as_c_function_ptr getter,
+        as_c_function_ptr setter, int flags = DefaultFlags);
+
+
+    /// \brief
+    /// Initialize a destructive getter property
+    ///
+    /// A destructive getter can be used as a place holder for the real
+    /// value of a property.  As soon as getValue is invoked on the getter,
+    /// it destroys itself after setting its property to the return value of
+    /// getValue.
+    ///
+    /// @param key
+    ///     Name of the property.
+    ///    Will be converted to lowercase if VM is initialized for SWF6 or 
lower.
+    ///
+    /// @param getter
+    ///    A function to invoke when this property value is requested.
+    ///    add_ref will be called on the function.
+    ///
+    /// @param flags
+    ///     Flags for the new member. By default dontDelete and dontEnum.
+    ///    See PropFlags::Flags.
+    ///
+    /// @param nsname
+    /// The id of the namespace to which this member belongs. 0 is a wildcard
+    /// and will be matched by anything not asking for a specific namespace.
+    ///
+    bool init_destructive_property(const ObjectURI& uri, as_function& getter,
+            int flags = PropFlags::dontEnum);
+
+    /// \brief
+    /// Initialize a destructive getter property
+    ///
+    /// A destructive getter can be used as a place holder for the real
+    /// value of a property.  As soon as getValue is invoked on the getter,
+    /// it destroys itself after setting its property to the return value of
+    /// getValue.
+    ///
+    /// @param key
+    ///     Name of the property.
+    ///    Will be converted to lowercase if VM is initialized for SWF6 or 
lower.
+    ///
+    /// @param getter
+    ///    A function to invoke when this property value is requested.
+    ///    add_ref will be called on the function.
+    ///
+    /// @param flags
+    ///     Flags for the new member. By default dontDelete and dontEnum.
+    ///    See PropFlags::Flags.
+    ///
+    /// @param nsname
+    /// The id of the namespace to which this member belongs. 0 is a wildcard
+    /// and will be matched by anything not asking for a specific namespace.
+    ///
+    bool init_destructive_property(const ObjectURI& uri, 
+            as_c_function_ptr getter, int flags = PropFlags::dontEnum);
 
 
     /// \brief
@@ -535,9 +510,8 @@
     void init_readonly_property(const std::string& key, as_function& getter,
             int flags = DefaultFlags, string_table::key nsname = 0);
 
-    void init_readonly_property(const string_table::key& key,
-            as_function& getter, int flags = DefaultFlags,
-            string_table::key nsname = 0);
+    void init_readonly_property(const ObjectURI& uri,
+            as_function& getter, int flags = DefaultFlags);
 
     /// Use this method for read-only properties.
     //
@@ -567,9 +541,8 @@
             as_c_function_ptr getter, int flags = DefaultFlags,
             string_table::key nsname = 0);
 
-    void init_readonly_property(const string_table::key& key,
-            as_c_function_ptr getter, int flags = DefaultFlags,
-            string_table::key nsname = 0);
+    void init_readonly_property(const ObjectURI& uri,
+            as_c_function_ptr getter, int flags = DefaultFlags);
 
     /// \brief
     /// Add a watch trigger, overriding any other defined for same name.
@@ -591,8 +564,7 @@
     /// @return true if the trigger was successfully added, false
     ///         otherwise (error? should always be possible to add...)
     ///
-    bool watch(string_table::key key, as_function& trig,
-        const as_value& cust, string_table::key ns = 0);
+    bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
 
     /// \brief
     /// Remove a watch trigger.
@@ -606,7 +578,7 @@
     /// @return true if the trigger was successfully removed, false
     ///         otherwise (no such trigger...)
     ///
-    bool unwatch(string_table::key key, string_table::key ns = 0);
+    bool unwatch(const ObjectURI& uri);
 
     /// Get a member as_value by name
     ///
@@ -631,8 +603,7 @@
     ///
     /// @return true of the named property was found, false otherwise.
     ///
-    virtual bool get_member(string_table::key name, as_value* val,
-        string_table::key nsname = 0);
+    virtual bool get_member(const ObjectURI& uri, as_value* val);
 
     /// Resolve the given relative path component
     //
@@ -666,33 +637,23 @@
     ///      that the 'getter' won't change this object trough
     ///     use of the 'this' reference. 
     ///
-    /// @param name
-    ///    Name of the property. Will be converted to lowercase
-    ///    if the current VM is initialized for a  target
-    ///    up to SWF6.
-    ///
-    /// @param nsname
-    /// The id of the namespace to which this member belongs. 0 is a wildcard
-    /// and will be matched by anything not asking for a specific namespace.
+    /// @param uri      Name and namespace of the property. Note that
+    ///                 if you do not care about the namespace (AS2 does not),
+    ///                 you can call this function with the name key only.
     ///
     /// @return value of the member (possibly undefined),
     ///    or undefined if not found. Use get_member if you
     ///    need to know wheter it was found or not.
     ///
-    as_value getMember(string_table::key name, string_table::key nsname = 0);
+    as_value getMember(const ObjectURI& uri);
 
     /// Delete a property of this object, unless protected from deletion.
     //
     /// This function does *not* recurse in this object's prototype.
-    ///
-    /// @param name
-    ///     Name of the property.
-    ///    Case insensitive up to SWF6,
-    ///    case *sensitive* from SWF7 up.
-    ///
-    /// @param nsname
-    /// The id of the namespace to which this member belongs. 0 is a wildcard
-    /// and will be matched by anything not asking for a specific namespace.
+    //
+    /// @param uri      Name and namespace of the property. Note that
+    ///                 if you do not care about the namespace (AS2 does not),
+    ///                 you can call this function with the name key only.
     ///
     /// @return a pair of boolean values expressing whether the property
     ///    was found (first) and whether it was deleted (second).
@@ -702,46 +663,29 @@
     ///    - (true, false) : property protected from deletion
     ///    - (true, true) : property successfully deleted
     ///
-    std::pair<bool,bool> delProperty(string_table::key name,
-            string_table::key nsname = 0);
+    std::pair<bool,bool> delProperty(const ObjectURI& uri);
 
     /// Get this object's own named property, if existing.
     //
     /// This function does *not* recurse in this object's prototype.
-    ///
-    /// @param name
-    ///     Name of the property.
-    ///    Case insensitive up to SWF6,
-    ///    case *sensitive* from SWF7 up.
-    ///
-    /// @param nsname
-    /// The id of the namespace to which this member belongs. 0 is a wildcard
-    /// and will be matched by anything not asking for a specific namespace.
-    ///
-    /// @return
-    ///    a Property pointer, or NULL if this object doesn't
-    ///    contain the named property.
-    ///
-    Property* getOwnProperty(string_table::key name,
-            string_table::key nsname = 0);
+    //
+    /// @param uri      The name and namespace of the property. Note that
+    ///                 if you do not care about the namespace (AS2 does not),
+    ///                 you can call this function with the name key only.
+    /// @return         A Property pointer, or NULL if this object doesn't
+    ///                 contain the named property.
+    Property* getOwnProperty(const ObjectURI& uri);
 
     /// Return true if this object has the named property
     //
-    /// @param name
-    ///     Name of the property.
-    ///    Case insensitive up to SWF6,
-    ///    case *sensitive* from SWF7 up.
-    ///
-    /// @param nsname
-    ///     The id of the namespace to which this member belongs.
-    ///     0 is a wildcard and will be matched by anything not asking
-    ///     for a specific namespace.
+    /// @param uri      Name and namespace of the property. Note that
+    ///                 if you do not care about the namespace (AS2 does not),
+    ///                 you can call this function with the name key only.
     ///
     /// @return
     ///    true if the object has the property, false otherwise.
     ///
-    bool hasOwnProperty(string_table::key name,
-            string_table::key nsname = 0);
+    bool hasOwnProperty(const ObjectURI& uri);
 
     /// Get a property from this object (or a prototype) by ordering index.
     ///
@@ -788,8 +732,7 @@
     /// @return true on success, false on failure
     ///    (non-existent or protected member)
     ///
-    bool set_member_flags(string_table::key name,
-            int setTrue, int setFalse=0, string_table::key nsname = 0);
+    bool 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 NULL; }
@@ -986,7 +929,6 @@
 
     ///Get a member value at a given slot.
     //
-    ///This is a wrapper around get_member_default.
     /// @param order
     /// The slot index of the property.
     ///
@@ -1161,28 +1103,6 @@
 
 as_object* getObjectWithPrototype(Global_as& gl, string_table::key c);
 
-/// Comparator for ObjectURI so it can serve as a key in stdlib containers.
-inline bool
-operator<(const ObjectURI& a, const ObjectURI& b)
-{
-    if (a.name < b.name) return true;
-    return a.ns < b.ns;
-}
-
-/// Get the name element of an ObjectURI
-inline string_table::key
-getName(const ObjectURI& o)
-{
-    return o.name;
-}
-
-/// Get the namespace element of an ObjectURI
-inline string_table::key
-getNamespace(const ObjectURI& o)
-{
-    return o.ns;
-}
-
 /// Check whether the object is an instance of a known type.
 //
 /// This is used to check the type of certain objects when it can't be

=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp      2009-12-01 09:35:54 +0000
+++ b/libcore/as_value.cpp      2009-12-02 14:27:13 +0000
@@ -176,9 +176,12 @@
            _st(vm.getStringTable())
        {}
     
-    bool accept(string_table::key key, const as_value& val) 
+    bool accept(const ObjectURI& uri, const as_value& val) 
     {
 
+        // We are not taking account of the namespace.
+        const string_table::key key = getName(uri);
+
         // Test conducted with AMFPHP:
         // '__proto__' and 'constructor' members
         // of an object don't get back from an 'echo-service'.
@@ -266,7 +269,7 @@
     
     bool success() const { return !_error; }
 
-    bool accept(string_table::key key, const as_value& val) 
+    bool accept(const ObjectURI& uri, const as_value& val) 
     {
         if ( _error ) return true;
 
@@ -277,13 +280,14 @@
             return true;
         }
 
+        const string_table::key key = getName(uri);
+
         // Test conducted with AMFPHP:
         // '__proto__' and 'constructor' members
         // of an object don't get back from an 'echo-service'.
         // Dunno if they are not serialized or just not sent back.
         // A '__constructor__' member gets back, but only if 
         // not a function. Actually no function gets back.
-        // 
         if (key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR)
         {
 #ifdef GNASH_DEBUG_AMF_SERIALIZE

=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp        2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Array_as.cpp        2009-12-02 14:27:13 +0000
@@ -812,9 +812,10 @@
 }
 
 bool
-IsStrictArray::accept(string_table::key key, const as_value& /*val*/)
+IsStrictArray::accept(const ObjectURI& uri, const as_value& /*val*/)
 {
-    if (isIndex(_st.value(key)) >= 0) return true;
+    // We ignore namespace.
+    if (isIndex(_st.value(getName(uri))) >= 0) return true;
     _strict = false;
     return false;
 }

=== modified file 'libcore/asobj/Array_as.h'
--- a/libcore/asobj/Array_as.h  2009-11-05 08:57:59 +0000
+++ b/libcore/asobj/Array_as.h  2009-12-02 14:27:13 +0000
@@ -55,7 +55,7 @@
 {
 public:
     IsStrictArray(string_table& st) : _strict(true), _st(st) {}
-    virtual bool accept(string_table::key key, const as_value& val);
+    virtual bool accept(const ObjectURI& uri, const as_value& val);
 
     bool strict() const {
         return _strict;

=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-12-01 11:02:43 +0000
+++ b/libcore/asobj/Globals.cpp 2009-12-02 15:31:53 +0000
@@ -106,6 +106,7 @@
 #include "QName_as.h"
 #include "Object.h"
 
+#include <map>
 #include <limits> 
 #include <sstream>
 #include <boost/lexical_cast.hpp>
@@ -130,7 +131,10 @@
 namespace {
 
     const ClassHierarchy::NativeClasses& avm1Classes();
-    const ClassHierarchy::NativeClasses& avm2Classes(string_table& st);
+
+    // 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);
@@ -271,14 +275,11 @@
 {
     registerNatives(*this);
 
-    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)); 
+    initObjectClass(_objectProto, *this, NSV::CLASS_OBJECT); 
+
+    function_class_init(*this, NSV::CLASS_FUNCTION);
+    string_class_init(*this, NSV::CLASS_STRING); 
+    array_class_init(*this, NSV::CLASS_ARRAY); 
 
     // No idea why, but it seems there's a NULL _global.o 
     // defined at player startup...
@@ -319,7 +320,7 @@
 
     // SWF8 visibility:
     const string_table::key NS_FLASH = st.find("flash");
-    flash_package_init(*this, ObjectURI(NS_FLASH, NS_GLOBAL)); 
+    flash_package_init(*this, NS_FLASH); 
 
     const int version = _vm.getSWFVersion();
 
@@ -407,7 +408,7 @@
     init_member("trace", createFunction(global_trace));
     init_member("escape", createFunction(global_escape));
 
-    _classes.declareAll(avm2Classes(_vm.getStringTable()));
+    _classes.declareAll(avm2Classes());
     _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
     _classes.getGlobalNs()->getScript(NSV::CLASS_FUNCTION)->setDeclared();
     _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
@@ -488,73 +489,47 @@
 avm1Classes()
 {
 
-    const string_table::key NS_GLOBAL = 0;
-
     typedef ClassHierarchy::NativeClass N;
 
     // Since we maintain separate lists for AVM1 and AVM2, these are all
-    // considered to be in the 'Global' namespace (AVM1 has no namespaces).
+    // considered to be in the 'Global' namespace (AVM1 has no namespaces)
+    // An ObjectURI constructed without a namespace is in the global namespace.
     static const ClassHierarchy::NativeClasses s = boost::assign::list_of
 
-        (N(system_class_init, NSV::CLASS_SYSTEM, 0, NS_GLOBAL, 1))
-        (N(stage_class_init, NSV::CLASS_STAGE, 0, NS_GLOBAL, 1))
-        (N(movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, NS_GLOBAL, 3))
-        (N(textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, NS_GLOBAL, 3))
-        (N(math_class_init, NSV::CLASS_MATH, 0, NS_GLOBAL, 4))
-        (N(boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(button_class_init, NSV::CLASS_BUTTON, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(color_class_init, NSV::CLASS_COLOR, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(selection_class_init, NSV::CLASS_SELECTION, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(sound_class_init, NSV::CLASS_SOUND, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(xmlsocket_class_init, NSV::CLASS_XMLSOCKET, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(date_class_init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, NS_GLOBAL, 5))
-        (N(xmlnode_class_init, NSV::CLASS_XMLNODE, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(xml_class_init, NSV::CLASS_XML, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT, NS_GLOBAL, 
5))
-        (N(number_class_init, NSV::CLASS_NUMBER, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(textformat_class_init, NSV::CLASS_TEXT_FORMAT, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(keyboard_class_init, NSV::CLASS_KEY, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(AsBroadcaster::init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, 
NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_OBJECT, NS_GLOBAL, 
6))
-        (N(camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(microphone_class_init, NSV::CLASS_MICROPHONE, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(sharedobject_class_init, NSV::CLASS_SHARED_OBJECT,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 5))
-        (N(loadvars_class_init, NSV::CLASS_LOAD_VARS, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(localconnection_class_init, NSV::CLASS_LOCALCONNECTION,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 6))
-        (N(customactions_class_init, NSV::CLASS_CUSTOM_ACTIONS,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 6))
-        (N(netconnection_class_init, NSV::CLASS_NET_CONNECTION,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 6))
-        (N(netstream_class_init, NSV::CLASS_NET_STREAM, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 6))
-        (N(contextmenu_class_init, NSV::CLASS_CONTEXTMENU, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(contextmenuitem_class_init, NSV::CLASS_CONTEXTMENUITEM,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 5))
-        (N(moviecliploader_class_init, NSV::CLASS_MOVIE_CLIP_LOADER,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 5))
-        (N(Error_class_init, NSV::CLASS_ERROR, NSV::CLASS_OBJECT, NS_GLOBAL, 
5))
-        (N(accessibility_class_init, NSV::CLASS_ACCESSIBILITY,
-           NSV::CLASS_OBJECT, NS_GLOBAL, 5));
+        (N(system_class_init, NSV::CLASS_SYSTEM, 0, 1))
+        (N(stage_class_init, NSV::CLASS_STAGE, 0, 1))
+        (N(movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, 3))
+        (N(textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, 3))
+        (N(math_class_init, NSV::CLASS_MATH, 0, 4))
+        (N(boolean_class_init, NSV::CLASS_BOOLEAN, 0, 5))
+        (N(button_class_init, NSV::CLASS_BUTTON, 0, 5))
+        (N(color_class_init, NSV::CLASS_COLOR, 0, 5))
+        (N(selection_class_init, NSV::CLASS_SELECTION, 0, 5))
+        (N(sound_class_init, NSV::CLASS_SOUND, 0, 5))
+        (N(xmlsocket_class_init, NSV::CLASS_XMLSOCKET, 0, 5))
+        (N(date_class_init, NSV::CLASS_DATE, 0, 5))
+        (N(xmlnode_class_init, NSV::CLASS_XMLNODE, 0, 5))
+        (N(xml_class_init, NSV::CLASS_XML, 0, 5))
+        (N(mouse_class_init, NSV::CLASS_MOUSE, 0, 5))
+        (N(number_class_init, NSV::CLASS_NUMBER, 0, 5))
+        (N(textformat_class_init, NSV::CLASS_TEXT_FORMAT, 0, 5))
+        (N(keyboard_class_init, NSV::CLASS_KEY, 0, 5))
+        (N(AsBroadcaster::init, NSV::CLASS_AS_BROADCASTER, 0, 5))
+        (N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, 0, 5))
+        (N(video_class_init, NSV::CLASS_VIDEO, 0, 6))
+        (N(camera_class_init, NSV::CLASS_CAMERA, 0, 5))
+        (N(microphone_class_init, NSV::CLASS_MICROPHONE, 0, 5))
+        (N(sharedobject_class_init, NSV::CLASS_SHARED_OBJECT, 0, 5))
+        (N(loadvars_class_init, NSV::CLASS_LOAD_VARS, 0, 5))
+        (N(localconnection_class_init, NSV::CLASS_LOCALCONNECTION, 0, 6))
+        (N(customactions_class_init, NSV::CLASS_CUSTOM_ACTIONS, 0, 6))
+        (N(netconnection_class_init, NSV::CLASS_NET_CONNECTION, 0, 6))
+        (N(netstream_class_init, NSV::CLASS_NET_STREAM, 0, 6))
+        (N(contextmenu_class_init, NSV::CLASS_CONTEXTMENU, 0, 5))
+        (N(contextmenuitem_class_init, NSV::CLASS_CONTEXTMENUITEM, 0, 5))
+        (N(moviecliploader_class_init, NSV::CLASS_MOVIE_CLIP_LOADER, 0, 5))
+        (N(Error_class_init, NSV::CLASS_ERROR, 0, 5))
+        (N(accessibility_class_init, NSV::CLASS_ACCESSIBILITY, 0, 5));
 
     return s;
 
@@ -563,147 +538,202 @@
 #ifdef ENABLE_AVM2
 
 const ClassHierarchy::NativeClasses&
-avm2Classes(string_table& st)
+avm2Classes()
 {
 
-    const string_table::key NS_GLOBAL = 0;
-
     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, NSV::CLASS_MATH, 0, NS_GLOBAL, 4))
-        (N(boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(number_class_init, NSV::CLASS_NUMBER, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(int_class_init, NSV::CLASS_INT, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(namespace_class_init, NSV::CLASS_NAMESPACE, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(qname_class_init, NSV::CLASS_QNAME, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
-        (N(date_class_init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, NS_GLOBAL, 5))
-        (N(Error_class_init, NSV::CLASS_ERROR, NSV::CLASS_OBJECT,
-           NS_GLOBAL, 5))
+        (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, NSV::CLASS_SYSTEM, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_SYSTEM, 1))
+        (N(system_class_init, c(NSV::CLASS_SYSTEM), c(NSV::CLASS_OBJECT), 1))
 
         // Display classes
-        (N(shape_class_init, st.find("Shape"), NSV::CLASS_DISPLAYOBJECT,
-           NSV::NS_FLASH_DISPLAY, 3))
-        (N(displayobject_class_init, NSV::CLASS_DISPLAYOBJECT,
-           NSV::CLASS_EVENTDISPATCHER, NSV::NS_FLASH_DISPLAY, 3))
-        (N(interactiveobject_class_init, NSV::CLASS_INTERACTIVEOBJECT,
-           NSV::CLASS_DISPLAYOBJECT, NSV::NS_FLASH_DISPLAY, 3))
-        (N(displayobjectcontainer_class_init, 
NSV::CLASS_DISPLAYOBJECTCONTAINER,
-           NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_DISPLAY, 3))
-        (N(sprite_class_init, NSV::CLASS_SPRITE,
-           NSV::CLASS_DISPLAYOBJECTCONTAINER, NSV::NS_FLASH_DISPLAY, 3))
-        (N(bitmap_class_init, NSV::CLASS_BITMAP, NSV::CLASS_DISPLAYOBJECT,
-           NSV::NS_FLASH_DISPLAY, 3))
-        (N(movieclip_class_init, NSV::CLASS_MOVIE_CLIP, NSV::CLASS_SPRITE,
-           NSV::NS_FLASH_DISPLAY, 3))
-        (N(stage_class_init, NSV::CLASS_STAGE, NSV::CLASS_MOVIE_CLIP,
-           NSV::NS_FLASH_DISPLAY, 1))
-        (N(button_class_init, st.find("SimpleButton"),
-           NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_DISPLAY, 5))
+        (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, NSV::CLASS_TEXT_FIELD,
-           NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_TEXT, 3))
-        (N(textformat_class_init, NSV::CLASS_TEXT_FORMAT, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_TEXT, 5))
-        (N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, 
NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_TEXT, 5))
-        (N(textfieldautosize_class_init, NSV::CLASS_TEXTFIELDAUTOSIZE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(font_class_init, NSV::CLASS_FONT, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_TEXT, 5))
-        (N(fontstyle_class_init, NSV::CLASS_FONTSTYLE, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_TEXT, 5))
-        (N(antialiastype_class_init, NSV::CLASS_ANTIALIASTYPE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(csmsettings_class_init, NSV::CLASS_CSMTEXTSETTINGS,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(gridfittype_class_init, NSV::CLASS_GRIDFITTYPE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(statictext_class_init, NSV::CLASS_STATICTEXT,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(stylesheet_class_init, NSV::CLASS_STYLESHEET,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
+        (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, NSV::CLASS_TEXTCOLOR,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
+        (N(textcolor_class_init, c(NSV::CLASS_TEXTCOLOR),
+           c(NSV::CLASS_OBJECT), 5))
 #endif
-        (N(textcolortype_class_init, NSV::CLASS_TEXTCOLORTYPE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(textdisplaymode_class_init, NSV::CLASS_TEXTDISPLAYMODE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(textfieldtype_class_init, NSV::CLASS_TEXTFIELDTYPE,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(textformatalign_class_init, NSV::CLASS_TEXTFORMATALIGN,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(textlinemetrics_class_init, NSV::CLASS_TEXTLINEMETRICS,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
-        (N(textrenderer_class_init, NSV::CLASS_TEXTRENDERER,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
+        (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, NSV::CLASS_SOUND, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_MEDIA, 5))
-        (N(video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_DISPLAYOBJECT,
-           NSV::NS_FLASH_MEDIA, 6))
-        (N(camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_MEDIA, 6))
-        (N(microphone_class_init, NSV::CLASS_MICROPHONE, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_MEDIA, 6))
-
+        (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, NSV::CLASS_XMLSOCKET, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_NET, 5))
-        (N(sharedobject_class_init, NSV::CLASS_SHARED_OBJECT,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 5))
-        (N(localconnection_class_init, NSV::CLASS_LOCALCONNECTION,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 6))
-        (N(netconnection_class_init, NSV::CLASS_NET_CONNECTION,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 6))
-        (N(netstream_class_init, NSV::CLASS_NET_STREAM, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_NET, 6))
-        
+        (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, NSV::CLASS_XMLNODE, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_XML, 5))
-        (N(xml_class_init, st.find("XMLDocument"), NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_XML, 5))
-
+        (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, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_UI, 5))
-        (N(keyboard_class_init, st.find("Keyboard"), NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_UI, 5))
-        (N(contextmenu_class_init, NSV::CLASS_CONTEXTMENU, NSV::CLASS_OBJECT,
-           NSV::NS_FLASH_UI, 7))
-        (N(contextmenuitem_class_init, NSV::CLASS_CONTEXTMENUITEM,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_UI, 5))
-        
+        (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, NSV::CLASS_ACCESSIBILITY,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_ACCESSIBILITY, 5))
-       
+        (N(accessibility_class_init, c(NSV::CLASS_ACCESSIBILITY),
+           c(NSV::CLASS_OBJECT), 5))
         // Event classes
-        (N(event_class_init, NSV::CLASS_EVENT,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_EVENTS, 5))
-        (N(eventdispatcher_class_init, NSV::CLASS_EVENTDISPATCHER,
-           NSV::CLASS_OBJECT, NSV::NS_FLASH_EVENTS, 5));
-        
-    return s;
+        (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

=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp     2009-11-30 11:12:37 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp     2009-12-02 12:30:12 
+0000
@@ -228,9 +228,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-       where.init_destructive_property(getName(uri),
-                get_flash_display_bitmap_data_constructor, flags,
-                getNamespace(uri));
+       where.init_destructive_property(uri,
+            get_flash_display_bitmap_data_constructor, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/display/display_pkg.cpp'
--- a/libcore/asobj/flash/display/display_pkg.cpp       2009-11-18 11:41:56 
+0000
+++ b/libcore/asobj/flash/display/display_pkg.cpp       2009-12-02 12:30:12 
+0000
@@ -52,8 +52,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-       where.init_destructive_property(getName(uri),
-                       get_flash_display_package, flags, getNamespace(uri));
+       where.init_destructive_property(uri, get_flash_display_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-11-18 
11:51:35 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-12-02 
12:30:12 +0000
@@ -70,8 +70,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), externalInterfaceConstructor,
-            flags, getNamespace(uri));
+    where.init_destructive_property(uri, externalInterfaceConstructor, flags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/external/external_pkg.cpp'
--- a/libcore/asobj/flash/external/external_pkg.cpp     2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/external/external_pkg.cpp     2009-12-02 12:30:12 
+0000
@@ -56,8 +56,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_external_package, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_external_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/filters/BitmapFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-11-30 11:12:37 
+0000
+++ b/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-12-02 12:30:12 
+0000
@@ -54,8 +54,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), getBitmapFilterConstructor,
-                   flags, getNamespace(uri));
+    where.init_destructive_property(uri, getBitmapFilterConstructor, flags);
 }
 
 void

=== modified file 'libcore/asobj/flash/filters/filters_pkg.cpp'
--- a/libcore/asobj/flash/filters/filters_pkg.cpp       2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/filters/filters_pkg.cpp       2009-12-02 12:30:12 
+0000
@@ -82,8 +82,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), get_flash_filters_package,
-                   flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_filters_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/flash_pkg.cpp'
--- a/libcore/asobj/flash/flash_pkg.cpp 2009-11-18 11:40:43 +0000
+++ b/libcore/asobj/flash/flash_pkg.cpp 2009-12-02 12:30:12 +0000
@@ -60,8 +60,7 @@
 flash_package_init(as_object& where, const ObjectURI& uri)
 {
     const int flags = PropFlags::dontEnum | PropFlags::onlySWF8Up;
-    where.init_destructive_property(getName(uri), get_flash_package, flags,
-        getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_package, flags);
 }
 
 }

=== modified file 'libcore/asobj/flash/geom/ColorTransform_as.cpp'
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp    2009-11-18 11:51:35 
+0000
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp    2009-12-02 12:30:12 
+0000
@@ -79,9 +79,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_geom_color_transform_constructor, flags,
-            getNamespace(uri));
+    where.init_destructive_property(uri,
+            get_flash_geom_color_transform_constructor, flags);
 }
 
 void

=== modified file 'libcore/asobj/flash/geom/Matrix_as.cpp'
--- a/libcore/asobj/flash/geom/Matrix_as.cpp    2009-11-30 11:12:37 +0000
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp    2009-12-02 12:30:12 +0000
@@ -97,8 +97,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_geom_matrix_constructor, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_geom_matrix_constructor,
+            flags);
 }
 
 

=== modified file 'libcore/asobj/flash/geom/Point_as.cpp'
--- a/libcore/asobj/flash/geom/Point_as.cpp     2009-11-30 11:12:37 +0000
+++ b/libcore/asobj/flash/geom/Point_as.cpp     2009-12-02 12:30:12 +0000
@@ -56,8 +56,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_geom_point_constructor, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_geom_point_constructor,
+            flags);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/geom/Rectangle_as.cpp'
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-11-30 11:12:37 +0000
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-12-02 12:30:12 +0000
@@ -71,8 +71,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_geom_rectangle_constructor, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_geom_rectangle_constructor,
+            flags);
 }
 
 

=== modified file 'libcore/asobj/flash/geom/Transform_as.cpp'
--- a/libcore/asobj/flash/geom/Transform_as.cpp 2009-11-30 11:12:37 +0000
+++ b/libcore/asobj/flash/geom/Transform_as.cpp 2009-12-02 12:30:12 +0000
@@ -110,8 +110,8 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), 
-            get_flash_geom_transform_constructor, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_geom_transform_constructor,
+            flags);
 
 }
 

=== modified file 'libcore/asobj/flash/geom/geom_pkg.cpp'
--- a/libcore/asobj/flash/geom/geom_pkg.cpp     2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/geom/geom_pkg.cpp     2009-12-02 12:30:12 +0000
@@ -63,8 +63,7 @@
 
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), get_flash_geom_package,
-            flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_geom_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp       2009-11-30 11:12:37 
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp       2009-12-02 14:27:13 
+0000
@@ -105,12 +105,13 @@
         _st(vm.getStringTable())
     {};
 
-    bool accept(string_table::key key, const as_value& val) 
+    bool accept(const ObjectURI& uri, const as_value& val) 
     {
         AMF amf;
         boost::shared_ptr<amf::Element> el;
         
-        const std::string& name = _st.string_table::value(key);
+        // We omit the namespace.
+        const std::string& name = _st.string_table::value(getName(uri));
 
         //log_debug("Serializing SharedObject property %s:%s", name, val);
 
@@ -167,7 +168,7 @@
     
     bool success() const { return !_error; }
 
-    virtual bool accept(string_table::key key, const as_value& val) 
+    virtual bool accept(const ObjectURI& uri, const as_value& val) 
     {
         assert(!_error);
 
@@ -176,6 +177,8 @@
             return true;
         }
 
+        const string_table::key key = getName(uri);
+
         // Test conducted with AMFPHP:
         // '__proto__' and 'constructor' members
         // of an object don't get back from an 'echo-service'.

=== modified file 'libcore/asobj/flash/net/net_pkg.cpp'
--- a/libcore/asobj/flash/net/net_pkg.cpp       2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/net/net_pkg.cpp       2009-12-02 12:30:12 +0000
@@ -51,8 +51,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri), get_flash_net_package,
-            flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_net_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/text/text_pkg.cpp'
--- a/libcore/asobj/flash/text/text_pkg.cpp     2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/text/text_pkg.cpp     2009-12-02 12:30:12 +0000
@@ -49,8 +49,7 @@
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_text_package, flags, getNamespace(uri));
+    where.init_destructive_property(uri, get_flash_text_package, flags);
 }
 
 

=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp  2009-11-05 21:33:24 +0000
+++ b/libcore/namedStrings.cpp  2009-12-02 12:30:12 +0000
@@ -116,7 +116,7 @@
        string_table::svt( "onResult", NSV::PROP_ON_RESULT ),
        string_table::svt( "onMetaData", NSV::PROP_ON_META_DATA ),
        string_table::svt( "onConnect", NSV::PROP_ON_CONNECT ),
-        string_table::svt( "onXML", NSV::PROP_ON_XML ),
+    string_table::svt( "onXML", NSV::PROP_ON_XML ),
        string_table::svt( "parseXML", NSV::PROP_PARSE_XML ),
        string_table::svt( "onTimer", NSV::PROP_ON_TIMER ),
        string_table::svt( "_parent", NSV::PROP_uPARENT ),
@@ -187,9 +187,12 @@
        string_table::svt( "Color", NSV::CLASS_COLOR ),
        string_table::svt( "Selection", NSV::CLASS_SELECTION ),
        string_table::svt( "Sound", NSV::CLASS_SOUND ),
+       string_table::svt( "SimpleButton", NSV::CLASS_SIMPLE_BUTTON ),
        string_table::svt( "XMLSocket", NSV::CLASS_XMLSOCKET ),
+       string_table::svt( "Shape", NSV::CLASS_SHAPE ),
        string_table::svt( "Date", NSV::CLASS_DATE ),
        string_table::svt( "XML", NSV::CLASS_XML ),
+       string_table::svt( "XMLDocument", NSV::CLASS_XML_DOCUMENT ),
        string_table::svt( "XMLNode", NSV::CLASS_XMLNODE ),
        string_table::svt( "Mouse", NSV::CLASS_MOUSE ),
        string_table::svt( "Object", NSV::CLASS_OBJECT ),
@@ -198,6 +201,7 @@
        string_table::svt( "Accessibility", NSV::CLASS_ACCESSIBILITY ), 
        string_table::svt( "Array", NSV::CLASS_ARRAY ),
        string_table::svt( "Key", NSV::CLASS_KEY ),
+       string_table::svt( "Keyboard", NSV::CLASS_KEYBOARD ),
        string_table::svt( "AsBroadcaster", NSV::CLASS_AS_BROADCASTER ),
        string_table::svt( "Function", NSV::CLASS_FUNCTION ),
        string_table::svt( "TextSnapshot", NSV::CLASS_TEXT_SNAPSHOT ),

=== modified file 'libcore/namedStrings.h'
--- a/libcore/namedStrings.h    2009-11-05 21:33:24 +0000
+++ b/libcore/namedStrings.h    2009-12-02 12:30:12 +0000
@@ -75,6 +75,7 @@
         CLASS_INT,
         CLASS_INTERACTIVEOBJECT,
         CLASS_KEY,
+        CLASS_KEYBOARD,
         CLASS_LOAD_VARS,
         CLASS_LOCALCONNECTION,
         CLASS_MATH,
@@ -89,7 +90,9 @@
         CLASS_OBJECT,
         CLASS_QNAME,
         CLASS_SELECTION,
+        CLASS_SHAPE,
         CLASS_SHARED_OBJECT,
+        CLASS_SIMPLE_BUTTON,
         CLASS_SOUND,
         CLASS_SPRITE,
         CLASS_STAGE,
@@ -110,6 +113,7 @@
         CLASS_TEXTRENDERER,
         CLASS_VIDEO,
         CLASS_XML,
+        CLASS_XML_DOCUMENT,
         CLASS_XMLNODE,
         CLASS_XMLSOCKET,
         NS_ADOBE_UTILS,

=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp    2009-12-01 11:02:43 +0000
+++ b/libcore/vm/Machine.cpp    2009-12-02 14:27:13 +0000
@@ -444,8 +444,9 @@
                     
                     // If we don't have a super, throw.
                     if (!super) throw ASReferenceError();
-                    Property *b = super->findProperty(a.getABCName(), 
-                        a.getNamespace()->getURI());
+                    const ObjectURI uri(a.getGlobalName(),
+                            a.getNamespace()->getURI());
+                    Property *b = super->findProperty(uri);
                     // The object is on the top already.
                     pushGet(super, _stack.top(0), b);
                     break;
@@ -474,8 +475,11 @@
                     as_object* super = _stack.pop().to_object(*_global)->
                         get_prototype();
                     if (!super) throw ASReferenceError();
-                    Property* b = super->findProperty(a.getABCName(), 
-                        a.getNamespace()->getURI());
+
+                    const ObjectURI uri(a.getGlobalName(),
+                            a.getNamespace()->getURI());
+                    Property* b = super->findProperty(uri);
+
                     _stack.push(vobj);
                     pushSet(super, vobj, b);
                     break;
@@ -949,7 +953,7 @@
                     
                     _stack.drop(1);
                     const Property *b = obj->getByIndex(index);
-                    if (b) _stack.top(0) = mST.value(b->getName());
+                    if (b) _stack.top(0) = mST.value(getName(b->uri()));
                     else _stack.top(0) = "";
                     break;
                 }
@@ -1361,8 +1365,9 @@
 
                     if (!super) throw ASReferenceError();
                     
-                    Property* b = super->findProperty(a.getABCName(),
+                    const ObjectURI uri(a.getGlobalName(),
                             a.getNamespace()->getURI());
+                    Property* b = super->findProperty(uri);
                     
                     if (!b) throw ASReferenceError();
                     
@@ -1422,8 +1427,8 @@
                     }
                     else {
 
-                        as_value property = object->getMember(
-                                a.getGlobalName(), 0);
+                        as_value property =
+                            object->getMember(a.getGlobalName());
                     
                         if (!property.is_undefined() && !property.is_null()) {
                             log_abc("Calling method %s on object %s",
@@ -1534,7 +1539,7 @@
                         throw ASException();
                     }
 
-                    as_value c = super->getMember(NSV::PROP_CONSTRUCTOR, 0);
+                    as_value c = super->getMember(NSV::PROP_CONSTRUCTOR);
                     pushCall(c.to_function(), super, mIgnoreReturn,
                             argc, -1);
                     break;
@@ -1578,7 +1583,8 @@
                     string_table::key ns = a.getNamespace() ?
                         a.getNamespace()->getURI() : 0;
 
-                    as_value c = object->getMember(a.getGlobalName(), ns);
+                    as_value c = object->getMember(
+                            ObjectURI(a.getGlobalName(), ns));
 
                     // TODO: don't do this. Scriptes should not be functions;
                     // we should always use the constructor member, most
@@ -1603,7 +1609,7 @@
                         }
                         else {
                             as_value val = c.to_object(*_global)->getMember(
-                                    NSV::PROP_CONSTRUCTOR, 0);
+                                    NSV::PROP_CONSTRUCTOR);
 
                             invoke(val, env, c.to_object(*_global), args);
 
@@ -1970,7 +1976,8 @@
                     
                     as_value prop;
                     
-                    const bool found = object->get_member(name, &prop, ns);
+                    const ObjectURI uri(name, ns);
+                    const bool found = object->get_member(uri, &prop);
                     if (!found) {
                         log_abc("GETPROPERTY: property %s not found",
                                 mST.value(name));
@@ -2041,7 +2048,8 @@
                     const string_table::key ns = n ? n->getURI() : 0;
                     const string_table::key prop = a.getGlobalName();
 
-                    const bool deleted = obj->delProperty(prop, ns).second;
+                    const bool deleted = obj->delProperty(
+                            ObjectURI(prop, ns)).second;
                     _stack.top(0) = deleted;
                     break;
                 }
@@ -3269,7 +3277,7 @@
                        continue;
                }
         
-        if (scope_object->get_member(var, &val, ns)) {
+        if (scope_object->get_member(ObjectURI(var, ns), &val)) {
             push_stack(_scopeStack.at(i));
                        return val;
                }


reply via email to

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