[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r12282: Fix the long-standing proper
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r12282: Fix the long-standing property case problem. The string_table is always |
Date: |
Fri, 09 Jul 2010 08:22:44 +0200 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 12282 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2010-07-09 08:22:44 +0200
message:
Fix the long-standing property case problem. The string_table is always
case-sensitive. Properties are looked up differently according to version.
Tests pass in swfdec and actionscript.all.
Drop core code that misused AVM1 facilities, including the PropertyList,
to try and implement AVM2. Disable AVM2 by default.
Gnash will currently fail to compile when AVM2 is enabled. This may be fixed
in later commits.
modified:
configure.ac
libbase/GnashAlgorithm.h
libbase/string_table.cpp
libbase/string_table.h
libcore/Button.cpp
libcore/DisplayList.cpp
libcore/DisplayList.h
libcore/DisplayObject.cpp
libcore/DisplayObject.h
libcore/MovieClip.cpp
libcore/Property.cpp
libcore/Property.h
libcore/PropertyList.cpp
libcore/PropertyList.h
libcore/as_object.cpp
libcore/as_object.h
libcore/asobj/Globals.cpp
libcore/asobj/Globals.h
libcore/asobj/flash/display/MovieClip_as.cpp
libcore/asobj/flash/text/TextField_as.cpp
libcore/movie_root.cpp
libcore/namedStrings.cpp
libcore/namedStrings.h
libcore/vm/ASHandlers.cpp
libcore/vm/ActionExec.cpp
libcore/vm/ActionExec.h
libcore/vm/VM.cpp
testsuite/MovieTester.cpp
testsuite/actionscript.all/case.as
testsuite/libbase.all/string_tableTest.cpp
testsuite/libcore.all/PropertyListTest.cpp
testsuite/swfdec/PASSING
=== modified file 'configure.ac'
--- a/configure.ac 2010-06-22 18:14:10 +0000
+++ b/configure.ac 2010-07-03 10:06:04 +0000
@@ -277,7 +277,7 @@
yes) avm2=yes ;;
no) avm2=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for enable-avm2 option]) ;;
- esac], avm2=yes
+ esac], avm2=no
)
AM_CONDITIONAL(ENABLE_AVM2, [test x"$avm2" = xyes])
if test x$avm2 = xyes; then
=== modified file 'libbase/GnashAlgorithm.h'
--- a/libbase/GnashAlgorithm.h 2010-03-11 01:47:08 +0000
+++ b/libbase/GnashAlgorithm.h 2010-07-05 10:05:40 +0000
@@ -39,6 +39,17 @@
}
};
+/// Retrieve the first element of a container with std::pairs.
+template<typename T>
+struct FirstElement
+{
+ typedef typename T::first_type result_type;
+
+ const result_type& operator()(const T& pair) const {
+ return pair.first;
+ }
+};
+
/// Return a pointer to a type
template<typename T>
struct CreatePointer
@@ -150,6 +161,22 @@
std::for_each(begin, end, boost::bind(op, boost::bind(S(), _1)));
}
+/// Call a functor on the first element of each element in a range.
+//
+/// @tparam T An iterator type satisfying the requirements of a
+/// forward iterator
+/// @tparam U The type of the functor op.
+/// @param begin The start of the range to call op on.
+/// @param end The end of the range to call op on.
+/// @param op The function to call on each second element.
+template<typename T, typename U>
+void
+foreachFirst(T begin, T end, U op)
+{
+ typedef FirstElement<typename std::iterator_traits<T>::value_type> S;
+ std::for_each(begin, end, boost::bind(op, boost::bind(S(), _1)));
+}
+
/// Safely call delete on each element in a range.
//
/// This checks that the type is fully known, but cannot check whether the
=== modified file 'libbase/string_table.cpp'
--- a/libbase/string_table.cpp 2010-01-25 18:52:20 +0000
+++ b/libbase/string_table.cpp 2010-07-05 12:29:23 +0000
@@ -20,103 +20,106 @@
#include "string_table.h"
#include <boost/algorithm/string/case_conv.hpp>
-using namespace gnash;
+namespace gnash {
-const std::string string_table::mEmpty;
+const std::string string_table::_empty;
string_table::key
string_table::find(const std::string& t_f, bool insert_unfound)
{
- std::string t_fcase;
- const std::string *to_find = NULL;
-
- if (mCaseInsensitive)
- {
- t_fcase = t_f;
- boost::to_lower(t_fcase);
- to_find = &t_fcase;
- }
- else
- to_find = &t_f;
-
- // Empty strings all map to 0
- if (to_find->empty()) return 0;
-
- table::nth_index<0>::type::iterator i = mTable.get<0>().find(*to_find);
-
- if (i == mTable.end())
- {
- if (insert_unfound)
- {
- svt theSvt;
-
+ if (t_f.empty()) return 0;
+
+ table::index<StringValue>::type::iterator i =
+ _table.get<StringValue>().find(t_f);
+
+ if (i == _table.get<StringValue>().end()) {
+
+ if (insert_unfound) {
// First we lock.
- boost::mutex::scoped_lock aLock(mLock);
+ boost::mutex::scoped_lock aLock(_lock);
// Then we see if someone else managed to sneak past us.
- i = mTable.get<0>().find(*to_find);
+ i = _table.get<StringValue>().find(t_f);
// If they did, use that value.
- if (i != mTable.end())
- return i->mId;
+ if (i != _table.end()) return i->id;
- // Otherwise, insert it.
- theSvt.mValue = t_f;
- theSvt.mComp = *to_find;
- theSvt.mId = ++mHighestKey;
- mTable.insert(theSvt);
- return theSvt.mId;
+ return already_locked_insert(t_f);
}
- else
- return 0;
+ return 0;
}
- return i->mId;
-}
-
-string_table::key
-string_table::find_dot_pair(string_table::key left, string_table::key right,
- bool insert_unfound)
-{
- if (!right)
- return left;
-
- std::string isit = value(left) + "." + value(right);
- return find(isit, insert_unfound);
+ return i->id;
}
string_table::key
string_table::insert(const std::string& to_insert)
{
- boost::mutex::scoped_lock aLock(mLock);
- svt theSvt(to_insert, ++mHighestKey);
-
- return mTable.insert(theSvt).first->mId;
+ boost::mutex::scoped_lock aLock(_lock);
+ return already_locked_insert(to_insert);
}
void
string_table::insert_group(const svt* l, std::size_t size)
{
- boost::mutex::scoped_lock aLock(mLock);
-
- for (std::size_t i = 0; i < size; ++i)
- {
+ boost::mutex::scoped_lock aLock(_lock);
+ for (std::size_t i = 0; i < size; ++i) {
// Copy to avoid changing the original table.
- svt s = l[i];
- if (mCaseInsensitive) boost::to_lower(s.mComp);
+ const svt s = l[i];
- // The keys don't have to be consecutive, so any time we find a
key
- // that is too big, jump a few keys to avoid rewriting this on
every
+ // The keys don't have to be consecutive, so any time we find a key
+ // that is too big, jump a few keys to avoid rewriting this on every
// item.
- if (s.mId > mHighestKey) mHighestKey = s.mId + 256;
- mTable.insert(s);
- }
-}
-
-string_table::key
-string_table::already_locked_insert(const std::string& to_insert,
boost::mutex&)
-{
- svt theSvt (to_insert, ++mHighestKey);
- if (mCaseInsensitive)
- boost::to_lower(theSvt.mComp);
- return mTable.insert(theSvt).first->mId;
-}
-
+ if (s.id > _highestKey) _highestKey = s.id + 256;
+ _table.insert(s);
+ }
+
+ for (std::size_t i = 0; i < size; ++i) {
+ const svt s = l[i];
+ const std::string& t = boost::to_lower_copy(s.value);
+ if (t != s.value) {
+ _caseTable[s.id] = already_locked_insert(t);
+ }
+ }
+
+}
+
+string_table::key
+string_table::already_locked_insert(const std::string& to_insert)
+{
+ const key ret = _table.insert(svt(to_insert, ++_highestKey)).first->id;
+
+ const std::string lower = boost::to_lower_copy(to_insert);
+
+ // Insert the caseless equivalent if it's not there. We're locked for
+ // the whole of this function, so we can do what we like.
+ if (lower != to_insert) {
+
+ // Find the caseless value in the table
+ table::index<StringValue>::type::iterator it =
+ _table.get<StringValue>().find(lower);
+
+ const key nocase = (it == _table.end()) ?
+ _table.insert(svt(lower, ++_highestKey)).first->id : it->id;
+
+ _caseTable[ret] = nocase;
+
+ }
+
+ return ret;
+}
+
+string_table::key
+string_table::noCase(key a) const
+{
+ std::map<key, key>::const_iterator i = _caseTable.find(a);
+ return i == _caseTable.end() ? a : i->second;
+}
+
+bool
+equal(string_table& st, string_table::key a, string_table::key b,
+ bool caseless)
+{
+ if (a == b) return true;
+ return caseless && (st.noCase(a) == st.noCase(b));
+}
+
+}
=== modified file 'libbase/string_table.h'
--- a/libbase/string_table.h 2010-03-11 01:47:08 +0000
+++ b/libbase/string_table.h 2010-07-05 07:14:31 +0000
@@ -32,10 +32,7 @@
#include <string>
#include "dsodefs.h"
-namespace gnash
-{
-
-class string_table;
+namespace gnash {
// So many strings are duplicated (such as standard property names)
// that a string table could give significant memory savings.
@@ -43,119 +40,131 @@
class DSOEXPORT string_table
{
public:
+
/// A little helper for indexing.
struct svt
{
- std::string mValue;
- std::size_t mId;
- std::string mComp;
-
- svt() : mValue(""), mId(0), mComp("") {/**/}
-
- svt(const std::string &val, std::size_t id) :
- mValue(val), mId(id), mComp(val) {/**/}
+ svt(const std::string& val, std::size_t i)
+ :
+ value(val),
+ id(i)
+ {}
+
+ std::string value;
+ std::size_t id;
};
-
-public:
+
+ /// A tag to identify the key index.
+ struct StringID {};
+
+ /// A tag to identify the string index.
+ struct StringValue {};
+
+ /// The container for indexing the strings
+ //
+ /// This contains two indices with no duplicate values:
+ /// 1. An index of unique, case-sensitive strings.
+ /// 2. An index of unique numeric keys.
typedef boost::multi_index_container<svt,
boost::multi_index::indexed_by<
- boost::multi_index::hashed_non_unique<
- boost::multi_index::member<svt, std::string,
&svt::mComp> >,
- boost::multi_index::hashed_non_unique< // caseless
- boost::multi_index::member<svt, std::size_t,
&svt::mId> >
+
+ boost::multi_index::hashed_unique<
+ boost::multi_index::tag<StringValue>,
+ boost::multi_index::member<svt, std::string,
&svt::value> >,
+
+ boost::multi_index::hashed_unique<
+ boost::multi_index::tag<StringID>,
+ boost::multi_index::member<svt, std::size_t,
&svt::id>
+
+ >
> > table;
typedef std::size_t key;
- /// \brief
- /// Find a string. If insert_unfound is true, the string will
- /// be inserted if the value is not found in the table already.
- /// @param to_find
- /// The string to be found. Case-sensitive comparison using < operator
- ///
- /// @param insert_unfound
- /// If this is set to false, a search is performed, but no update.
- /// By update, any unfound string is added to the table.
- ///
- /// @return
- /// A key which can be used in value or 0 if the string is
- /// not yet in the table and insert_unfound was false.
+ /// Find a key for a string.
+ //
+ /// By default a key will be created for a string that isn't present.
+ //
+ /// @param to_find The string to be found.
+ /// @param insert_unfound If this is set to false, a search is
+ /// performed, but no update.
+ /// @return A key which can be used in value or 0 if the
+ /// string is not yet in the table and
+ /// insert_unfound was false.
key find(const std::string& to_find, bool insert_unfound = true);
- /// \brief
- /// Find a string which is the concatentation of two known strings
- /// with a dot between them. (Used for namespaces.)
- /// Otherwise, just like find.
- key find_dot_pair(key left, key right, bool insert_unfound = true);
-
/// Find a string by its key.
- ///
- /// @return
- /// The string which matches key or "" if an invalid key is given.
+ //
+ /// @param key The key of the string to return.
+ /// @return The string which matches key or "" if an invalid key is
+ /// given.
const std::string& value(key to_find)
{
- if (mTable.empty() || !to_find)
- return mEmpty;
- table::nth_index<1>::type::iterator r =
- mTable.get<1>().find(to_find);
- return (r == mTable.get<1>().end()) ? mEmpty : r->mValue;
+ if (_table.empty() || !to_find) return _empty;
+
+ table::index<StringID>::type::iterator r =
+ _table.get<StringID>().find(to_find);
+ return (r == _table.get<StringID>().end()) ? _empty : r->value;
}
- /// \brief
- /// Force insert a string with auto-assigned id. Does not prevent
- /// duplicate insertions.
- ///
+ /// Insert a string with auto-assigned id.
+ //
/// @return The assigned key
key insert(const std::string& to_insert);
/// Insert a group of strings with their ids preset.
//
- /// This allows
- /// for switches and enums and such, but be careful you don't set two
- /// strings with the same id, as this does not check for such
occurrences.
- ///
- /// @param pList
- /// An array of svt objects, these should be fully constructed,
including
- /// their ids.
- ///
- /// @param size
- /// Number of elements in the svt objects array
- ///
+ /// @param pList An array of svt objects, these should be fully
+ /// constructed, including their ids. If any id is
+ /// duplicated, the insertion will fail.
+ /// @param size Number of elements in the svt objects array
void insert_group(const svt* pList, std::size_t size);
/// Insert a string when you will handle the locking yourself.
//
- /// @param to_insert
- /// String to insert
- ///
- /// @param lock
- /// Use lock_mutex to obtain the correct mutex to use for this -- using
- /// a different mutex will not be thread safe.
- ///
- /// @return The assigned key
- key already_locked_insert(const std::string& to_insert, boost::mutex&
lock);
-
- /// @return A mutex which can be used to lock the string table to
inserts.
- boost::mutex& lock_mutex() { return mLock; }
-
- /// Make the comparisons case-insensitive.
- void set_insensitive() { mCaseInsensitive = true; }
+ /// @param to_insert The string to insert
+ /// @return The assigned key
+ key already_locked_insert(const std::string& to_insert);
/// Construct the empty string_table
- string_table() :
- mTable(),
- mLock(),
- mHighestKey(0),
- mCaseInsensitive(false)
- {/**/}
+ string_table()
+ :
+ _highestKey(0)
+ {}
+
+ /// Return a caseless equivalent of the passed key.
+ //
+ /// @param a The key to find a caseless equivalent for. The key
+ /// may be its own caseless equivalent, in which case the
+ /// same key will be returned.
+ key noCase(key a) const;
private:
- table mTable;
- static const std::string mEmpty; // The empty string, universally.
- boost::mutex mLock;
- std::size_t mHighestKey;
- bool mCaseInsensitive;
+
+ table _table;
+ static const std::string _empty;
+ boost::mutex _lock;
+ std::size_t _highestKey;
+
+ std::map<key, key> _caseTable;
};
-} /* namespace gnash */
-#endif /* GNASH_STRING_TABLE_H */
+/// Check whether two keys are equivalent
+//
+/// This function provides a simple way to check for equivalence either in
+/// a case sensitive or case-insensitive way. It is mainly for convenience, to
+/// reduce conditionals in the code.
+//
+/// If the comparison is case-sensitive, the keys are equivalent if they are
+/// equal.
+//
+/// @param st The string table to use
+/// @param a One key to check
+/// @param b The other key to check
+/// @param caseless Whether to compare in a case-insensitive way.
+/// @return True if the keys are equivalent.
+bool equal(string_table& st, string_table::key a, string_table::key b,
+ bool caseless);
+
+}
+#endif
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2010-06-22 06:03:32 +0000
+++ b/libcore/Button.cpp 2010-07-05 08:32:15 +0000
@@ -226,16 +226,16 @@
namespace {
void addInstanceProperty(Button& b, DisplayObject* d) {
if (!d) return;
- const std::string& name = d->get_name();
- if (name.empty()) return;
+ const string_table::key name = d->get_name();
+ if (!name) return;
getObject(&b)->init_member(name, getObject(d), 0);
}
void removeInstanceProperty(Button& b, DisplayObject* d) {
if (!d) return;
- const std::string& name = d->get_name();
- if (name.empty()) return;
- getObject(&b)->delProperty(getStringTable(*getObject(&b)).find(name));
+ const string_table::key name = d->get_name();
+ if (!name) return;
+ getObject(&b)->delProperty(name);
}
}
=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp 2010-06-25 17:51:25 +0000
+++ b/libcore/DisplayList.cpp 2010-07-05 08:32:15 +0000
@@ -106,43 +106,34 @@
class NameEquals
{
public:
- NameEquals(const std::string& name) : _name(name) {}
-
- bool operator() (const DisplayObject* item) {
- assert (item);
- // TODO: this is necessary because destroy() is called in
- // movie_root, leaving destroyed items on the DisplayList. They
- // shouldn't be found. A better fix would be to stop destroying
- // objects there and add to the invariant that there are never
- // destroyed DisplayObjects in the DisplayList.
- if (item->isDestroyed()) return false;
- return item->get_name() == _name;
- }
-
-private:
- const std::string& _name;
-};
-
-
-class NameEqualsNoCase
-{
-public:
- NameEqualsNoCase(const std::string& name) : _name(name) {}
-
- bool operator() (const DisplayObject* item) {
- assert (item);
- // TODO: this is necessary because destroy() is called in
- // movie_root, leaving destroyed items on the DisplayList. They
- // shouldn't be found. A better fix would be to stop destroying
- // objects there and add to the invariant that there are never
- // destroyed DisplayObjects in the DisplayList.
- if (item->isDestroyed()) return false;
- return _noCaseEquals(item->get_name(), _name);
- }
-
-private:
- const std::string& _name;
- StringNoCaseEqual _noCaseEquals;
+ NameEquals(string_table& st, string_table::key name, bool caseless)
+ :
+ _st(st),
+ _caseless(caseless),
+ _name(caseless ? _st.noCase(name) : name)
+ {}
+
+ bool operator() (const DisplayObject* item) {
+ assert (item);
+
+ // TODO: this is necessary because destroy() is called in
+ // movie_root, leaving destroyed items on the DisplayList. They
+ // shouldn't be found. A better fix would be to stop destroying
+ // objects there and add to the invariant that there are never
+ // destroyed DisplayObjects in the DisplayList.
+ if (item->isDestroyed()) return false;
+
+ const string_table::key itname =
+ _caseless ? _st.noCase(item->get_name()) : item->get_name();
+
+ return itname == _name;
+
+ }
+
+private:
+ string_table& _st;
+ const bool _caseless;
+ const string_table::key _name;
};
} // anonymous namespace
@@ -167,11 +158,11 @@
}
DisplayObject*
-DisplayList::getDisplayObjectAtDepth(int depth)
+DisplayList::getDisplayObjectAtDepth(int depth) const
{
testInvariant();
- for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end();
+ for (const_iterator it = _charsByDepth.begin(), itEnd =
_charsByDepth.end();
it != itEnd; ++it) {
DisplayObject* ch = *it;
@@ -192,14 +183,15 @@
DisplayObject*
-DisplayList::getDisplayObjectByName(const std::string& name)
+DisplayList::getDisplayObjectByName(string_table& st, string_table::key name,
+ bool caseless) const
{
testInvariant();
- const container_type::iterator e = _charsByDepth.end();
+ const container_type::const_iterator e = _charsByDepth.end();
container_type::const_iterator it =
- std::find_if( _charsByDepth.begin(), e, NameEquals(name));
+ std::find_if(_charsByDepth.begin(), e, NameEquals(st, name, caseless));
if (it == e) return 0;
@@ -207,21 +199,6 @@
}
-DisplayObject*
-DisplayList::getDisplayObjectByName_i(const std::string& name)
-{
- testInvariant();
-
- const container_type::iterator e = _charsByDepth.end();
-
- container_type::const_iterator it =
- std::find_if( _charsByDepth.begin(), e, NameEqualsNoCase(name));
-
- if ( it == e ) return NULL;
-
- return *it;
-}
-
void
DisplayList::placeDisplayObject(DisplayObject* ch, int depth)
{
=== modified file 'libcore/DisplayList.h'
--- a/libcore/DisplayList.h 2010-06-25 17:51:25 +0000
+++ b/libcore/DisplayList.h 2010-07-05 08:32:15 +0000
@@ -244,25 +244,11 @@
void omit_display();
/// May return NULL.
- DisplayObject* getDisplayObjectAtDepth(int depth);
-
- const DisplayObject* getDisplayObjectAtDepth(int depth) const {
- return
const_cast<DisplayList*>(this)->getDisplayObjectAtDepth(depth);
- }
-
- /// \brief
- /// May return NULL.
- /// If there are multiples, returns the *first* match only!
- DisplayObject* getDisplayObjectByName(const std::string& name);
-
- const DisplayObject* getDisplayObjectByName(const std::string& name)
const {
- return
const_cast<DisplayList*>(this)->getDisplayObjectByName(name);
- }
-
- /// \brief
- /// May return NULL.
- /// If there are multiples, returns the *first* match only!
- DisplayObject* getDisplayObjectByName_i(const std::string& name);
+ DisplayObject* getDisplayObjectAtDepth(int depth) const;
+
+ /// If there are multiples, returns the *first* match only!
+ DisplayObject* getDisplayObjectByName(string_table& st,
+ string_table::key name, bool caseless) const;
/// \brief
/// Visit each DisplayObject in the list in depth order
=== modified file 'libcore/DisplayObject.cpp'
--- a/libcore/DisplayObject.cpp 2010-06-25 18:21:57 +0000
+++ b/libcore/DisplayObject.cpp 2010-07-05 08:32:15 +0000
@@ -134,14 +134,16 @@
UNUSED(extern_movie);
}
-std::string
+string_table::key
DisplayObject::getNextUnnamedInstanceName()
{
assert(_object);
movie_root& mr = getRoot(*_object);
std::ostringstream ss;
ss << "instance" << mr.nextUnnamedInstance();
- return ss.str();
+
+ string_table& st = getStringTable(*_object);
+ return st.find(ss.str());
}
@@ -189,9 +191,14 @@
as_object* obj = getObject(this);
if (!obj) return 0;
- string_table& st = getStringTable(*obj);
+ string_table& st = stage().getVM().getStringTable();
if (key == st.find("..")) return getObject(get_parent());
- if (key == st.find(".") || key == st.find("this")) return obj;
+ if (key == st.find(".")) return obj;
+
+ // The check is case-insensitive for SWF6 and below.
+ if (equal(st, key, NSV::PROP_THIS, caseless(*obj))) {
+ return obj;
+ }
return 0;
}
@@ -502,10 +509,8 @@
DisplayObject::queueEvent(const event_id& id, int lvl)
{
if (!_object) return;
- assert(_object);
- movie_root& root = getRoot(*_object);
std::auto_ptr<ExecutableCode> event(new QueuedEvent(this, id));
- root.pushAction(event, lvl);
+ stage().pushAction(event, lvl);
}
bool
@@ -611,7 +616,6 @@
}
-/*public*/
std::string
DisplayObject::getTargetPath() const
{
@@ -625,6 +629,8 @@
// Build parents stack
const DisplayObject* topLevel = 0;
const DisplayObject* ch = this;
+
+ string_table& st = getStringTable(*getObject(this));
for (;;)
{
const DisplayObject* parent = ch->get_parent();
@@ -635,14 +641,14 @@
break;
}
- path.push_back(ch->get_name());
+ path.push_back(st.value(ch->get_name()));
ch = parent;
}
assert(topLevel);
if (path.empty()) {
- if (&getRoot(*_object).getRootMovie() == this) return "/";
+ if (&stage().getRootMovie() == this) return "/";
std::stringstream ss;
ss << "_level" << _depth-DisplayObject::staticDepthOffset;
return ss.str();
@@ -650,7 +656,7 @@
// Build the target string from the parents stack
std::string target;
- if (topLevel != &getRoot(*_object).getRootMovie()) {
+ if (topLevel != &stage().getRootMovie()) {
std::stringstream ss;
ss << "_level" <<
topLevel->get_depth() - DisplayObject::staticDepthOffset;
@@ -664,7 +670,6 @@
}
-/*public*/
std::string
DisplayObject::getTarget() const
{
@@ -678,6 +683,7 @@
// Build parents stack
const DisplayObject* ch = this;
+ string_table& st = stage().getVM().getStringTable();
for (;;)
{
const DisplayObject* parent = ch->get_parent();
@@ -703,7 +709,7 @@
break;
}
- path.push_back(ch->get_name());
+ path.push_back(st.value(ch->get_name()));
ch = parent;
}
@@ -947,7 +953,7 @@
const std::string& propname = st.value(key);
// Check _level0.._level9
- movie_root& mr = getRoot(*o);
+ movie_root& mr = getRoot(*getObject(&obj));
unsigned int levelno;
if (isLevelTarget(getSWFVersion(*o), propname, levelno)) {
MovieClip* mo = mr.getLevel(levelno);
@@ -967,10 +973,12 @@
}
}
+ const string_table::key noCaseKey = st.noCase(key);
+
// These properties have normal case-sensitivity.
// They are tested to exist for TextField, MovieClip, and Button
// but do not belong to the inheritance chain.
- switch (key)
+ switch (caseless(*o) ? noCaseKey : key)
{
default:
break;
@@ -987,8 +995,6 @@
}
// These magic properties are case insensitive in all versions!
- const string_table::key noCaseKey =
st.find(boost::to_lower_copy(propname));
-
if (doGet(noCaseKey, obj, val)) return true;
// Check MovieClip such as TextField variables.
@@ -1005,9 +1011,7 @@
{
// These magic properties are case insensitive in all versions!
string_table& st = getStringTable(*getObject(&obj));
- const std::string& propname = st.value(key);
- const string_table::key noCaseKey =
st.find(boost::to_lower_copy(propname));
- return doSet(noCaseKey, obj, val);
+ return doSet(st.noCase(key), obj, val);
}
namespace {
@@ -1368,7 +1372,8 @@
as_value
getNameProperty(DisplayObject& o)
{
- const std::string& name = o.get_name();
+ string_table& st = getStringTable(*getObject(&o));
+ const std::string& name = st.value(o.get_name());
if (getSWFVersion(*getObject(&o)) < 6 && name.empty()) return as_value();
return as_value(name);
}
@@ -1376,7 +1381,8 @@
void
setName(DisplayObject& o, const as_value& val)
{
- o.set_name(val.to_string().c_str());
+ string_table& st = getStringTable(*getObject(&o));
+ o.set_name(st.find(val.to_string().c_str()));
}
void
@@ -1518,6 +1524,10 @@
//
/// Return true if the property is a DisplayObject property, regardless of
/// whether it was successfully set or not.
+//
+/// @param prop The property to search for. Note that all special
+/// properties are lower-case, so for a caseless check
+/// it is sufficient for prop to be caseless.
bool
doSet(string_table::key prop, DisplayObject& o, const as_value& val)
{
=== modified file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h 2010-06-25 18:21:57 +0000
+++ b/libcore/DisplayObject.h 2010-07-05 08:32:15 +0000
@@ -421,12 +421,11 @@
}
/// Set DisplayObject name, initializing the original target member
- void set_name(const std::string& name)
- {
+ void set_name(string_table::key name) {
_name = name;
}
- const std::string& get_name() const { return _name; }
+ string_table::key get_name() const { return _name; }
/// \brief
/// Get our concatenated SWFMatrix (all our ancestor transforms,
@@ -906,7 +905,7 @@
#endif
/// Used to assign a name to unnamed instances
- std::string getNextUnnamedInstanceName();
+ string_table::key getNextUnnamedInstanceName();
enum BlendMode
{
@@ -990,7 +989,7 @@
virtual bool unloadChildren() { return false; }
/// Get the movie_root to which this DisplayObject belongs.
- movie_root& stage() {
+ movie_root& stage() const {
return _stage;
}
@@ -1014,7 +1013,7 @@
void set_event_handlers(const Events& copyfrom);
/// Name of this DisplayObject (if any)
- std::string _name;
+ string_table::key _name;
DisplayObject* _parent;
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2010-06-29 14:41:42 +0000
+++ b/libcore/MovieClip.cpp 2010-07-05 08:38:28 +0000
@@ -559,7 +559,9 @@
NSV::CLASS_MOVIE_CLIP);
MovieClip* newmovieclip = new MovieClip(o, _def.get(), _swf, parent);
- newmovieclip->set_name(newname);
+
+ const string_table::key nn =
getStringTable(*getObject(this)).find(newname);
+ newmovieclip->set_name(nn);
newmovieclip->setDynamic();
@@ -1160,10 +1162,12 @@
Global_as& gl = getGlobal(*getObject(this));
DisplayObject* ch = cdef->createDisplayObject(gl, this);
- if (tag->hasName()) ch->set_name(tag->getName());
+ string_table& st = getStringTable(*getObject(this));
+
+ if (tag->hasName()) ch->set_name(st.find(tag->getName()));
else if (isReferenceable(*ch))
{
- std::string instance_name = getNextUnnamedInstanceName();
+ const string_table::key instance_name = getNextUnnamedInstanceName();
ch->set_name(instance_name);
}
@@ -1241,14 +1245,16 @@
Global_as& gl = getGlobal(*getObject(this));
DisplayObject* ch = cdef->createDisplayObject(gl, this);
+
// TODO: check if we can drop this for REPLACE!
// should we rename the DisplayObject when it's REPLACE tag?
- if(tag->hasName()) {
- ch->set_name(tag->getName());
+ if (tag->hasName()) {
+ string_table& st = getStringTable(*getObject(this));
+ ch->set_name(st.find(tag->getName()));
}
else if (isReferenceable(*ch)) {
- std::string instance_name = getNextUnnamedInstanceName();
+ const string_table::key instance_name = getNextUnnamedInstanceName();
ch->set_name(instance_name);
}
if (tag->hasRatio()) {
@@ -1652,14 +1658,15 @@
MovieClip::getDisplayListObject(string_table::key key)
{
- const std::string& name = getStringTable(*getObject(this)).value(key);
+ as_object* obj = getObject(this);
+ assert(obj);
+
+ string_table& st = getStringTable(*obj);
// Try items on our display list.
- DisplayObject* ch;
- if (getSWFVersion(*getObject(this)) >= 7 ) {
- ch = _displayList.getDisplayObjectByName(name);
- }
- else ch = _displayList.getDisplayObjectByName_i(name);
+ DisplayObject* ch = _displayList.getDisplayObjectByName(st, key,
+ caseless(*obj));
+
if (!ch) return 0;
// Found object.
@@ -1888,8 +1895,8 @@
// Copy own name
// TODO: check empty != none...
- const std::string& name = get_name();
- if( !name.empty() ) extern_movie->set_name(name);
+ const string_table::key name = get_name();
+ if (name) extern_movie->set_name(name);
// Copy own clip depth (TODO: check this)
extern_movie->set_clip_depth(get_clip_depth());
@@ -2069,16 +2076,21 @@
_env(env)
{}
- void operator() (DisplayObject* ch)
- {
+ void operator() (DisplayObject* ch) {
+
+ if (!isReferenceable(*ch)) return;
+
// Don't enumerate unloaded DisplayObjects
if (ch->unloaded()) return;
- const std::string& name = ch->get_name();
+ string_table::key name = ch->get_name();
// Don't enumerate unnamed DisplayObjects
- if (name.empty()) return;
+ if (!name) return;
- _env.push(name);
+ // Referenceable DisplayObject always have an object.
+ assert(getObject(ch));
+ string_table& st = getStringTable(*getObject(ch));
+ _env.push(st.value(name));
}
};
=== modified file 'libcore/Property.cpp'
--- a/libcore/Property.cpp 2010-01-11 06:41:38 +0000
+++ b/libcore/Property.cpp 2010-07-05 15:43:51 +0000
@@ -81,7 +81,7 @@
}
void
-Property::setDelayedValue(as_object& this_ptr, const as_value& value)
+Property::setDelayedValue(as_object& this_ptr, const as_value& value) const
{
GetterSetter* a = boost::get<GetterSetter>(&_bound);
@@ -173,7 +173,7 @@
}
void
-Property::setValue(as_object& this_ptr, const as_value &value)
+Property::setValue(as_object& this_ptr, const as_value &value) const
{
switch (_bound.which())
{
=== modified file 'libcore/Property.h'
--- a/libcore/Property.h 2010-03-11 17:03:04 +0000
+++ b/libcore/Property.h 2010-07-05 15:43:51 +0000
@@ -249,6 +249,12 @@
};
/// An abstract property
+//
+/// A Property is a holder for a value or a getter-setter.
+//
+/// Properties have special const semantics: the value of a Property does
+/// not affect its outward state, so the value of a const Property can be
+/// changed.
class Property
{
public:
@@ -257,8 +263,7 @@
:
_bound(as_value()),
_destructive(false),
- _uri(uri),
- _orderID(0)
+ _uri(uri)
{}
/// Copy constructor
@@ -267,8 +272,7 @@
_flags(p._flags),
_bound(p._bound),
_destructive(p._destructive),
- _uri(p._uri),
- _orderID(p._orderID)
+ _uri(p._uri)
{}
Property(const ObjectURI& uri, const as_value& value,
@@ -277,8 +281,7 @@
_flags(flags),
_bound(value),
_destructive(false),
- _uri(uri),
- _orderID(0)
+ _uri(uri)
{}
Property(const ObjectURI& uri,
@@ -288,8 +291,7 @@
_flags(flags),
_bound(GetterSetter(getter, setter)),
_destructive(destroy),
- _uri(uri),
- _orderID(0)
+ _uri(uri)
{}
Property(const ObjectURI& uri, as_function *getter, as_function *setter,
@@ -298,8 +300,7 @@
_flags(),
_bound(GetterSetter(getter, setter)),
_destructive(destroy),
- _uri(uri),
- _orderID(0)
+ _uri(uri)
{}
Property(const ObjectURI& uri, as_c_function_ptr getter,
@@ -309,8 +310,7 @@
_flags(flags),
_bound(GetterSetter(getter, setter)),
_destructive(destroy),
- _uri(uri),
- _orderID(0)
+ _uri(uri)
{}
/// Set a user-defined setter
@@ -321,7 +321,11 @@
/// accessor to the properties flags
const PropFlags& getFlags() const { return _flags; }
- PropFlags& getFlags() { return _flags; }
+
+ /// Set the flags of the property
+ void setFlags(const PropFlags& flags) const {
+ _flags = flags;
+ }
/// Get value of this property
//
@@ -351,7 +355,6 @@
/// to watch for infinitely recurse on calling the getter
/// or setter; Native getter-setter has no cache,
/// nothing would happen for them.
- ///
void setCache(const as_value& v);
/// Set value of this property
@@ -370,21 +373,7 @@
/// argument of the 'setter' function if this is a Getter/Setter
/// property. @see isGetterSetter().
///
- void setValue(as_object& this_ptr, const as_value &value);
-
- /// Set the order id
- //
- /// NOTE: this field is used by one of the indexes
- /// in the boost::multi_index used by PropertyList,
- /// so changing this value on an instance which was
- /// put in that index might result in corruption of
- /// the index invariant. (at least this is what happens
- /// with standard containers indexed on an element's member).
- ///
- void setOrder(int order) { _orderID = order; }
-
- /// Get the order id
- int getOrder() const { return _orderID; }
+ void setValue(as_object& this_ptr, const as_value &value) const;
/// is this a read-only member ?
bool isReadOnly() const { return _flags.get_read_only(); }
@@ -417,9 +406,12 @@
void setReachable() const;
private:
+
+ /// Get a value from a getter function.
+ as_value getDelayedValue(const as_object& this_ptr) const;
- /// Properties flags
- PropFlags _flags;
+ /// Set a value using a setter function.
+ void setDelayedValue(as_object& this_ptr, const as_value& value) const;
enum Type {
TYPE_EMPTY,
@@ -427,11 +419,13 @@
TYPE_GETTER_SETTER
};
+ /// Properties flags
+ mutable PropFlags _flags;
+
// Store the various types of things that can be held.
typedef boost::variant<boost::blank, as_value, GetterSetter> BoundType;
- // Changing this doesn't change the identity of the property, so it is
- // mutable.
+ /// The value of the property.
mutable BoundType _bound;
// If true, as soon as getValue has been invoked once, the
@@ -442,16 +436,6 @@
// TODO: this should be const, but the assignment operator is still needed
ObjectURI _uri;
- // An ordering number, for access by order
- // (AS3 enumeration and slots, AS2 arrays)
- int _orderID;
-
- /// Get a value from a getter function.
- as_value getDelayedValue(const as_object& this_ptr) const;
-
- /// Set a value using a setter function.
- void setDelayedValue(as_object& this_ptr, const as_value& value);
-
};
} // namespace gnash
=== modified file 'libcore/PropertyList.cpp'
--- a/libcore/PropertyList.cpp 2010-01-25 18:52:20 +0000
+++ b/libcore/PropertyList.cpp 2010-07-09 05:14:26 +0000
@@ -26,6 +26,7 @@
#include "as_value.h" // for enumerateValues
#include "VM.h" // For string_table
#include "string_table.h"
+#include "GnashAlgorithm.h"
#include <utility> // for std::make_pair
#include <boost/bind.hpp>
@@ -41,79 +42,37 @@
namespace {
inline
-PropertyList::container::iterator
-iterator_find(const PropertyList::container &p, const ObjectURI& uri)
-{
- return p.find(uri);
-}
-
-}
-
-typedef PropertyList::container::index<PropertyList::OrderTag>::type::iterator
- order_iterator;
-
-order_iterator
-iterator_find(PropertyList::container &p, int order)
-{
- return p.get<1>().find(order);
-}
-
-const Property*
-PropertyList::getPropertyByOrder(int order)
-{
- order_iterator i = iterator_find(_props, order);
- if (i == _props.get<1>().end()) return 0;
-
- return &(*i);
-}
-
-const Property*
-PropertyList::getOrderAfter(int order)
-{
- order_iterator i = iterator_find(_props, order);
-
- if (i == _props.get<1>().end()) return 0;
-
- do {
- ++i;
- if (i == _props.get<1>().end()) return 0;
- } while (i->getFlags().get_dont_enum());
-
- return &(*i);
-}
-
-bool
-PropertyList::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
-{
- order_iterator found = iterator_find(_props, slotId + 1);
- if (found != _props.get<1>().end()) return false;
-
- Property a(uri, as_value());
- a.setOrder(slotId + 1);
- _props.insert(a);
-
-#ifdef GNASH_DEBUG_PROPERTY
- ObjectURI::Logger l(getStringTable(_owner));
- log_debug("Slot for AS property %s inserted with flags %s", l(uri)
- a.getFlags());
-#endif
-
- return true;
+PropertyList::const_iterator
+iterator_find(const PropertyList::container& p, const ObjectURI& uri, VM& vm)
+{
+
+ const bool caseless = vm.getSWFVersion() < 7;
+
+ if (!caseless) {
+ return p.project<0>(p.get<1>().find(uri));
+ }
+
+ string_table& st = vm.getStringTable();
+ const string_table::key nocase = st.noCase(uri.name);
+ return p.project<0>(p.get<2>().find(nocase));
+}
+
}
bool
PropertyList::setValue(const ObjectURI& uri, const as_value& val,
const PropFlags& flagsIfMissing)
{
- container::iterator found = iterator_find(_props, uri);
+ const_iterator found = iterator_find(_props, uri, getVM(_owner));
+ string_table& st = getStringTable(_owner);
+
if (found == _props.end())
{
// create a new member
Property a(uri, val, flagsIfMissing);
// Non slot properties are negative ordering in insertion order
- a.setOrder(- ++_defaultOrder - 1);
- _props.insert(a);
+ _props.push_back(std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
log_debug("Simple AS property %s inserted with flags %s",
@@ -122,7 +81,7 @@
return true;
}
- const Property& prop = *found;
+ const Property& prop = found->first;
if (prop.isReadOnly() && ! prop.isDestructive())
{
ObjectURI::Logger l(getStringTable(_owner));
@@ -131,61 +90,51 @@
return false;
}
- // Property is const because the container uses its members
- // for indexing. We don't use value (only name and namespace)
- // so this const_cast is safe
- const_cast<Property&>(prop).setValue(_owner, val);
+ prop.setValue(_owner, val);
return true;
}
-bool
+void
PropertyList::setFlags(const ObjectURI& uri, int setFlags, int clearFlags)
{
- container::iterator found = iterator_find(_props, uri);
- if ( found == _props.end() ) return false;
-
- PropFlags oldFlags = found->getFlags();
-
- PropFlags& f = const_cast<PropFlags&>(found->getFlags());
- return f.set_flags(setFlags, clearFlags);
-
-#ifdef GNASH_DEBUG_PROPERTY
- ObjectURI::Logger l(getStringTable(_owner));
- log_debug("Flags of property %s changed from %s to %s",
- l(uri), oldFlags, found->getFlags());
-#endif
+ iterator found = iterator_find(_props, uri, getVM(_owner));
+ if (found == _props.end()) return;
+ PropFlags f = found->first.getFlags();
+ f.set_flags(setFlags, clearFlags);
+ found->first.setFlags(f);
+
}
void
PropertyList::setFlagsAll(int setFlags, int clearFlags)
{
- PropertyList::container::iterator it;
- for (it=_props.begin(); it != _props.end(); ++it) {
- PropFlags& f = const_cast<PropFlags&>(it->getFlags());
- f.set_flags(setFlags, clearFlags);
+ for (const_iterator it = _props.begin(); it != _props.end(); ++it) {
+ PropFlags f = it->first.getFlags();
+ f.set_flags(setFlags, clearFlags);
+ it->first.setFlags(f);
}
}
Property*
PropertyList::getProperty(const ObjectURI& uri) const
{
- container::iterator found = iterator_find(_props, uri);
+ iterator found = iterator_find(_props, uri, getVM(_owner));
if (found == _props.end()) return 0;
- return const_cast<Property*>(&(*found));
+ return const_cast<Property*>(&(found->first));
}
std::pair<bool,bool>
PropertyList::delProperty(const ObjectURI& uri)
{
//GNASH_REPORT_FUNCTION;
- container::iterator found = iterator_find(_props, uri);
+ iterator found = iterator_find(_props, uri, getVM(_owner));
if (found == _props.end()) {
return std::make_pair(false, false);
}
// check if member is protected from deletion
- if (found->getFlags().get_dont_delete()) {
+ if (found->first.getFlags().get_dont_delete()) {
return std::make_pair(true, false);
}
@@ -193,18 +142,15 @@
return std::make_pair(true, true);
}
-
-/// This does not reflect the normal enumeration order. It is sorted
-/// lexicographically by property.
void
PropertyList::dump(std::map<std::string, as_value>& to)
{
ObjectURI::Logger l(getStringTable(_owner));
- for (container::const_iterator i=_props.begin(), ie=_props.end();
+ for (const_iterator i=_props.begin(), ie=_props.end();
i != ie; ++i)
{
- to.insert(std::make_pair(l(i->uri()), i->getValue(_owner)));
+ to.insert(std::make_pair(l(i->first.uri()),
i->first.getValue(_owner)));
}
}
@@ -215,14 +161,12 @@
string_table& st = getStringTable(_owner);
// We should enumerate in order of creation, not lexicographically.
- typedef container::nth_index<1>::type ContainerByOrder;
-
- for (ContainerByOrder::const_reverse_iterator
i=_props.get<1>().rbegin(),
- ie=_props.get<1>().rend(); i != ie; ++i) {
-
- if (i->getFlags().get_dont_enum()) continue;
-
- const ObjectURI& uri = i->uri();
+ for (const_iterator i = _props.begin(),
+ ie = _props.end(); i != ie; ++i) {
+
+ if (i->first.getFlags().get_dont_enum()) continue;
+
+ const ObjectURI& uri = i->first.uri();
if (donelist.insert(uri).second) {
@@ -239,9 +183,9 @@
PropertyList::dump()
{
ObjectURI::Logger l(getStringTable(_owner));
- for (container::const_iterator it=_props.begin(), itEnd=_props.end();
+ for (const_iterator it=_props.begin(), itEnd=_props.end();
it != itEnd; ++it) {
- log_debug(" %s: %s", l(it->uri()), it->getValue(_owner));
+ log_debug(" %s: %s", l(it->first.uri()),
it->first.getValue(_owner));
}
}
@@ -251,16 +195,15 @@
const PropFlags& flagsIfMissing)
{
Property a(uri, &getter, setter, flagsIfMissing);
- a.setOrder(- ++_defaultOrder - 1);
-
- container::iterator found = iterator_find(_props, uri);
+ iterator found = iterator_find(_props, uri, getVM(_owner));
+
+ string_table& st = getStringTable(_owner);
if (found != _props.end())
{
// copy flags from previous member (even if it's a normal
member ?)
- PropFlags& f = a.getFlags();
- f = found->getFlags();
- a.setCache(found->getCache());
- _props.replace(found, a);
+ a.setFlags(found->first.getFlags());
+ a.setCache(found->first.getCache());
+ _props.replace(found, std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
@@ -272,7 +215,7 @@
else
{
a.setCache(cacheVal);
- _props.insert(a);
+ _props.push_back(std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
log_debug("AS GetterSetter %s inserted with flags %s", l(uri),
@@ -288,15 +231,14 @@
as_c_function_ptr setter, const PropFlags& flagsIfMissing)
{
Property a(uri, getter, setter, flagsIfMissing);
- a.setOrder(- ++_defaultOrder - 1);
- container::iterator found = iterator_find(_props, uri);
+ string_table& st = getStringTable(_owner);
+ const_iterator found = iterator_find(_props, uri, getVM(_owner));
if (found != _props.end())
{
// copy flags from previous member (even if it's a normal
member ?)
- PropFlags& f = a.getFlags();
- f = found->getFlags();
- _props.replace(found, a);
+ a.setFlags(found->first.getFlags());
+ _props.replace(found, std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
@@ -307,7 +249,7 @@
}
else
{
- _props.insert(a);
+ _props.push_back(std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
string_table& st = getStringTable(_owner);
log_debug("Native GetterSetter %s in namespace %s inserted with
"
@@ -322,7 +264,7 @@
PropertyList::addDestructiveGetter(const ObjectURI& uri, as_function& getter,
const PropFlags& flagsIfMissing)
{
- container::iterator found = iterator_find(_props, uri);
+ const_iterator found = iterator_find(_props, uri, getVM(_owner));
if (found != _props.end())
{
ObjectURI::Logger l(getStringTable(_owner));
@@ -333,8 +275,9 @@
// destructive getter don't need a setter
Property a(uri, &getter, (as_function*)0, flagsIfMissing, true);
- a.setOrder(- ++_defaultOrder - 1);
- _props.insert(a);
+
+ string_table& st = getStringTable(_owner);
+ _props.push_back(std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
@@ -349,13 +292,13 @@
PropertyList::addDestructiveGetter(const ObjectURI& uri,
as_c_function_ptr getter, const PropFlags& flagsIfMissing)
{
- container::iterator found = iterator_find(_props, uri);
+ iterator found = iterator_find(_props, uri, getVM(_owner));
if (found != _props.end()) return false;
// destructive getter don't need a setter
Property a(uri, getter, (as_c_function_ptr)0, flagsIfMissing, true);
- a.setOrder(- ++_defaultOrder - 1);
- _props.insert(a);
+ string_table& st = getStringTable(_owner);
+ _props.push_back(std::make_pair(a, st.noCase(uri.name)));
#ifdef GNASH_DEBUG_PROPERTY
ObjectURI::Logger l(getStringTable(_owner));
@@ -374,7 +317,7 @@
void
PropertyList::setReachable() const
{
- std::for_each(_props.begin(), _props.end(),
+ foreachFirst(_props.begin(), _props.end(),
boost::mem_fn(&Property::setReachable));
}
=== modified file 'libcore/PropertyList.h'
--- a/libcore/PropertyList.h 2010-06-05 09:29:30 +0000
+++ b/libcore/PropertyList.h 2010-07-09 05:14:26 +0000
@@ -29,6 +29,7 @@
#include <boost/cstdint.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/noncopyable.hpp>
@@ -59,34 +60,36 @@
/// owner.
class PropertyList : boost::noncopyable
{
+
public:
typedef std::set<ObjectURI> PropertyTracker;
-
- /// A tag for identifying an index in the container.
- struct OrderTag {};
-
- /// The actual container
- /// index 0 is the fully indexed name/namespace pairs, which are unique
- /// Because of the way searching works, this index can also be
- /// used to search for the names alone (composite keys are sorted
- /// lexographically, beginning with the first element specified)
- ///
- /// index 1 is an ordered sequence, and it is used for the AS3 style
- /// enumeration (which requires an order number for each property),
- /// for slot access, and for array access.
+ typedef std::pair<Property, string_table::key> value_type;
+
+ struct NameExtractor
+ {
+ typedef const ObjectURI& result_type;
+ const result_type operator()(const value_type& r) const {
+ return r.first.uri();
+ }
+ const result_type operator()(value_type& r) {
+ return r.first.uri();
+ }
+ };
+
+ typedef boost::multi_index::member<value_type, value_type::second_type,
+ &value_type::second> KeyExtractor;
+
typedef boost::multi_index_container<
- Property,
+ value_type,
boost::multi_index::indexed_by<
- boost::multi_index::ordered_unique<
- boost::multi_index::const_mem_fun<Property,const
ObjectURI&,&Property::uri>
- >,
- boost::multi_index::ordered_unique<
- boost::multi_index::tag<OrderTag>,
-
boost::multi_index::const_mem_fun<Property,int,&Property::getOrder>
+ boost::multi_index::sequenced<>,
+ boost::multi_index::ordered_unique<NameExtractor>,
+ boost::multi_index::ordered_non_unique<KeyExtractor>
>
- >
- > container;
+ > container;
+ typedef container::iterator iterator;
+ typedef container::const_iterator const_iterator;
/// Construct the PropertyList
//
@@ -96,7 +99,6 @@
PropertyList(as_object& obj)
:
_props(),
- _defaultOrder(0),
_owner(obj)
{
}
@@ -119,18 +121,15 @@
template <class U, class V>
void visitValues(V& visitor, U cmp = U()) const
{
- typedef container::nth_index<1>::type ContainerByOrder;
-
// The template keyword is not required by the Standard here, but the
// OpenBSD compiler needs it. Use of the template keyword where it is
// not necessary is not an error.
- for (ContainerByOrder::const_reverse_iterator
- it = _props.template get<1>().rbegin(),
- ie = _props.template get<1>().rend(); it != ie; ++it)
+ for (const_iterator it = _props.begin(), ie = _props.end();
+ it != ie; ++it)
{
- if (!cmp(*it)) continue;
- as_value val = it->getValue(_owner);
- if (!visitor.accept(it->uri(), val)) return;
+ if (!cmp(it->first)) continue;
+ as_value val = it->first.getValue(_owner);
+ if (!visitor.accept(it->first.uri(), val)) return;
}
}
@@ -145,14 +144,6 @@
/// Enumerated properties are added to donelist.
void enumerateKeys(as_environment& env, PropertyTracker& donelist) const;
- /// Get the order number just after the passed order number.
- ///
- /// @param order 0 is a special value indicating the first order
- /// should be returned, otherwise, this should be the
- /// result of a previous call to getOrderAfter
- /// @return A value which can be used for ordered access.
- const Property* getOrderAfter(int order);
-
/// Set the value of a property, creating a new one if it doesn't exist.
//
/// If the named property is a getter/setter one it's setter
@@ -174,16 +165,6 @@
bool setValue(const ObjectURI& uri, const as_value& value,
const PropFlags& flagsIfMissing = 0);
- /// Reserves a slot number for a property
- ///
- /// @param slotId
- /// The slot id to use. (Note that getOrder() on this property will return
- /// this slot number + 1 if the assignment was successful.)
- /// @param key Name of the property.
- /// @param nsId The namespace in which the property should be found.
- /// @return true if the slot did not previously exist.
- bool reserveSlot(const ObjectURI& uri, boost::uint16_t slotId);
-
/// Get a property if it exists.
//
/// @param key Name of the property. Search is case-*sensitive*
@@ -194,11 +175,6 @@
Property* getProperty(const ObjectURI& uri)
const;
- /// Get a property, if existing, by order
- //
- /// @param order The ordering id
- const Property* getPropertyByOrder(int order);
-
/// Delete a Property, if existing and not protected from deletion.
//
///
@@ -271,9 +247,7 @@
/// @param key Name of the property. Search is case-*sensitive*
/// @param setTrue The set of flags to set
/// @param setFalse The set of flags to clear
- /// @return true if the value was successfully set, false
- /// otherwise (either not found or protected)
- bool setFlags(const ObjectURI& uri, int setTrue, int setFalse);
+ void setFlags(const ObjectURI& uri, int setTrue, int setFalse);
/// Set the flags of all properties.
//
@@ -310,8 +284,6 @@
container _props;
- boost::uint32_t _defaultOrder;
-
as_object& _owner;
};
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp 2010-05-08 21:33:27 +0000
+++ b/libcore/as_object.cpp 2010-07-09 05:14:26 +0000
@@ -450,23 +450,6 @@
}
-const Property*
-as_object::getByIndex(int index)
-{
- // The low byte is used to contain the depth of the property.
- unsigned char depth = index & 0xFF;
- index /= 256; // Signed
- as_object *obj = this;
- while (depth--)
- {
- obj = obj->get_prototype();
- if (!obj)
- return NULL;
- }
-
- return obj->_members.getPropertyByOrder(index);
-}
-
as_object*
as_object::get_super(string_table::key fname)
{
@@ -489,44 +472,6 @@
return super;
}
-int
-as_object::nextIndex(int index, as_object **owner)
-{
- skip_duplicates:
- unsigned char depth = index & 0xFF;
- unsigned char i = depth;
- index /= 256; // Signed
- as_object *obj = this;
- while (i--)
- {
- obj = obj->get_prototype();
- if (!obj)
- return 0;
- }
-
- const Property *p = obj->_members.getOrderAfter(index);
- if (!p)
- {
- obj = obj->get_prototype();
- if (!obj)
- return 0;
- p = obj->_members.getOrderAfter(0);
- ++depth;
- }
- if (p)
- {
- if (findProperty(p->uri()) != p)
- {
- index = p->getOrder() * 256 | depth;
- goto skip_duplicates; // Faster than recursion.
- }
- if (owner)
- *owner = obj;
- return p->getOrder() * 256 | depth;
- }
- return 0;
-}
-
/*private*/
Property*
as_object::findProperty(const ObjectURI& uri, as_object **owner)
@@ -581,33 +526,6 @@
}
void
-as_object::reserveSlot(const ObjectURI& uri, boost::uint16_t slotId)
-{
- _members.reserveSlot(uri, slotId);
-}
-
-bool
-as_object::get_member_slot(int order, as_value* val){
-
- const Property* prop = _members.getPropertyByOrder(order);
- if (prop) {
- return get_member(prop->uri(), val);
- }
- return false;
-}
-
-
-bool
-as_object::set_member_slot(int order, const as_value& val, bool ifFound)
-{
- const Property* prop = _members.getPropertyByOrder(order);
- if (prop) {
- return set_member(prop->uri(), val, ifFound);
- }
- return false;
-}
-
-void
as_object::executeTriggers(Property* prop, const ObjectURI& uri,
const as_value& val)
{
@@ -757,17 +675,9 @@
}
void
-as_object::init_member(const ObjectURI& uri, const as_value& val, int flags,
- int order)
+as_object::init_member(const ObjectURI& uri, const as_value& val, int flags)
{
- if (order >= 0 && !_members.reserveSlot(uri,
-
static_cast<boost::uint16_t>(order))) {
- log_error(_("Attempt to set a slot for either a slot or a property "
- "which already exists."));
- return;
- }
-
// Set (or create) a SimpleProperty
if (!_members.setValue(uri, val, flags)) {
ObjectURI::Logger l(getStringTable(*this));
@@ -873,10 +783,10 @@
}
-bool
+void
as_object::set_member_flags(const ObjectURI& uri, int setTrue, int setFalse)
{
- return _members.setFlags(uri, setTrue, setFalse);
+ _members.setFlags(uri, setTrue, setFalse);
}
void
@@ -1016,15 +926,7 @@
}
// set_member_flags will take care of case conversion
- if (!set_member_flags(getStringTable(*this).find(prop), set_true,
- set_false) )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Can't set propflags on object "
- "property %s "
- "(either not found or protected)"), prop);
- );
- }
+ set_member_flags(getStringTable(*this).find(prop), set_true,
set_false);
if (next_comma == std::string::npos) {
break;
=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h 2010-03-31 08:08:58 +0000
+++ b/libcore/as_object.h 2010-07-09 05:14:26 +0000
@@ -42,10 +42,6 @@
// Forward declarations
namespace gnash {
- namespace abc {
- class Machine;
- class Class;
- }
class as_function;
class MovieClip;
class DisplayObject;
@@ -301,7 +297,7 @@
/// an unsigned short, this is used as the slotId and
/// can be subsequently found with get_slot
void init_member(const ObjectURI& uri, const as_value& val,
- int flags = DefaultFlags, int slotId = -1);
+ int flags = DefaultFlags);
/// Initialize a getter/setter property by name
//
@@ -566,28 +562,6 @@
/// @return true if the object has the property, false otherwise.
bool hasOwnProperty(const ObjectURI& uri);
- /// Get a property from this object (or a prototype) by ordering index.
- ///
- /// @param index An index returned by nextIndex
- /// @return The property associated with the order index.
- const Property* getByIndex(int index);
-
- /// Get the next index after the one whose index was used as a parameter.
- ///
- /// @param index
- /// 0 is a starter index -- use it to get the first index. Using the
- /// return value in subsequent calls will walk through all enumerable
- /// properties in the list.
- ///
- /// @param owner
- /// If owner is not NULL, it will be set to the exact object to which
- /// the property used for the value of index belongs, if such a property
- /// exists, and left untouched otherwise.
- ///
- /// @return
- /// A value which can be fed to getByIndex, or 0 if there are no more.
- int nextIndex(int index, as_object **owner = NULL);
-
/// Set member flags (probably used by ASSetPropFlags)
//
/// @param name Name of the property. Must be all lowercase
@@ -595,9 +569,7 @@
/// up to SWF6.
/// @param setTrue The set of flags to set
/// @param setFalse The set of flags to clear
- /// @return true on success, false on failure (non-existent or
- /// protected member)
- bool set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
+ void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
/// Cast to a as_function, or return NULL
virtual as_function* to_function() { return 0; }
@@ -767,33 +739,6 @@
_displayObject = d;
}
- /// Get a member value at a given slot.
- //
- /// Note it is quite likely that slots only apply to static properties.
- //
- /// @param order The slot index of the property.
- /// @param val The as_value to store a found variable's value in.
- /// @return true if a member exists at the given slot,
- /// and the member's value is successfully retrieved,
- /// false otherwise.
- bool get_member_slot(int order, as_value* val);
-
- /// Set a member value at a given slot.
- //
- /// Note it is quite likely that slots only apply to static properties.
- //
- /// @param order The slot index of the property.
- /// @param val Value to assign to the named property.
- /// @param ifFound If true, don't create a new member, but only update
- /// an existing one.
- /// @return true if the member exists at the given slot,
- /// false otherwise.
- ///
- /// NOTE: the return doesn't tell if the member exists after
- /// the call, as watch triggers might have deleted it
- /// after setting.
- bool set_member_slot(int order, const as_value& val, bool ifFound = false);
-
protected:
/// Construct an as_object associated with a VM.
@@ -992,6 +937,10 @@
/// Return whether the object is an AS3 object.
bool isAS3(const as_object& o);
+/// Return whether property matching is caseless
+inline bool caseless(const as_object& o) {
+ return getSWFVersion(o) < 7;
+}
} // namespace gnash
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2010-06-22 06:03:51 +0000
+++ b/libcore/asobj/Globals.cpp 2010-07-09 05:14:26 +0000
@@ -135,10 +135,6 @@
const ClassHierarchy::NativeClasses& avm1Classes();
- // These functions are for AVM2 only.
- const ClassHierarchy::NativeClasses& avm2Classes();
- ObjectURI knownClass(string_table::key key);
-
as_value global_trace(const fn_call& fn);
as_value global_isNaN(const fn_call& fn);
as_value global_isfinite(const fn_call& fn);
@@ -388,107 +384,6 @@
}
-#ifdef ENABLE_AVM2
-
-AVM2Global::AVM2Global(abc::Machine& /*machine*/, VM& vm)
- :
- Global_as(vm),
- _classes(this, 0),
- _objectProto(new as_object(*this))
-{
-}
-
-void
-AVM2Global::registerClasses()
-{
-
- const string_table::key NS_GLOBAL(0);
-
- initObjectClass(_objectProto, *this,
- ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL));
-
- function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
- string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL));
- array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL));
-
- init_member("trace", createFunction(global_trace));
- init_member("escape", createFunction(global_escape));
-
- _classes.declareAll(avm2Classes());
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
- _classes.getGlobalNs()->getScript(NSV::CLASS_FUNCTION)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
- _classes.getGlobalNs()->getScript(NSV::CLASS_OBJECT)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
- _classes.getGlobalNs()->getScript(NSV::CLASS_ARRAY)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_STRING);
- _classes.getGlobalNs()->getScript(NSV::CLASS_STRING)->setDeclared();
-
-}
-
-as_object*
-AVM2Global::createObject()
-{
- as_object* obj = new as_object(*this);
- obj->set_prototype(_objectProto);
- return obj;
-}
-
-builtin_function*
-AVM2Global::createFunction(Global_as::ASFunction function)
-{
- builtin_function* f = new builtin_function(*this, function);
- f->init_member(NSV::PROP_CONSTRUCTOR,
- as_function::getFunctionConstructor());
- return f;
-}
-
-as_object*
-AVM2Global::createClass(Global_as::ASFunction ctor, as_object* prototype)
-{
- // TODO: this should attach the function to the prototype as its
- as_object* cl = new builtin_function(*this, ctor);
-
- if (prototype) {
- prototype->init_member(NSV::PROP_CONSTRUCTOR, cl);
- cl->init_member(NSV::PROP_PROTOTYPE, prototype);
- }
- return cl;
-}
-
-as_object*
-AVM2Global::createString(const std::string& s)
-{
- // What AVM2 does for createString is untested, so we do the same
- // as AVM1 for now.
- return constructObject(*this, s, NSV::CLASS_STRING);
-}
-
-as_object*
-AVM2Global::createNumber(double d)
-{
- return constructObject(*this, d, NSV::CLASS_NUMBER);
-}
-
-as_object*
-AVM2Global::createBoolean(bool b)
-{
- return constructObject(*this, b, NSV::CLASS_BOOLEAN);
-}
-
-/// This serves the purpose of hiding the Array_as type from the
-/// implementation, which at least enforces good behaviour from users.
-as_object*
-AVM2Global::createArray()
-{
- as_object* array = new as_object(*this);
- array->setArray();
- array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
- return array;
-}
-
-#endif
-
namespace {
const ClassHierarchy::NativeClasses&
@@ -541,209 +436,6 @@
}
-#ifdef ENABLE_AVM2
-
-const ClassHierarchy::NativeClasses&
-avm2Classes()
-{
-
- typedef ClassHierarchy::NativeClass N;
-
- ObjectURI(*c)(string_table::key) = knownClass;
-
- static const ClassHierarchy::NativeClasses s = boost::assign::list_of
-
- // Global classes
- (N(math_class_init, c(NSV::CLASS_MATH), c(NSV::CLASS_OBJECT), 4))
- (N(boolean_class_init, c(NSV::CLASS_BOOLEAN), c(NSV::CLASS_OBJECT), 5))
- (N(number_class_init, c(NSV::CLASS_NUMBER), c(NSV::CLASS_OBJECT), 5))
- (N(int_class_init, c(NSV::CLASS_INT), c(NSV::CLASS_OBJECT), 5))
- (N(namespace_class_init, c(NSV::CLASS_NAMESPACE),
- c(NSV::CLASS_OBJECT), 5))
- (N(qname_class_init, c(NSV::CLASS_QNAME), c(NSV::CLASS_OBJECT), 5))
- (N(date_class_init, c(NSV::CLASS_DATE), c(NSV::CLASS_OBJECT), 5))
- (N(Error_class_init, c(NSV::CLASS_ERROR), c(NSV::CLASS_OBJECT), 5))
-
- // System classes
- (N(system_class_init, c(NSV::CLASS_SYSTEM), c(NSV::CLASS_OBJECT), 1))
-
- // Display classes
- (N(shape_class_init, c(NSV::CLASS_SHAPE),
- c(NSV::CLASS_DISPLAYOBJECT), 3))
- (N(displayobject_class_init, c(NSV::CLASS_DISPLAYOBJECT),
- c(NSV::CLASS_EVENTDISPATCHER), 3))
- (N(interactiveobject_class_init, c(NSV::CLASS_INTERACTIVEOBJECT),
- c(NSV::CLASS_DISPLAYOBJECT), 3))
- (N(displayobjectcontainer_class_init,
- c(NSV::CLASS_DISPLAYOBJECTCONTAINER),
- c(NSV::CLASS_INTERACTIVEOBJECT), 3))
- (N(sprite_class_init, c(NSV::CLASS_SPRITE),
- c(NSV::CLASS_DISPLAYOBJECTCONTAINER), 3))
- (N(bitmap_class_init, c(NSV::CLASS_BITMAP),
- c(NSV::CLASS_DISPLAYOBJECT), 3))
- (N(movieclip_class_init, c(NSV::CLASS_MOVIE_CLIP),
- c(NSV::CLASS_SPRITE), 3))
- (N(stage_class_init, c(NSV::CLASS_STAGE),
- c(NSV::CLASS_MOVIE_CLIP), 1))
- (N(button_class_init, c(NSV::CLASS_SIMPLE_BUTTON),
- c(NSV::CLASS_INTERACTIVEOBJECT), 5))
-
- // Text classes
- (N(textfield_class_init, c(NSV::CLASS_TEXT_FIELD),
- c(NSV::CLASS_INTERACTIVEOBJECT), 3))
- (N(textformat_class_init, c(NSV::CLASS_TEXT_FORMAT),
- c(NSV::CLASS_OBJECT), 5))
- (N(textsnapshot_class_init, c(NSV::CLASS_TEXT_SNAPSHOT),
- c(NSV::CLASS_OBJECT), 5))
- (N(textfieldautosize_class_init, c(NSV::CLASS_TEXTFIELDAUTOSIZE),
- c(NSV::CLASS_OBJECT), 5))
- (N(font_class_init, c(NSV::CLASS_FONT), c(NSV::CLASS_OBJECT), 5))
- (N(fontstyle_class_init, c(NSV::CLASS_FONTSTYLE),
- c(NSV::CLASS_OBJECT), 5))
- (N(antialiastype_class_init, c(NSV::CLASS_ANTIALIASTYPE),
- c(NSV::CLASS_OBJECT), 5))
- (N(csmsettings_class_init, c(NSV::CLASS_CSMTEXTSETTINGS),
- c(NSV::CLASS_OBJECT), 5))
- (N(gridfittype_class_init, c(NSV::CLASS_GRIDFITTYPE),
- c(NSV::CLASS_OBJECT), 5))
- (N(statictext_class_init, c(NSV::CLASS_STATICTEXT),
- c(NSV::CLASS_OBJECT), 5))
- (N(stylesheet_class_init, c(NSV::CLASS_STYLESHEET),
- c(NSV::CLASS_OBJECT), 5))
-#if 0
- // This one isn't stubbed for some reason.
- (N(textcolor_class_init, c(NSV::CLASS_TEXTCOLOR),
- c(NSV::CLASS_OBJECT), 5))
-#endif
- (N(textcolortype_class_init, c(NSV::CLASS_TEXTCOLORTYPE),
- c(NSV::CLASS_OBJECT), 5))
- (N(textdisplaymode_class_init, c(NSV::CLASS_TEXTDISPLAYMODE),
- c(NSV::CLASS_OBJECT), 5))
- (N(textfieldtype_class_init, c(NSV::CLASS_TEXTFIELDTYPE),
- c(NSV::CLASS_OBJECT), 5))
- (N(textformatalign_class_init, c(NSV::CLASS_TEXTFORMATALIGN),
- c(NSV::CLASS_OBJECT), 5))
- (N(textlinemetrics_class_init, c(NSV::CLASS_TEXTLINEMETRICS),
- c(NSV::CLASS_OBJECT), 5))
- (N(textrenderer_class_init, c(NSV::CLASS_TEXTRENDERER),
- c(NSV::CLASS_OBJECT), 5))
-
- // Media classes
- (N(sound_class_init, c(NSV::CLASS_SOUND), c(NSV::CLASS_OBJECT), 5))
- (N(video_class_init, c(NSV::CLASS_VIDEO),
- c(NSV::CLASS_DISPLAYOBJECT), 6))
- (N(camera_class_init, c(NSV::CLASS_CAMERA), c(NSV::CLASS_OBJECT), 6))
- (N(microphone_class_init, c(NSV::CLASS_MICROPHONE),
- c(NSV::CLASS_OBJECT), 6))
- // Net classes
- (N(xmlsocket_class_init, c(NSV::CLASS_XMLSOCKET),
- c(NSV::CLASS_OBJECT), 5))
- (N(sharedobject_class_init, c(NSV::CLASS_SHARED_OBJECT),
- c(NSV::CLASS_OBJECT), 5))
- (N(localconnection_class_init, c(NSV::CLASS_LOCALCONNECTION),
- c(NSV::CLASS_OBJECT), 6))
- (N(netconnection_class_init, c(NSV::CLASS_NET_CONNECTION),
- c(NSV::CLASS_OBJECT), 6))
- (N(netstream_class_init, c(NSV::CLASS_NET_STREAM),
- c(NSV::CLASS_OBJECT), 6))
- // Error classes
- // XML classes
- (N(xmlnode_class_init, c(NSV::CLASS_XMLNODE),
- c(NSV::CLASS_OBJECT), 5))
- (N(xml_class_init, c(NSV::CLASS_XML_DOCUMENT),
- c(NSV::CLASS_OBJECT), 5))
- // UI classes
- (N(mouse_class_init, c(NSV::CLASS_MOUSE),
- c(NSV::CLASS_OBJECT), 5))
- (N(keyboard_class_init, c(NSV::CLASS_KEYBOARD),
- c(NSV::CLASS_OBJECT), 5))
- (N(contextmenu_class_init, c(NSV::CLASS_CONTEXTMENU),
- c(NSV::CLASS_OBJECT), 7))
- (N(contextmenuitem_class_init, c(NSV::CLASS_CONTEXTMENUITEM),
- c(NSV::CLASS_OBJECT), 5))
- // Accessibility classes
- (N(accessibility_class_init, c(NSV::CLASS_ACCESSIBILITY),
- c(NSV::CLASS_OBJECT), 5))
- // Event classes
- (N(event_class_init, c(NSV::CLASS_EVENT), c(NSV::CLASS_OBJECT), 5))
- (N(eventdispatcher_class_init, c(NSV::CLASS_EVENTDISPATCHER),
- c(NSV::CLASS_OBJECT), 5));
-
- return s;
-
-}
-
-ObjectURI
-knownClass(string_table::key key)
-{
- typedef std::map<string_table::key, string_table::key> KnownClasses;
-
- const string_table::key NS_GLOBAL(0);
-
- static const KnownClasses knownClasses = boost::assign::map_list_of
- (NSV::CLASS_OBJECT, NS_GLOBAL)
- (NSV::CLASS_MATH, NS_GLOBAL)
- (NSV::CLASS_BOOLEAN, NS_GLOBAL)
- (NSV::CLASS_NUMBER, NS_GLOBAL)
- (NSV::CLASS_INT, NS_GLOBAL)
- (NSV::CLASS_NAMESPACE, NS_GLOBAL)
- (NSV::CLASS_QNAME, NS_GLOBAL)
- (NSV::CLASS_DATE, NS_GLOBAL)
- (NSV::CLASS_ERROR, NS_GLOBAL)
- (NSV::CLASS_SYSTEM, NSV::NS_FLASH_SYSTEM)
- (NSV::CLASS_SHAPE, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_DISPLAYOBJECT, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_DISPLAYOBJECTCONTAINER, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_SPRITE, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_BITMAP, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_MOVIE_CLIP, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_STAGE, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_SIMPLE_BUTTON, NSV::NS_FLASH_DISPLAY)
- (NSV::CLASS_TEXT_FIELD, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXT_FORMAT, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXT_SNAPSHOT, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTFIELDAUTOSIZE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_FONT, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_FONTSTYLE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_ANTIALIASTYPE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_CSMTEXTSETTINGS, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_GRIDFITTYPE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_STATICTEXT, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_STYLESHEET, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTCOLORTYPE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTDISPLAYMODE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTFIELDTYPE, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTFORMATALIGN, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTLINEMETRICS, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_TEXTRENDERER, NSV::NS_FLASH_TEXT)
- (NSV::CLASS_SOUND, NSV::NS_FLASH_MEDIA)
- (NSV::CLASS_VIDEO, NSV::NS_FLASH_MEDIA)
- (NSV::CLASS_CAMERA, NSV::NS_FLASH_MEDIA)
- (NSV::CLASS_MICROPHONE, NSV::NS_FLASH_MEDIA)
- (NSV::CLASS_XMLSOCKET, NSV::NS_FLASH_NET)
- (NSV::CLASS_SHARED_OBJECT, NSV::NS_FLASH_NET)
- (NSV::CLASS_LOCALCONNECTION, NSV::NS_FLASH_NET)
- (NSV::CLASS_NET_CONNECTION, NSV::NS_FLASH_NET)
- (NSV::CLASS_NET_STREAM, NSV::NS_FLASH_NET)
- (NSV::CLASS_XMLNODE, NSV::NS_FLASH_XML)
- (NSV::CLASS_XML_DOCUMENT, NSV::NS_FLASH_XML)
- (NSV::CLASS_MOUSE, NSV::NS_FLASH_UI)
- (NSV::CLASS_KEYBOARD, NSV::NS_FLASH_UI)
- (NSV::CLASS_SHAPE, NSV::NS_FLASH_UI)
- (NSV::CLASS_CONTEXTMENU, NSV::NS_FLASH_UI)
- (NSV::CLASS_CONTEXTMENUITEM, NSV::NS_FLASH_UI)
- (NSV::CLASS_ACCESSIBILITY, NSV::NS_FLASH_ACCESSIBILITY)
- (NSV::CLASS_EVENT, NSV::NS_FLASH_EVENTS)
- (NSV::CLASS_EVENTDISPATCHER, NSV::NS_FLASH_EVENTS);
-
- KnownClasses::const_iterator it = knownClasses.find(key);
- assert(it != knownClasses.end());
- return ObjectURI(key, it->second);
-}
-
-#endif
-
as_value
global_trace(const fn_call& fn)
{
=== modified file 'libcore/asobj/Globals.h'
--- a/libcore/asobj/Globals.h 2010-03-31 08:08:58 +0000
+++ b/libcore/asobj/Globals.h 2010-07-09 05:14:26 +0000
@@ -117,69 +117,6 @@
};
-#ifdef ENABLE_AVM2
-
-class AVM2Global : public Global_as
-{
-public:
-
- /// Construct the AVM2 global object.
- //
- /// This takes a VM argument because most access to necessary
- /// resources is still through the VM.
- AVM2Global(abc::Machine& m, VM& vm);
- ~AVM2Global() {}
-
- void registerClasses();
-
- /// Create an ActionScript function
- virtual builtin_function* createFunction(Global_as::ASFunction function);
-
- /// Create an ActionScript class
- //
- /// An AS3 class is generally an object (the prototype) with a constructor.
- virtual as_object* createClass(Global_as::ASFunction ctor,
- as_object* prototype);
-
- virtual as_object* createString(const std::string& s);
-
- virtual as_object* createNumber(double d);
-
- virtual as_object* createBoolean(bool b);
-
- virtual as_object* createObject();
-
- virtual as_object* createArray();
-
- virtual const ClassHierarchy& classHierarchy() const {
- return _classes;
- }
-
- virtual ClassHierarchy& classHierarchy() {
- return _classes;
- }
-
- virtual VM& getVM() const {
- return vm();
- }
-
-protected:
-
- virtual void markReachableResources() const {
- _classes.markReachableResources();
- _objectProto->setReachable();
- markAsObjectReachable();
- }
-
-private:
-
- ClassHierarchy _classes;
- as_object* _objectProto;
-
-};
-
-#endif
-
} // namespace gnash
#endif
=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp 2010-06-10 13:43:34
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp 2010-07-05 08:32:15
+0000
@@ -333,7 +333,8 @@
as_object* o = getObjectWithPrototype(getGlobal(fn),
NSV::CLASS_MOVIE_CLIP);
MovieClip* mc = new MovieClip(o, 0, m, ptr);
- mc->set_name(fn.arg(0).to_string());
+ string_table& st = getStringTable(fn);
+ mc->set_name(st.find(fn.arg(0).to_string()));
mc->setDynamic();
// Unlike other MovieClip methods, the depth argument of an empty movie
clip
@@ -500,7 +501,8 @@
Global_as& gl = getGlobal(fn);
DisplayObject* newch = exported_movie->createDisplayObject(gl, movieclip);
- newch->set_name(newname);
+ string_table& st = getStringTable(fn);
+ newch->set_name(st.find(newname));
newch->setDynamic();
boost::intrusive_ptr<as_object> initObj;
=== modified file 'libcore/asobj/flash/text/TextField_as.cpp'
--- a/libcore/asobj/flash/text/TextField_as.cpp 2010-04-21 22:07:20 +0000
+++ b/libcore/asobj/flash/text/TextField_as.cpp 2010-07-05 08:32:15 +0000
@@ -259,8 +259,10 @@
DisplayObject* tf = new TextField(obj, ptr, bounds);
+ string_table& st = getStringTable(fn);
+
// Give name and mark as dynamic
- tf->set_name(name);
+ tf->set_name(st.find(name));
tf->setDynamic();
// Set _x and _y
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2010-06-18 03:28:37 +0000
+++ b/libcore/movie_root.cpp 2010-07-05 06:57:11 +0000
@@ -556,7 +556,7 @@
if (_scaleMode == SCALEMODE_NOSCALE) {
//log_debug("Rescaling disabled");
- as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+ as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
if (stage) {
log_debug("notifying Stage listeners about a resize");
callMethod(stage, NSV::PROP_BROADCAST_MESSAGE, "onResize");
@@ -1367,7 +1367,7 @@
callInterface("Stage.align");
if (notifyResize) {
- as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+ as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
if (stage) {
log_debug("notifying Stage listeners about a resize");
callMethod(stage, NSV::PROP_BROADCAST_MESSAGE, "onResize");
@@ -1380,7 +1380,7 @@
{
_displayState = ds;
- as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
+ as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
if (stage) {
log_debug("notifying Stage listeners about fullscreen state");
const bool fs = _displayState == DISPLAYSTATE_FULLSCREEN;
=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp 2010-01-25 18:52:20 +0000
+++ b/libcore/namedStrings.cpp 2010-07-05 06:48:13 +0000
@@ -44,7 +44,7 @@
string_table::svt( "c", NSV::PROP_C ),
string_table::svt( "callee", NSV::PROP_CALLEE ),
string_table::svt( "caller", NSV::PROP_CALLER ),
- //string_table::svt( "color", NSV::PROP_COLOR ), // clashes with
CLASS_COLOR in case-insensitive mode
+ string_table::svt( "color", NSV::PROP_COLOR ),
string_table::svt( "concat", NSV::PROP_CONCAT ),
string_table::svt( "constructor", NSV::PROP_CONSTRUCTOR ),
string_table::svt( "__constructor__", NSV::PROP_uuCONSTRUCTORuu ),
@@ -131,7 +131,6 @@
string_table::svt( "size", NSV::PROP_SIZE ),
string_table::svt( "_soundbuftime", NSV::PROP_uSOUNDBUFTIME ),
string_table::svt( "splice", NSV::PROP_SPLICE ),
- string_table::svt( "Stage", NSV::PROP_iSTAGE ),
string_table::svt( "status", NSV::PROP_STATUS ),
string_table::svt( "super", NSV::PROP_SUPER ),
string_table::svt( "target", NSV::PROP_TARGET ),
@@ -140,6 +139,7 @@
string_table::svt( "textColor", NSV::PROP_TEXT_COLOR ),
string_table::svt( "textWidth", NSV::PROP_TEXT_WIDTH ),
string_table::svt( "textHeight", NSV::PROP_TEXT_HEIGHT ),
+ string_table::svt( "this", NSV::PROP_THIS ),
string_table::svt( "toString", NSV::PROP_TO_STRING ),
string_table::svt( "toLowerCase", NSV::PROP_TO_LOWER_CASE ),
string_table::svt( "_totalframes", NSV::PROP_uTOTALFRAMES ),
@@ -174,7 +174,7 @@
string_table::svt( "TextFormatAlign", NSV::CLASS_TEXTFORMATALIGN),
string_table::svt( "TextLineMetrics", NSV::CLASS_TEXTLINEMETRICS),
string_table::svt( "TextRenderer", NSV::CLASS_TEXTRENDERER),
-// string_table::svt( "Stage", NSV::CLASS_STAGE ), // Identical to PROP_iSTAGE
+ string_table::svt( "Stage", NSV::CLASS_STAGE ),
string_table::svt( "MovieClip", NSV::CLASS_MOVIE_CLIP ),
string_table::svt( "TextField", NSV::CLASS_TEXT_FIELD ),
string_table::svt( "Button", NSV::CLASS_BUTTON ),
@@ -247,12 +247,8 @@
};
void
-loadStrings(string_table& table, int version)
+loadStrings(string_table& table)
{
- if (version < 7) {
- table.set_insensitive();
- }
-
table.insert_group(preload_names, arraySize(preload_names));
}
=== modified file 'libcore/namedStrings.h'
--- a/libcore/namedStrings.h 2010-01-01 17:48:26 +0000
+++ b/libcore/namedStrings.h 2010-07-05 06:48:13 +0000
@@ -32,8 +32,6 @@
///
/// Lowercase letters in the enum value signal the format of the string
/// literals associated with these enums.
-/// i: Initial capital for groups which are normally initial lower case.
-/// For example: PROP_iSTAGE is "Stage";
/// u: An underscore
/// For example: PROP_uuPROTOuu is "__proto__"
/// _: The next letter is capitalized
@@ -96,7 +94,6 @@
CLASS_SOUND,
CLASS_SPRITE,
CLASS_STAGE,
- PROP_iSTAGE = CLASS_STAGE,
CLASS_STATICTEXT,
CLASS_STRING,
CLASS_STYLESHEET,
@@ -144,7 +141,7 @@
PROP_C,
PROP_CALLEE,
PROP_CALLER,
- //PROP_COLOR, // clashes with CLASS_COLOR in case-insensitive mode
+ PROP_COLOR,
PROP_CONCAT,
PROP_CONSTRUCTOR,
PROP_CONTENT_TYPE,
@@ -219,6 +216,7 @@
PROP_TEXT_COLOR,
PROP_TEXT_HEIGHT,
PROP_TEXT_WIDTH,
+ PROP_THIS,
PROP_TO_LOWER_CASE,
PROP_TO_STRING,
PROP_TX,
@@ -267,8 +265,7 @@
};
/// Load the prenamed strings.
-/// version controls case
-void loadStrings(string_table &table, int version);
+void loadStrings(string_table &table);
} // namespace NSV
} // namespace gnash
=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2010-06-15 06:40:04 +0000
+++ b/libcore/vm/ASHandlers.cpp 2010-07-07 09:19:47 +0000
@@ -53,6 +53,7 @@
#include "as_value.h"
#include "RunResources.h"
#include "with_stack_entry.h"
+#include "ObjectURI.h"
#include <string>
#include <vector>
@@ -98,7 +99,6 @@
/// @param thread The current execution thread.
void commonSetTarget(ActionExec& thread, const std::string& target_name);
-
enum as_encoding_guess_t {
ENCGUESS_UNICODE = 0,
ENCGUESS_JIS = 1,
@@ -2645,11 +2645,12 @@
as_object* ao = gl.createArray();
+ string_table& st = getStringTable(env);
// Fill the elements with the initial values from the stack.
for (int i = 0; i < array_size; i++) {
- // @@ TODO a set_member that takes an int or as_value?
- thread.setObjectMember(*ao, boost::lexical_cast<std::string>(i),
- env.pop());
+ const string_table::key k =
+ st.find(boost::lexical_cast<std::string>(i));
+ ao->set_member(k, env.pop());
}
env.push(ao);
@@ -2678,12 +2679,13 @@
obj->init_member(NSV::PROP_CONSTRUCTOR, gl.getMember(NSV::CLASS_OBJECT));
+ string_table& st = getStringTable(env);
+
// Set provided members
for (int i = 0; i < nmembers; ++i) {
- as_value member_value = env.top(0);
+ const as_value& member_value = env.top(0);
std::string member_name = env.top(1).to_string();
-
- thread.setObjectMember(*obj, member_name, member_value);
+ obj->set_member(st.find(member_name), member_value);
env.drop(2);
}
@@ -2873,8 +2875,11 @@
target, static_cast<void *>(obj.get()));
);
- if (!thread.getObjectMember(*obj, member_name.to_string(), env.top(1)))
- {
+ string_table& st = getStringTable(env);
+ const string_table::key k = st.find(member_name.to_string());
+
+ if (!obj->get_member(k, &env.top(1))) {
+
IF_VERBOSE_ASCODING_ERRORS(
log_aserror("Reference to undefined member %s of object %s",
member_name,
@@ -2913,7 +2918,8 @@
);
}
else if (obj) {
- thread.setObjectMember(*(obj.get()), member_name, member_value);
+ string_table& st = getStringTable(env);
+ obj->set_member(st.find(member_name), member_value);
IF_VERBOSE_ACTION (
log_action(_("-- set_member %s.%s=%s"),
@@ -3042,11 +3048,7 @@
// The method value
as_value method_value;
- // Alright, not using 'thread' object here is kind of
- // a policy break, but saves a duplicated string_table::find
- // call so for now I'm fine like this ...
- //if (!thread.getObjectMember(*obj, method_string, method_value)) {
- if ( ! obj->get_member(method_key, &method_value) ) {
+ if (!obj->get_member(method_key, &method_value) ) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("ActionCallMethod: "
"Can't find method %s of object %s"),
@@ -3172,7 +3174,9 @@
method_val = obj_val;
}
else {
- if (!thread.getObjectMember(*obj, method_string, method_val)) {
+ string_table& st = getStringTable(env);
+ const string_table::key k = st.find(method_string);
+ if (!obj->get_member(k, &method_val)) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("ActionNewMethod: can't find method %s of "
"object %s"), method_string, obj_val);
@@ -4160,7 +4164,6 @@
return ENCGUESS_OTHER;
}
-
}
=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2010-05-19 07:45:49 +0000
+++ b/libcore/vm/ActionExec.cpp 2010-07-07 09:19:47 +0000
@@ -713,22 +713,6 @@
}
}
-void
-ActionExec::setObjectMember(as_object& obj, const std::string& var,
- const as_value& val)
-{
- string_table& st = getStringTable(env);
- obj.set_member(st.find(var), val);
-}
-
-bool
-ActionExec::getObjectMember(as_object& obj, const std::string& var,
- as_value& val)
-{
- string_table& st = getStringTable(env);
- return obj.get_member(st.find(var), &val);
-}
-
as_object*
ActionExec::getTarget()
{
=== modified file 'libcore/vm/ActionExec.h'
--- a/libcore/vm/ActionExec.h 2010-03-12 03:52:58 +0000
+++ b/libcore/vm/ActionExec.h 2010-07-07 09:19:47 +0000
@@ -369,37 +369,6 @@
///
as_value getVariable(const std::string& name, as_object** target);
- /// Set an object's member.
- //
- /// @param obj
- /// The object we want to set the member of.
- ///
- /// @param name
- /// Name of the variable. Supports slash and dot syntax.
- /// Name is converted to lowercase if SWF version is < 7.
- ///
- /// @param val
- /// The value to assign to the object's member.
- ///
- void setObjectMember(as_object& obj, const std::string& name, const
as_value& val);
-
- /// Get an object's member.
- //
- /// @param obj
- /// The object we want to set the member of.
- ///
- /// @param name
- /// Name of the variable. Supports slash and dot syntax.
- /// Name is converted to lowercase if SWF version is < 7.
- ///
- /// @param val
- /// The as_value to write member value into.
- ///
- /// @returns
- /// True if the member was found, false otherwise.
- ///
- bool getObjectMember(as_object& obj, const std::string& name, as_value&
val);
-
/// Get current target.
//
/// This function returns top 'with' stack entry, if any.
=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2010-01-13 09:10:35 +0000
+++ b/libcore/vm/VM.cpp 2010-07-04 12:57:34 +0000
@@ -66,7 +66,7 @@
_singleton.reset(new VM(version, root, clock));
assert(_singleton.get());
- NSV::loadStrings(_singleton->_stringTable, _singleton->getSWFVersion());
+ NSV::loadStrings(_singleton->_stringTable);
AVM1Global* gl(new AVM1Global(*_singleton));
=== modified file 'testsuite/MovieTester.cpp'
--- a/testsuite/MovieTester.cpp 2010-05-21 01:26:20 +0000
+++ b/testsuite/MovieTester.cpp 2010-07-05 08:32:15 +0000
@@ -316,7 +316,8 @@
const std::string& name)
{
const DisplayList& dlist = mc.getDisplayList();
- return dlist.getDisplayObjectByName(name);
+ string_table& st = getStringTable(*getObject(&mc));
+ return dlist.getDisplayObjectByName(st, st.find(name), false);
}
const DisplayObject*
=== modified file 'testsuite/actionscript.all/case.as'
--- a/testsuite/actionscript.all/case.as 2010-01-01 17:48:26 +0000
+++ b/testsuite/actionscript.all/case.as 2010-07-02 13:33:51 +0000
@@ -209,7 +209,7 @@
propRecorder.sort(); // case sensitive sort
check_equals(propRecorder.length, 2);
#if OUTPUT_VERSION < 7
-xcheck_equals(propRecorder[0], 'A')
+check_equals(propRecorder[0], 'A')
#else
check_equals(propRecorder[0], 'A')
#endif
@@ -224,7 +224,7 @@
propRecorder.sort(); //case sensitive sort
#if OUTPUT_VERSION < 7
check_equals(propRecorder.length, 2);
- xcheck_equals(propRecorder[0], 'A')
+ check_equals(propRecorder[0], 'A')
check_equals(propRecorder[1], 'b')
#else
check_equals(propRecorder.length, 3);
@@ -242,7 +242,7 @@
propRecorder.sort(); //case sensitive sort
#if OUTPUT_VERSION < 7
check_equals(propRecorder.length, 2);
- xcheck_equals(propRecorder[0], 'A')
+ check_equals(propRecorder[0], 'A')
check_equals(propRecorder[1], 'b')
#else
check_equals(propRecorder.length, 4);
@@ -292,8 +292,8 @@
// gnash fails here because 'B' will point to a previously used 'b'
// and 'a' will point to a previously used 'A'
// in the global string_table
- xcheck_equals(propRecorder[0], 'B');
- xcheck_equals(propRecorder[1], 'a');
+ check_equals(propRecorder[0], 'B');
+ check_equals(propRecorder[1], 'a');
#else
// The problem above is a non-issue in SWF7 or higher, as 'b' and
// 'B' will be separate entries in the string_table
=== modified file 'testsuite/libbase.all/string_tableTest.cpp'
--- a/testsuite/libbase.all/string_tableTest.cpp 2010-01-11 06:41:38
+0000
+++ b/testsuite/libbase.all/string_tableTest.cpp 2010-07-05 10:35:12
+0000
@@ -36,19 +36,26 @@
int
main(int /*argc*/, char** /*argv*/)
{
- string_table testTable;
+ string_table st;
LogFile& lgf = LogFile::getDefaultInstance();
lgf.setVerbosity(2);
- testTable.insert("A");
- testTable.insert("B");
- testTable.insert("C");
-
- check_equals(testTable.find("D",false),0);
- check_equals(testTable.find("D"),4);
- check_equals(testTable.find("A",false),1);
- check_equals(testTable.find("B",false),2);
- check_equals(testTable.find("C",false),3);
- check_equals(testTable.find("D",false),4);
+ st.insert("A");
+ st.insert("B");
+ st.insert("C");
+
+ check_equals(st.find("D",false),0);
+ check(st.find("D") > 0);
+ check(st.find("A") > 0);
+ check(st.find("B") > 0);
+ check(st.find("C") > 0);
+
+ const bool nocase = true;
+ check(equal(st, st.find("AbAb"), st.find("abaB"), nocase));
+ check(equal(st, st.find("AbAb"), st.find("ABAB"), nocase));
+ check(!equal(st, st.find("AbAb"), st.find("abaB"), false));
+ check(!equal(st, st.find("AbAb"), st.find("ABAB"), false));
+
+
}
=== modified file 'testsuite/libcore.all/PropertyListTest.cpp'
--- a/testsuite/libcore.all/PropertyListTest.cpp 2010-05-21 01:26:20
+0000
+++ b/testsuite/libcore.all/PropertyListTest.cpp 2010-07-05 15:43:30
+0000
@@ -142,7 +142,8 @@
check_equals(props.size(), 4);
// Set property var2 as protected from deletion!
- check(props.setFlags(st.find("var2"), PropFlags::dontDelete,
0));
+ props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
+ check(props.getProperty(st.find("var2")));
// this fails (protected from deletion)
std::pair<bool, bool> delpair =
props.delProperty(st.find("var2"));
check_equals(delpair.first, true); // property was found
@@ -197,7 +198,8 @@
check_equals(props.size(), 3);
// Set property var2 as protected from deletion!
- check(props.setFlags(st.find("var2"), PropFlags::dontDelete,
0));
+ props.setFlags(st.find("var2"), PropFlags::dontDelete, 0);
+ check(props.getProperty(st.find("var2")));
// this fails (protected from deletion)
std::pair<bool, bool> delpair =
props.delProperty(st.find("var2"));
check_equals(delpair.first, true); // property was found
=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING 2010-06-29 10:22:08 +0000
+++ b/testsuite/swfdec/PASSING 2010-07-02 15:36:43 +0000
@@ -711,6 +711,7 @@
loadobject-sendandload-8.swf:75cc0c0c435987ef63b0abc9a327a2b2
loadvariables-5.swf:a24997be9ca59d8da2216f9527d0279a
loadvars-5.swf:378a93e3fc7821a72f61332dcfa6cbf7
+loadvars-decode-6.swf:9c41bfc273298905ba56dfa0308212b7
loadvars-decode-7.swf:c56b42214f26888edba5d991f711c209
loadvars-decode-8.swf:ed7cb98e1a1ec7f7e6a6730a3d884f9a
loadvars-decode-return-5.swf:7d961f35feb3d46db0725e93c26bb90a
@@ -898,6 +899,7 @@
object-properties-6.swf:c34734222b0c6eef649ab3b92b1b830f
object-properties-7.swf:71ebb1f47408d993409748dae8d32d5e
object-properties-8.swf:992fafbfd6ae4927116892eb205aac0f
+object-resolve-5.swf:5ec01818d35026f5ec889416fbbf8320
object-resolve-propflags-9.swf:db769008cba912cd906834a4722fdb95
object-valueof-5.swf:2520f058ac5a1af3db81ba9b3002e6ab
object-valueof-6.swf:68d80a5ba580357d1dfeb3b515691e7e
@@ -1421,6 +1423,8 @@
text-field-variable-5.swf:20821d0f34ab14b27bbc55f27c70c57f
textformat-init-5.swf:52dec30885359d5bdda450588076eb10
textformat-init-5.swf:d45b857148b96635af7d18855cb067ae
+textformat-properties-5.swf:a879a08351954d91c45d4f67e5ba2edd
+textformat-properties-6.swf:15e2a52688f6b11796dabf9d26061276
textformat-properties-7.swf:390495b699f387f9647c8cf47afa2175
text-snapshot-properties-5.swf:caf502463913e8aa1959715f629b92aa
text-snapshot-properties-6.swf:b17d4634477fa1e2a5a095fba489d3ed
@@ -1501,6 +1505,9 @@
xml-cdata-6.swf:d7559375e07591033d7739671a8c4d42
xml-cdata-7.swf:5e51dafbe7f6af8206041ecabf0016f8
xml-cdata-8.swf:d5537f4fb83eaf49d615eecb89b2ae95
+xml-errors-5.swf:d97d4e6fd3a604ff845c7cbdee144003
+xml-errors-6.swf:147e755000980143b5c145867523da
+xml-errors-6.swf:147e755000980143b5c145867523da51
xml-errors-7.swf:0f90a1e9ae561ecc4c3206bb1e966ca1
xml-errors-8.swf:321a6535952813fadeaef64c99fa467d
xml-escape-6.swf:302349505514bd60239c7019355f6ab8
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r12282: Fix the long-standing property case problem. The string_table is always,
Benjamin Wolsey <=