gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, master, updated. db12478c8e056799a3c1


From: Sandro Santilli
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. db12478c8e056799a3c120a4ef8a8c327b535e80
Date: Thu, 25 Nov 2010 15:01:56 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  db12478c8e056799a3c120a4ef8a8c327b535e80 (commit)
       via  4c18be0d39151da1bed49c31638e313cd8136939 (commit)
      from  ee0fee39a0f1a96cb776f844e3e9189c14e3accc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=db12478c8e056799a3c120a4ef8a8c327b535e80


commit db12478c8e056799a3c120a4ef8a8c327b535e80
Merge: ee0fee3 4c18be0
Author: Sandro Santilli <address@hidden>
Date:   Thu Nov 25 15:31:56 2010 +0100

    Merge branch 'topic/objecturi'


http://git.savannah.gnu.org/cgit//commit/?id=4c18be0d39151da1bed49c31638e313cd8136939


commit 4c18be0d39151da1bed49c31638e313cd8136939
Author: Sandro Santilli <address@hidden>
Date:   Thu Nov 25 15:25:38 2010 +0100

    use ObjectURI more consistently

diff --git a/libcore/AMFConverter.cpp b/libcore/AMFConverter.cpp
index a152e99..291a5bf 100644
--- a/libcore/AMFConverter.cpp
+++ b/libcore/AMFConverter.cpp
@@ -192,10 +192,9 @@ Writer::writeObject(as_object* obj)
     // Arrays are handled specially.
     if (obj->array()) {
 
-        string_table& st = vm.getStringTable();
         const size_t len = arrayLength(*obj);
         if (_strictArray) {
-            IsStrictArray s(st);
+            IsStrictArray s(vm);
             // Check if any non-hidden properties are non-numeric.
             obj->visitProperties<IsEnumerable>(s);
 
@@ -211,7 +210,7 @@ Writer::writeObject(as_object* obj)
 
                 as_value elem;
                 for (size_t i = 0; i < len; ++i) {
-                    elem = getMember(*obj, arrayKey(st, i));
+                    elem = getMember(*obj,arrayKey(vm, i));
                     if (!elem.writeAMF0(*this)) {
                         log_error("Problems serializing strict array "
                                 "member %d=%s", i, elem);
@@ -463,7 +462,7 @@ Reader::readArray()
 #endif
 
     as_value objectElement;
-    string_table& st = getStringTable(_global);
+    VM& vm = getVM(_global);
     for (;;) {
 
         // It seems we don't mind about this situation, although it means
@@ -507,7 +506,7 @@ Reader::readArray()
         if (!operator()(objectElement)) {
             throw AMFException("Unable to read array element");
         }
-        array->set_member(st.find(name), objectElement);
+        array->set_member(getURI(vm, name), objectElement);
     }
     return as_value(array);
 }
@@ -515,8 +514,7 @@ Reader::readArray()
 as_value
 Reader::readObject()
 {
-
-    string_table& st = getStringTable(_global);
+    VM& vm = getVM(_global);
     as_object* obj = createObject(_global); 
 
 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
@@ -550,7 +548,7 @@ Reader::readObject()
         if (!operator()(tmp)) {
             throw AMFException("Unable to read object member");
         }
-        obj->set_member(st.find(keyString), tmp);
+        obj->set_member(getURI(vm, keyString), tmp);
     }
 }
 
diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index abbfaaa..a5f525a 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -315,10 +315,13 @@ Button::trackAsMenu()
     as_object* obj = getObject(this);
     assert(obj);
 
+    VM& vm = getVM(*obj);
+
     as_value track;
-    string_table& st = getStringTable(*obj);
-    if (obj->get_member(st.find("trackAsMenu"), &track)) {
-        return toBool(track, getVM(*obj));
+    // TODO: use NSV
+    const ObjectURI& propTrackAsMenu = getURI(vm, "trackAsMenu");
+    if (obj->get_member(propTrackAsMenu, &track)) {
+        return toBool(track, vm);
     }
     if (_def) return _def->trackAsMenu();
     return false;
diff --git a/libcore/DisplayObject.cpp b/libcore/DisplayObject.cpp
index 6e3513f..59c12ba 100644
--- a/libcore/DisplayObject.cpp
+++ b/libcore/DisplayObject.cpp
@@ -128,7 +128,7 @@ DisplayObject::getLoadedMovie(Movie* extern_movie)
     UNUSED(extern_movie);
 }
 
-string_table::key
+ObjectURI
 DisplayObject::getNextUnnamedInstanceName()
 {
     assert(_object);
@@ -136,8 +136,8 @@ DisplayObject::getNextUnnamedInstanceName()
        std::ostringstream ss;
        ss << "instance" << mr.nextUnnamedInstance();
 
-    string_table& st = getStringTable(*_object);
-       return st.find(ss.str());
+    VM& vm = getVM(*_object);
+       return getURI(vm, ss.str(), true);
 }
 
 
@@ -1385,8 +1385,7 @@ getNameProperty(DisplayObject& o)
 void
 setName(DisplayObject& o, const as_value& val)
 {
-    string_table& st = getStringTable(*getObject(&o));
-    o.set_name(st.find(val.to_string().c_str()));
+    o.set_name(getURI(getVM(*getObject(&o)), val.to_string()));
 }
 
 void
diff --git a/libcore/DisplayObject.h b/libcore/DisplayObject.h
index 055c8d4..dc8cfd2 100644
--- a/libcore/DisplayObject.h
+++ b/libcore/DisplayObject.h
@@ -876,7 +876,7 @@ public:
 #endif
     
     /// Used to assign a name to unnamed instances
-    string_table::key getNextUnnamedInstanceName();
+    ObjectURI getNextUnnamedInstanceName();
 
     enum BlendMode
     {
diff --git a/libcore/Function.h b/libcore/Function.h
index eefe169..ca402b2 100644
--- a/libcore/Function.h
+++ b/libcore/Function.h
@@ -25,6 +25,7 @@
 
 #include "UserFunction.h"
 #include "smart_ptr.h"
+#include "ObjectURI.h"
 
 // Forward declarations
 namespace gnash {
@@ -107,7 +108,7 @@ public:
     //
     /// @param reg      The register for the argument.
     /// @param name     The name of the argument.
-       void add_arg(boost::uint8_t reg, string_table::key name) {
+       void add_arg(boost::uint8_t reg, const ObjectURI& name) {
         _args.push_back(Argument(reg, name));
        }
 
@@ -130,9 +131,9 @@ protected:
        
     struct Argument
        {
-        Argument(boost::uint8_t r, string_table::key n) : reg(r), name(n) {}
+        Argument(boost::uint8_t r, const ObjectURI& n) : reg(r), name(n) {}
         boost::uint8_t reg;
-        string_table::key name;
+        ObjectURI name;
        };
 
        std::vector<Argument> _args;
diff --git a/libcore/MovieClip.cpp b/libcore/MovieClip.cpp
index 2874869..cf54110 100644
--- a/libcore/MovieClip.cpp
+++ b/libcore/MovieClip.cpp
@@ -691,7 +691,7 @@ MovieClip::duplicateMovieClip(const std::string& newname, 
int depth,
 
     MovieClip* newmovieclip = new MovieClip(o, _def.get(), _swf, parent);
 
-    const string_table::key nn = 
getStringTable(*getObject(this)).find(newname);
+    const ObjectURI& nn = getURI(getVM(*getObject(this)), newname);
     newmovieclip->set_name(nn);
 
     newmovieclip->setDynamic();
@@ -1278,14 +1278,13 @@ MovieClip::add_display_object(const 
SWF::PlaceObject2Tag* tag,
     if (existing_char) return NULL;
 
     Global_as& gl = getGlobal(*getObject(this));
+    VM& vm = getVM(*getObject(this));
     DisplayObject* ch = cdef->createDisplayObject(gl, this);
 
-    string_table& st = getStringTable(*getObject(this));
-
-    if (tag->hasName()) ch->set_name(st.find(tag->getName()));
+    if (tag->hasName()) ch->set_name(getURI(vm, tag->getName()));
     else if (isReferenceable(*ch))
     {
-        const string_table::key instance_name = getNextUnnamedInstanceName();
+        const ObjectURI& instance_name = getNextUnnamedInstanceName();
         ch->set_name(instance_name);
     }
 
@@ -1368,12 +1367,11 @@ MovieClip::replace_display_object(const 
SWF::PlaceObject2Tag* tag,
     // TODO: check if we can drop this for REPLACE!
     // should we rename the DisplayObject when it's REPLACE tag?
     if (tag->hasName()) {
-        string_table& st = getStringTable(*getObject(this));
-        ch->set_name(st.find(tag->getName()));
+        VM& vm = getVM(*getObject(this));
+        ch->set_name(getURI(vm, tag->getName()));
     }
     else if (isReferenceable(*ch)) {
-        const string_table::key instance_name = getNextUnnamedInstanceName();
-        ch->set_name(instance_name);
+        ch->set_name(getNextUnnamedInstanceName());
     }
     if (tag->hasRatio()) {
         ch->set_ratio(tag->getRatio());
@@ -1573,11 +1571,11 @@ MovieClip::trackAsMenu()
     as_object* obj = getObject(this);
     assert(obj);
 
-    string_table& st = getStringTable(*obj);
-
     as_value track;
-    return (obj->get_member(st.find("trackAsMenu"), &track) &&
-            toBool(track, getVM(*obj)));
+    VM& vm = getVM(*obj);
+    // TODO: use namedStrings here
+    return (obj->get_member(getURI(vm, "trackAsMenu"), &track) &&
+            toBool(track, vm));
 }
 
 bool
@@ -1997,13 +1995,13 @@ MovieClip::processCompletedLoadVariableRequests()
 void
 MovieClip::setVariables(const MovieVariables& vars)
 {
-    string_table& st = getStringTable(*getObject(this));
+    VM& vm = getVM(*getObject(this));
     for (MovieVariables::const_iterator it=vars.begin(), itEnd=vars.end();
         it != itEnd; ++it)
     {
         const std::string& name = it->first;
         const std::string& val = it->second;
-        getObject(this)->set_member(st.find(name), val);
+        getObject(this)->set_member(getURI(vm, name), val);
     }
 }
 
diff --git a/libcore/ObjectURI.h b/libcore/ObjectURI.h
index 52842de..a16af85 100644
--- a/libcore/ObjectURI.h
+++ b/libcore/ObjectURI.h
@@ -19,11 +19,13 @@
 #ifndef GNASH_OBJECTURI_H
 #define GNASH_OBJECTURI_H
 
-#include "string_table.h"
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h" // GNASH_STATS_OBJECT_URI_NOCASE
 #endif
 
+#include "string_table.h"
+#include "namedStrings.h"
+
 #include <string>
 #include <ostream>
 #include <sstream>
@@ -65,7 +67,7 @@ struct ObjectURI
     {}
 
     /// Construct an ObjectURI from name
-    ObjectURI(string_table::key name)
+    ObjectURI(NSV::NamedStrings name)
         :
         name(name),
         nameNoCase(0)
diff --git a/libcore/TextField.cpp b/libcore/TextField.cpp
index 80e1703..d960743 100644
--- a/libcore/TextField.cpp
+++ b/libcore/TextField.cpp
@@ -48,6 +48,7 @@
 #include "Global_as.h"
 #include "Renderer.h"
 #include "Transform.h"
+#include "ObjectURI.h"
 
 #include <algorithm> 
 #include <string>
@@ -2001,7 +2002,7 @@ TextField::parseTextVariableRef(const std::string& 
variableName) const
     }
 
     ret.first = target;
-    ret.second = getStringTable(*object()).find(parsedName);
+    ret.second = getURI(getVM(*object()), parsedName);
 
     return ret;
 }
@@ -2041,7 +2042,7 @@ TextField::registerTextVariable()
         return;
     }
 
-    const string_table::key key = varRef.second;
+    const ObjectURI& key = varRef.second;
     as_object* obj = getObject(this);
     const int version = getSWFVersion(*obj);
     string_table& st = getStringTable(*obj);
@@ -2085,7 +2086,7 @@ TextField::registerTextVariable()
         log_debug("Calling set_textfield_variable(%s) against sprite %s",
                 st.value(key), sprite->getTarget());
 #endif
-        sprite->set_textfield_variable(st.value(key), this);
+        sprite->set_textfield_variable(key.toString(st), this);
 
     }
     _text_variable_registered=true;
diff --git a/libcore/TextField.h b/libcore/TextField.h
index d1a1785..e0f72bf 100644
--- a/libcore/TextField.h
+++ b/libcore/TextField.h
@@ -679,7 +679,7 @@ private:
        ///
        void registerTextVariable();
 
-       typedef std::pair<as_object*, string_table::key> VariableRef;
+       typedef std::pair<as_object*, ObjectURI> VariableRef;
 
        /// \brief
        /// Parse the given variable name
diff --git a/libcore/Timers.cpp b/libcore/Timers.cpp
index bfef844..8bca16c 100644
--- a/libcore/Timers.cpp
+++ b/libcore/Timers.cpp
@@ -43,7 +43,7 @@ Timer::Timer(as_function& method, unsigned long ms,
     _interval(ms),
     _start(std::numeric_limits<unsigned long>::max()),
     _function(&method),
-    _methodName(0),
+    _methodName(),
     _object(this_ptr),
     _args(args),
     _runOnce(runOnce)
@@ -51,7 +51,7 @@ Timer::Timer(as_function& method, unsigned long ms,
     start();
 }
 
-Timer::Timer(as_object* this_ptr, string_table::key methodName,
+Timer::Timer(as_object* this_ptr, const ObjectURI& methodName,
         unsigned long ms, const fn_call::Args& args, bool runOnce)
     :
     _interval(ms),
@@ -104,7 +104,8 @@ Timer::execute()
 
     // If _function is not 0, _methodName should be 0 anyway, but the
     // ternary operator is there for clarity.
-    as_object* super = _object->get_super(_function ? 0 : _methodName);
+    as_object* super = _function ? _object->get_super()
+                                 : _object->get_super(_methodName);
     VM& vm = getVM(*_object);
 
     as_value timer_method = _function ? _function :
diff --git a/libcore/Timers.h b/libcore/Timers.h
index 5a1b946..9d4d52b 100644
--- a/libcore/Timers.h
+++ b/libcore/Timers.h
@@ -96,7 +96,7 @@ public:
     ///
     /// @param runOnce
     ///     If true the interval will run only once. False if omitted.
-    Timer(as_object* obj, string_table::key methodName, unsigned long ms,
+    Timer(as_object* obj, const ObjectURI& methodName, unsigned long ms,
             const fn_call::Args& args, bool runOnce = false);
 
     /// Clear the timer, ready for reuse
@@ -185,7 +185,7 @@ private:
     /// an intrusive pointer
     as_function* _function;
 
-    string_table::key _methodName;
+    ObjectURI _methodName;
 
     /// Context for the function call. Will be used as 'this' pointer.
     as_object* _object;
diff --git a/libcore/as_environment.cpp b/libcore/as_environment.cpp
index e993bcb..00e379b 100644
--- a/libcore/as_environment.cpp
+++ b/libcore/as_environment.cpp
@@ -212,7 +212,7 @@ findObject(const as_environment& ctx, const std::string& 
path,
         // No more components to scan
         if (subpart.empty()) break;
 
-        const ObjectURI subpartURI(st.find(subpart));
+        const ObjectURI subpartURI(getURI(vm, subpart));
 
         if (!firstElementParsed) {
             as_object* element(0);
@@ -301,7 +301,7 @@ getVariable(const as_environment& env, const std::string& 
varname,
 
         if (target) {
             as_value val;
-            target->get_member(env.getVM().getStringTable().find(var), &val);
+            target->get_member(getURI(env.getVM(), var), &val);
             if (retTarget) *retTarget = target;
             return val;
         }
@@ -340,7 +340,7 @@ setVariable(const as_environment& env, const std::string& 
varname,
     if (parsePath(varname, path, var)) {
         as_object* target = findObject(env, path, &scope); 
         if (target) {
-            target->set_member(env.getVM().getStringTable().find(var), val);
+            target->set_member(getURI(env.getVM(), var), val);
         }
         else {
             IF_VERBOSE_ASCODING_ERRORS(
@@ -363,7 +363,7 @@ delVariable(const as_environment& ctx, const std::string& 
varname,
 
     VM& vm = ctx.getVM();
 
-    string_table::key varkey = vm.getStringTable().find(varname);
+    const ObjectURI& varkey = getURI(vm, varname);
 
     // Check the with-stack.
     for (size_t i = scope.size(); i > 0; --i) {
@@ -449,8 +449,7 @@ setVariableRaw(const as_environment& env, const 
std::string& varname,
     }
 
     VM& vm = env.getVM();
-    string_table& st = vm.getStringTable();
-    string_table::key varkey = st.find(varname);
+    const ObjectURI& varkey = getURI(vm, varname);
 
     // in SWF5 and lower, scope stack should just contain 'with' elements 
 
@@ -496,8 +495,7 @@ getVariableRaw(const as_environment& env, const 
std::string& varname,
 
     VM& vm = env.getVM();
     const int swfVersion = vm.getSWFVersion();
-    string_table& st = vm.getStringTable();
-    string_table::key key = st.find(varname);
+    const ObjectURI& key = getURI(vm, varname);
 
     // Check the scope stack.
     for (size_t i = scope.size(); i > 0; --i) {
@@ -544,7 +542,9 @@ getVariableRaw(const as_environment& env, const 
std::string& varname,
 
     as_object* global = vm.getGlobal();
 
-    if (swfVersion > 5 && key == NSV::PROP_uGLOBAL) {
+    // TODO: check if we really want case-sensitive comparison
+    ObjectURI::CaseEquals eq(getVM(env).getStringTable());
+    if (swfVersion > 5 && eq(key, NSV::PROP_uGLOBAL)) {
 #ifdef GNASH_DEBUG_GET_VARIABLE
         log_debug("Took %s as _global, returning _global", varname);
 #endif
@@ -573,8 +573,7 @@ getVariableRaw(const as_environment& env, const 
std::string& varname,
 bool
 getLocal(as_object& locals, const std::string& name, as_value& ret)
 {
-    string_table& st = getStringTable(locals);
-    return locals.get_member(st.find(name), &ret);
+    return locals.get_member(getURI(getVM(locals), name), &ret);
 }
 
 bool
@@ -593,15 +592,13 @@ findLocal(as_object& locals, const std::string& varname, 
as_value& ret,
 bool
 deleteLocal(as_object& locals, const std::string& varname)
 {
-    string_table& st = getStringTable(locals);
-    return locals.delProperty(st.find(varname)).second;
+    return locals.delProperty(getURI(getVM(locals), varname)).second;
 }
 
 bool
 setLocal(as_object& locals, const std::string& varname, const as_value& val)
 {
-    string_table& st = getStringTable(locals);
-    Property* prop = locals.getOwnProperty(st.find(varname));
+    Property* prop = locals.getOwnProperty(getURI(getVM(locals), varname));
     if (!prop) return false;
     prop->setValue(locals, val);
     return true;
diff --git a/libcore/as_object.cpp b/libcore/as_object.cpp
index 11904f3..c2b4e5e 100644
--- a/libcore/as_object.cpp
+++ b/libcore/as_object.cpp
@@ -324,8 +324,7 @@ void
 as_object::add_property(const std::string& name, as_function& getter,
                         as_function* setter)
 {
-    string_table& st = getStringTable(*this);
-    ObjectURI uri(st.find(name));
+    const ObjectURI& uri = getURI(vm(), name);
 
     Property* prop = _members.getProperty(uri);
 
@@ -604,7 +603,7 @@ as_object::set_member(const ObjectURI& uri, const as_value& 
val, bool ifFound)
             
         if (displayObject()) {
             DisplayObject* d = displayObject();
-            if (setDisplayObjectProperty(*d, getName(uri), val)) return true;
+            if (setDisplayObjectProperty(*d, uri, val)) return true;
             // TODO: should we execute triggers?
         }
             
@@ -666,7 +665,7 @@ as_object::set_member(const ObjectURI& uri, const as_value& 
val, bool ifFound)
 void
 as_object::init_member(const std::string& key1, const as_value& val, int flags)
 {
-    const ObjectURI uri(getStringTable(*this).find(key1));
+    const ObjectURI& uri(getURI(vm(), key1));
     init_member(uri, val, flags);
 }
 
@@ -685,11 +684,11 @@ as_object::init_member(const ObjectURI& uri, const 
as_value& val, int flags)
 }
 
 void
-as_object::init_property(const std::string& key, as_function& getter,
+as_object::init_property(const std::string& name, as_function& getter,
                          as_function& setter, int flags)
 {
-    string_table::key k = getStringTable(*this).find(key);
-    init_property(k, getter, setter, flags);
+    const ObjectURI& uri = getURI(vm(), name);
+    init_property(uri, getter, setter, flags);
 }
 
 void
@@ -700,11 +699,11 @@ as_object::init_property(const ObjectURI& uri, 
as_function& getter,
 }
 
 void
-as_object::init_property(const std::string& key, as_c_function_ptr getter,
+as_object::init_property(const std::string& name, as_c_function_ptr getter,
                          as_c_function_ptr setter, int flags)
 {
-    string_table::key k = getStringTable(*this).find(key);
-    init_property(k, getter, setter, flags);
+    const ObjectURI& uri = getURI(vm(), name);
+    init_property(uri, getter, setter, flags);
 }
 
 void
@@ -729,23 +728,22 @@ as_object::init_destructive_property(const ObjectURI& uri,
 }
 
 void
-as_object::init_readonly_property(const std::string& key, as_function& getter,
+as_object::init_readonly_property(const std::string& name, as_function& getter,
                                   int initflags)
 {
-    string_table::key k = getStringTable(*this).find(key);
+    const ObjectURI& uri = getURI(vm(), name);
 
-    init_property(k, getter, getter, initflags | PropFlags::readOnly);
-    assert(_members.getProperty(k));
+    init_property(uri, getter, getter, initflags | PropFlags::readOnly);
+    assert(_members.getProperty(uri));
 }
 
 void
-as_object::init_readonly_property(const std::string& key,
+as_object::init_readonly_property(const std::string& name,
                                   as_c_function_ptr getter, int initflags)
 {
-    string_table::key k = getStringTable(*this).find(key);
-
-    init_property(k, getter, getter, initflags | PropFlags::readOnly);
-    assert(_members.getProperty(k));
+    const ObjectURI& uri = getURI(vm(), name);
+    init_property(uri, getter, getter, initflags | PropFlags::readOnly);
+    assert(_members.getProperty(uri));
 }
 
 void
@@ -884,7 +882,7 @@ as_object::setPropFlags(const as_value& props_val, int 
set_false, int set_true)
         }
 
         // set_member_flags will take care of case conversion
-        set_member_flags(getStringTable(*this).find(prop), set_true, 
set_false);
+        set_member_flags(getURI(vm(), prop), set_true, set_false);
 
         if (next_comma == std::string::npos) {
             break;
@@ -1111,7 +1109,7 @@ sendEvent(as_object& o, const as_environment& env, const 
ObjectURI& name)
 }
 
 as_object*
-getObjectWithPrototype(Global_as& gl, string_table::key c)
+getObjectWithPrototype(Global_as& gl, const ObjectURI& c)
 {
     as_object* ctor = toObject(getMember(gl, c), getVM(gl));
     as_object* proto = ctor ? 
diff --git a/libcore/as_object.h b/libcore/as_object.h
index f281309..9edf79f 100644
--- a/libcore/as_object.h
+++ b/libcore/as_object.h
@@ -861,7 +861,7 @@ hasOwnProperty(as_object& o, const ObjectURI& uri)
     return (o.getOwnProperty(uri));
 }
 
-as_object* getObjectWithPrototype(Global_as& gl, string_table::key c);
+as_object* getObjectWithPrototype(Global_as& gl, const ObjectURI& c);
 
 /// Check whether the object is an instance of a known type.
 //
diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index bdab196..3f5a913 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -69,9 +69,9 @@ namespace {
             int version);
     bool compareBoolean(const as_value& boolean, const as_value& other,
             int version);
-    inline bool findMethod(as_object& obj, string_table::key m, as_value& ret);
+    inline bool findMethod(as_object& obj, const ObjectURI& m, as_value& ret);
     template<typename T> as_object* constructObject(VM& vm, const T& arg,
-            string_table::key className);
+            const ObjectURI& className);
 }
 
 namespace {
@@ -983,7 +983,7 @@ stringEqualsNumber(const as_value& str, const as_value& 
num, int version)
 
 /// Returns a member only if it is an object.
 inline bool
-findMethod(as_object& obj, string_table::key m, as_value& ret)
+findMethod(as_object& obj, const ObjectURI& m, as_value& ret)
 {
     return obj.get_member(m, &ret) && ret.is_object();
 }
@@ -997,7 +997,7 @@ findMethod(as_object& obj, string_table::key m, as_value& 
ret)
 /// TODO: test the other failure cases.
 template<typename T>
 as_object*
-constructObject(VM& vm, const T& arg, string_table::key className)
+constructObject(VM& vm, const T& arg, const ObjectURI& className)
 {
 
     as_object& gl = *vm.getGlobal();
diff --git a/libcore/asobj/Array_as.cpp b/libcore/asobj/Array_as.cpp
index e371ec5..4ade499 100644
--- a/libcore/asobj/Array_as.cpp
+++ b/libcore/asobj/Array_as.cpp
@@ -85,7 +85,7 @@ enum SortFlags {
     as_value array_sort(const fn_call& fn);
     as_value array_splice(const fn_call& fn);
 
-    string_table::key getKey(const fn_call& fn, size_t i);
+    ObjectURI getKey(const fn_call& fn, size_t i);
     int isIndex(const std::string& name);
 
     /// Implementation of foreachArray that takes a start and end range.
@@ -208,7 +208,7 @@ bool sort(as_object& o, AVCMP avc, AVEQ ave)
 
     if (std::adjacent_find(v.begin(), v.end(), ave) != v.end()) return false;
 
-    string_table& st = getStringTable(o);
+    VM& vm = getVM(o);
 
     SortContainer::const_iterator it = v.begin();
 
@@ -216,7 +216,7 @@ bool sort(as_object& o, AVCMP avc, AVEQ ave)
         if (i >= v.size()) {
             break;
         }
-        o.set_member(arrayKey(st, i), *it);
+        o.set_member(arrayKey(vm, i), *it);
         ++it;
     }
     return true;
@@ -238,7 +238,7 @@ sort(as_object& o, AVCMP avc)
 
     v.sort(avc);
 
-    string_table& st = getStringTable(o);
+    VM& vm = getVM(o);
 
     SortContainer::const_iterator it = v.begin();
 
@@ -246,7 +246,7 @@ sort(as_object& o, AVCMP avc)
         if (it == v.end()) {
             break;
         }
-        o.set_member(arrayKey(st, i), *it);
+        o.set_member(arrayKey(vm, i), *it);
         ++it;
     }
 }
@@ -610,7 +610,7 @@ class as_value_prop
 public:
     
     // Note: cmpfn must implement a strict weak ordering
-    as_value_prop(string_table::key name, as_cmp_fn cmpfn, const as_object& o)
+    as_value_prop(ObjectURI name, as_cmp_fn cmpfn, const as_object& o)
         :
         _comp(cmpfn),
         _prop(name),
@@ -634,7 +634,7 @@ public:
     }
 private:
     as_cmp_fn _comp;
-    string_table::key _prop;
+    ObjectURI _prop;
     const as_object& _obj;
 };
 
@@ -645,13 +645,13 @@ public:
     typedef std::vector<as_cmp_fn> Comps;
     Comps& _cmps;
 
-    typedef std::vector<string_table::key> Props;
+    typedef std::vector<ObjectURI> Props;
     Props& _prps;
     
     const as_object& _obj;
 
     // Note: all as_cmp_fns in *cmps must implement strict weak ordering
-    as_value_multiprop(std::vector<string_table::key>& prps, 
+    as_value_multiprop(std::vector<ObjectURI>& prps, 
         std::vector<as_cmp_fn>& cmps, const as_object& o)
         :
         _cmps(cmps),
@@ -694,7 +694,7 @@ public:
 class as_value_multiprop_eq : public as_value_multiprop
 {
 public:
-    as_value_multiprop_eq(std::vector<string_table::key>& prps, 
+    as_value_multiprop_eq(std::vector<ObjectURI>& prps, 
         std::vector<as_cmp_fn>& cmps, const as_object& o)
         :
         as_value_multiprop(prps, cmps, o),
@@ -742,18 +742,18 @@ flag_preprocess(boost::uint8_t flgs, bool* douniq, bool* 
doindex)
 class GetKeys
 {
 public:
-    GetKeys(std::vector<string_table::key>& v, string_table& st, int version)
+    GetKeys(std::vector<ObjectURI>& v, VM& vm, int version)
         :
         _v(v),
-        _st(st),
+        _vm(vm),
         _version(version)
     {}
     void operator()(const as_value& val) {
-        _v.push_back(_st.find(val.to_string(_version)));
+        _v.push_back(getURI(_vm, val.to_string(_version)));
     }
 private:
-    std::vector<string_table::key>& _v;
-    string_table& _st;
+    std::vector<ObjectURI>& _v;
+    VM& _vm;
     const int _version;
 };
 
@@ -806,7 +806,7 @@ bool
 IsStrictArray::accept(const ObjectURI& uri, const as_value& /*val*/)
 {
     // We ignore namespace.
-    if (isIndex(_st.value(getName(uri))) >= 0) return true;
+    if (isIndex(uri.toString(_st.getStringTable())) >= 0) return true;
     _strict = false;
     return false;
 }
@@ -814,13 +814,16 @@ IsStrictArray::accept(const ObjectURI& uri, const 
as_value& /*val*/)
 void
 checkArrayLength(as_object& array, const ObjectURI& uri, const as_value& val)
 {
-    const string_table::key name = getName(uri);
-    if (name == NSV::PROP_LENGTH) {
+    // TODO: check if we should really be doing
+    //       case-sensitive comparison here!
+    const bool caseless = true;
+    ObjectURI::CaseEquals eq(getStringTable(array), caseless);
+    if (eq(uri, getURI(getVM(array), NSV::PROP_LENGTH))) {
         resizeArray(array, toInt(val, getVM(array)));
         return;
     }
 
-    const int index = isIndex(getStringTable(array).value(name));
+    const int index = isIndex(uri.toString(getStringTable(array)));
 
     // if we were sent a valid array index
     if (index >= 0) {
@@ -884,10 +887,11 @@ array_class_init(as_object& where, const ObjectURI& uri)
 }
 
 // Used by foreachArray, declared in Array_as.h
-string_table::key
-arrayKey(string_table& st, size_t i)
+ObjectURI
+arrayKey(VM& vm, size_t i)
 {
-    return st.find(boost::lexical_cast<std::string>(i));
+    // TODO: tell getURI that the string is already lowercase!
+    return getURI(vm, boost::lexical_cast<std::string>(i), true);
 }
 
 namespace {
@@ -974,8 +978,9 @@ array_splice(const fn_call& fn)
     const size_t newelements = fn.nargs > 2 ? fn.nargs - 2 : 0;
     
     // Push removed elements to the new array.
+    ObjectURI propPush = getURI(getVM(fn), NSV::PROP_PUSH);
     for (size_t i = 0; i < remove; ++i) {
-        const size_t key = getKey(fn, start + i);
+        const ObjectURI& key = getKey(fn, start + i);
         callMethod(ret, NSV::PROP_PUSH, getOwnProperty(*array, key));
     }
 
@@ -994,7 +999,8 @@ array_splice(const fn_call& fn)
     }
     
     // This one is correct!
-    array->set_member(NSV::PROP_LENGTH, size + newelements - remove);
+    ObjectURI propLen = getURI(getVM(fn), NSV::PROP_LENGTH);
+    array->set_member(propLen, size + newelements - remove);
 
     return as_value(ret);
 }
@@ -1076,15 +1082,15 @@ array_sortOn(const fn_call& fn)
     boost::uint8_t flags = 0;
 
     const int version = getSWFVersion(fn);
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     if (fn.nargs == 0) return as_value();
 
     // cases: sortOn("prop) and sortOn("prop", Array.FLAG)
     if (fn.arg(0).is_string()) 
     {
-        string_table::key propField =
-            st.find(fn.arg(0).to_string(version));
+        ObjectURI propField =
+            getURI(vm, fn.arg(0).to_string(version));
 
         if (fn.nargs > 1 && fn.arg(1).is_number()) {
             flags = static_cast<boost::uint8_t>(toNumber(fn.arg(1), 
getVM(fn)));
@@ -1116,8 +1122,8 @@ array_sortOn(const fn_call& fn)
         as_object* props = toObject(fn.arg(0), getVM(fn));
         assert(props);
 
-        std::vector<string_table::key> prp;
-        GetKeys gk(prp, st, version);
+        std::vector<ObjectURI> prp;
+        GetKeys gk(prp, vm, version);
         foreachArray(*props, gk);
         
         std::vector<as_cmp_fn> cmp;
@@ -1231,8 +1237,8 @@ array_unshift(const fn_call& fn)
     const size_t size = arrayLength(*array);
 
     for (size_t i = size + shift - 1; i >= shift ; --i) {
-        const string_table::key nextkey = getKey(fn, i - shift);
-        const string_table::key currentkey = getKey(fn, i);
+        const ObjectURI nextkey = getKey(fn, i - shift);
+        const ObjectURI currentkey = getKey(fn, i);
         array->delProperty(currentkey);
         array->set_member(currentkey, getOwnProperty(*array, nextkey));
     }
@@ -1257,7 +1263,7 @@ array_pop(const fn_call& fn)
     const size_t size = arrayLength(*array);
     if (size < 1) return as_value();
 
-    const string_table::key ind = getKey(fn, size - 1);
+    const ObjectURI ind = getKey(fn, size - 1);
     as_value ret = getOwnProperty(*array, ind);
     array->delProperty(ind);
     
@@ -1279,8 +1285,8 @@ array_shift(const fn_call& fn)
     as_value ret = getOwnProperty(*array, getKey(fn, 0));
 
     for (size_t i = 0; i < static_cast<size_t>(size - 1); ++i) {
-        const string_table::key nextkey = getKey(fn, i + 1);
-        const string_table::key currentkey = getKey(fn, i);
+        const ObjectURI nextkey = getKey(fn, i + 1);
+        const ObjectURI currentkey = getKey(fn, i);
         array->delProperty(currentkey);
         array->set_member(currentkey, getOwnProperty(*array, nextkey));
     }
@@ -1301,8 +1307,8 @@ array_reverse(const fn_call& fn)
     if (size < 2) return as_value();
 
     for (size_t i = 0; i < static_cast<size_t>(size) / 2; ++i) {
-        const string_table::key bottomkey = getKey(fn, i);
-        const string_table::key topkey = getKey(fn, size - i - 1);
+        const ObjectURI bottomkey = getKey(fn, i);
+        const ObjectURI topkey = getKey(fn, size - i - 1);
         const as_value top = getOwnProperty(*array, topkey);
         const as_value bottom = getOwnProperty(*array, bottomkey);
         array->delProperty(topkey);
@@ -1349,6 +1355,7 @@ array_concat(const fn_call& fn)
     PushToArray push(*newarray);
     foreachArray(*array, push);
 
+    ObjectURI propPush = getURI(getVM(fn), NSV::PROP_PUSH);
     for (size_t i = 0; i < fn.nargs; ++i) {
 
         // Array args get concatenated by elements
@@ -1366,7 +1373,7 @@ array_concat(const fn_call& fn)
                 continue;
             }
         }
-        callMethod(newarray, NSV::PROP_PUSH, fn.arg(i));
+        callMethod(newarray, propPush, fn.arg(i));
     }
 
     return as_value(newarray);        
@@ -1443,23 +1450,23 @@ join(as_object* array, const std::string& separator)
 
     std::string s;
 
-    string_table& st = getStringTable(*array);
+    VM& vm = getVM(*array);
     const int version = getSWFVersion(*array);
 
     for (size_t i = 0; i < size; ++i) {
         if (i) s += separator;
         const std::string& index = boost::lexical_cast<std::string>(i);
-        const as_value& el = getOwnProperty(*array, st.find(index));
+        const as_value& el = getOwnProperty(*array, getURI(vm, index));
         s += el.to_string(version);
     }
     return as_value(s);
 }
 
-string_table::key
+ObjectURI
 getKey(const fn_call& fn, size_t i)
 {
-    string_table& st = getStringTable(fn);
-    return arrayKey(st, i);
+    VM& vm = getVM(fn);
+    return arrayKey(vm, i);
 }
 
 template<typename T>
@@ -1480,10 +1487,10 @@ void foreachArray(as_object& array, int start, int end, 
T& pred)
     assert(end >= start);
     assert(size >= end);
 
-    string_table& st = getStringTable(array);
+    VM& vm = getVM(array);
 
     for (size_t i = start; i < static_cast<size_t>(end); ++i) {
-        pred(getOwnProperty(array, arrayKey(st, i)));
+        pred(getOwnProperty(array, arrayKey(vm, i)));
     }
 }
 
@@ -1511,9 +1518,9 @@ resizeArray(as_object& o, const int size)
 
     const size_t currentSize = arrayLength(o);
     if (realSize < currentSize) {
-        string_table& st = getStringTable(o);
+        VM& vm = getVM(o);
         for (size_t i = realSize; i < currentSize; ++i) {
-            o.delProperty(arrayKey(st, i));
+            o.delProperty(arrayKey(vm, i));
         }
     }
 }
diff --git a/libcore/asobj/Array_as.h b/libcore/asobj/Array_as.h
index 1f1e9be..9e1b097 100644
--- a/libcore/asobj/Array_as.h
+++ b/libcore/asobj/Array_as.h
@@ -38,14 +38,14 @@ namespace gnash {
 ///                 found.
 size_t arrayLength(as_object& array);
 
-/// Convert an integral value into an array key
+/// Convert an integral value into an ObjectURI
 //
-/// NB this function adds a string value to the string_table for each separate
-/// integral value. It's the way the string_table works.
+/// NB this function adds a string value to the VM for each separate
+/// integral value. It's the way the VM works.
 //
 /// @param i        The integral value to find
-/// @return         The string table key to look up.
-string_table::key arrayKey(string_table& st, size_t i);
+/// @return         The ObjectURI to look up.
+ObjectURI arrayKey(VM& vm, size_t i);
 
 /// A visitor to check whether an array is strict or not.
 //
@@ -54,7 +54,7 @@ string_table::key arrayKey(string_table& st, size_t i);
 class IsStrictArray : public PropertyVisitor
 {
 public:
-    IsStrictArray(string_table& st) : _strict(true), _st(st) {}
+    IsStrictArray(VM& st) : _strict(true), _st(st) {}
     virtual bool accept(const ObjectURI& uri, const as_value& val);
 
     bool strict() const {
@@ -62,7 +62,7 @@ public:
     }
 private:
     bool _strict;
-    string_table& _st;
+    VM& _st;
 };
 
 
@@ -80,10 +80,10 @@ void foreachArray(as_object& array, T& pred)
     size_t size = arrayLength(array);
     if (!size) return;
 
-    string_table& st = getStringTable(array);
+    VM& vm = getVM(array);
 
     for (size_t i = 0; i < static_cast<size_t>(size); ++i) {
-        pred(getOwnProperty(array, arrayKey(st, i)));
+        pred(getOwnProperty(array, arrayKey(vm, i)));
     }
 }
 
diff --git a/libcore/asobj/AsBroadcaster.cpp b/libcore/asobj/AsBroadcaster.cpp
index 6d8e705..935946a 100644
--- a/libcore/asobj/AsBroadcaster.cpp
+++ b/libcore/asobj/AsBroadcaster.cpp
@@ -51,16 +51,16 @@ namespace {
 
 #ifdef GNASH_DEBUG_BROADCASTER
 struct BroadcasterStats {
-    typedef std::map<string_table::key, unsigned long int> Stat;
+    typedef std::map<ObjectURI&, unsigned long int> Stat;
     Stat stat;
-    const string_table& _st;
-    BroadcasterStats(const string_table& st) : _st(st) {}
-    void check(string_table::key k) {
+    const VM& _st;
+    BroadcasterStats(const VM& vm) : _st(st) {}
+    void check(ObjectURI& k) {
         if ( ! (++stat[k] % 100) ) dump();
     }
     void dump() {
         using namespace std;
-        typedef std::map<unsigned long int, string_table::key> Sorted;
+        typedef std::map<unsigned long int, ObjectURI&> Sorted;
         Sorted sorted;
         for (Stat::iterator i=stat.begin(), e=stat.end(); i!=e; ++i)
             sorted[i->second] = i->first;
@@ -89,7 +89,7 @@ public:
     ///
     BroadcasterVisitor(const fn_call& fn)
         :
-        _eventURI(getStringTable(fn).find(fn.arg(0).to_string())),
+        _eventURI(getURI(getVM(fn),fn.arg(0).to_string())),
         _dispatched(0),
         _fn(fn)
     {
@@ -105,7 +105,7 @@ public:
 
 #ifdef GNASH_DEBUG_BROADCASTER
         static stats::KeyLookup stats("BroadcasterVisitor call operator",
-            getStringTable(_fn), 1);
+            getVM(_fn), 1);
         stats.check(_eventURI.name);
 #endif
         as_value method;
@@ -361,14 +361,16 @@ asbroadcaster_removeListener(const fn_call& fn)
     const int length = toInt(getMember(*listeners, NSV::PROP_LENGTH),
             getVM(fn));
     int i = 0;
-    string_table& st = getStringTable(fn);
+
+    VM& vm = getVM(fn);
+    const ObjectURI& propSplice = getURI(vm, NSV::PROP_SPLICE);
 
     while (i < length) {
         std::ostringstream s;
         s << i;
-        as_value el = getMember(*listeners, st.find(s.str()));
+        as_value el = getMember(*listeners, getURI(vm, s.str()));
         if (equals(el, listenerToRemove, getVM(fn))) {
-            callMethod(listeners, NSV::PROP_SPLICE, s.str(), 1);
+            callMethod(listeners, propSplice, s.str(), 1);
             return as_value(true);
         }
         ++i;
diff --git a/libcore/asobj/Color_as.cpp b/libcore/asobj/Color_as.cpp
index b3a423b..d1134c5 100644
--- a/libcore/asobj/Color_as.cpp
+++ b/libcore/asobj/Color_as.cpp
@@ -45,7 +45,7 @@ namespace {
     as_value color_ctor(const fn_call& fn);
 
     void attachColorInterface(as_object& o);
-    inline void parseColorTransProp(as_object& obj, string_table::key key,
+    inline void parseColorTransProp(as_object& obj, const ObjectURI& key,
             boost::int16_t& target, bool scale);
     inline MovieClip* getTarget(as_object* obj, const fn_call& fn);
 }
@@ -204,21 +204,23 @@ color_settransform(const fn_call& fn)
     MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
-       string_table& st = getStringTable(*obj);
+       VM& vm = getVM(*obj);
 
        SWFCxForm newTrans = getCxForm(*sp);
 
+    // TODO: use NSV 
+
        // multipliers
-       parseColorTransProp(*trans, st.find("ra"), newTrans.ra, true);
-       parseColorTransProp(*trans, st.find("ga"), newTrans.ga, true);
-       parseColorTransProp(*trans, st.find("ba"), newTrans.ba, true);
-       parseColorTransProp(*trans, st.find("aa"), newTrans.aa, true);
+       parseColorTransProp(*trans, getURI(vm, "ra"), newTrans.ra, true);
+       parseColorTransProp(*trans, getURI(vm, "ga"), newTrans.ga, true);
+       parseColorTransProp(*trans, getURI(vm, "ba"), newTrans.ba, true);
+       parseColorTransProp(*trans, getURI(vm, "aa"), newTrans.aa, true);
 
        // offsets
-       parseColorTransProp(*trans, st.find("rb"), newTrans.rb, false);
-       parseColorTransProp(*trans, st.find("gb"), newTrans.gb, false);
-       parseColorTransProp(*trans, st.find("bb"), newTrans.bb, false);
-       parseColorTransProp(*trans, st.find("ab"), newTrans.ab, false);
+       parseColorTransProp(*trans, getURI(vm, "rb"), newTrans.rb, false);
+       parseColorTransProp(*trans, getURI(vm, "gb"), newTrans.gb, false);
+       parseColorTransProp(*trans, getURI(vm, "bb"), newTrans.bb, false);
+       parseColorTransProp(*trans, getURI(vm, "ab"), newTrans.ab, false);
 
        sp->setCxForm(newTrans);
 
@@ -252,7 +254,7 @@ color_ctor(const fn_call& fn)
 }
 
 inline void
-parseColorTransProp(as_object& obj, string_table::key key, boost::int16_t&
+parseColorTransProp(as_object& obj, const ObjectURI& key, boost::int16_t&
         target, bool scale)
 {
        as_value tmp;
diff --git a/libcore/asobj/ContextMenuItem_as.cpp 
b/libcore/asobj/ContextMenuItem_as.cpp
index 8e56424..6494c43 100644
--- a/libcore/asobj/ContextMenuItem_as.cpp
+++ b/libcore/asobj/ContextMenuItem_as.cpp
@@ -63,19 +63,19 @@ contextmenuitem_copy(const fn_call& fn)
     as_object* ptr = ensure<ValidThis>(fn);
 
     Global_as& gl = getGlobal(fn);
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     as_function* ctor =
-        getMember(gl, st.find("ContextMenuItem")).to_function();
+        getMember(gl, getURI(vm, "ContextMenuItem")).to_function();
 
     if (!ctor) return as_value();
 
     fn_call::Args args;
-    args += getMember(*ptr, st.find("caption")),
+    args += getMember(*ptr, getURI(vm, "caption")),
         getMember(*ptr, NSV::PROP_ON_SELECT),
-        getMember(*ptr, st.find("separatorBefore")),
+        getMember(*ptr, getURI(vm, "separatorBefore")),
         getMember(*ptr, NSV::PROP_ENABLED),
-        getMember(*ptr, st.find("visible"));
+        getMember(*ptr, getURI(vm, "visible"));
 
     return constructInstance(*ctor, fn.env(), args);
 }
@@ -86,14 +86,14 @@ contextmenuitem_ctor(const fn_call& fn)
 {
     as_object* obj = fn.this_ptr;
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    obj->set_member(st.find("caption"), fn.nargs ? fn.arg(0) : as_value());
+    obj->set_member(getURI(vm, "caption"), fn.nargs ? fn.arg(0) : as_value());
     obj->set_member(NSV::PROP_ON_SELECT, fn.nargs > 1 ? fn.arg(1) : 
as_value());
-    obj->set_member(st.find("separatorBefore"), fn.nargs > 2 ?
+    obj->set_member(getURI(vm, "separatorBefore"), fn.nargs > 2 ?
             fn.arg(2) : false);
     obj->set_member(NSV::PROP_ENABLED, fn.nargs > 3 ? fn.arg(3) : true);
-    obj->set_member(st.find("visible"), fn.nargs > 4 ? fn.arg(4) : true);
+    obj->set_member(getURI(vm, "visible"), fn.nargs > 4 ? fn.arg(4) : true);
 
     return as_value(); 
 }
diff --git a/libcore/asobj/ContextMenu_as.cpp b/libcore/asobj/ContextMenu_as.cpp
index c649426..93047e5 100644
--- a/libcore/asobj/ContextMenu_as.cpp
+++ b/libcore/asobj/ContextMenu_as.cpp
@@ -59,7 +59,7 @@ namespace {
 class CopyMenuItems
 {
 public:
-    CopyMenuItems(string_table::key c, as_object& nc) : _c(c), _target(nc) {}
+    CopyMenuItems(const ObjectURI& c, as_object& nc) : _c(c), _target(nc) {}
 
     void operator()(const as_value& val) {
         as_object* obj = toObject(val, getVM(_target));
@@ -67,7 +67,7 @@ public:
         callMethod(&_target, NSV::PROP_PUSH, cp);
     }
 private:
-    const string_table::key _c;
+    ObjectURI _c;
     as_object& _target;
 };
 
@@ -76,15 +76,15 @@ void
 setBuiltInItems(as_object& o, bool setting)
 {
     const int flags = 0;
-    string_table& st = getStringTable(o);
-    o.set_member(st.find("print"), setting, flags);
-    o.set_member(st.find("forward_back"), setting, flags);
-    o.set_member(st.find("rewind"), setting, flags);
-    o.set_member(st.find("loop"), setting, flags);
-    o.set_member(st.find("play"), setting, flags);
-    o.set_member(st.find("quality"), setting, flags);
-    o.set_member(st.find("zoom"), setting, flags);
-    o.set_member(st.find("save"), setting, flags);
+    VM& vm = getVM(o);
+    o.set_member(getURI(vm, "print"), setting, flags);
+    o.set_member(getURI(vm, "forward_back"), setting, flags);
+    o.set_member(getURI(vm, "rewind"), setting, flags);
+    o.set_member(getURI(vm, "loop"), setting, flags);
+    o.set_member(getURI(vm, "play"), setting, flags);
+    o.set_member(getURI(vm, "quality"), setting, flags);
+    o.set_member(getURI(vm, "zoom"), setting, flags);
+    o.set_member(getURI(vm, "save"), setting, flags);
 }
 
 
@@ -105,12 +105,12 @@ as_value
 contextmenu_hideBuiltInItems(const fn_call& fn)
 {
     as_object* ptr = ensure<ValidThis>(fn);
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     Global_as& gl = getGlobal(fn);
     as_object* builtIns = createObject(gl);
     setBuiltInItems(*builtIns, false);
-    ptr->set_member(st.find("builtInItems"), builtIns);
+    ptr->set_member(getURI(vm, "builtInItems"), builtIns);
     return as_value();
 }
 
@@ -132,18 +132,18 @@ contextmenu_copy(const fn_call& fn)
 
     if (!o) return as_value();
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
     as_value onSelect, builtInItems;
     as_value customItems = gl.createArray();
 
     ptr->get_member(NSV::PROP_ON_SELECT, &onSelect);
-    ptr->get_member(st.find("builtInItems"), &builtInItems);
-    ptr->get_member(st.find("customItems"), &customItems);
+    ptr->get_member(getURI(vm, "builtInItems"), &builtInItems);
+    ptr->get_member(getURI(vm, "customItems"), &customItems);
 
     // The onSelect and the builtInItems property are simple copies, which
     // means the new object has a reference to the same object.
     o->set_member(NSV::PROP_ON_SELECT, onSelect);
-    o->set_member(st.find("builtInItems"), builtInItems);
+    o->set_member(getURI(vm, "builtInItems"), builtInItems);
 
     // The customItems object is a deep copy that works by calling
     // the copy property of each array member.
@@ -159,7 +159,7 @@ contextmenu_copy(const fn_call& fn)
             as_object* customs;
             if (customItems.is_object() &&
                     (customs = toObject(customItems, getVM(fn)))) {
-                string_table::key copykey = getStringTable(fn).find("copy");
+                const ObjectURI& copykey = getURI(getVM(fn), "copy");
                 CopyMenuItems c(copykey, *arr);
                 foreachArray(*customs, c);
             }
@@ -167,7 +167,7 @@ contextmenu_copy(const fn_call& fn)
         }
     }
 
-    o->set_member(st.find("customItems"), nc);
+    o->set_member(getURI(vm, "customItems"), nc);
 
     return as_value(o);
 }
@@ -182,15 +182,15 @@ contextmenu_ctor(const fn_call& fn)
     const as_value& callback = fn.nargs ? fn.arg(0) : as_value();
     obj->set_member(NSV::PROP_ON_SELECT, callback);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
     Global_as& gl = getGlobal(fn);
     as_object* builtInItems = createObject(gl);
     setBuiltInItems(*builtInItems, true);
-    obj->set_member(st.find("builtInItems"), builtInItems);
+    obj->set_member(getURI(vm, "builtInItems"), builtInItems);
 
     // There is an empty customItems array.
     as_object* customItems = gl.createArray();
-    obj->set_member(st.find("customItems"), customItems);
+    obj->set_member(getURI(vm, "customItems"), customItems);
 
     return as_value();
 }
diff --git a/libcore/asobj/Date_as.cpp b/libcore/asobj/Date_as.cpp
index 0ac5f57..f999554 100644
--- a/libcore/asobj/Date_as.cpp
+++ b/libcore/asobj/Date_as.cpp
@@ -376,8 +376,7 @@ attachDateInterface(as_object& o)
     o.init_member("setUTCSeconds", vm.getNative(103, 142));
     o.init_member("setUTCMilliseconds", vm.getNative(103, 143));
 
-    string_table& st = getStringTable(o);
-    o.init_member("valueOf", getMember(o, st.find("getTime")));
+    o.init_member("valueOf", getMember(o, getURI(vm, "getTime")));
 
 }   
 
diff --git a/libcore/asobj/Error_as.cpp b/libcore/asobj/Error_as.cpp
index 9a3f21c..9832ec2 100644
--- a/libcore/asobj/Error_as.cpp
+++ b/libcore/asobj/Error_as.cpp
@@ -68,9 +68,9 @@ error_toString(const fn_call& fn)
 {
        as_object* ptr = ensure<ValidThis>(fn);
 
-    string_table& st = getStringTable(*ptr);
+    VM& vm = getVM(*ptr);
     as_value message;
-    ptr->get_member(st.find("message"), &message);
+    ptr->get_member(getURI(vm, "message"), &message);
 
        return as_value(message);   
 }
@@ -82,10 +82,10 @@ error_ctor(const fn_call& fn)
     as_object* err = fn.this_ptr;
     if (!err) return as_value();
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     if (fn.nargs && !fn.arg(0).is_undefined()) {
-               err->set_member(st.find("message"), fn.arg(0));
+               err->set_member(getURI(vm, "message"), fn.arg(0));
        }
 
        return as_value();
diff --git a/libcore/asobj/Global_as.cpp b/libcore/asobj/Global_as.cpp
index a3e616b..fd9200b 100644
--- a/libcore/asobj/Global_as.cpp
+++ b/libcore/asobj/Global_as.cpp
@@ -275,13 +275,12 @@ Global_as::registerClasses()
     init_member("enableDebugConsole", edc);
     init_member("showRedrawRegions", vm.getNative(1021, 1));
     
-    string_table& st = getStringTable(*this);
-    init_member("clearTimeout", getMember(*this, st.find("clearInterval")));
+    init_member("clearTimeout", getMember(*this, getURI(vm, "clearInterval")));
 
     _classes.declareAll(avm1Classes());
 
     // SWF8 visibility:
-    const string_table::key NS_FLASH = st.find("flash");
+    const ObjectURI& NS_FLASH = getURI(vm, "flash");
     flash_package_init(*this, NS_FLASH); 
 
     const int version = vm.getSWFVersion();
@@ -925,8 +924,8 @@ local_errorConstructor(const fn_call& fn)
 {
     as_object* obj = ensure<ValidThis>(fn);
     const as_value& arg = fn.nargs ? fn.arg(0) : as_value();
-    string_table& st = getStringTable(fn);
-    obj->set_member(st.find("message"), arg);
+    VM& vm = getVM(fn);
+    obj->set_member(getURI(vm, "message"), arg);
     return as_value();
 }
 
@@ -953,7 +952,7 @@ global_assetuperror(const fn_call& fn)
 
         const std::string& err = std::string(pos, comma);
 
-        string_table& st = getStringTable(fn);
+        VM& vm = getVM(fn);
 
         as_function* ctor = getMember(gl, NSV::CLASS_ERROR).to_function();
         if (ctor) {
@@ -962,8 +961,8 @@ global_assetuperror(const fn_call& fn)
 
             // Not really sure what the point of this is.
             gl.createClass(local_errorConstructor, proto);
-            proto->set_member(st.find("name"), err);
-            proto->set_member(st.find("message"), err);
+            proto->set_member(getURI(vm, "name"), err);
+            proto->set_member(getURI(vm, "message"), err);
         }
         
         if (comma == errors.end()) break;
@@ -1000,12 +999,12 @@ global_setInterval(const fn_call& fn)
                return as_value();
        }
 
-    string_table::key methodName(0);
+    ObjectURI methodName;
 
        // Get interval function
        as_function* as_func = obj->to_function(); 
        if (!as_func) {
-               methodName = getStringTable(fn).find(fn.arg(1).to_string());
+               methodName = getURI(getVM(fn), fn.arg(1).to_string());
                timer_arg = 2;
        }
 
@@ -1071,12 +1070,12 @@ global_setTimeout(const fn_call& fn)
                return as_value();
        }
 
-    string_table::key methodName(0);
+    ObjectURI methodName;
 
        // Get interval function
        as_function* as_func = obj->to_function(); 
        if (!as_func) {
-               methodName = getStringTable(fn).find(fn.arg(1).to_string());
+               methodName = getURI(getVM(fn), fn.arg(1).to_string());
                timer_arg = 2;
        }
 
diff --git a/libcore/asobj/LoadVars_as.cpp b/libcore/asobj/LoadVars_as.cpp
index 2e172a7..60f7f38 100644
--- a/libcore/asobj/LoadVars_as.cpp
+++ b/libcore/asobj/LoadVars_as.cpp
@@ -100,8 +100,8 @@ loadvars_onData(const fn_call& fn)
     }
     else {
                VM& vm = getVM(fn);
-               string_table& st = vm.getStringTable();
-               string_table::key decodeKey = st.find("decode"); 
+               // TODO: use NSV
+               const ObjectURI& decodeKey = getURI(vm, "decode"); 
 
                thisPtr->set_member(NSV::PROP_LOADED, true);
                callMethod(thisPtr, decodeKey, src);
diff --git a/libcore/asobj/LoadableObject.cpp b/libcore/asobj/LoadableObject.cpp
index 896ec7d..2364220 100644
--- a/libcore/asobj/LoadableObject.cpp
+++ b/libcore/asobj/LoadableObject.cpp
@@ -265,7 +265,7 @@ loadableobject_decode(const fn_call& fn)
     typedef boost::tokenizer<Sep> Tok;
     Tok t1(qs, Sep("&"));
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     for (Tok::iterator tit=t1.begin(); tit!=t1.end(); ++tit) {
 
@@ -284,7 +284,7 @@ loadableobject_decode(const fn_call& fn)
         URL::decode(name);
         URL::decode(value);
 
-        if (!name.empty()) ptr->set_member(st.find(name), value);
+        if (!name.empty()) ptr->set_member(getURI(vm, name), value);
     }
 
     return as_value(); 
diff --git a/libcore/asobj/LocalConnection_as.cpp 
b/libcore/asobj/LocalConnection_as.cpp
index 509be3f..be2b155 100644
--- a/libcore/asobj/LocalConnection_as.cpp
+++ b/libcore/asobj/LocalConnection_as.cpp
@@ -895,8 +895,8 @@ executeAMFFunction(as_object& o, amf::Reader& rd)
     args.swap(d);
 
     // Call the method on this LocalConnection object.
-    string_table& st = getStringTable(o);
-    as_function* f = getMember(o, st.find(meth)).to_function();
+    VM& vm = getVM(o);
+    as_function* f = getMember(o, getURI(vm, meth)).to_function();
 
     invoke(f, as_environment(getVM(o)), &o, args);
 }
diff --git a/libcore/asobj/MovieClipLoader.cpp 
b/libcore/asobj/MovieClipLoader.cpp
index d133400..5bb5c5d 100644
--- a/libcore/asobj/MovieClipLoader.cpp
+++ b/libcore/asobj/MovieClipLoader.cpp
@@ -30,7 +30,7 @@
 #include "log.h"
 #include "URL.h" // for url parsing
 #include "VM.h" // for the string table.
-#include "string_table.h" // for the string table.
+#include "VM.h" // for the string table.
 #include "builtin_function.h"
 #include "AsBroadcaster.h" // for initializing self as a broadcaster
 #include "namedStrings.h"
@@ -206,11 +206,11 @@ moviecliploader_getProgress(const fn_call& fn)
        size_t bytesLoaded = sp->get_bytes_loaded();
        size_t bytesTotal = sp->get_bytes_total();
 
-       string_table& st = getStringTable(fn);
+       VM& vm = getVM(fn);
 
        // We want these to be enumerable
-       mcl_obj->set_member(st.find("bytesLoaded"), bytesLoaded);
-       mcl_obj->set_member(st.find("bytesTotal"),  bytesTotal);
+       mcl_obj->set_member(getURI(vm, "bytesLoaded"), bytesLoaded);
+       mcl_obj->set_member(getURI(vm, "bytesTotal"),  bytesTotal);
   
        return as_value(mcl_obj); 
 }
diff --git a/libcore/asobj/MovieClip_as.cpp b/libcore/asobj/MovieClip_as.cpp
index 55e5c61..b98dd44 100644
--- a/libcore/asobj/MovieClip_as.cpp
+++ b/libcore/asobj/MovieClip_as.cpp
@@ -312,8 +312,8 @@ movieclip_createEmptyMovieClip(const fn_call& fn)
     as_object* o = getObjectWithPrototype(getGlobal(fn), 
NSV::CLASS_MOVIE_CLIP);
     MovieClip* mc = new MovieClip(o, 0, m, ptr);
 
-    string_table& st = getStringTable(fn);
-    mc->set_name(st.find(fn.arg(0).to_string()));
+    VM& vm = getVM(fn);
+    mc->set_name(getURI(vm, fn.arg(0).to_string()));
     mc->setDynamic();
 
     // Unlike other MovieClip methods, the depth argument of an empty movie 
clip
@@ -491,8 +491,8 @@ movieclip_attachMovie(const fn_call& fn)
     Global_as& gl = getGlobal(fn);
     DisplayObject* newch = exported_movie->createDisplayObject(gl, movieclip);
 
-    string_table& st = getStringTable(fn);
-    newch->set_name(st.find(newname));
+    VM& vm = getVM(fn);
+    newch->set_name(getURI(vm, newname));
     newch->setDynamic();
 
     boost::intrusive_ptr<as_object> initObj;
@@ -1810,13 +1810,13 @@ movieclip_beginGradientFill(const fn_call& fn)
     // Create the gradients vector
     // ----------------------------
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     std::vector<GradientRecord> gradients;
     gradients.reserve(stops);
     for (size_t i = 0; i < stops; ++i) {
 
-        string_table::key key = st.find(boost::lexical_cast<std::string>(i));
+        const ObjectURI& key = getURI(vm, boost::lexical_cast<std::string>(i));
 
         as_value colVal = getMember(*colors, key);
         boost::uint32_t col = colVal.is_number() ? toInt(colVal, getVM(fn)) : 
0;
diff --git a/libcore/asobj/NetConnection_as.cpp 
b/libcore/asobj/NetConnection_as.cpp
index 7293d86..0672e2e 100644
--- a/libcore/asobj/NetConnection_as.cpp
+++ b/libcore/asobj/NetConnection_as.cpp
@@ -827,8 +827,7 @@ local_onResult(const fn_call& fn)
     as_object* obj = fn.this_ptr;
 
     if (obj) {
-        string_table& st = getStringTable(fn);
-        const ObjectURI conn(st.find("_conn"));
+        const ObjectURI conn = getURI(getVM(fn), "_conn");
         as_value f = getMember(*obj, conn);
         as_object* nc = toObject(f, getVM(fn));
         if (nc) {
@@ -902,8 +901,7 @@ handleAMFInvoke(amf::Reader& rd, const boost::uint8_t*& b,
         }
 
         VM& vm = getVM(owner);
-        string_table& st = vm.getStringTable();
-        string_table::key key = st.find(headerName);
+        ObjectURI key = getURI(vm, headerName);
 #ifdef GNASH_DEBUG_REMOTING
         log_debug("Invoking %s(%s)", headerName, arg);
 #endif
@@ -995,7 +993,7 @@ HTTPRequest::handleAMFReplies(amf::Reader& rd, const 
boost::uint8_t*& b,
             continue;
         }
 
-        string_table::key methodKey;
+        ObjectURI methodKey;
         if (methodName == "onResult") {
             methodKey = NSV::PROP_ON_RESULT;
         }
@@ -1241,8 +1239,7 @@ RTMPConnection::handleInvoke(const boost::uint8_t* 
payload,
 
     log_debug( "Server invoking <%s>", method);
     
-    string_table& st = getStringTable(_nc.owner());
-    const ObjectURI methodname(st.find(method));
+    const ObjectURI methodname = getURI(getVM(_nc.owner()), method);
 
     // _result means it's the answer to a remote method call initiated
     // by us.
diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index 54dc37d..3506811 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -1937,8 +1937,8 @@ executeTag(const SimpleBuffer& _buffer, as_object& 
thisPtr)
 
        log_debug("funcName: %s", funcName);
 
-       string_table& st = getStringTable(thisPtr);
-       string_table::key funcKey = st.find(funcName);
+       VM& vm = getVM(thisPtr);
+       const ObjectURI& funcKey = getURI(vm, funcName);
 
     amf::Reader rd(ptr, endptr, getGlobal(thisPtr));
 
diff --git a/libcore/asobj/Object.cpp b/libcore/asobj/Object.cpp
index d9b0e82..d4a1475 100644
--- a/libcore/asobj/Object.cpp
+++ b/libcore/asobj/Object.cpp
@@ -360,7 +360,7 @@ object_hasOwnProperty(const fn_call& fn)
         return as_value(false);
     }
 
-    const bool found = hasOwnProperty(*obj, getStringTable(fn).find(propname));
+    const bool found = hasOwnProperty(*obj, getURI(getVM(fn), propname));
     return as_value(found);
 }
 
@@ -385,7 +385,7 @@ object_isPropertyEnumerable(const fn_call& fn)
         return as_value();
     }
 
-    Property* prop = obj->getOwnProperty(getStringTable(fn).find(propname));
+    Property* prop = obj->getOwnProperty(getURI(getVM(fn),propname));
 
     if (!prop) {
         return as_value(false);
@@ -447,10 +447,10 @@ object_watch(const fn_call& fn)
         return as_value(false);
     }
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     std::string propname = propval.to_string();
-    string_table::key propkey = st.find(propname);
+    const ObjectURI& propkey = getURI(vm, propname);
     as_function* trig = funcval.to_function();
     as_value cust; if ( fn.nargs > 2 ) cust = fn.arg(2);
 
@@ -474,10 +474,10 @@ object_unwatch(const fn_call& fn)
 
     const as_value& propval = fn.arg(0);
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     std::string propname = propval.to_string();
-    string_table::key propkey = st.find(propname);
+    const ObjectURI& propkey = getURI(vm, propname);
 
     return as_value(obj->unwatch(propkey));
 }
diff --git a/libcore/asobj/SharedObject_as.cpp 
b/libcore/asobj/SharedObject_as.cpp
index fb70a67..577ca10 100644
--- a/libcore/asobj/SharedObject_as.cpp
+++ b/libcore/asobj/SharedObject_as.cpp
@@ -42,7 +42,7 @@
 #include "NativeFunction.h" 
 #include "VM.h"
 #include "Property.h"
-#include "string_table.h"
+#include "VM.h"
 #include "rc.h" // for use of rcfile
 #include "URL.h"
 #include "NetConnection_as.h"
@@ -110,10 +110,10 @@ class SOLPropsBufSerializer : public PropertyVisitor
 
 public:
 
-    SOLPropsBufSerializer(amf::Writer w, string_table& st)
+    SOLPropsBufSerializer(amf::Writer w, VM& vm)
         :
         _writer(w),
-        _st(st),
+        _vm(vm),
         _error(false),
         _count(0)
        {}
@@ -142,20 +142,22 @@ public:
             return true;
         }
 
-        const string_table::key key = getName(uri);
-
         // Test conducted with AMFPHP:
         // '__proto__' and 'constructor' members of an object are not returned
         // from an 'echo-service'.
         // Dunno if they are not serialized or just not sent back.
         // A '__constructor__' member is returned, but only if 
         // not a function; no functions are returned at all.
-        if (key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR) {
+       
+       // TODO: check if this comparison must _really_ be case-sensitive
+       bool caseless = false;
+       ObjectURI::CaseEquals eq(_vm.getStringTable(), caseless);
+        if (eq(uri, NSV::PROP_uuPROTOuu) || eq(uri, NSV::PROP_CONSTRUCTOR)) {
             return true;
         }
 
         // write property name
-        const std::string& name = _st.value(key);
+        const std::string& name = toString(_vm, uri);
         
         _writer.writePropertyName(name);
 
@@ -181,7 +183,7 @@ private:
     amf::Writer _writer;
 
     /// String table for looking up property names as strings.
-    string_table& _st;
+    VM& _vm;
 
     /// Whether an error has been encountered.
     bool _error;
@@ -977,8 +979,7 @@ readSOL(VM& vm, const std::string& filespec)
                     prop_name, len, as);
 
             // set name/value as a member of this (SharedObject) object
-            string_table& st = vm.getStringTable();
-            data->set_member(st.find(prop_name), as);
+            data->set_member(getURI(vm, prop_name), as);
             
             if (buf == end) break;;
 
@@ -1056,9 +1057,9 @@ encodeData(const std::string& name, as_object& data, 
SimpleBuffer& buf)
     // see http://osflash.org/documentation/amf/envelopes/sharedobject
     // Do not encode strict arrays!
     amf::Writer w(buf, false);
-    string_table& st = getStringTable(data);
+    VM& vm = getVM(data);
 
-    SOLPropsBufSerializer props(w, st);
+    SOLPropsBufSerializer props(w, vm);
 
     // Visit all existing properties.
     data.visitProperties<Exists>(props);
diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 88c1d51..1180e74 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -335,11 +335,11 @@ Sound_as::update()
 {
     probeAudio();
 
-    string_table& st = getStringTable(owner());
+    VM& vm = getVM(owner());
 
     if (active()) {
-        owner().set_member(st.find("duration"), getDuration());
-        owner().set_member(st.find("position"), getPosition());
+        owner().set_member(getURI(vm, "duration"), getDuration());
+        owner().set_member(getURI(vm, "position"), getPosition());
     }
 }
 
@@ -427,9 +427,9 @@ Sound_as::attachSound(int si, const std::string& name)
     soundId = si;
     soundName = name;
     
-    string_table& st = getStringTable(owner());
-    owner().set_member(st.find("duration"), getDuration());
-    owner().set_member(st.find("position"), getPosition());
+    VM& vm = getVM(owner());
+    owner().set_member(getURI(vm, "duration"), getDuration());
+    owner().set_member(getURI(vm, "position"), getPosition());
 
 }
 
@@ -562,9 +562,9 @@ Sound_as::loadSound(const std::string& file, bool streaming)
         // if not streaming, we'll probe on .start()
     }
 
-    string_table& st = getStringTable(owner());
-    owner().set_member(st.find("duration"), getDuration());
-    owner().set_member(st.find("position"), getPosition());
+    VM& vm = getVM(owner());
+    owner().set_member(getURI(vm, "duration"), getDuration());
+    owner().set_member(getURI(vm, "position"), getPosition());
 }
 
 sound::InputStream*
diff --git a/libcore/asobj/System_as.cpp b/libcore/asobj/System_as.cpp
index 28bdb27..b96c20e 100644
--- a/libcore/asobj/System_as.cpp
+++ b/libcore/asobj/System_as.cpp
@@ -284,16 +284,15 @@ attachSystemInterface(as_object& proto)
 {
     Global_as& gl = getGlobal(proto);
     
-    string_table& st = getStringTable(proto);
+    VM& vm = getVM(proto);
     registerBuiltinObject(proto, attachSystemSecurityInterface,
-                          st.find("security"));
+                          getURI(vm, "security"));
     registerBuiltinObject(proto, attachSystemCapabilitiesInterface,
-                          st.find("capabilities"));
+                          getURI(vm, "capabilities"));
     
     proto.init_member("setClipboard", 
                       gl.createFunction(system_setClipboard));
     
-    VM& vm = getVM(proto);
     proto.init_member("showSettings", vm.getNative(2107, 0));
     proto.init_property("useCodepage", &system_usecodepage,
                         &system_usecodepage);
diff --git a/libcore/asobj/TextField_as.cpp b/libcore/asobj/TextField_as.cpp
index 2d6ca94..a775027 100644
--- a/libcore/asobj/TextField_as.cpp
+++ b/libcore/asobj/TextField_as.cpp
@@ -259,10 +259,10 @@ textfield_createTextField(const fn_call& fn)
 
     DisplayObject* tf = new TextField(obj, ptr, bounds);
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
     // Give name and mark as dynamic
-    tf->set_name(st.find(name));
+    tf->set_name(getURI(vm, name));
     tf->setDynamic();
 
     // Set _x and _y
diff --git a/libcore/asobj/XMLNode_as.cpp b/libcore/asobj/XMLNode_as.cpp
index 8dc90d5..ed29975 100644
--- a/libcore/asobj/XMLNode_as.cpp
+++ b/libcore/asobj/XMLNode_as.cpp
@@ -27,7 +27,7 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
 #include "NativeFunction.h"
-#include "string_table.h"
+#include "VM.h"
 #include "PropertyList.h"
 #include "Global_as.h"
 #include "Object.h"
@@ -147,14 +147,14 @@ XMLNode_as::updateChildNodes()
 
     if (_children.empty()) return;
 
-    string_table& st = getStringTable(_global);
+    VM& vm = getVM(_global);
 
     // Set up the array without calling push()!
     const size_t size = _children.size();
     Children::const_iterator it = _children.begin();
     for (size_t i = 0; i != size; ++i, ++it) {
         XMLNode_as* node = *it;
-        const string_table::key key = arrayKey(st, i);
+        const ObjectURI& key = arrayKey(vm, i);
         _childNodes->set_member(key, node->object());
 
         // All elements are set to readonly.
@@ -292,8 +292,8 @@ void
 XMLNode_as::setAttribute(const std::string& name, const std::string& value)
 {
     if (_attributes) {
-        string_table& st = getStringTable(_global);
-        _attributes->set_member(st.find(name), value);
+        VM& vm = getVM(_global);
+        _attributes->set_member(getURI(vm, name), value);
     }
 }
 
diff --git a/libcore/asobj/XML_as.cpp b/libcore/asobj/XML_as.cpp
index d6a0a3f..f33ba3b 100644
--- a/libcore/asobj/XML_as.cpp
+++ b/libcore/asobj/XML_as.cpp
@@ -518,8 +518,9 @@ bool
 XML_as::ignoreWhite() 
 {
 
-    const string_table::key propnamekey =
-        getStringTable(_global).find("ignoreWhite");
+    // TODO: use NSV:
+    const ObjectURI& propnamekey =
+        getURI(getVM(_global), "ignoreWhite");
     as_value val;
 
     as_object* obj = object();
diff --git a/libcore/asobj/flash/display/display_pkg.cpp 
b/libcore/asobj/flash/display/display_pkg.cpp
index de41756..197baae 100644
--- a/libcore/asobj/flash/display/display_pkg.cpp
+++ b/libcore/asobj/flash/display/display_pkg.cpp
@@ -20,7 +20,7 @@
 
 #include "as_object.h"
 
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "MovieClip.h"
@@ -40,9 +40,9 @@ get_flash_display_package(const fn_call& fn)
 
     as_object* pkg = createObject(gl);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    bitmapdata_class_init(*pkg, st.find("BitmapData"));
+    bitmapdata_class_init(*pkg, getURI(vm, "BitmapData"));
 
        return pkg;
 }
diff --git a/libcore/asobj/flash/external/ExternalInterface_as.cpp 
b/libcore/asobj/flash/external/ExternalInterface_as.cpp
index 47e5dfc..f1d7e2c 100644
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp
@@ -109,14 +109,13 @@ public:
 
     void operator()(const as_value& val) {
         VM& vm = getVM(_fn);
-        string_table& st = getStringTable(_fn);
 
         newAdd(_ret, "<property id=\"", vm);
         newAdd(_ret, static_cast<double>(_count), vm);
         newAdd(_ret, "\">", vm);
         as_object* ei = 
             findObject(_fn.env(), "flash.external.ExternalInterface");
-        const as_value& x = callMethod(ei, st.find("_toXML"), val);
+        const as_value& x = callMethod(ei, getURI(vm, "_toXML"), val);
         newAdd(_ret, x, vm);
         newAdd(_ret, "</property>", vm);
         ++_count;
@@ -140,8 +139,7 @@ public:
         VM& vm = getVM(_fn);
         as_object* ei = 
             findObject(_fn.env(), "flash.external.ExternalInterface");
-        string_table& st = getStringTable(_fn);
-        const as_value& x = callMethod(ei, st.find("_toXML"), val);
+        const as_value& x = callMethod(ei, getURI(vm, "_toXML"), val);
         newAdd(_ret, x, vm);
     }
 private:
@@ -368,13 +366,13 @@ externalinterface_objectID(const fn_call& fn)
 
     movie_root& mr = getRoot(fn);
     MovieClip *mc = mr.getLevel(0);
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
     
     as_value id;
-    getObject(mc)->get_member(st.find("id"), &id);
+    getObject(mc)->get_member(getURI(vm, "id"), &id);
 
     as_value name;
-    getObject(mc)->get_member(st.find("name"), &name);
+    getObject(mc)->get_member(getURI(vm, "name"), &name);
 
     if (id.is_undefined() && !name.is_undefined()) {
         return name;
@@ -418,14 +416,14 @@ externalinterface_uArgumentsToXML(const fn_call& fn)
     as_value ret("<arguments>");
 
     if (fn.nargs) {
-        as_object *obj = toObject(fn.arg(0), getVM(fn));
+        VM& vm = getVM(fn);
+        as_object *obj = toObject(fn.arg(0), vm);
         if (obj) {
             ArgsToXML tx(ret, fn);
             size_t size = arrayLength(*obj);
-            string_table& st = getStringTable(*obj);
             if (size) {
                 for (size_t i = 1; i < static_cast<size_t>(size); ++i) {
-                    tx(getOwnProperty(*obj, arrayKey(st, i)));
+                    tx(getOwnProperty(*obj, arrayKey(vm, i)));
                 }
             }
         }
@@ -568,7 +566,7 @@ externalinterface_uObjectToXML(const fn_call& fn)
                 as_object* ei = 
                     findObject(fn.env(), "flash.external.ExternalInterface");
                 const as_value& val = getMember(*obj, *i); 
-                newAdd(ret, callMethod(ei, st.find("_toXML"), val), vm);
+                newAdd(ret, callMethod(ei, getURI(vm, "_toXML"), val), vm);
                 newAdd(ret, "</property>", vm);
             }
         }
@@ -595,13 +593,12 @@ externalinterface_uToXML(const fn_call& fn)
 
         as_object* ei = 
             findObject(fn.env(), "flash.external.ExternalInterface");
-        string_table& st = getStringTable(fn);
         VM& vm = getVM(fn);
 
         const as_value& val = fn.arg(0);
         if (val.is_string()) {
             as_value ret = "<string>";
-            newAdd(ret, callMethod(ei, st.find("_escapeXML"), val), vm);
+            newAdd(ret, callMethod(ei, getURI(vm, "_escapeXML"), val), vm);
             newAdd(ret, "</string>", vm);
             return ret;
         }
@@ -624,9 +621,9 @@ externalinterface_uToXML(const fn_call& fn)
             as_object* obj = toObject(val, vm);
             assert(obj);
             if (hasOwnProperty(*obj, NSV::PROP_LENGTH)) {
-                return callMethod(ei, st.find("_arrayToXML"), val);
+                return callMethod(ei, getURI(vm, "_arrayToXML"), val);
             }
-            return callMethod(ei, st.find("_objectToXML"), val);
+            return callMethod(ei, getURI(vm, "_objectToXML"), val);
         }
     }
     return as_value("<null/>");
@@ -643,25 +640,27 @@ externalinterface_uToAS(const fn_call& fn)
     if (!o) {
         return as_value();
     }
-    string_table& st = getStringTable(fn);
-    const ObjectURI nodeName(st.find("nodeName"));
-    const ObjectURI firstChild(st.find("firstChild"));
+
+    VM& vm = getVM(fn);
+    // TODO: use NSV ?
+    const ObjectURI& nodeName = getURI(vm, "nodeName");
+    const ObjectURI& firstChild = getURI(vm, "firstChild");
 
     const as_value& nn = getMember(*o, nodeName);
 
-    if (equals(nn, as_value("number"), getVM(fn))) {
-        as_object* fc = toObject(getMember(*o, firstChild), getVM(fn));
+    if (equals(nn, as_value("number"), vm)) {
+        as_object* fc = toObject(getMember(*o, firstChild), vm);
         const as_value v = callMethod(fc, NSV::PROP_TO_STRING);
         // This should call Number(obj.firstChild.toString()), i.e. use
         // the non-constructing number conversion function, but the extra
         // code needed to implement that isn't worth it.
-        return as_value(toNumber(v, getVM(fn)));
+        return as_value(toNumber(v, vm));
     }
     if (equals(nn, as_value("string"), getVM(fn))) {
         as_object* ei =
             findObject(fn.env(), "flash.external.ExternalInterface");
         as_value fc = getMember(*o, firstChild);
-        return callMethod(ei, st.find("_unescapeXML"),
+        return callMethod(ei, getURI(vm, "_unescapeXML"),
                 fc.to_string(getSWFVersion(fn)));
     }
     if (equals(nn, as_value("false"), getVM(fn))) {
@@ -681,12 +680,12 @@ externalinterface_uToAS(const fn_call& fn)
     if (equals(nn, as_value("object"), getVM(fn))) {
         as_object* ei =
             findObject(fn.env(), "flash.external.ExternalInterface");
-        return callMethod(ei, st.find("_objectToXML"), o);
+        return callMethod(ei, getURI(vm, "_objectToXML"), o);
     }
     if (equals(nn, as_value("array"), getVM(fn))) {
         as_object* ei =
             findObject(fn.env(), "flash.external.ExternalInterface");
-        return callMethod(ei, st.find("_arrayToXML"), o);
+        return callMethod(ei, getURI(vm, "_arrayToXML"), o);
     }
     if (equals(nn, as_value("class"), getVM(fn))) {
         as_value fc = getMember(*o, firstChild);
diff --git a/libcore/asobj/flash/external/external_pkg.cpp 
b/libcore/asobj/flash/external/external_pkg.cpp
index cf8dcf4..85c7127 100644
--- a/libcore/asobj/flash/external/external_pkg.cpp
+++ b/libcore/asobj/flash/external/external_pkg.cpp
@@ -19,7 +19,7 @@
 //
 
 #include "as_object.h"
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "ExternalInterface_as.h"
@@ -41,9 +41,9 @@ get_flash_external_package(const fn_call& fn)
 
     as_object* pkg = createObject(gl);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    externalinterface_class_init(*pkg, st.find("ExternalInterface"));
+    externalinterface_class_init(*pkg, getURI(vm, "ExternalInterface"));
 
     return pkg;
 }
diff --git a/libcore/asobj/flash/filters/BitmapFilter_as.cpp 
b/libcore/asobj/flash/filters/BitmapFilter_as.cpp
index 4b2aeae..5e939ad 100644
--- a/libcore/asobj/flash/filters/BitmapFilter_as.cpp
+++ b/libcore/asobj/flash/filters/BitmapFilter_as.cpp
@@ -73,14 +73,14 @@ registerBitmapClass(as_object& where, Global_as::ASFunction 
ctor,
 {
     Global_as& gl = getGlobal(where);
 
-    string_table& st = getStringTable(where);
+    VM& vm = getVM(where);
 
     // We should be looking for flash.filters.BitmapFilter, but as this
     // triggers a lookup of the flash.filters package while we are creating
     // it, so entering infinite recursion, we'll cheat and assume that
     // the object 'where' is the filters package.
     as_function* constructor =
-        getMember(where, st.find("BitmapFilter")).to_function();
+        getMember(where, getURI(vm, "BitmapFilter")).to_function();
     
     as_object* proto;
     if (constructor) {
diff --git a/libcore/asobj/flash/filters/filters_pkg.cpp 
b/libcore/asobj/flash/filters/filters_pkg.cpp
index e6d6600..cdce6b1 100644
--- a/libcore/asobj/flash/filters/filters_pkg.cpp
+++ b/libcore/asobj/flash/filters/filters_pkg.cpp
@@ -19,7 +19,7 @@
 //
 
 #include "as_object.h"
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "MovieClip.h"
@@ -49,18 +49,18 @@ get_flash_filters_package(const fn_call& fn)
     Global_as& gl = getGlobal(fn);
     as_object* pkg = createObject(gl);
 
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    bitmapfilter_class_init(*pkg, st.find("BitmapFilter"));
-    bevelfilter_class_init(*pkg, st.find("BevelFilter"));
-    blurfilter_class_init(*pkg, st.find("BlurFilter"));
-    colormatrixfilter_class_init(*pkg, st.find("ColorMatrixFilter"));
-    convolutionfilter_class_init(*pkg, st.find("ConvolutionFilter"));
-    displacementmapfilter_class_init(*pkg, st.find("DisplacementMapFilter"));
-    dropshadowfilter_class_init(*pkg, st.find("DropShadowFilter"));
-    glowfilter_class_init(*pkg, st.find("GlowFilter"));
-    gradientbevelfilter_class_init(*pkg, st.find("GradientBevelFilter"));
-    gradientglowfilter_class_init(*pkg, st.find("GradientGlowFilter"));
+    bitmapfilter_class_init(*pkg, getURI(vm, "BitmapFilter"));
+    bevelfilter_class_init(*pkg, getURI(vm, "BevelFilter"));
+    blurfilter_class_init(*pkg, getURI(vm, "BlurFilter"));
+    colormatrixfilter_class_init(*pkg, getURI(vm, "ColorMatrixFilter"));
+    convolutionfilter_class_init(*pkg, getURI(vm, "ConvolutionFilter"));
+    displacementmapfilter_class_init(*pkg, getURI(vm, 
"DisplacementMapFilter"));
+    dropshadowfilter_class_init(*pkg, getURI(vm, "DropShadowFilter"));
+    glowfilter_class_init(*pkg, getURI(vm, "GlowFilter"));
+    gradientbevelfilter_class_init(*pkg, getURI(vm, "GradientBevelFilter"));
+    gradientglowfilter_class_init(*pkg, getURI(vm, "GradientGlowFilter"));
     
     return pkg;
 }
diff --git a/libcore/asobj/flash/flash_pkg.cpp 
b/libcore/asobj/flash/flash_pkg.cpp
index befbac2..7f88c90 100644
--- a/libcore/asobj/flash/flash_pkg.cpp
+++ b/libcore/asobj/flash/flash_pkg.cpp
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "namedStrings.h"
@@ -42,14 +42,14 @@ get_flash_package(const fn_call& fn)
 
     as_object* pkg = createObject(gl);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    flash_text_package_init(*pkg, st.find("text"));
-    flash_display_package_init(*pkg, st.find("display"));
-    flash_filters_package_init(*pkg, st.find("filters"));
-    flash_geom_package_init(*pkg, st.find("geom"));
-    flash_net_package_init(*pkg, st.find("net"));
-    flash_external_package_init(*pkg, st.find("external"));
+    flash_text_package_init(*pkg, getURI(vm, "text"));
+    flash_display_package_init(*pkg, getURI(vm, "display"));
+    flash_filters_package_init(*pkg, getURI(vm, "filters"));
+    flash_geom_package_init(*pkg, getURI(vm, "geom"));
+    flash_net_package_init(*pkg, getURI(vm, "net"));
+    flash_external_package_init(*pkg, getURI(vm, "external"));
 
     return pkg;
 }
diff --git a/libcore/asobj/flash/geom/ColorTransform_as.cpp 
b/libcore/asobj/flash/geom/ColorTransform_as.cpp
index 9235a96..42e66b4 100644
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp
@@ -278,19 +278,17 @@ colortransform_toString(const fn_call& fn)
 
     as_object* ptr = ensure<ValidThis>(fn);
 
-    string_table& st = getStringTable(fn);
-
-    const as_value& am = getMember(*ptr, st.find("alphaMultiplier"));
-    const as_value& ao = getMember(*ptr, st.find("alphaOffset"));
-    const as_value& bm = getMember(*ptr, st.find("blueMultiplier"));
-    const as_value& bo = getMember(*ptr, st.find("blueOffset"));
-    const as_value& gm = getMember(*ptr, st.find("greenMultiplier"));
-    const as_value& go = getMember(*ptr, st.find("greenOffset"));
-    const as_value& rm = getMember(*ptr, st.find("redMultiplier"));
-    const as_value& ro = getMember(*ptr, st.find("redOffset"));
-   
     VM& vm = getVM(fn);
 
+    const as_value& am = getMember(*ptr, getURI(vm, "alphaMultiplier"));
+    const as_value& ao = getMember(*ptr, getURI(vm, "alphaOffset"));
+    const as_value& bm = getMember(*ptr, getURI(vm, "blueMultiplier"));
+    const as_value& bo = getMember(*ptr, getURI(vm, "blueOffset"));
+    const as_value& gm = getMember(*ptr, getURI(vm, "greenMultiplier"));
+    const as_value& go = getMember(*ptr, getURI(vm, "greenOffset"));
+    const as_value& rm = getMember(*ptr, getURI(vm, "redMultiplier"));
+    const as_value& ro = getMember(*ptr, getURI(vm, "redOffset"));
+   
     as_value ret("(redMultiplier=");
     newAdd(ret, rm, vm);
     newAdd(ret, ", greenMultiplier=", vm);
diff --git a/libcore/asobj/flash/geom/Matrix_as.cpp 
b/libcore/asobj/flash/geom/Matrix_as.cpp
index 55e12cb..c30f4c2 100644
--- a/libcore/asobj/flash/geom/Matrix_as.cpp
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp
@@ -868,7 +868,8 @@ matrix_ctor(const fn_call& fn)
     as_object* obj = ensure<ValidThis>(fn);
     
     if (!fn.nargs) {
-        const string_table::key identity = getStringTable(fn).find("identity");
+        // TODO: use NSV
+        const ObjectURI& identity = getURI(getVM(fn), "identity");
         callMethod(obj, identity);
         return as_value();
     }
diff --git a/libcore/asobj/flash/geom/Rectangle_as.cpp 
b/libcore/asobj/flash/geom/Rectangle_as.cpp
index b7c8138..5c1cb6e 100644
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp
@@ -658,7 +658,8 @@ Rectangle_ctor(const fn_call& fn)
     as_object* obj = ensure<ValidThis>(fn);
 
     if (!fn.nargs) {
-        const string_table::key setEmpty = getStringTable(fn).find("setEmpty");
+        // TODO: use NSV !
+        const ObjectURI& setEmpty = getURI(getVM(fn), "setEmpty");
         callMethod(obj, setEmpty);
         return as_value();
     }
diff --git a/libcore/asobj/flash/geom/geom_pkg.cpp 
b/libcore/asobj/flash/geom/geom_pkg.cpp
index 3bb2a08..e4bbf10 100644
--- a/libcore/asobj/flash/geom/geom_pkg.cpp
+++ b/libcore/asobj/flash/geom/geom_pkg.cpp
@@ -20,7 +20,7 @@
 
 #include "Global_as.h" 
 #include "as_object.h"
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "ColorTransform_as.h"
@@ -43,13 +43,13 @@ get_flash_geom_package(const fn_call& fn)
 
     as_object *pkg = createObject(gl);
        
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    colortransform_class_init(*pkg, st.find("ColorTransform"));
-       matrix_class_init(*pkg, st.find("Matrix"));
-       point_class_init(*pkg, st.find("Point"));
-       rectangle_class_init(*pkg, st.find("Rectangle"));
-       transform_class_init(*pkg, st.find("Transform"));
+    colortransform_class_init(*pkg, getURI(vm, "ColorTransform"));
+       matrix_class_init(*pkg, getURI(vm, "Matrix"));
+       point_class_init(*pkg, getURI(vm, "Point"));
+       rectangle_class_init(*pkg, getURI(vm, "Rectangle"));
+       transform_class_init(*pkg, getURI(vm, "Transform"));
 
     return pkg;
 }
diff --git a/libcore/asobj/flash/net/net_pkg.cpp 
b/libcore/asobj/flash/net/net_pkg.cpp
index 864984f..12b5ac6 100644
--- a/libcore/asobj/flash/net/net_pkg.cpp
+++ b/libcore/asobj/flash/net/net_pkg.cpp
@@ -19,7 +19,7 @@
 //
 
 #include "as_object.h"
-#include "string_table.h"
+#include "VM.h"
 #include "VM.h"
 #include "fn_call.h"
 #include "namedStrings.h"
@@ -39,9 +39,9 @@ get_flash_net_package(const fn_call& fn)
 
     as_object* pkg = createObject(gl);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    filereference_class_init(*pkg, st.find("FileReference"));
+    filereference_class_init(*pkg, getURI(vm, "FileReference"));
 
     return pkg;
 }
diff --git a/libcore/asobj/flash/text/text_pkg.cpp 
b/libcore/asobj/flash/text/text_pkg.cpp
index 5d0ad18..bd67637 100644
--- a/libcore/asobj/flash/text/text_pkg.cpp
+++ b/libcore/asobj/flash/text/text_pkg.cpp
@@ -19,7 +19,7 @@
 //
 
 #include "as_object.h"
-#include "string_table.h"
+#include "VM.h"
 #include "fn_call.h"
 #include "TextRenderer_as.h"
 #include "namedStrings.h"
@@ -37,9 +37,9 @@ get_flash_text_package(const fn_call& fn)
 
     as_object* pkg = createObject(gl);
     
-    string_table& st = getStringTable(fn);
+    VM& vm = getVM(fn);
 
-    textrenderer_class_init(*pkg, st.find("TextRenderer"));
+    textrenderer_class_init(*pkg, getURI(vm, "TextRenderer"));
 
     return pkg;
 }
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index bc2bba7..95a6fb0 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -91,7 +91,7 @@ namespace gnash {
 namespace {
     bool generate_mouse_button_events(movie_root& mr, MouseButtonState& ms);
     const DisplayObject* getNearestObject(const DisplayObject* o);
-    as_object* getBuiltinObject(movie_root& mr, string_table::key cl);
+    as_object* getBuiltinObject(movie_root& mr, const ObjectURI& cl);
     void advanceLiveChar(MovieClip* ch);
 
     /// Push a DisplayObject listener to the front of given container, if not
@@ -546,9 +546,11 @@ movie_root::setDimensions(size_t w, size_t h)
     _stageHeight = h;
 
     if (_scaleMode == SCALEMODE_NOSCALE) {
-        as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
+        as_object* stage = getBuiltinObject(*this,
+            getURI(_vm, NSV::CLASS_STAGE));
         if (stage) {
-            callMethod(stage, NSV::PROP_BROADCAST_MESSAGE, "onResize");
+            callMethod(stage, getURI(_vm, NSV::PROP_BROADCAST_MESSAGE),
+                "onResize");
         }
 
     }
@@ -594,7 +596,7 @@ movie_root::keyEvent(key::code k, bool down)
     }
 
     // Broadcast event to Key._listeners.
-    as_object* key = getBuiltinObject(*this, NSV::CLASS_KEY);
+    as_object* key = getBuiltinObject(*this, getURI(_vm, NSV::CLASS_KEY));
     if (key) {
 
         try {
@@ -603,10 +605,10 @@ movie_root::keyEvent(key::code k, bool down)
             // A stack limit like that is hardly of any use, but could be used
             // maliciously to crash Gnash.
             if (down) {
-                callMethod(key, NSV::PROP_BROADCAST_MESSAGE, "onKeyDown");
+                callMethod(key, getURI(_vm, NSV::PROP_BROADCAST_MESSAGE), 
"onKeyDown");
             }
             else {
-                callMethod(key, NSV::PROP_BROADCAST_MESSAGE, "onKeyUp");
+                callMethod(key, getURI(_vm,NSV::PROP_BROADCAST_MESSAGE), 
"onKeyUp");
             }
         }
         catch (ActionLimitException &e)
@@ -650,7 +652,7 @@ movie_root::keyEvent(key::code k, bool down)
 bool
 movie_root::mouseWheel(int delta)
 {
-    as_object* mouseObj = getBuiltinObject(*this, NSV::CLASS_MOUSE);
+    as_object* mouseObj = getBuiltinObject(*this, 
getURI(_vm,NSV::CLASS_MOUSE));
     if (!mouseObj) return false;
     
     const boost::int32_t x = pixelsToTwips(_mouseX);
@@ -659,7 +661,7 @@ movie_root::mouseWheel(int delta)
     DisplayObject* i = getTopmostMouseEntity(x, y);
 
     // Always called with two arguments.
-    callMethod(mouseObj, NSV::PROP_BROADCAST_MESSAGE, "onMouseWheel",
+    callMethod(mouseObj, getURI(_vm,NSV::PROP_BROADCAST_MESSAGE), 
"onMouseWheel",
             delta, i ? getObject(i) : as_value());
 
     return true;
@@ -998,15 +1000,18 @@ movie_root::notify_mouse_listeners(const event_id& event)
         }
     }
 
-    as_object* mouseObj = getBuiltinObject(*this, NSV::CLASS_MOUSE);
+    const ObjectURI& propMouse = getURI(_vm, NSV::CLASS_MOUSE);
+    const ObjectURI& propBroadcastMessage =
+        getURI(_vm, NSV::PROP_BROADCAST_MESSAGE);
+
+    as_object* mouseObj = getBuiltinObject(*this, propMouse);
     if (mouseObj) {
 
         // Can throw an action limit exception if the stack limit is 0 or 1.
         // A stack limit like that is hardly of any use, but could be used
         // maliciously to crash Gnash.
         try {
-            callMethod(mouseObj, NSV::PROP_BROADCAST_MESSAGE, 
-                    event.functionName());
+            callMethod(mouseObj, propBroadcastMessage, event.functionName());
         }
         catch (ActionLimitException &e) {
             log_error(_("ActionLimits hit notifying mouse events: %s."),
@@ -1540,18 +1545,18 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
     } else if (invoke->name == "SetVariable") {
         MovieClip *mc = getLevel(0);
         as_object *obj = getObject(mc);
-        string_table &st = getStringTable(*obj);
+        VM &vm = getVM();
         std::string var = invoke->args[0].to_string();
         as_value &val = invoke->args[1] ;
-        obj->set_member(st.find(var), val);
+        obj->set_member(getURI(vm, var), val);
        // SetVariable doesn't send a response
     } else if (invoke->name == "GetVariable") {
         MovieClip *mc = getLevel(0);
         as_object *obj = getObject(mc);
-        string_table &st = getStringTable(*obj);
+        VM &vm = getVM();
         std::string var = invoke->args[0].to_string();
         as_value val;
-        obj->get_member(st.find(var), &val);
+        obj->get_member(getURI(vm, var), &val);
        // GetVariable sends the value of the variable
        ss << ExternalInterface::toXML(val);
     } else if (invoke->name == "GotoFrame") {
@@ -1850,8 +1855,7 @@ movie_root::callExternalCallback(const std::string &name,
     MovieClip *mc = getLevel(0);
     as_object *obj = getObject(mc);
 
-    string_table& st = getStringTable(*obj);
-    const string_table::key key = st.find(name);
+    const ObjectURI& key = getURI(getVM(), name);
     // FIXME: there has got to be a better way of handling the variable
     // length arg list
     as_value val;
@@ -2053,8 +2057,6 @@ movie_root::findCharacterByTarget(const std::string& 
tgtstr) const
 {
     if (tgtstr.empty()) return 0;
 
-    string_table& st = _vm.getStringTable();
-
     // NOTE: getRootMovie() would be problematic in case the original
     //       root movie is replaced by a load to _level0... 
     //       (but I guess we'd also drop loadMovie requests in that
@@ -2068,7 +2070,7 @@ movie_root::findCharacterByTarget(const std::string& 
tgtstr) const
         std::string part(tgtstr, from, to - from);
 
         // TODO: there is surely a cleaner way to implement path finding.
-        ObjectURI uri(st.find(part));
+        const ObjectURI& uri = getURI(_vm, part);
         o = o->displayObject() ?
             o->displayObject()->pathElement(uri) :
             getPathElement(*o, uri);
@@ -2536,7 +2538,7 @@ getNearestObject(const DisplayObject* o)
 }
 
 as_object*
-getBuiltinObject(movie_root& mr, string_table::key cl)
+getBuiltinObject(movie_root& mr, const ObjectURI& cl)
 {
     Global_as& gl = *mr.getVM().getGlobal();
 
diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 5d2696f..e3a113b 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -2142,8 +2142,8 @@ ActionDelete(ActionExec& thread)
         return;
     }
 
-    string_table& st = getStringTable(env);
-    const std::pair<bool, bool> ret = obj->delProperty(st.find(propertyname));
+    VM& vm = getVM(env);
+    const std::pair<bool, bool> ret = obj->delProperty(getURI(vm, 
propertyname));
 
     env.top(1).set_bool(ret.second);
 
@@ -2185,8 +2185,8 @@ ActionDelete2(ActionExec& thread)
 
     as_object* obj = safeToObject(getVM(thread.env), target);
 
-    string_table& st = getStringTable(env);
-    const std::pair<bool, bool> ret = obj->delProperty(st.find(var));
+    VM& vm = getVM(env);
+    const std::pair<bool, bool> ret = obj->delProperty(getURI(vm, var));
 
     env.top(1).set_bool(ret.second);
 }
@@ -2353,7 +2353,7 @@ ActionVar(ActionExec& thread)
     as_environment& env = thread.env;
     
     const std::string& varname = env.top(0).to_string();
-    const string_table::key name = getStringTable(env).find(varname);
+    const ObjectURI& name = getURI(getVM(env), varname);
     VM& vm = getVM(env);
 
     if (vm.calling()) {
@@ -2380,11 +2380,11 @@ ActionInitArray(ActionExec& thread)
 
     as_object* ao = gl.createArray();
 
-    string_table& st = getStringTable(env);
+    VM& vm = getVM(env);
     // Fill the elements with the initial values from the stack.
     for (int i = 0; i < array_size; i++) {
-        const string_table::key k = 
-            st.find(boost::lexical_cast<std::string>(i));
+        const ObjectURI& k = 
+            getURI(vm, boost::lexical_cast<std::string>(i));
         ao->set_member(k, env.pop());
     }
 
@@ -2413,13 +2413,13 @@ ActionInitObject(ActionExec& thread)
 
     obj->init_member(NSV::PROP_CONSTRUCTOR, getMember(gl, NSV::CLASS_OBJECT));
 
-    string_table& st = getStringTable(env);
+    VM& vm = getVM(env);
 
     // Set provided members
     for (int i = 0; i < nmembers; ++i) {
         const as_value& member_value = env.top(0);
         std::string member_name = env.top(1).to_string();
-        obj->set_member(st.find(member_name), member_value);
+        obj->set_member(getURI(vm, member_name), member_value);
         env.drop(2);
     }
 
@@ -2604,8 +2604,7 @@ ActionGetMember(ActionExec& thread)
                    target, static_cast<void*>(obj));
     );
 
-    string_table& st = getStringTable(env);
-    const string_table::key k = st.find(member_name.to_string());
+    const ObjectURI& k = getURI(getVM(env), member_name.to_string());
 
     if (!obj->get_member(k, &env.top(1))) {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -2641,8 +2640,7 @@ ActionSetMember(ActionExec& thread)
         );
     }
     else if (obj) {
-        string_table& st = getStringTable(env);
-        obj->set_member(st.find(member_name), member_value);
+        obj->set_member(getURI(getVM(env), member_name), member_value);
 
         IF_VERBOSE_ACTION (
             log_action(_("-- set_member %s.%s=%s"),
@@ -2752,7 +2750,7 @@ ActionCallMethod(ActionExec& thread)
     as_object* this_ptr(0);
 
     // Will be used to find super later
-    string_table::key method_key = 0;
+    ObjectURI methURI;
 
     // If the method name is undefined or evaluates to an empty string,
     // the first argument is used as the method name and the 'this' pointer
@@ -2763,13 +2761,12 @@ ActionCallMethod(ActionExec& thread)
     }
     else {
 
-        string_table& st = getStringTable(env);
-        method_key = st.find(method_string);
+        methURI = getURI(getVM(env), method_string);
 
         // The method value
         as_value method_value; 
 
-        if (!obj->get_member(method_key, &method_value) ) {
+        if (!obj->get_member(methURI, &method_value) ) {
             IF_VERBOSE_ASCODING_ERRORS(
             log_aserror(_("ActionCallMethod: "
                 "Can't find method %s of object %s"),
@@ -2816,7 +2813,7 @@ ActionCallMethod(ActionExec& thread)
         super = 0;
     }
     else {
-        super = obj->get_super(method_key);
+        super = obj->get_super(methURI);
     }
 
     fn_call call(this_ptr, env, args);
@@ -2882,8 +2879,7 @@ ActionNewMethod(ActionExec& thread)
         method_val = obj_val;
     }
     else {
-        string_table& st = getStringTable(env);
-        const string_table::key k = st.find(method_string);
+        const ObjectURI& k = getURI(getVM(env), method_string);
         if (!obj->get_member(k, &method_val)) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("ActionNewMethod: can't find method %s of "
@@ -3181,8 +3177,6 @@ ActionDefineFunction2(ActionExec& thread)
 
     func->setFlags(flags);
 
-    string_table& st = getStringTable(env);
-
     // Get the register assignments and names of the arguments.
     for (size_t n = 0; n < nargs; ++n) {
         boost::uint8_t arg_register = code[i];
@@ -3191,7 +3185,7 @@ ActionDefineFunction2(ActionExec& thread)
         // @@ security: watch out for possible missing terminator here!
         const std::string arg(code.read_string(i));
 
-        func->add_arg(arg_register, st.find(arg));
+        func->add_arg(arg_register, getURI(getVM(env), arg));
         i += arg.size() + 1;
     }
 
@@ -3399,12 +3393,10 @@ ActionDefineFunction(ActionExec& thread)
     const size_t nargs = code.read_uint16(i);
     i += 2;
     
-    string_table& st = getStringTable(env);
-
     // Get the names of the arguments.
     for (size_t n = 0; n < nargs; ++n) {
         const std::string arg(code.read_string(i));
-        func->add_arg(0, st.find(arg));
+        func->add_arg(0, getURI(getVM(env), arg));
         i += arg.size() + 1; 
     }
 
diff --git a/libcore/vm/ActionExec.cpp b/libcore/vm/ActionExec.cpp
index 74d15b5..f6a0a75 100644
--- a/libcore/vm/ActionExec.cpp
+++ b/libcore/vm/ActionExec.cpp
@@ -625,9 +625,8 @@ void
 ActionExec::setLocalVariable(const std::string& name, const as_value& val)
 {
     if (isFunction()) {
-        string_table& st = getStringTable(env);
         // TODO: set local in the function object?
-        setLocal(getVM(env).currentCall(), st.find(name), val);
+        setLocal(getVM(env).currentCall(), getURI(getVM(env), name), val);
     } else {
         // TODO: set target member  ?
         //       what about 'with' stack ?
diff --git a/libcore/vm/CallStack.cpp b/libcore/vm/CallStack.cpp
index 07df061..933cb11 100644
--- a/libcore/vm/CallStack.cpp
+++ b/libcore/vm/CallStack.cpp
@@ -69,7 +69,7 @@ CallFrame::setLocalRegister(size_t i, const as_value& val)
 }
 
 void
-declareLocal(CallFrame& c, string_table::key name)
+declareLocal(CallFrame& c, const ObjectURI& name)
 {
     as_object& locals = c.locals();
     if (!hasOwnProperty(locals, name)) {
@@ -78,7 +78,7 @@ declareLocal(CallFrame& c, string_table::key name)
 }
 
 void
-setLocal(CallFrame& c, string_table::key name, const as_value& val)
+setLocal(CallFrame& c, const ObjectURI& name, const as_value& val)
 {
     as_object& locals = c.locals();
 
diff --git a/libcore/vm/CallStack.h b/libcore/vm/CallStack.h
index d68ac84..e8a6f3d 100644
--- a/libcore/vm/CallStack.h
+++ b/libcore/vm/CallStack.h
@@ -27,6 +27,7 @@
 // Forward declarations
 namespace gnash {
     class as_object;
+    struct ObjectURI;
     class UserFunction;
 }
 
@@ -132,7 +133,7 @@ private:
 //
 /// @param c    The CallFrame to set the variable in.
 /// @param name The name of the variable to declare.
-void declareLocal(CallFrame& c, string_table::key name);
+void declareLocal(CallFrame& c, const ObjectURI& name);
 
 /// Set a local variable in this CallFrame
 //
@@ -141,7 +142,7 @@ void declareLocal(CallFrame& c, string_table::key name);
 /// @param c    The CallFrame to set the variable in.
 /// @param name The name of the variable to set.
 /// @param val  The value to set the variable to.
-void setLocal(CallFrame& c, string_table::key name, const as_value& val);
+void setLocal(CallFrame& c, const ObjectURI& name, const as_value& val);
 
 typedef std::vector<CallFrame> CallStack;
 
diff --git a/libcore/vm/ExecutableCode.h b/libcore/vm/ExecutableCode.h
index acc98ae..62229da 100644
--- a/libcore/vm/ExecutableCode.h
+++ b/libcore/vm/ExecutableCode.h
@@ -167,7 +167,7 @@ class DelayedFunctionCall : public ExecutableCode
 public:
 
     DelayedFunctionCall(DisplayObject* target,
-            as_object* obj, string_table::key name,
+            as_object* obj, const ObjectURI& name,
             const as_value& arg1, const as_value& arg2)
         :
         ExecutableCode(target),
@@ -190,7 +190,7 @@ public:
 
 private:
     as_object* _obj;
-    string_table::key _name;
+    ObjectURI _name;
     as_value _arg1, _arg2;
 };
 
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index 0b18fdf..2e66990 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -40,6 +40,8 @@
 #include "CallStack.h"
 #include "smart_ptr.h"
 #include "as_value.h"
+#include "namedStrings.h"
+#include "ObjectURI.h"
 
 // Forward declarations
 namespace gnash {
@@ -281,6 +283,34 @@ private:
 
 };
 
+// @param lowerCaseHint if true the caller guarantees
+//        that the lowercase equivalent of `str' is `str' again
+//
+inline ObjectURI
+getURI(const VM& vm, const std::string& str, bool lowerCaseHint=false)
+{
+    lowerCaseHint=lowerCaseHint; // TODO pass hint to ObjectURI ctor
+    // Possible optimization here is to directly compute
+    // noCase value if VM version is < 7
+    return ObjectURI((NSV::NamedStrings)vm.getStringTable().find(str));
+}
+
+inline ObjectURI
+getURI(const VM&, NSV::NamedStrings s)
+{
+    // Possible optimization here is to directly
+    // compute noCase values if VM version is < 7
+    // (using the known information in NSV)
+    return ObjectURI(s);
+}
+
+inline const std::string&
+toString(VM& vm, const ObjectURI& uri)
+{
+       return uri.toString(vm.getStringTable());
+}
+
+
 /// A class to wrap frame access.  Stack allocating a frame guard
 /// will ensure that all CallFrame pushes have a corresponding
 /// CallFrame pop, even in the presence of extraordinary returns.
diff --git a/testsuite/MovieTester.cpp b/testsuite/MovieTester.cpp
index e8a79f4..1f24b82 100644
--- a/testsuite/MovieTester.cpp
+++ b/testsuite/MovieTester.cpp
@@ -318,7 +318,8 @@ MovieTester::findDisplayItemByName(const MovieClip& mc,
 {
     const DisplayList& dlist = mc.getDisplayList();
     string_table& st = getStringTable(*getObject(&mc));
-    return dlist.getDisplayObjectByName(st, st.find(name), false);
+    VM& vm = getVM(*getObject(&mc));
+    return dlist.getDisplayObjectByName(st, getURI(vm, name), false);
 }
 
 const DisplayObject*
diff --git a/testsuite/libcore.all/PropertyListTest.cpp 
b/testsuite/libcore.all/PropertyListTest.cpp
index 39b5eda..32fe181 100644
--- a/testsuite/libcore.all/PropertyListTest.cpp
+++ b/testsuite/libcore.all/PropertyListTest.cpp
@@ -47,7 +47,7 @@ using namespace std;
 using namespace gnash;
 
 bool
-getVal(PropertyList& p, string_table::key k, as_value& val, as_object& obj)
+getVal(PropertyList& p, const ObjectURI& k, as_value& val, as_object& obj)
 {
     if (Property* prop = p.getProperty(k)) {
         val = prop->getValue(obj);
@@ -96,54 +96,52 @@ main(int /*argc*/, char** /*argv*/)
        as_value val3("value3");
        as_value ret;
 
-       string_table& st = vm.getStringTable();
-
        if (vm.getSWFVersion() > 6) // SWF 7 or higher is case sensitive.
        {
                check_equals(props.size(), 0);
-               check ( props.setValue(st.find("Var0"), val) );
+               check ( props.setValue(getURI(vm, "Var0"), val) );
                check_equals(props.size(), 1);
 
-               check (getVal(props, st.find("Var0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "Var0"), ret, *obj) );
                check_strictly_equals ( ret, val );
 
                // search should be case-sensitive
-               check (!getVal(props, st.find("var0"), ret, *obj) );
+               check (!getVal(props, getURI(vm, "var0"), ret, *obj) );
 
                // new value overrides existing value
-               check ( props.setValue(st.find("Var0"), val2) );
+               check ( props.setValue(getURI(vm, "Var0"), val2) );
                check_equals(props.size(), 1);
-               check (getVal(props, st.find("Var0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "Var0"), ret, *obj) );
                check_strictly_equals ( ret, val2 );
 
                // case-sensitive setting value doesn't overrides existing value
-               check ( props.setValue(st.find("var0"), val3) );
+               check ( props.setValue(getURI(vm, "var0"), val3) );
                check_equals(props.size(), 2);
-               check (!getVal(props, st.find("vAr0"), ret, *obj) );
+               check (!getVal(props, getURI(vm, "vAr0"), ret, *obj) );
 
                // Now add some new labels
-               check ( props.setValue(st.find("var1"), val) );
+               check ( props.setValue(getURI(vm, "var1"), val) );
                check_equals(props.size(), 3);
-               check ( props.setValue(st.find("var2"), val) );
+               check ( props.setValue(getURI(vm, "var2"), val) );
                check_equals(props.size(), 4);
-               check ( props.setValue(st.find("var3"), val) );
+               check ( props.setValue(getURI(vm, "var3"), val) );
                check_equals(props.size(), 5);
 
                // Test deletion of properties
 
                // this succeeds
-               check(props.delProperty(st.find("var3")).second);
+               check(props.delProperty(getURI(vm, "var3")).second);
                check_equals(props.size(), 4);
 
                // this fails (non existent property)
-               check(!props.delProperty(st.find("non-existent")).first);
+               check(!props.delProperty(getURI(vm, "non-existent")).first);
                check_equals(props.size(), 4);
 
                // Set property var2 as protected from deletion!
-               props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
-        check(props.getProperty(st.find("var2")));
+               props.setFlags(getURI(vm, "var2"), PropFlags::dontDelete, 0);
+        check(props.getProperty(getURI(vm, "var2")));
                // this fails (protected from deletion)
-               std::pair<bool, bool> delpair = 
props.delProperty(st.find("var2"));
+               std::pair<bool, bool> delpair = props.delProperty(getURI(vm, 
"var2"));
                check_equals(delpair.first, true); // property was found
                check_equals(delpair.second, false); // property was NOT deleted
                check_equals(props.size(), 4);
@@ -155,51 +153,51 @@ main(int /*argc*/, char** /*argv*/)
                // Below SWF or is not case sensitive.
 
                check_equals(props.size(), 0);
-               check ( props.setValue(st.find("Var0"), val) );
+               check ( props.setValue(getURI(vm, "Var0"), val) );
                check_equals(props.size(), 1);
 
-               check (getVal(props, st.find("Var0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "Var0"), ret, *obj) );
                check_strictly_equals ( ret, val );
 
                // search should be case-insensitive
-               check (getVal(props, st.find("var0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "var0"), ret, *obj) );
                check_strictly_equals ( ret, val );
 
                // new value overrides existing value
-               check ( props.setValue(st.find("Var0"), val2) );
+               check ( props.setValue(getURI(vm, "Var0"), val2) );
                check_equals(props.size(), 1);
-               check (getVal(props, st.find("Var0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "Var0"), ret, *obj) );
                check_strictly_equals ( ret, val2 );
 
                // case-insensitive setting value should override existing value
-               check ( props.setValue(st.find("var0"), val3) );
+               check ( props.setValue(getURI(vm, "var0"), val3) );
                check_equals(props.size(), 1);
-               check (getVal(props, st.find("vAr0"), ret, *obj) );
+               check (getVal(props, getURI(vm, "vAr0"), ret, *obj) );
                check_strictly_equals ( ret, val3 );
 
                // Now add some new labels
-               check ( props.setValue(st.find("var1"), val) );
+               check ( props.setValue(getURI(vm, "var1"), val) );
                check_equals(props.size(), 2);
-               check ( props.setValue(st.find("var2"), val) );
+               check ( props.setValue(getURI(vm, "var2"), val) );
                check_equals(props.size(), 3);
-               check ( props.setValue(st.find("var3"), val) );
+               check ( props.setValue(getURI(vm, "var3"), val) );
                check_equals(props.size(), 4);
 
                // Test deletion of properties
 
                // this succeeds
-               check(props.delProperty(st.find("var3")).second);
+               check(props.delProperty(getURI(vm, "var3")).second);
                check_equals(props.size(), 3);
 
                // this fails (non existent property)
-               check(!props.delProperty(st.find("non-existent")).first);
+               check(!props.delProperty(getURI(vm, "non-existent")).first);
                check_equals(props.size(), 3);
 
                // Set property var2 as protected from deletion!
-               props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
-        check(props.getProperty(st.find("var2")));
+               props.setFlags(getURI(vm, "var2"), PropFlags::dontDelete, 0);
+        check(props.getProperty(getURI(vm, "var2")));
                // this fails (protected from deletion)
-               std::pair<bool, bool> delpair = 
props.delProperty(st.find("var2"));
+               std::pair<bool, bool> delpair = props.delProperty(getURI(vm, 
"var2"));
                check_equals(delpair.first, true); // property was found
                check_equals(delpair.second, false); // property was NOT deleted
                check_equals(props.size(), 3);
diff --git a/testsuite/misc-ming.all/DefineTextTest-Runner.cpp 
b/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
index 686c60d..4ab531d 100644
--- a/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
+++ b/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
@@ -112,10 +112,10 @@ main(int /*argc*/, char** /*argv*/)
 
        for (int i=0; i<3; ++i) tester.advance(); // get to the end
 
-       string_table& st = tester.vm().getStringTable();
+       VM& vm = tester.vm();
 
        as_value eot;
-       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
+       bool endOfTestFound = getObject(root)->get_member(getURI(vm, 
"endoftest"), &eot);
        check(endOfTestFound);
        check(eot.is_bool());
        check(eot.to_bool(8));
diff --git a/testsuite/misc-ming.all/DragDropTestRunner.cpp 
b/testsuite/misc-ming.all/DragDropTestRunner.cpp
index 319f853..7ae1646 100644
--- a/testsuite/misc-ming.all/DragDropTestRunner.cpp
+++ b/testsuite/misc-ming.all/DragDropTestRunner.cpp
@@ -53,7 +53,7 @@ main(int /*argc*/, char** /*argv*/)
        assert(root);
 
        // for variables lookup (consistency checking)
-       string_table& st = getStringTable(*getObject(root));
+       VM& vm = getVM(*getObject(root));
 
        rgba white(255, 255, 255, 255); // background color
        rgba blue(0, 0, 255, 255);      // blue circles fill color
@@ -168,7 +168,7 @@ main(int /*argc*/, char** /*argv*/)
        // Consistency check !!
        as_value eot;
        // It's an swf6, so lowercase 'ENDOFTEST'
-       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
+       bool endOfTestFound = getObject(root)->get_member(getURI(vm, 
"endoftest"), &eot);
        check(endOfTestFound);
        if ( endOfTestFound )
        {
diff --git a/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp 
b/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
index b5056a5..2bb2041 100644
--- a/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
+++ b/testsuite/misc-ming.all/EmbeddedSoundTest-Runner.cpp
@@ -62,7 +62,7 @@ main(int /*argc*/, char** /*argv*/)
         }
     }
     as_value eot;
-    xcheck(getObject(root)->get_member(st.find("finished"), &eot));
+    xcheck(getObject(root)->get_member(getURI(vm, "finished"), &eot));
 
 }
 
diff --git a/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp 
b/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
index 7b7cbe0..b44fdb8 100644
--- a/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
+++ b/testsuite/misc-ming.all/NetStream-SquareTestRunner.cpp
@@ -66,8 +66,9 @@ main(int /*argc*/, char** /*argv*/)
        // When all possible tests are implemented as self-contained, we'll
        // add tests that can't be self-contained.
        //
-       string_table& st = tester.vm().getStringTable();
-       string_table::key k = st.find("startNotified");
+       VM& vm = tester.vm();
+
+       const ObjectURI& k = getURI(vm, "startNotified");
        as_value tmp;
        while (!getObject(root)->get_member(k, &tmp) )
        {
@@ -95,7 +96,7 @@ main(int /*argc*/, char** /*argv*/)
 
        // Consistency check 
        as_value eot;
-       bool endOfTestFound = 
getObject(root)->get_member(st.find("end_of_test"),
+       bool endOfTestFound = getObject(root)->get_member(getURI(vm, 
"end_of_test"),
                &eot);
        check(endOfTestFound);
 
diff --git a/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp 
b/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
index 0025ab2..3d4a971 100644
--- a/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
+++ b/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
@@ -51,7 +51,7 @@ main(int /*argc*/, char** /*argv*/)
        assert(root);
 
        // for variables lookup (consistency checking)
-       string_table& st = getStringTable(*getObject(root));
+       VM& vm = getVM(*getObject(root));
 
        check_equals(root->get_frame_count(), 2);
        check_equals(root->get_current_frame(), 0);
@@ -72,7 +72,7 @@ main(int /*argc*/, char** /*argv*/)
        // Consistency check !!
        as_value eot;
        // It's an swf6, so lowercase 'ENDOFTEST'
-       bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
+       bool endOfTestFound = getObject(root)->get_member(getURI(vm, 
"endoftest"), &eot);
        check(endOfTestFound);
 
        if ( endOfTestFound )
diff --git a/testsuite/misc-ming.all/attachMovieTestRunner.cpp 
b/testsuite/misc-ming.all/attachMovieTestRunner.cpp
index 61386f4..33db5e6 100644
--- a/testsuite/misc-ming.all/attachMovieTestRunner.cpp
+++ b/testsuite/misc-ming.all/attachMovieTestRunner.cpp
@@ -80,26 +80,26 @@ main(int /*argc*/, char** /*argv*/)
        check_pixel(100, 30, 2, rgba(255,255,255,255), 2);
 
        VM& vm = tester.vm();
+       const ObjectURI& mousedown = getURI(vm, "mousedown");
+       const ObjectURI& mouseup = getURI(vm, "mouseup");
 
-       string_table& st = vm.getStringTable();
-
-       getObject(root)->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(mousedown, &tmp);
        check(tmp.is_undefined());
-       getObject(root)->get_member(st.find("mouseup"), &tmp);
+       getObject(root)->get_member(mouseup, &tmp);
        check(tmp.is_undefined());
 
        // Note that we are *not* on an active entity !
        tester.pressMouseButton();
 
-       getObject(root)->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(mousedown, &tmp);
        check_equals(toNumber(tmp, vm), 1);
-       check ( ! getObject(root)->get_member(st.find("mouseup"), &tmp) );
+       check ( ! getObject(root)->get_member(mouseup, &tmp) );
 
        tester.depressMouseButton();
 
-       getObject(root)->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(mousedown, &tmp);
        check_equals(toNumber(tmp, vm), 1);
-       getObject(root)->get_member(st.find("mouseup"), &tmp);
+       getObject(root)->get_member(mouseup, &tmp);
        check_equals(toNumber(tmp, vm), 1);
 
        tester.advance();
@@ -156,7 +156,7 @@ main(int /*argc*/, char** /*argv*/)
        // Note that we are *not* on an active entity !
        tester.pressMouseButton();
 
-       getObject(root)->get_member(st.find("mousedown"), &tmp);
+       getObject(root)->get_member(mousedown, &tmp);
        check_equals(toNumber(tmp, vm), 5);
 
 }
diff --git a/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp 
b/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
index bf813ce..808967d 100644
--- a/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
+++ b/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
@@ -98,9 +98,9 @@ main(int /*argc*/, char** /*argv*/)
        int test = 0;
        while (frame <= totalFrames) {
                as_value testReady;
-               if (getObject(root)->get_member(st.find("testReady"), 
&testReady))
+               if (getObject(root)->get_member(getURI(vm, "testReady"), 
&testReady))
                {
-                       getObject(root)->delProperty(st.find("testReady"));
+                       getObject(root)->delProperty(getURI(vm, "testReady"));
                        
                        // When a test is ready, check the result of the 
previous test.
                        if (testPasses[test]) {
@@ -128,7 +128,7 @@ main(int /*argc*/, char** /*argv*/)
 
     // Consistency checking
     as_value eot;
-    bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
+    bool endOfTestFound = getObject(root)->get_member(getURI(vm, "endoftest"), 
&eot);
     check(endOfTestFound);
 
 }
diff --git a/testsuite/misc-ming.all/intervalTestRunner.cpp 
b/testsuite/misc-ming.all/intervalTestRunner.cpp
index 3d42ea9..d296c2a 100644
--- a/testsuite/misc-ming.all/intervalTestRunner.cpp
+++ b/testsuite/misc-ming.all/intervalTestRunner.cpp
@@ -62,78 +62,81 @@ main(int /*argc*/, char** /*argv*/)
        // Now timers are set and counters initialized
 
        VM& vm = tester.vm();
-       string_table& st = vm.getStringTable();
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       const ObjectURI& thisCounter = getURI(vm, "this_counter");
+       const ObjectURI& thatCounter = getURI(vm, "that_counter");
+       const ObjectURI& pushedArgs = getURI(vm, "pushed_args");
+       const ObjectURI& testCompleted = getURI(vm, "test_completed");
+
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 0);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 0);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 1);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 0);
 
        tester.advanceClock(600); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 2);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 1);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 3);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 1);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 4);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 2);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 4);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 3);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 4);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 4);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("this_counter"), &tmp);
+       getObject(root)->get_member(thisCounter, &tmp);
        check_equals(toNumber(tmp, vm), 5);
-       getObject(root)->get_member(st.find("that_counter"), &tmp);
+       getObject(root)->get_member(thatCounter, &tmp);
        check_equals(toNumber(tmp, vm), 4);
 
-       getObject(root)->get_member(st.find("pushed_args"), &tmp);
+       getObject(root)->get_member(pushedArgs, &tmp);
        as_environment env(vm); // needed for proper to_string()
        check_equals(tmp.to_string(), std::string("8,9,10"));
 
        tester.advanceClock(100); // "sleep" another 100 milliseconds
        tester.advance(); // run expired timers
 
-       getObject(root)->get_member(st.find("test_completed"), &tmp);
+       getObject(root)->get_member(testCompleted, &tmp);
        check_equals(toNumber(tmp, vm), 1);
 
-
 }
 
diff --git a/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp 
b/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
index 63413fe..488a507 100644
--- a/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
+++ b/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
@@ -191,10 +191,10 @@ main(int /*argc*/, char** /*argv*/)
        tester->releaseKey(key::SHIFT);
 
        // Consistency checking
-       string_table& st = getStringTable(*getObject(root));
+       VM& vm = getVM(*getObject(root));
        as_value eot;
        // It's an swf6, so lowercase 'END_OF_TEST'
-       bool endOfTestFound = 
getObject(root)->get_member(st.find("end_of_test"), &eot);
+       bool endOfTestFound = getObject(root)->get_member(getURI(vm, 
"end_of_test"), &eot);
        check(endOfTestFound);
        if ( endOfTestFound )
        {
diff --git a/testsuite/misc-swfc.all/button_test1runner.cpp 
b/testsuite/misc-swfc.all/button_test1runner.cpp
index eb39d2b..d5f1505 100644
--- a/testsuite/misc-swfc.all/button_test1runner.cpp
+++ b/testsuite/misc-swfc.all/button_test1runner.cpp
@@ -28,7 +28,6 @@
 #include "log.h"
 #include "Point2d.h"
 #include "VM.h"
-#include "string_table.h"
 #include "as_value.h"
 
 #include "check.h"
@@ -65,7 +64,6 @@ main(int /*argc*/, char** /*argv*/)
 
        MovieClip* root = tester.getRootMovie();
        VM& vm = getVM(*getObject(root));
-       string_table& st = vm.getStringTable();
 
        check_equals(root->get_frame_count(), 1);
 
@@ -158,7 +156,7 @@ main(int /*argc*/, char** /*argv*/)
 
        as_value eot;
         
-    getObject(root)->get_member(st.find("testcompleted"), &eot);
+    getObject(root)->get_member(getURI(vm, "testcompleted"), &eot);
         
        //cerr << "EOT is " << eot.to_debug_string() << endl;
        check(eot.to_bool(8));
diff --git a/testsuite/movies.all/gravity_embedded-TestRunner.cpp 
b/testsuite/movies.all/gravity_embedded-TestRunner.cpp
index c93dcdf..8bed48a 100644
--- a/testsuite/movies.all/gravity_embedded-TestRunner.cpp
+++ b/testsuite/movies.all/gravity_embedded-TestRunner.cpp
@@ -65,9 +65,8 @@ main(int /*argc*/, char** /*argv*/)
 
        VM& vm = tester.vm();
 
-       string_table& st = vm.getStringTable();
-       string_table::key xscale = st.find("_xscale");
-       string_table::key yscale = st.find("_yscale");
+       const ObjectURI& xscale = getURI(vm, "_xscale");
+       const ObjectURI& yscale = getURI(vm, "_yscale");
        // we need a const_cast as get_member *might* eventually
        // change the DisplayObject (fetching _x shouldn't change it though)
        check(getObject(const_cast<DisplayObject*>(loaded))->get_member(xscale, 
&tmp));

-----------------------------------------------------------------------

Summary of changes:
 libcore/AMFConverter.cpp                           |   14 +--
 libcore/Button.cpp                                 |    9 +-
 libcore/DisplayObject.cpp                          |    9 +-
 libcore/DisplayObject.h                            |    2 +-
 libcore/Function.h                                 |    7 +-
 libcore/MovieClip.cpp                              |   28 +++---
 libcore/ObjectURI.h                                |    6 +-
 libcore/TextField.cpp                              |    7 +-
 libcore/TextField.h                                |    2 +-
 libcore/Timers.cpp                                 |    7 +-
 libcore/Timers.h                                   |    4 +-
 libcore/as_environment.cpp                         |   27 +++---
 libcore/as_object.cpp                              |   40 ++++----
 libcore/as_object.h                                |    2 +-
 libcore/as_value.cpp                               |    8 +-
 libcore/asobj/Array_as.cpp                         |   99 +++++++++++---------
 libcore/asobj/Array_as.h                           |   18 ++--
 libcore/asobj/AsBroadcaster.cpp                    |   22 +++--
 libcore/asobj/Color_as.cpp                         |   24 +++--
 libcore/asobj/ContextMenuItem_as.cpp               |   18 ++--
 libcore/asobj/ContextMenu_as.cpp                   |   44 +++++-----
 libcore/asobj/Date_as.cpp                          |    3 +-
 libcore/asobj/Error_as.cpp                         |    8 +-
 libcore/asobj/Global_as.cpp                        |   23 ++---
 libcore/asobj/LoadVars_as.cpp                      |    4 +-
 libcore/asobj/LoadableObject.cpp                   |    4 +-
 libcore/asobj/LocalConnection_as.cpp               |    4 +-
 libcore/asobj/MovieClipLoader.cpp                  |    8 +-
 libcore/asobj/MovieClip_as.cpp                     |   12 +-
 libcore/asobj/NetConnection_as.cpp                 |   11 +--
 libcore/asobj/NetStream_as.cpp                     |    4 +-
 libcore/asobj/Object.cpp                           |   12 +-
 libcore/asobj/SharedObject_as.cpp                  |   25 +++---
 libcore/asobj/Sound_as.cpp                         |   18 ++--
 libcore/asobj/System_as.cpp                        |    7 +-
 libcore/asobj/TextField_as.cpp                     |    4 +-
 libcore/asobj/XMLNode_as.cpp                       |   10 +-
 libcore/asobj/XML_as.cpp                           |    5 +-
 libcore/asobj/flash/display/display_pkg.cpp        |    6 +-
 .../asobj/flash/external/ExternalInterface_as.cpp  |   47 +++++-----
 libcore/asobj/flash/external/external_pkg.cpp      |    6 +-
 libcore/asobj/flash/filters/BitmapFilter_as.cpp    |    4 +-
 libcore/asobj/flash/filters/filters_pkg.cpp        |   24 +++---
 libcore/asobj/flash/flash_pkg.cpp                  |   16 ++--
 libcore/asobj/flash/geom/ColorTransform_as.cpp     |   20 ++--
 libcore/asobj/flash/geom/Matrix_as.cpp             |    3 +-
 libcore/asobj/flash/geom/Rectangle_as.cpp          |    3 +-
 libcore/asobj/flash/geom/geom_pkg.cpp              |   14 ++--
 libcore/asobj/flash/net/net_pkg.cpp                |    6 +-
 libcore/asobj/flash/text/text_pkg.cpp              |    6 +-
 libcore/movie_root.cpp                             |   44 +++++----
 libcore/vm/ASHandlers.cpp                          |   46 ++++------
 libcore/vm/ActionExec.cpp                          |    3 +-
 libcore/vm/CallStack.cpp                           |    4 +-
 libcore/vm/CallStack.h                             |    5 +-
 libcore/vm/ExecutableCode.h                        |    4 +-
 libcore/vm/VM.h                                    |   30 ++++++
 testsuite/MovieTester.cpp                          |    3 +-
 testsuite/libcore.all/PropertyListTest.cpp         |   64 ++++++-------
 testsuite/misc-ming.all/DefineTextTest-Runner.cpp  |    4 +-
 testsuite/misc-ming.all/DragDropTestRunner.cpp     |    4 +-
 .../misc-ming.all/EmbeddedSoundTest-Runner.cpp     |    2 +-
 .../misc-ming.all/NetStream-SquareTestRunner.cpp   |    7 +-
 .../PrototypeEventListenersTestRunner.cpp          |    4 +-
 testsuite/misc-ming.all/attachMovieTestRunner.cpp  |   18 ++--
 testsuite/misc-ming.all/eventSoundTest1-Runner.cpp |    6 +-
 testsuite/misc-ming.all/intervalTestRunner.cpp     |   43 +++++----
 .../misc-ming.all/loading/loadMovieTestRunner.cpp  |    4 +-
 testsuite/misc-swfc.all/button_test1runner.cpp     |    4 +-
 .../movies.all/gravity_embedded-TestRunner.cpp     |    5 +-
 70 files changed, 523 insertions(+), 495 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

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